From 8f5d7d1d1f990f174c7f2682271a83acf64dd93d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 21 Jun 2013 16:28:10 +0000 Subject: [PATCH] [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 . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184560 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/FrontendActions.h | 4 +++ include/clang/Lex/DirectoryLookup.h | 5 +++ include/clang/Lex/HeaderSearch.h | 16 ++++++--- include/clang/Lex/ModuleMap.h | 5 ++- lib/Frontend/CompilerInstance.cpp | 2 +- lib/Frontend/FrontendActions.cpp | 2 +- lib/Lex/HeaderSearch.cpp | 43 +++++++++++++----------- lib/Lex/ModuleMap.cpp | 18 ++++++---- test/Modules/Inputs/module.map | 4 +++ test/Modules/Inputs/warning.h | 1 + test/Modules/system_headers.m | 8 +++++ 11 files changed, 75 insertions(+), 33 deletions(-) create mode 100644 test/Modules/Inputs/warning.h create mode 100644 test/Modules/system_headers.m diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 178619047a..9c9f131699 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -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 diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index 6675ea22a7..dff3e8c360 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -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; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 4e54fe0b2c..84dd6eb441 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -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); diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 924e696672..8e588bfdc1 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -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(); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index a2872dd4f2..8011a8b679 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -881,7 +881,7 @@ static void compileModule(CompilerInstance &ImportingInstance, // 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. diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 91eccbb26f..3b37e8a5c7 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -232,7 +232,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, // 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()) { diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index d2bc5ad5e5..631a7fd1da 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -160,9 +160,11 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { // 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(StringRef ModuleName, bool AllowSearch) { 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::LookupFile( // 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::getUniqueFrameworkName(StringRef Framework) { } bool HeaderSearch::hasModuleMap(StringRef FileName, - const DirectoryEntry *Root) { + const DirectoryEntry *Root, + bool IsSystem) { SmallVector FixUpDirectories; StringRef DirName = FileName; @@ -943,7 +947,7 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, 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 FileEntry *File) 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::iterator KnownDir @@ -986,14 +990,14 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File) { 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::loadFrameworkModule(StringRef Name, 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::loadFrameworkModule(StringRef Name, 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::iterator KnownDir = DirectoryHasModuleMap.find(Dir); if (KnownDir != DirectoryHasModuleMap.end()) @@ -1067,7 +1071,7 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) { 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 DirectoryEntry *Dir) { 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(SmallVectorImpl &Modules) { // 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(SmallVectorImpl &Modules) { 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(SmallVectorImpl &Modules) { 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::loadTopLevelSystemModules() { } // 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::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { 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); diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index f46a87abc9..4c876f92b9 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -476,7 +476,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, 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::iterator Known = ParsedModuleMap.find(File); if (Known != ParsedModuleMap.end()) @@ -1973,7 +1977,7 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File) { 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; diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 5a95ce9edc..65c75fdc1c 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -217,3 +217,7 @@ module linkage_merge { module incomplete_mod { header "incomplete_mod.h" } + +module warning { + header "warning.h" +} diff --git a/test/Modules/Inputs/warning.h b/test/Modules/Inputs/warning.h new file mode 100644 index 0000000000..a90c628867 --- /dev/null +++ b/test/Modules/Inputs/warning.h @@ -0,0 +1 @@ +enum { bigger_than_int = 0x80000000 }; diff --git a/test/Modules/system_headers.m b/test/Modules/system_headers.m new file mode 100644 index 0000000000..39b13ca5fc --- /dev/null +++ b/test/Modules/system_headers.m @@ -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 + +@import warning; +int i = bigger_than_int; -- 2.40.0