[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>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184560 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 1786190..9c9f131 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -99,6 +99,7 @@
class GenerateModuleAction : public ASTFrontendAction {
clang::Module *Module;
+ bool IsSystem;
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
@@ -111,6 +112,9 @@
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 6675ea2..dff3e8c 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -130,6 +130,11 @@
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 4e54fe0..84dd6eb 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -496,7 +496,11 @@
///
/// \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 @@
/// \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 @@
///
/// \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 924e696..8e588bf 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -337,8 +337,11 @@
///
/// \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 a2872dd..8011a8b 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -881,7 +881,7 @@
// 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 91eccbb..3b37e8a 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -232,7 +232,7 @@
// 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 d2bc5ad..631a7fd 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -160,9 +160,11 @@
// 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 @@
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 @@
// 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 @@
}
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 @@
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 @@
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 @@
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 @@
return Module;
// Try to load a module map file.
- switch (loadModuleMapFile(Dir)) {
+ switch (loadModuleMapFile(Dir, IsSystem)) {
case LMM_InvalidModuleMap:
break;
@@ -1047,15 +1051,15 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
}
// 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 @@
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 f46a87a..4c876f9 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -476,7 +476,7 @@
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 @@
/// \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 @@
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 @@
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 @@
} 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 @@
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 5a95ce9..65c75fd 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -217,3 +217,7 @@
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 0000000..a90c628
--- /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 0000000..39b13ca
--- /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;