]> granicus.if.org Git - clang/commitdiff
Keep track of import dependencies between submodules within the module
authorDouglas Gregor <dgregor@apple.com>
Thu, 8 Dec 2011 17:01:29 +0000 (17:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 8 Dec 2011 17:01:29 +0000 (17:01 +0000)
that's currently being built. This is important for supporting
transitive dependencies ("export *" in the module map) completely.

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

include/clang/Lex/DirectoryLookup.h
include/clang/Lex/HeaderSearch.h
lib/Frontend/CompilerInstance.cpp
lib/Lex/HeaderSearch.cpp
lib/Lex/PPDirectives.cpp
test/Modules/Inputs/Module.framework/Headers/Sub.h
test/Modules/Inputs/Module.framework/Headers/Sub2.h [new file with mode: 0644]
test/Modules/submodules.m [new file with mode: 0644]

index 47fb7d28e458a0d49d0d2fecb4ec70ffd09892e2..148f599cc3acd1f1a12466945c55f5bd139892d1 100644 (file)
@@ -142,15 +142,12 @@ public:
   /// SearchPath at which the file was found. This only differs from the
   /// Filename for framework includes.
   ///
-  /// \param BuildingModule The name of the module we're currently building.
-  ///
   /// \param SuggestedModule If non-null, and the file found is semantically
   /// part of a known module, this will be set to the module that should
   /// be imported instead of preprocessing/parsing the file found.
   const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
-                              StringRef BuildingModule,
                               Module **SuggestedModule) const;
 
 private:
@@ -158,7 +155,6 @@ private:
       StringRef Filename, HeaderSearch &HS,
       SmallVectorImpl<char> *SearchPath,
       SmallVectorImpl<char> *RelativePath,
-      StringRef BuildingModule,
       Module **SuggestedModule) const;
 
 };
index fba3606f440ed579c64c9adbe6b9698f943cbce3..02f8c0212085b4b2f129a2200aaacf678d3985db 100644 (file)
@@ -135,9 +135,6 @@ class HeaderSearch {
   /// \brief The path to the module cache.
   std::string ModuleCachePath;
   
-  /// \brief The name of the module we're building.
-  std::string BuildingModule;
-  
   /// FileInfo - This contains all of the preprocessor-specific data about files
   /// that are included.  The vector is indexed by the FileEntry's UID.
   ///
@@ -216,11 +213,9 @@ public:
     SystemDirIdx++;
   }
 
-  /// \brief Set the path to the module cache and the name of the module
-  /// we're building
-  void configureModules(StringRef CachePath, StringRef BuildingModule) {
+  /// \brief Set the path to the module cache.
+  void setModuleCachePath(StringRef CachePath) {
     ModuleCachePath = CachePath;
-    this->BuildingModule = BuildingModule;
   }
   
   /// \brief Retrieve the path to the module cache.
index 4463fa7f2c13b6c2e1b86cbbabea610c18bf8f25..84df382e27335ddb12933da7642683732de1b673 100644 (file)
@@ -278,8 +278,7 @@ void CompilerInstance::createPreprocessor() {
   if (!getHeaderSearchOpts().DisableModuleHash)
     llvm::sys::path::append(SpecificModuleCache,
                             getInvocation().getModuleHash());
-  PP->getHeaderSearchInfo().configureModules(SpecificModuleCache,
-                                             getLangOpts().CurrentModule);
+  PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
 
   // Handle generating dependencies, if requested.
   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
@@ -1105,7 +1104,14 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
   // If we don't already have information on this module, load the module now.
   llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
     = KnownModules.find(Path[0].first);
-  if (Known == KnownModules.end()) {  
+  if (Known != KnownModules.end()) {
+    // Retrieve the cached top-level module.
+    Module = Known->second;    
+  } else if (ModuleName == getLangOpts().CurrentModule) {
+    // This is the module we're building. 
+    Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName);
+    Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
+  } else {
     // Search for a module with the given name.
     std::string ModuleFileName;
     ModuleFile
@@ -1204,9 +1210,6 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
     
     // Cache the result of this top-level module lookup for later.
     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
-  } else {
-    // Retrieve the cached top-level module.
-    Module = Known->second;
   }
   
   // If we never found the module, fail.
@@ -1265,8 +1268,10 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
     }
   }
   
-  // Make the named module visible.
-  ModuleManager->makeModuleVisible(Module, Visibility);
+  // Make the named module visible, if it's not already part of the module
+  // we are parsing.
+  if (ModuleName != getLangOpts().CurrentModule)
+    ModuleManager->makeModuleVisible(Module, Visibility);
 
   // If this module import was due to an inclusion directive, create an 
   // implicit import declaration to capture it in the AST.
index 9a7230c24e672d1b240f60a0727ce0077540da13..b0668c53a44345e26123d1af5ae37f3417588943 100644 (file)
@@ -197,7 +197,6 @@ const FileEntry *DirectoryLookup::LookupFile(
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
-    StringRef BuildingModule,
     Module **SuggestedModule) const {
   llvm::SmallString<1024> TmpDir;
   if (isNormalDir()) {
@@ -224,10 +223,7 @@ const FileEntry *DirectoryLookup::LookupFile(
       
       // If there is a module that corresponds to this header, 
       // suggest it.
-      Module *Module = HS.findModuleForHeader(File);
-      if (Module && Module->getTopLevelModuleName() != BuildingModule)
-        *SuggestedModule = Module;
-      
+      *SuggestedModule = HS.findModuleForHeader(File);
       return File;
     }
     
@@ -236,7 +232,7 @@ const FileEntry *DirectoryLookup::LookupFile(
 
   if (isFramework())
     return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
-                             BuildingModule, SuggestedModule);
+                             SuggestedModule);
 
   assert(isHeaderMap() && "Unknown directory lookup");
   const FileEntry * const Result = getHeaderMap()->LookupFile(
@@ -263,7 +259,6 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
-    StringRef BuildingModule,
     Module **SuggestedModule) const 
 {
   FileManager &FileMgr = HS.getFileMgr();
@@ -322,11 +317,8 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
   Module *Module = 0;
   if (SuggestedModule) {
     if (const DirectoryEntry *FrameworkDir
-                                    = FileMgr.getDirectory(FrameworkName)) {
-      if ((Module = HS.getFrameworkModule(ModuleName, FrameworkDir)) &&
-          Module->Name == BuildingModule)
-        Module = 0;
-    }
+                                    = FileMgr.getDirectory(FrameworkName))
+      Module = HS.getFrameworkModule(ModuleName, FrameworkDir);
   }
   
   // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
@@ -475,7 +467,7 @@ const FileEntry *HeaderSearch::LookupFile(
   for (; i != SearchDirs.size(); ++i) {
     const FileEntry *FE =
       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
-                               BuildingModule, SuggestedModule);
+                               SuggestedModule);
     if (!FE) continue;
 
     CurDir = &SearchDirs[i];
index b44a0a2934fc994ea5dc46f88b612c5cb3c4aa88..ba65c29e69b6beecb2e65b5e53029ccdff2298fc 100644 (file)
@@ -1352,12 +1352,21 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
       break;
     }
 
-    CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd), 
-                                 /*IsTokenRange=*/false);
-    Diag(HashLoc, diag::warn_auto_module_import)
-      << IncludeKind << PathString 
-      << FixItHint::CreateReplacement(ReplaceRange,
-           "__import_module__ " + PathString.str().str() + ";");
+    // Determine whether we are actually building the module that this
+    // include directive maps to.
+    bool BuildingImportedModule
+      = Path[0].first->getName() == getLangOptions().CurrentModule;
+    
+    if (!BuildingImportedModule) {
+      // If we're not building the imported module, warn that we're going
+      // to automatically turn this inclusion directive into a module import.
+      CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd), 
+                                   /*IsTokenRange=*/false);
+      Diag(HashLoc, diag::warn_auto_module_import)
+        << IncludeKind << PathString 
+        << FixItHint::CreateReplacement(ReplaceRange,
+             "__import_module__ " + PathString.str().str() + ";");
+    }
     
     // Load the module.
     // If this was an #__include_macros directive, only make macros visible.
@@ -1365,7 +1374,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
       = (IncludeKind == 3)? Module::MacrosVisible : Module::AllVisible;
     TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,
                                /*IsIncludeDirective=*/true);
-    return;
+    
+    // If this header isn't part of the module we're building, we're done.
+    if (!BuildingImportedModule)
+      return;
   }
   
   // The #included file will be considered to be a system header if either it is
index 64be702fdc50098aef5a2dbfb260d875ef4ec477..dea76e7646176d0b691142eefadee4c51cfc3f47 100644 (file)
@@ -1,2 +1,3 @@
+#include <Module/Sub2.h>
 int *Module_Sub;
 
diff --git a/test/Modules/Inputs/Module.framework/Headers/Sub2.h b/test/Modules/Inputs/Module.framework/Headers/Sub2.h
new file mode 100644 (file)
index 0000000..beed4a8
--- /dev/null
@@ -0,0 +1 @@
+int *Module_Sub2;
diff --git a/test/Modules/submodules.m b/test/Modules/submodules.m
new file mode 100644 (file)
index 0000000..e5a050f
--- /dev/null
@@ -0,0 +1,11 @@
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -Wauto-import -fmodule-cache-path %t -fauto-module-import -F %S/Inputs %s -verify
+
+// Note: transitively imports Module.Sub2.
+__import_module__ Module.Sub;
+
+int getValue() { 
+  return *Module_Sub + *Module_Sub2;
+}
+