mirror of
https://github.com/intel/llvm.git
synced 2026-02-01 17:07:36 +08:00
[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>. llvm-svn: 184560
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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<const DirectoryEntry *, 2> 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<const DirectoryEntry *, bool>::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<const DirectoryEntry *, bool>::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<Module *> &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<Module *> &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<Module *> &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);
|
||||
|
||||
@@ -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<const FileEntry *, bool>::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;
|
||||
|
||||
@@ -217,3 +217,7 @@ module linkage_merge {
|
||||
module incomplete_mod {
|
||||
header "incomplete_mod.h"
|
||||
}
|
||||
|
||||
module warning {
|
||||
header "warning.h"
|
||||
}
|
||||
|
||||
1
clang/test/Modules/Inputs/warning.h
Normal file
1
clang/test/Modules/Inputs/warning.h
Normal file
@@ -0,0 +1 @@
|
||||
enum { bigger_than_int = 0x80000000 };
|
||||
8
clang/test/Modules/system_headers.m
Normal file
8
clang/test/Modules/system_headers.m
Normal file
@@ -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;
|
||||
Reference in New Issue
Block a user