diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-02 00:08:08 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-02 00:08:08 +0000 |
commit | 3c1a41ad9969ae4e3353f5984d66af85ce56cf9a (patch) | |
tree | f19e3452dbc34c152accbcee5057286a353da704 /clang/lib/Lex/ModuleMap.cpp | |
parent | 4cdf4eba74df1c2a679931716fc630fd484bdb3c (diff) | |
download | bcm5719-llvm-3c1a41ad9969ae4e3353f5984d66af85ce56cf9a.tar.gz bcm5719-llvm-3c1a41ad9969ae4e3353f5984d66af85ce56cf9a.zip |
[modules] Track how 'header' directives were written in module map files,
rather than trying to extract this information from the FileEntry after the
fact.
This has a number of beneficial effects. For instance, diagnostic messages for
failed module builds give a path relative to the "module root" rather than an
absolute file path, and the contents of the module includes file is no longer
dependent on what files the including TU happened to inspect prior to
triggering the module build.
llvm-svn: 223095
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 109 |
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. |