summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp109
1 files changed, 63 insertions, 46 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 6a470ef886c..a270b56e6af 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -220,12 +220,14 @@ static bool violatesPrivateInclude(Module *RequestingModule,
// as obtained from the lookup and as obtained from the module.
// This check is not cheap, so enable it only for debugging.
bool IsPrivate = false;
- SmallVectorImpl<const FileEntry *> *HeaderList[] =
- {&RequestedModule->PrivateHeaders,
- &RequestedModule->PrivateTextualHeaders};
+ SmallVectorImpl<Module::Header> *HeaderList[] =
+ {&RequestedModule->Headers[Module::HK_Private],
+ &RequestedModule->Headers[Module::HK_PrivateTextual]};
for (auto *Hdrs : HeaderList)
IsPrivate |=
- std::find(Hdrs->begin(), Hdrs->end(), IncFileEnt) != Hdrs->end();
+ std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) {
+ return H.Entry == IncFileEnt;
+ }) != Hdrs->end();
assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
#endif
return IsPrivateRole &&
@@ -778,40 +780,40 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
UmbrellaDirs[UmbrellaDir] = Mod;
}
-void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
- ModuleHeaderRole Role) {
+static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
switch ((int)Role) {
- default:
- llvm_unreachable("unknown header role");
- case NormalHeader:
- Mod->NormalHeaders.push_back(Header);
- break;
- case PrivateHeader:
- Mod->PrivateHeaders.push_back(Header);
- break;
- case TextualHeader:
- Mod->TextualHeaders.push_back(Header);
- break;
- case PrivateHeader | TextualHeader:
- Mod->PrivateTextualHeaders.push_back(Header);
- break;
+ default: llvm_unreachable("unknown header role");
+ case ModuleMap::NormalHeader:
+ return Module::HK_Normal;
+ case ModuleMap::PrivateHeader:
+ return Module::HK_Private;
+ case ModuleMap::TextualHeader:
+ return Module::HK_Textual;
+ case ModuleMap::PrivateHeader | ModuleMap::TextualHeader:
+ return Module::HK_PrivateTextual;
}
+}
+void ModuleMap::addHeader(Module *Mod, Module::Header Header,
+ ModuleHeaderRole Role) {
if (!(Role & TextualHeader)) {
bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
- HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
+ HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
+ isCompilingModuleHeader);
}
- Headers[Header].push_back(KnownHeader(Mod, Role));
-}
+ Headers[Header.Entry].push_back(KnownHeader(Mod, Role));
-void ModuleMap::excludeHeader(Module *Mod, const FileEntry *Header) {
- Mod->ExcludedHeaders.push_back(Header);
+ Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
+}
+void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
// Add this as a known header so we won't implicitly add it to any
// umbrella directory module.
// FIXME: Should we only exclude it from umbrella modules within the
// specified module?
- (void) Headers[Header];
+ (void) Headers[Header.Entry];
+
+ Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
}
const FileEntry *
@@ -1447,6 +1449,7 @@ void ModuleMapParser::parseModuleDecl() {
ActiveModule->IsSystem = true;
if (Attrs.IsExternC)
ActiveModule->IsExternC = true;
+ ActiveModule->Directory = Directory;
bool Done = false;
do {
@@ -1699,7 +1702,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
HadError = true;
return;
}
- Module::HeaderDirective Header;
+ Module::UnresolvedHeaderDirective Header;
Header.FileName = Tok.getString();
Header.FileNameLoc = consumeToken();
@@ -1714,33 +1717,39 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// Look for this file.
const FileEntry *File = nullptr;
const FileEntry *BuiltinFile = nullptr;
- SmallString<128> PathName;
+ SmallString<128> RelativePathName;
if (llvm::sys::path::is_absolute(Header.FileName)) {
- PathName = Header.FileName;
- File = SourceMgr.getFileManager().getFile(PathName);
+ RelativePathName = Header.FileName;
+ File = SourceMgr.getFileManager().getFile(RelativePathName);
} else {
// Search for the header file within the search directory.
- PathName = Directory->getName();
- unsigned PathLength = PathName.size();
+ SmallString<128> FullPathName(Directory->getName());
+ unsigned FullPathLength = FullPathName.size();
if (ActiveModule->isPartOfFramework()) {
- appendSubframeworkPaths(ActiveModule, PathName);
+ appendSubframeworkPaths(ActiveModule, RelativePathName);
// Check whether this file is in the public headers.
- llvm::sys::path::append(PathName, "Headers", Header.FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
+ llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
+ llvm::sys::path::append(FullPathName, RelativePathName.str());
+ File = SourceMgr.getFileManager().getFile(FullPathName);
if (!File) {
// Check whether this file is in the private headers.
- PathName.resize(PathLength);
- llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
+ // FIXME: Should we retain the subframework paths here?
+ RelativePathName.clear();
+ FullPathName.resize(FullPathLength);
+ llvm::sys::path::append(RelativePathName, "PrivateHeaders",
+ Header.FileName);
+ llvm::sys::path::append(FullPathName, RelativePathName.str());
+ File = SourceMgr.getFileManager().getFile(FullPathName);
}
} else {
// Lookup for normal headers.
- llvm::sys::path::append(PathName, Header.FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
-
+ llvm::sys::path::append(RelativePathName, Header.FileName);
+ llvm::sys::path::append(FullPathName, RelativePathName.str());
+ File = SourceMgr.getFileManager().getFile(FullPathName);
+
// If this is a system module with a top-level header, this header
// may have a counterpart (or replacement) in the set of headers
// supplied by Clang. Find that builtin header.
@@ -1750,18 +1759,19 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
llvm::sys::path::append(BuiltinPathName, Header.FileName);
BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
-
+
// If Clang supplies this header but the underlying system does not,
// just silently swap in our builtin version. Otherwise, we'll end
// up adding both (later).
if (!File && BuiltinFile) {
File = BuiltinFile;
+ RelativePathName = BuiltinPathName;
BuiltinFile = nullptr;
}
}
}
}
-
+
// FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
// Come up with a lazy way to do this.
if (File) {
@@ -1776,16 +1786,23 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
Map.setUmbrellaHeader(ActiveModule, File);
}
} else if (LeadingToken == MMToken::ExcludeKeyword) {
- Map.excludeHeader(ActiveModule, File);
+ Map.excludeHeader(ActiveModule,
+ Module::Header{RelativePathName.str(), File});
} else {
// If there is a builtin counterpart to this file, add it now, before
// the "real" header, so we build the built-in one first when building
// the module.
if (BuiltinFile)
- Map.addHeader(ActiveModule, BuiltinFile, Role);
+ // FIXME: Taking the name from the FileEntry is unstable and can give
+ // different results depending on how we've previously named that file
+ // in this build.
+ Map.addHeader(ActiveModule,
+ Module::Header{BuiltinFile->getName(), BuiltinFile},
+ Role);
// Record this header.
- Map.addHeader(ActiveModule, File, Role);
+ Map.addHeader(ActiveModule, Module::Header{RelativePathName.str(), File},
+ Role);
}
} else if (LeadingToken != MMToken::ExcludeKeyword) {
// Ignore excluded header files. They're optional anyway.
OpenPOWER on IntegriCloud