r197034 - Modules: Let -fmodules-decluse ignore headers that aren't in a module

Daniel Jasper djasper at google.com
Wed Dec 11 04:13:00 PST 2013


Author: djasper
Date: Wed Dec 11 06:13:00 2013
New Revision: 197034

URL: http://llvm.org/viewvc/llvm-project?rev=197034&view=rev
Log:
Modules: Let -fmodules-decluse ignore headers that aren't in a module

Includes might always pull in arbitrary header or data files outside of
modules. Among others, this includes builtin includes, which do not have
a module (story) yet.

Also cleanup implementation of ModuleMap::findModuleForHeader() to be
non-recursive.

Modified:
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/test/Modules/declare-use1.cpp

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=197034&r1=197033&r2=197034&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Wed Dec 11 06:13:00 2013
@@ -213,11 +213,15 @@ public:
   /// used from.  Used to disambiguate if a header is present in multiple
   /// modules.
   ///
+  /// \param FoundInModule If not null will be set to \c true if the header was
+  /// found in non-exclude header declaration of a module.
+  ///
   /// \returns The module KnownHeader, which provides the module that owns the
   /// given header file.  The KnownHeader is default constructed to indicate
   /// that no module owns this header file.
   KnownHeader findModuleForHeader(const FileEntry *File,
-                                  Module *RequestingModule = NULL);
+                                  Module *RequestingModule = NULL,
+                                  bool *FoundInModule = NULL);
 
   /// \brief Determine whether the given header is part of a module
   /// marked 'unavailable'.

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=197034&r1=197033&r2=197034&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Wed Dec 11 06:13:00 2013
@@ -168,8 +168,19 @@ static bool isBuiltinHeader(StringRef Fi
 
 ModuleMap::KnownHeader
 ModuleMap::findModuleForHeader(const FileEntry *File,
-                               Module *RequestingModule) {
+                               Module *RequestingModule,
+                               bool *FoundInModule) {
   HeadersMap::iterator Known = Headers.find(File);
+
+  // If we've found a builtin header within Clang's builtin include directory,
+  // load all of the module maps to see if it will get associated with a
+  // specific module (e.g., in /usr/include).
+  if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
+      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+    HeaderInfo.loadTopLevelSystemModules();
+    Known = Headers.find(File);
+  }
+
   if (Known != Headers.end()) {
     ModuleMap::KnownHeader Result = KnownHeader();
 
@@ -177,9 +188,15 @@ ModuleMap::findModuleForHeader(const Fil
     for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
                                                 E = Known->second.end();
          I != E; ++I) {
-      // Cannot use a module if the header is excluded or unavailable in it.
-      if (I->getRole() == ModuleMap::ExcludedHeader ||
-          !I->getModule()->isAvailable())
+      // Cannot use a module if the header is excluded in it.
+      if (I->getRole() == ModuleMap::ExcludedHeader)
+        continue;
+
+      if (FoundInModule)
+        *FoundInModule = true;
+
+      // Cannot use a module if it is unavailable.
+      if (!I->getModule()->isAvailable())
         continue;
 
       // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
@@ -194,6 +211,7 @@ ModuleMap::findModuleForHeader(const Fil
                     RequestingModule->DirectUses.end(),
                     I->getModule()) == RequestingModule->DirectUses.end())
         continue;
+
       Result = *I;
       // If 'File' is a public header of this module, this is as good as we
       // are going to get.
@@ -203,18 +221,6 @@ ModuleMap::findModuleForHeader(const Fil
     return Result;
   }
 
-  // If we've found a builtin header within Clang's builtin include directory,
-  // load all of the module maps to see if it will get associated with a
-  // specific module (e.g., in /usr/include).
-  if (File->getDir() == BuiltinIncludeDir &&
-      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
-    HeaderInfo.loadTopLevelSystemModules();
-
-    // Check again.
-    if (Headers.find(File) != Headers.end())
-      return findModuleForHeader(File, RequestingModule);
-  }
-  
   const DirectoryEntry *Dir = File->getDir();
   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
 

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=197034&r1=197033&r2=197034&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Wed Dec 11 06:13:00 2013
@@ -588,9 +588,13 @@ void Preprocessor::verifyModuleInclude(S
   Module *RequestingModule = getModuleForLocation(FilenameLoc);
   if (RequestingModule)
     HeaderInfo.getModuleMap().resolveUses(RequestingModule, /*Complain=*/false);
+  bool FoundInModule = false;
   ModuleMap::KnownHeader RequestedModule =
-      HeaderInfo.getModuleMap().findModuleForHeader(IncFileEnt,
-                                                    RequestingModule);
+      HeaderInfo.getModuleMap().findModuleForHeader(
+          IncFileEnt, RequestingModule, &FoundInModule);
+
+  if (!FoundInModule)
+    return; // The header is not part of a module.
 
   if (RequestingModule == RequestedModule.getModule())
     return; // No faults wihin a module, or between files both not in modules.

Modified: cfe/trunk/test/Modules/declare-use1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/declare-use1.cpp?rev=197034&r1=197033&r2=197034&view=diff
==============================================================================
--- cfe/trunk/test/Modules/declare-use1.cpp (original)
+++ cfe/trunk/test/Modules/declare-use1.cpp Wed Dec 11 06:13:00 2013
@@ -4,4 +4,5 @@
 #include "g.h"
 #include "e.h"
 #include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}}
-const int g2 = g1+e+f;
+#include "i.h"
+const int g2 = g1 + e + f + aux_i;





More information about the cfe-commits mailing list