]> granicus.if.org Git - clang/commitdiff
[HeaderSearch] Fix issue where if a headermap entry maps the filename to a framework...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 11 Mar 2014 06:21:28 +0000 (06:21 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 11 Mar 2014 06:21:28 +0000 (06:21 +0000)
then we fail to find it if it is re-included later on.

rdar://16285490

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203542 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/DirectoryLookup.h
include/clang/Lex/HeaderSearch.h
lib/Lex/HeaderSearch.cpp
test/Preprocessor/headermap-rel.c

index 89939c84cacfd69bbeff98f4ee861f4cdd16f2df..16899a074b6c98b3f8c8bc0a70d713c626968cb8 100644 (file)
@@ -170,6 +170,7 @@ public:
                               SmallVectorImpl<char> *RelativePath,
                               ModuleMap::KnownHeader *SuggestedModule,
                               bool &InUserSpecifiedSystemFramework,
+                              bool &HasBeenMapped,
                               SmallVectorImpl<char> &MappedName) const;
 
 private:
index 796ea3fec16811c382f22e9ff062394354149a1d..d1cb8118c0c3d67a82bfd1202831ad3c1cb65a6b 100644 (file)
@@ -186,15 +186,19 @@ class HeaderSearch {
   /// included, indexed by the FileEntry's UID.
   std::vector<HeaderFileInfo> FileInfo;
 
-  /// \brief Keeps track of each lookup performed by LookupFile.
-  ///
-  /// The first part of the value is the starting index in SearchDirs
-  /// that the cached search was performed from.  If there is a hit and
-  /// this value doesn't match the current query, the cache has to be
-  /// ignored.  The second value is the entry in SearchDirs that satisfied
-  /// the query.
-  llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
-    LookupFileCache;
+  /// Keeps track of each lookup performed by LookupFile.
+  struct LookupFileCacheInfo {
+    /// Starting index in SearchDirs that the cached search was performed from.
+    /// If there is a hit and this value doesn't match the current query, the
+    /// cache has to be ignored.
+    unsigned StartIdx = 0;
+    /// The entry in SearchDirs that satisfied the query.
+    unsigned HitIdx = 0;
+    /// This is non-null if the original filename was mapped to a framework
+    /// include via a headermap.
+    const char *MappedName = nullptr;
+  };
+  llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
 
   /// \brief Collection mapping a framework or subframework
   /// name like "Carbon" to the Carbon.framework directory.
index 3c5eb0ead8ce12e1a9cf0ea50933e05c7dc33d9e..97bff4f27739bff13ef8250544e882ce76f3e10d 100644 (file)
@@ -255,8 +255,10 @@ const FileEntry *DirectoryLookup::LookupFile(
     SmallVectorImpl<char> *RelativePath,
     ModuleMap::KnownHeader *SuggestedModule,
     bool &InUserSpecifiedSystemFramework,
+    bool &HasBeenMapped,
     SmallVectorImpl<char> &MappedName) const {
   InUserSpecifiedSystemFramework = false;
+  HasBeenMapped = false;
 
   SmallString<1024> TmpDir;
   if (isNormalDir()) {
@@ -298,6 +300,7 @@ const FileEntry *DirectoryLookup::LookupFile(
     MappedName.clear();
     MappedName.append(Dest.begin(), Dest.end());
     Filename = StringRef(MappedName.begin(), MappedName.size());
+    HasBeenMapped = true;
     Result = HM->LookupFile(Filename, HS.getFileMgr());
 
   } else {
@@ -533,6 +536,14 @@ static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
   return false;
 }
 
+static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
+  assert(!Str.empty());
+  char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
+  std::copy(Str.begin(), Str.end(), CopyStr);
+  CopyStr[Str.size()] = '\0';
+  return CopyStr;
+}
+
 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
 /// return null on failure.  isAngled indicates whether the file reference is
 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
@@ -673,20 +684,22 @@ const FileEntry *HeaderSearch::LookupFile(
   // multiply included, and the "pragma once" optimization prevents them from
   // being relex/pp'd, but they would still have to search through a
   // (potentially huge) series of SearchDirs to find it.
-  std::pair<unsigned, unsigned> &CacheLookup =
+  LookupFileCacheInfo &CacheLookup =
     LookupFileCache.GetOrCreateValue(Filename).getValue();
 
   // If the entry has been previously looked up, the first value will be
   // non-zero.  If the value is equal to i (the start point of our search), then
   // this is a matching hit.
-  if (!SkipCache && CacheLookup.first == i+1) {
+  if (!SkipCache && CacheLookup.StartIdx == i+1) {
     // Skip querying potentially lots of directories for this lookup.
-    i = CacheLookup.second;
+    i = CacheLookup.HitIdx;
+    if (CacheLookup.MappedName)
+      Filename = CacheLookup.MappedName;
   } else {
     // Otherwise, this is the first query, or the previous query didn't match
     // our search start.  We will fill in our found location below, so prime the
     // start point value.
-    CacheLookup.first = i+1;
+    CacheLookup.StartIdx = i+1;
   }
 
   SmallString<64> MappedName;
@@ -694,10 +707,15 @@ const FileEntry *HeaderSearch::LookupFile(
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
     bool InUserSpecifiedSystemFramework = false;
+    bool HasBeenMapped = false;
     const FileEntry *FE =
       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
                                SuggestedModule, InUserSpecifiedSystemFramework,
-                               MappedName);
+                               HasBeenMapped, MappedName);
+    if (HasBeenMapped) {
+      CacheLookup.MappedName =
+          copyString(Filename, LookupFileCache.getAllocator());
+    }
     if (!FE) continue;
 
     CurDir = &SearchDirs[i];
@@ -740,7 +758,7 @@ const FileEntry *HeaderSearch::LookupFile(
     }
 
     // Remember this location for the next lookup we do.
-    CacheLookup.second = i;
+    CacheLookup.HitIdx = i;
     return FE;
   }
 
@@ -767,10 +785,10 @@ const FileEntry *HeaderSearch::LookupFile(
         return MSFE;
       }
 
-      std::pair<unsigned, unsigned> &CacheLookup 
+      LookupFileCacheInfo &CacheLookup 
         = LookupFileCache.GetOrCreateValue(Filename).getValue();
-      CacheLookup.second
-        = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second;
+      CacheLookup.HitIdx
+        = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().HitIdx;
       // FIXME: SuggestedModule.
       return FE;
     }
@@ -783,7 +801,7 @@ const FileEntry *HeaderSearch::LookupFile(
   }
 
   // Otherwise, didn't find it. Remember we didn't find this.
-  CacheLookup.second = SearchDirs.size();
+  CacheLookup.HitIdx = SearchDirs.size();
   return 0;
 }
 
index a3b11218d57628f90239689f2bbdcb7a7cf2788b..38500a70f69717790727b90ff717a16c93c18310 100644 (file)
@@ -5,6 +5,8 @@
 // RUN: %clang_cc1 -E %s -o %t.i -I %S/Inputs/headermap-rel/foo.hmap -F %S/Inputs/headermap-rel
 // RUN: FileCheck %s -input-file %t.i
 
+// CHECK: Foo.h is parsed
 // CHECK: Foo.h is parsed
 
 #include "Foo.h"
+#include "Foo.h"