r184560 - [Modules] If a module map resides in a system header directory, treat it as a system module.

Douglas Gregor dgregor at apple.com
Fri Jun 21 09:28:11 PDT 2013


Author: dgregor
Date: Fri Jun 21 11:28:10 2013
New Revision: 184560

URL: http://llvm.org/viewvc/llvm-project?rev=184560&view=rev
Log:
[Modules] If a module map resides in a system header directory, treat it as a system module.

This prevents -pedantic from causing warnings in the system headers
used to create modules. Fixes <rdar://problem/14201171>.

Added:
    cfe/trunk/test/Modules/Inputs/warning.h
    cfe/trunk/test/Modules/system_headers.m
Modified:
    cfe/trunk/include/clang/Frontend/FrontendActions.h
    cfe/trunk/include/clang/Lex/DirectoryLookup.h
    cfe/trunk/include/clang/Lex/HeaderSearch.h
    cfe/trunk/include/clang/Lex/ModuleMap.h
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/Lex/HeaderSearch.cpp
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/test/Modules/Inputs/module.map

Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendActions.h Fri Jun 21 11:28:10 2013
@@ -99,6 +99,7 @@ public:
 
 class GenerateModuleAction : public ASTFrontendAction {
   clang::Module *Module;
+  bool IsSystem;
   
 protected:
   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
@@ -111,6 +112,9 @@ protected:
   virtual bool hasASTFileSupport() const { return false; }
   
 public:
+  explicit GenerateModuleAction(bool IsSystem = false)
+    : ASTFrontendAction(), IsSystem(IsSystem) { }
+
   virtual bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename);
   
   /// \brief Compute the AST consumer arguments that will be used to

Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Fri Jun 21 11:28:10 2013
@@ -130,6 +130,11 @@ public:
     return (SrcMgr::CharacteristicKind)DirCharacteristic;
   }
 
+  /// \brief Whether this describes a system header directory.
+  bool isSystemHeaderDirectory() const {
+    return getDirCharacteristic() != SrcMgr::C_User;
+  }
+
   /// \brief Whether this header map is building a framework or not.
   bool isIndexHeaderMap() const { 
     return isHeaderMap() && IsIndexHeaderMap; 

Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Fri Jun 21 11:28:10 2013
@@ -496,7 +496,11 @@ public:
   ///
   /// \param Root The "root" directory, at which we should stop looking for
   /// module maps.
-  bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root);
+  ///
+  /// \param IsSystem Whether the directories we're looking at are system
+  /// header directories.
+  bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
+                    bool IsSystem);
   
   /// \brief Retrieve the module that corresponds to the given file, if any.
   ///
@@ -506,9 +510,10 @@ public:
   /// \brief Read the contents of the given module map file.
   ///
   /// \param File The module map file.
+  /// \param IsSystem Whether this file is in a system header directory.
   ///
   /// \returns true if an error occurred, false otherwise.
-  bool loadModuleMapFile(const FileEntry *File);
+  bool loadModuleMapFile(const FileEntry *File, bool IsSystem);
 
   /// \brief Collect the set of all known, top-level modules.
   ///
@@ -602,18 +607,21 @@ private:
   ///
   /// \param DirName The name of the directory where we will look for a module
   /// map file.
+  /// \param IsSystem Whether this is a system header directory.
   ///
   /// \returns The result of attempting to load the module map file from the
   /// named directory.
-  LoadModuleMapResult loadModuleMapFile(StringRef DirName);
+  LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem);
 
   /// \brief Try to load the module map file in the given directory.
   ///
   /// \param Dir The directory where we will look for a module map file.
+  /// \param IsSystem Whether this is a system header directory.
   ///
   /// \returns The result of attempting to load the module map file from the
   /// named directory.
-  LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir);
+  LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
+                                        bool IsSystem);
 
   /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
   HeaderFileInfo &getFileInfo(const FileEntry *FE);

Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Fri Jun 21 11:28:10 2013
@@ -337,8 +337,11 @@ public:
   ///
   /// \param File The file to be parsed.
   ///
+  /// \param IsSystem Whether this module map file is in a system header
+  /// directory, and therefore should be considered a system module.
+  ///
   /// \returns true if an error occurred, false otherwise.
-  bool parseModuleMapFile(const FileEntry *File);
+  bool parseModuleMapFile(const FileEntry *File, bool IsSystem);
     
   /// \brief Dump the contents of the module map, for debugging purposes.
   void dump();

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Fri Jun 21 11:28:10 2013
@@ -881,7 +881,7 @@ static void compileModule(CompilerInstan
 
 
   // Construct a module-generating action.
-  GenerateModuleAction CreateModuleAction;
+  GenerateModuleAction CreateModuleAction(Module->IsSystem);
   
   // Execute the action to actually build the module in-place. Use a separate
   // thread so that we get a stack large enough.

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Fri Jun 21 11:28:10 2013
@@ -232,7 +232,7 @@ bool GenerateModuleAction::BeginSourceFi
   
   // Parse the module map file.
   HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
-  if (HS.loadModuleMapFile(ModuleMap))
+  if (HS.loadModuleMapFile(ModuleMap, IsSystem))
     return false;
   
   if (CI.getLangOpts().CurrentModule.empty()) {

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Fri Jun 21 11:28:10 2013
@@ -160,9 +160,11 @@ Module *HeaderSearch::lookupModule(Strin
     // Only deal with normal search directories.
     if (!SearchDirs[Idx].isNormalDir())
       continue;
-    
+
+    bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
     // Search for a module map file in this directory.
-    if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) {
+    if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem)
+          == LMM_NewlyLoaded) {
       // We just loaded a module map file; check whether the module is
       // available now.
       Module = ModMap.findModule(ModuleName);
@@ -175,7 +177,7 @@ Module *HeaderSearch::lookupModule(Strin
     SmallString<128> NestedModuleMapDirName;
     NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
     llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
-    if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) {
+    if (loadModuleMapFile(NestedModuleMapDirName, IsSystem) == LMM_NewlyLoaded){
       // If we just loaded a module map file, look for the module again.
       Module = ModMap.findModule(ModuleName);
       if (Module)
@@ -244,7 +246,8 @@ const FileEntry *DirectoryLookup::Lookup
     
     // If we have a module map that might map this header, load it and
     // check whether we'll have a suggestion for a module.
-    if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) {
+    if (SuggestedModule &&
+        HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory())) {
       const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 
                                                       /*openFile=*/false);
       if (!File)
@@ -927,7 +930,8 @@ StringRef HeaderSearch::getUniqueFramewo
 }
 
 bool HeaderSearch::hasModuleMap(StringRef FileName, 
-                                const DirectoryEntry *Root) {
+                                const DirectoryEntry *Root,
+                                bool IsSystem) {
   SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
   
   StringRef DirName = FileName;
@@ -943,7 +947,7 @@ bool HeaderSearch::hasModuleMap(StringRe
       return false;
     
     // Try to load the module map file in this directory.
-    switch (loadModuleMapFile(Dir)) {
+    switch (loadModuleMapFile(Dir, IsSystem)) {
     case LMM_NewlyLoaded:
     case LMM_AlreadyLoaded:
       // Success. All of the directories we stepped through inherit this module
@@ -978,7 +982,7 @@ HeaderSearch::findModuleForHeader(const
   return ModMap.findModuleForHeader(File);
 }
 
-bool HeaderSearch::loadModuleMapFile(const FileEntry *File) {
+bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
   const DirectoryEntry *Dir = File->getDir();
   
   llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
@@ -986,14 +990,14 @@ bool HeaderSearch::loadModuleMapFile(con
   if (KnownDir != DirectoryHasModuleMap.end())
     return !KnownDir->second;
   
-  bool Result = ModMap.parseModuleMapFile(File);
+  bool Result = ModMap.parseModuleMapFile(File, IsSystem);
   if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") {
     // If the file we loaded was a module.map, look for the corresponding
     // module_private.map.
     SmallString<128> PrivateFilename(Dir->getName());
     llvm::sys::path::append(PrivateFilename, "module_private.map");
     if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename))
-      Result = ModMap.parseModuleMapFile(PrivateFile);
+      Result = ModMap.parseModuleMapFile(PrivateFile, IsSystem);
   }
   
   DirectoryHasModuleMap[Dir] = !Result;  
@@ -1007,7 +1011,7 @@ Module *HeaderSearch::loadFrameworkModul
     return Module;
   
   // Try to load a module map file.
-  switch (loadModuleMapFile(Dir)) {
+  switch (loadModuleMapFile(Dir, IsSystem)) {
   case LMM_InvalidModuleMap:
     break;
     
@@ -1047,15 +1051,15 @@ Module *HeaderSearch::loadFrameworkModul
 
 
 HeaderSearch::LoadModuleMapResult 
-HeaderSearch::loadModuleMapFile(StringRef DirName) {
+HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem) {
   if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
-    return loadModuleMapFile(Dir);
+    return loadModuleMapFile(Dir, IsSystem);
   
   return LMM_NoDirectory;
 }
 
 HeaderSearch::LoadModuleMapResult 
-HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) {
+HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem) {
   llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
     = DirectoryHasModuleMap.find(Dir);
   if (KnownDir != DirectoryHasModuleMap.end())
@@ -1067,7 +1071,7 @@ HeaderSearch::loadModuleMapFile(const Di
   llvm::sys::path::append(ModuleMapFileName, "module.map");
   if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
     // We have found a module map file. Try to parse it.
-    if (ModMap.parseModuleMapFile(ModuleMapFile)) {
+    if (ModMap.parseModuleMapFile(ModuleMapFile, IsSystem)) {
       // No suitable module map.
       DirectoryHasModuleMap[Dir] = false;
       return LMM_InvalidModuleMap;
@@ -1082,7 +1086,7 @@ HeaderSearch::loadModuleMapFile(const Di
     llvm::sys::path::append(ModuleMapFileName, "module_private.map");
     if (const FileEntry *PrivateModuleMapFile
                                         = FileMgr.getFile(ModuleMapFileName)) {
-      if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) {
+      if (ModMap.parseModuleMapFile(PrivateModuleMapFile, IsSystem)) {
         // No suitable module map.
         DirectoryHasModuleMap[Dir] = false;
         return LMM_InvalidModuleMap;
@@ -1102,6 +1106,7 @@ void HeaderSearch::collectAllModules(Sma
   
   // Load module maps for each of the header search directories.
   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
+    bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
     if (SearchDirs[Idx].isFramework()) {
       llvm::error_code EC;
       SmallString<128> DirNative;
@@ -1109,7 +1114,6 @@ void HeaderSearch::collectAllModules(Sma
                               DirNative);
       
       // Search each of the ".framework" directories to load them as modules.
-      bool IsSystem = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
       for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
            Dir != DirEnd && !EC; Dir.increment(EC)) {
         if (llvm::sys::path::extension(Dir->path()) != ".framework")
@@ -1131,7 +1135,7 @@ void HeaderSearch::collectAllModules(Sma
       continue;
     
     // Try to load a module map file for the search directory.
-    loadModuleMapFile(SearchDirs[Idx].getDir());
+    loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem);
     
     // Try to load module map files for immediate subdirectories of this search
     // directory.
@@ -1156,7 +1160,8 @@ void HeaderSearch::loadTopLevelSystemMod
     }
 
     // Try to load a module map file for the search directory.
-    loadModuleMapFile(SearchDirs[Idx].getDir());
+    loadModuleMapFile(SearchDirs[Idx].getDir(),
+                      SearchDirs[Idx].isSystemHeaderDirectory());
   }
 }
 
@@ -1169,7 +1174,7 @@ void HeaderSearch::loadSubdirectoryModul
   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());
+    loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory());
   }
 
   SearchDir.setSearchedAllModuleMaps(true);

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Fri Jun 21 11:28:10 2013
@@ -476,7 +476,7 @@ ModuleMap::inferFrameworkModule(StringRe
           SmallString<128> ModMapPath = Parent;
           llvm::sys::path::append(ModMapPath, "module.map");
           if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
-            parseModuleMapFile(ModMapFile);
+            parseModuleMapFile(ModMapFile, IsSystem);
             inferred = InferredDirectories.find(ParentDir);
           }
 
@@ -789,6 +789,9 @@ namespace clang {
     /// \brief The directory containing Clang-supplied headers.
     const DirectoryEntry *BuiltinIncludeDir;
 
+    /// \brief Whether this module map is in a system header directory.
+    bool IsSystem;
+    
     /// \brief Whether an error occurred.
     bool HadError;
         
@@ -831,10 +834,11 @@ namespace clang {
                              DiagnosticsEngine &Diags,
                              ModuleMap &Map,
                              const DirectoryEntry *Directory,
-                             const DirectoryEntry *BuiltinIncludeDir)
+                             const DirectoryEntry *BuiltinIncludeDir,
+                             bool IsSystem)
       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 
-        Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir), 
-        HadError(false), ActiveModule(0)
+        Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
+        IsSystem(IsSystem), HadError(false), ActiveModule(0)
     {
       Tok.clear();
       consumeToken();
@@ -1170,7 +1174,7 @@ void ModuleMapParser::parseModuleDecl()
   ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
                                         Explicit).first;
   ActiveModule->DefinitionLoc = ModuleNameLoc;
-  if (Attrs.IsSystem)
+  if (Attrs.IsSystem || IsSystem)
     ActiveModule->IsSystem = true;
   
   bool Done = false;
@@ -1957,7 +1961,7 @@ bool ModuleMapParser::parseModuleMapFile
   } while (true);
 }
 
-bool ModuleMap::parseModuleMapFile(const FileEntry *File) {
+bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
   llvm::DenseMap<const FileEntry *, bool>::iterator Known
     = ParsedModuleMap.find(File);
   if (Known != ParsedModuleMap.end())
@@ -1973,7 +1977,7 @@ bool ModuleMap::parseModuleMapFile(const
   Lexer L(ID, SourceMgr->getBuffer(ID), *SourceMgr, MMapLangOpts);
   Diags->getClient()->BeginSourceFile(MMapLangOpts);
   ModuleMapParser Parser(L, *SourceMgr, Target, *Diags, *this, File->getDir(),
-                         BuiltinIncludeDir);
+                         BuiltinIncludeDir, IsSystem);
   bool Result = Parser.parseModuleMapFile();
   Diags->getClient()->EndSourceFile();
   ParsedModuleMap[File] = Result;

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=184560&r1=184559&r2=184560&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Fri Jun 21 11:28:10 2013
@@ -217,3 +217,7 @@ module linkage_merge {
 module incomplete_mod {
   header "incomplete_mod.h"
 }
+
+module warning {
+  header "warning.h"
+}

Added: cfe/trunk/test/Modules/Inputs/warning.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/warning.h?rev=184560&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/warning.h (added)
+++ cfe/trunk/test/Modules/Inputs/warning.h Fri Jun 21 11:28:10 2013
@@ -0,0 +1 @@
+enum { bigger_than_int = 0x80000000 };

Added: cfe/trunk/test/Modules/system_headers.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/system_headers.m?rev=184560&view=auto
==============================================================================
--- cfe/trunk/test/Modules/system_headers.m (added)
+++ cfe/trunk/test/Modules/system_headers.m Fri Jun 21 11:28:10 2013
@@ -0,0 +1,8 @@
+// Test that system-headerness works for building modules.
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -isystem %S/Inputs -pedantic -Werror %s -verify
+// expected-no-diagnostics
+
+ at import warning;
+int i = bigger_than_int;





More information about the cfe-commits mailing list