r201419 - If the headermap maps the filename to a framework include ("Foo.h" -> "Foo/Foo.h"),

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Feb 14 06:58:29 PST 2014


Author: akirtzidis
Date: Fri Feb 14 08:58:28 2014
New Revision: 201419

URL: http://llvm.org/viewvc/llvm-project?rev=201419&view=rev
Log:
If the headermap maps the filename to a framework include ("Foo.h" -> "Foo/Foo.h"),
continue header lookup using the framework include as filename.

This allows us to conveniently treat
  #import "Foo.h"
as an implicit module import if we can resolve "Foo/Foo.h" as such.

rdar://16042979

Added:
    cfe/trunk/test/Preprocessor/headermap-rel/
    cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/
    cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/Headers/
    cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/Headers/Foo.h
    cfe/trunk/test/Preprocessor/headermap-rel/foo.hmap
    cfe/trunk/test/Preprocessor/headermap-rel/headermap-rel.c
Modified:
    cfe/trunk/include/clang/Lex/DirectoryLookup.h
    cfe/trunk/include/clang/Lex/HeaderMap.h
    cfe/trunk/lib/Lex/HeaderMap.cpp
    cfe/trunk/lib/Lex/HeaderSearch.cpp

Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=201419&r1=201418&r2=201419&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Fri Feb 14 08:58:28 2014
@@ -161,11 +161,16 @@ public:
   /// \param [out] InUserSpecifiedSystemFramework If the file is found,
   /// set to true if the file is located in a framework that has been
   /// user-specified to be treated as a system framework.
-  const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
+  ///
+  /// \param [out] MappedName if this is a headermap which maps the filename to
+  /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
+  /// vector and point Filename to it.
+  const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
                               ModuleMap::KnownHeader *SuggestedModule,
-                              bool &InUserSpecifiedSystemFramework) const;
+                              bool &InUserSpecifiedSystemFramework,
+                              SmallVectorImpl<char> &MappedName) const;
 
 private:
   const FileEntry *DoFrameworkLookup(

Modified: cfe/trunk/include/clang/Lex/HeaderMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderMap.h?rev=201419&r1=201418&r2=201419&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderMap.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderMap.h Fri Feb 14 08:58:28 2014
@@ -55,6 +55,11 @@ public:
   /// "../../file.h".
   const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
 
+  /// If the specified relative filename is located in this HeaderMap return
+  /// the filename it is mapped to, otherwise return an empty StringRef.
+  StringRef lookupFilename(StringRef Filename,
+                           SmallVectorImpl<char> &DestPath) const;
+
   /// getFileName - Return the filename of the headermap.
   const char *getFileName() const;
 

Modified: cfe/trunk/lib/Lex/HeaderMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderMap.cpp?rev=201419&r1=201418&r2=201419&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderMap.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderMap.cpp Fri Feb 14 08:58:28 2014
@@ -201,18 +201,29 @@ void HeaderMap::dump() const {
 /// this HeaderMap.  If so, open it and return its FileEntry.
 const FileEntry *HeaderMap::LookupFile(
     StringRef Filename, FileManager &FM) const {
+
+  SmallString<1024> Path;
+  StringRef Dest = lookupFilename(Filename, Path);
+  if (Dest.empty())
+    return 0;
+
+  return FM.getFile(Dest);
+}
+
+StringRef HeaderMap::lookupFilename(StringRef Filename,
+                                    SmallVectorImpl<char> &DestPath) const {
   const HMapHeader &Hdr = getHeader();
   unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
 
   // If the number of buckets is not a power of two, the headermap is corrupt.
   // Don't probe infinitely.
   if (NumBuckets & (NumBuckets-1))
-    return 0;
+    return StringRef();
 
   // Linearly probe the hash table.
   for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
     HMapBucket B = getBucket(Bucket & (NumBuckets-1));
-    if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss.
+    if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss.
 
     // See if the key matches.  If not, probe on.
     if (!Filename.equals_lower(getString(B.Key)))
@@ -220,9 +231,11 @@ const FileEntry *HeaderMap::LookupFile(
 
     // If so, we have a match in the hash table.  Construct the destination
     // path.
-    SmallString<1024> DestPath;
-    DestPath += getString(B.Prefix);
-    DestPath += getString(B.Suffix);
-    return FM.getFile(DestPath.str());
+    StringRef Prefix = getString(B.Prefix);
+    StringRef Suffix = getString(B.Suffix);
+    DestPath.clear();
+    DestPath.append(Prefix.begin(), Prefix.end());
+    DestPath.append(Suffix.begin(), Suffix.end());
+    return StringRef(DestPath.begin(), DestPath.size());
   }
 }

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=201419&r1=201418&r2=201419&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Fri Feb 14 08:58:28 2014
@@ -223,12 +223,13 @@ const char *DirectoryLookup::getName() c
 /// LookupFile - Lookup the specified file in this search path, returning it
 /// if it exists or returning null if not.
 const FileEntry *DirectoryLookup::LookupFile(
-    StringRef Filename,
+    StringRef &Filename,
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
     ModuleMap::KnownHeader *SuggestedModule,
-    bool &InUserSpecifiedSystemFramework) const {
+    bool &InUserSpecifiedSystemFramework,
+    SmallVectorImpl<char> &MappedName) const {
   InUserSpecifiedSystemFramework = false;
 
   SmallString<1024> TmpDir;
@@ -271,8 +272,27 @@ const FileEntry *DirectoryLookup::Lookup
                              SuggestedModule, InUserSpecifiedSystemFramework);
 
   assert(isHeaderMap() && "Unknown directory lookup");
-  const FileEntry * const Result = getHeaderMap()->LookupFile(
-      Filename, HS.getFileMgr());
+  const HeaderMap *HM = getHeaderMap();
+  SmallString<1024> Path;
+  StringRef Dest = HM->lookupFilename(Filename, Path);
+  if (Dest.empty())
+    return 0;
+
+  const FileEntry *Result;
+
+  // Check if the headermap maps the filename to a framework include
+  // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
+  // framework include.
+  if (llvm::sys::path::is_relative(Dest)) {
+    MappedName.clear();
+    MappedName.append(Dest.begin(), Dest.end());
+    Filename = StringRef(MappedName.begin(), MappedName.size());
+    Result = HM->LookupFile(Filename, HS.getFileMgr());
+
+  } else {
+    Result = HS.getFileMgr().getFile(Dest);
+  }
+
   if (Result) {
     if (SearchPath != NULL) {
       StringRef SearchPathRef(getName());
@@ -620,12 +640,15 @@ const FileEntry *HeaderSearch::LookupFil
     CacheLookup.first = i+1;
   }
 
+  SmallString<64> MappedName;
+
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
     bool InUserSpecifiedSystemFramework = false;
     const FileEntry *FE =
       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
-                               SuggestedModule, InUserSpecifiedSystemFramework);
+                               SuggestedModule, InUserSpecifiedSystemFramework,
+                               MappedName);
     if (!FE) continue;
 
     CurDir = &SearchDirs[i];

Added: cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/Headers/Foo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/Headers/Foo.h?rev=201419&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/Headers/Foo.h (added)
+++ cfe/trunk/test/Preprocessor/headermap-rel/Foo.framework/Headers/Foo.h Fri Feb 14 08:58:28 2014
@@ -0,0 +1,2 @@
+
+Foo.h is parsed

Added: cfe/trunk/test/Preprocessor/headermap-rel/foo.hmap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/headermap-rel/foo.hmap?rev=201419&view=auto
==============================================================================
Binary files cfe/trunk/test/Preprocessor/headermap-rel/foo.hmap (added) and cfe/trunk/test/Preprocessor/headermap-rel/foo.hmap Fri Feb 14 08:58:28 2014 differ

Added: cfe/trunk/test/Preprocessor/headermap-rel/headermap-rel.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/headermap-rel/headermap-rel.c?rev=201419&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/headermap-rel/headermap-rel.c (added)
+++ cfe/trunk/test/Preprocessor/headermap-rel/headermap-rel.c Fri Feb 14 08:58:28 2014
@@ -0,0 +1,10 @@
+
+// This uses a headermap with this entry:
+//   Foo.h -> Foo/Foo.h
+
+// RUN: %clang_cc1 -E %s -o %t.i -I %S/foo.hmap -F %S
+// RUN: FileCheck %s -input-file %t.i
+
+// CHECK: Foo.h is parsed
+
+#include "Foo.h"





More information about the cfe-commits mailing list