<rdar://problem/13037793> Allow the names of modules to differ from the name of their...
authorDouglas Gregor <dgregor@apple.com>
Thu, 21 Mar 2013 01:08:50 +0000 (01:08 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 21 Mar 2013 01:08:50 +0000 (01:08 +0000)
llvm-svn: 177621

clang/include/clang/Lex/DirectoryLookup.h
clang/include/clang/Lex/HeaderSearch.h
clang/lib/Lex/HeaderSearch.cpp
clang/test/Modules/Inputs/Modified/B.h
clang/test/Modules/Inputs/Modified/module.map
clang/test/Modules/Inputs/oldname/module.map [new file with mode: 0644]
clang/test/Modules/Inputs/oldname/new_name.h [new file with mode: 0644]
clang/test/Modules/modify-module.m
clang/test/Modules/renamed.m [new file with mode: 0644]

index 0539018..261dfab 100644 (file)
@@ -56,6 +56,10 @@ private:
   
   /// \brief Whether this is a header map used when building a framework.
   unsigned IsIndexHeaderMap : 1;
+
+  /// \brief Whether we've performed an exhaustive search for module maps
+  /// within the subdirectories of this directory.
+  unsigned SearchedAllModuleMaps : 1;
   
 public:
   /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
@@ -64,7 +68,7 @@ public:
                   bool isFramework)
     : DirCharacteristic(DT),
       LookupType(isFramework ? LT_Framework : LT_NormalDir),
-      IsIndexHeaderMap(false) {
+      IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
     u.Dir = dir;
   }
 
@@ -73,7 +77,7 @@ public:
   DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
                   bool isIndexHeaderMap)
     : DirCharacteristic(DT), LookupType(LT_HeaderMap),
-      IsIndexHeaderMap(isIndexHeaderMap) {
+      IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
     u.Map = map;
   }
 
@@ -109,6 +113,16 @@ public:
   /// isHeaderMap - Return true if this is a header map, not a normal directory.
   bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
 
+  /// \brief Determine whether we have already searched this entire
+  /// directory for module maps.
+  bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
+
+  /// \brief Specify whether we have already searched all of the subdirectories
+  /// for module maps.
+  void setSearchedAllModuleMaps(bool SAMM) {
+    SearchedAllModuleMaps = SAMM;
+  }
+
   /// DirCharacteristic - The type of directory this is, one of the DirType enum
   /// values.
   SrcMgr::CharacteristicKind getDirCharacteristic() const {
index a0ce139..8a5a798 100644 (file)
@@ -505,7 +505,11 @@ private:
   Module *loadFrameworkModule(StringRef Name, 
                               const DirectoryEntry *Dir,
                               bool IsSystem);
-  
+
+  /// \brief Load all of the module maps within the immediate subdirectories
+  /// of the given search directory.
+  void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
+
 public:
   /// \brief Retrieve the module map.
   ModuleMap &getModuleMap() { return ModMap; }
index 9e4b682..304bd69 100644 (file)
@@ -181,8 +181,22 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
       if (Module)
         break;
     }
+
+    // If we've already performed the exhaustive search for module maps in this
+    // search directory, don't do it again.
+    if (SearchDirs[Idx].haveSearchedAllModuleMaps())
+      continue;
+
+    // Load all module maps in the immediate subdirectories of this search
+    // directory.
+    loadSubdirectoryModuleMaps(SearchDirs[Idx]);
+
+    // Look again for the module.
+    Module = ModMap.findModule(ModuleName);
+    if (Module)
+      break;
   }
-  
+
   return Module;
 }
 
@@ -1126,13 +1140,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
     
     // Try to load module map files for immediate subdirectories of this search
     // directory.
-    llvm::error_code EC;
-    SmallString<128> DirNative;
-    llvm::sys::path::native(SearchDirs[Idx].getDir()->getName(), DirNative);
-    for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
-         Dir != DirEnd && !EC; Dir.increment(EC)) {
-      loadModuleMapFile(Dir->path());
-    }
+    loadSubdirectoryModuleMaps(SearchDirs[Idx]);
   }
   
   // Populate the list of modules.
@@ -1142,3 +1150,18 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
     Modules.push_back(M->getValue());
   }
 }
+
+void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
+  if (SearchDir.haveSearchedAllModuleMaps())
+    return;
+  
+  llvm::error_code EC;
+  SmallString<128> DirNative;
+  llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
+  for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
+       Dir != DirEnd && !EC; Dir.increment(EC)) {
+    loadModuleMapFile(Dir->path());
+  }
+
+  SearchDir.setSearchedAllModuleMaps(true);
+}
index 50aaebc..27b0d70 100644 (file)
@@ -1,5 +1,5 @@
-module A { header "A.h" }
-module B { 
+module ModA { header "A.h" }
+module ModB { 
   header "B.h" 
   export *
 }
diff --git a/clang/test/Modules/Inputs/oldname/module.map b/clang/test/Modules/Inputs/oldname/module.map
new file mode 100644 (file)
index 0000000..5812f86
--- /dev/null
@@ -0,0 +1,4 @@
+module NewName {
+  header "new_name.h"
+  export *
+}
diff --git a/clang/test/Modules/Inputs/oldname/new_name.h b/clang/test/Modules/Inputs/oldname/new_name.h
new file mode 100644 (file)
index 0000000..8bf2f1c
--- /dev/null
@@ -0,0 +1 @@
+int same_api;
index decd07d..953c917 100644 (file)
@@ -11,9 +11,9 @@
 // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
 // RUN: echo 'int getA(); int getA2();' > %t/include/A.h
 // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
-// RUN: rm %t/cache/A.pcm
+// RUN: rm %t/cache/ModA.pcm
 // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
-// RUN: touch %t/cache/A.pcm
+// RUN: touch %t/cache/ModA.pcm
 // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -I %t/include %s -verify
 
 // expected-no-diagnostics
@@ -21,7 +21,7 @@
 // FIXME: It is intended to suppress this on win32.
 // REQUIRES: ansi-escape-sequences
 
-@import B;
+@import ModB;
 
 int getValue() { return getA() + getB(); }
 
diff --git a/clang/test/Modules/renamed.m b/clang/test/Modules/renamed.m
new file mode 100644 (file)
index 0000000..4e8f532
--- /dev/null
@@ -0,0 +1,8 @@
+@import NewName;
+
+int f() { return same_api; }
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -I %S/Inputs -fmodules-cache-path=%t %s -verify
+
+// expected-no-diagnostics