diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-24 20:23:01 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-24 20:23:01 +0000 |
commit | 202210b3694940b4e5cca50aa3b6208e0298121b (patch) | |
tree | 4979cefac81736c80c162bd4d1ad11a0833d8eba /clang/lib | |
parent | 90a3b19e645143e320b8ea4b5ca348bc6fb34e94 (diff) | |
download | bcm5719-llvm-202210b3694940b4e5cca50aa3b6208e0298121b.tar.gz bcm5719-llvm-202210b3694940b4e5cca50aa3b6208e0298121b.zip |
[modules] Support combining 'textual' with 'private'.
llvm-svn: 220589
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 132 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 58 |
3 files changed, 93 insertions, 124 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index c191e0199a9..fb4135c2bc1 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -202,7 +202,7 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, return KnownHeader(); } -// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'. +// Returns true if RequestingModule directly uses RequestedModule. static bool directlyUses(const Module *RequestingModule, const Module *RequestedModule) { return std::find(RequestingModule->DirectUses.begin(), @@ -214,19 +214,19 @@ static bool violatesPrivateInclude(Module *RequestingModule, const FileEntry *IncFileEnt, ModuleMap::ModuleHeaderRole Role, Module *RequestedModule) { - #ifndef NDEBUG + bool IsPrivateRole = Role & ModuleMap::PrivateHeader; +#ifndef NDEBUG // Check for consistency between the module header role // as obtained from the lookup and as obtained from the module. // This check is not cheap, so enable it only for debugging. - SmallVectorImpl<const FileEntry *> &PvtHdrs - = RequestedModule->PrivateHeaders; - SmallVectorImpl<const FileEntry *>::iterator Look - = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt); - bool IsPrivate = Look != PvtHdrs.end(); - assert((IsPrivate && Role == ModuleMap::PrivateHeader) - || (!IsPrivate && Role != ModuleMap::PrivateHeader)); - #endif - return Role == ModuleMap::PrivateHeader && + bool IsPrivate = false; + for (auto *Hdrs : {&RequestedModule->PrivateHeaders, + &RequestedModule->PrivateTextualHeaders}) + IsPrivate |= + std::find(Hdrs->begin(), Hdrs->end(), IncFileEnt) != Hdrs->end(); + assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles"); +#endif + return IsPrivateRole && RequestedModule->getTopLevelModule() != RequestingModule; } @@ -316,13 +316,13 @@ ModuleMap::findModuleForHeader(const FileEntry *File, HeadersMap::iterator Known = findKnownHeader(File); auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { - if (!IncludeTextualHeaders && R.getRole() == ModuleMap::TextualHeader) + if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader)) return ModuleMap::KnownHeader(); return R; }; if (Known != Headers.end()) { - ModuleMap::KnownHeader Result = KnownHeader(); + ModuleMap::KnownHeader Result; // Iterate over all modules that 'File' is part of to find the best fit. for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), @@ -343,14 +343,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File, !directlyUses(RequestingModule, I->getModule())) continue; - Result = *I; - // If 'File' is a public header of this module, this is as good as we - // are going to get. - // FIXME: If we have a RequestingModule, we should prefer the header from - // that module. - if (I->getRole() == ModuleMap::NormalHeader || - I->getRole() == ModuleMap::TextualHeader) - break; + // Prefer a public header over a private header. + if (!Result || (Result.getRole() & ModuleMap::PrivateHeader)) + Result = *I; } return MakeResult(Result); } @@ -783,13 +778,12 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, ModuleHeaderRole Role) { - if (Role == TextualHeader) { - Mod->TextualHeaders.push_back(Header); - } else { - if (Role == PrivateHeader) - Mod->PrivateHeaders.push_back(Header); - else - Mod->NormalHeaders.push_back(Header); + auto HeaderLists = {&Mod->NormalHeaders, &Mod->PrivateHeaders, + &Mod->TextualHeaders, &Mod->PrivateTextualHeaders}; + assert(Role >= 0 && Role < HeaderLists.size() && "unknown header role"); + HeaderLists.begin()[Role]->push_back(Header); + + if (!(Role & TextualHeader)) { bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader); } @@ -1475,16 +1469,9 @@ void ModuleMapParser::parseModuleDecl() { parseRequiresDecl(); break; - case MMToken::TextualKeyword: { - SourceLocation TextualLoc = consumeToken(); - if (Tok.is(MMToken::HeaderKeyword)) { - parseHeaderDecl(MMToken::TextualKeyword, TextualLoc); - } else { - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) - << "textual"; - } + case MMToken::TextualKeyword: + parseHeaderDecl(MMToken::TextualKeyword, consumeToken()); break; - } case MMToken::UmbrellaKeyword: { SourceLocation UmbrellaLoc = consumeToken(); @@ -1494,31 +1481,17 @@ void ModuleMapParser::parseModuleDecl() { parseUmbrellaDirDecl(UmbrellaLoc); break; } - - case MMToken::ExcludeKeyword: { - SourceLocation ExcludeLoc = consumeToken(); - if (Tok.is(MMToken::HeaderKeyword)) { - parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc); - } else { - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) - << "exclude"; - } + + case MMToken::ExcludeKeyword: + parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken()); break; - } - - case MMToken::PrivateKeyword: { - SourceLocation PrivateLoc = consumeToken(); - if (Tok.is(MMToken::HeaderKeyword)) { - parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc); - } else { - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) - << "private"; - } + + case MMToken::PrivateKeyword: + parseHeaderDecl(MMToken::PrivateKeyword, consumeToken()); break; - } - + case MMToken::HeaderKeyword: - parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation()); + parseHeaderDecl(MMToken::HeaderKeyword, consumeToken()); break; case MMToken::LinkKeyword: @@ -1673,16 +1646,37 @@ static void appendSubframeworkPaths(Module *Mod, /// \brief Parse a header declaration. /// /// header-declaration: -/// 'exclude'[opt] 'header' string-literal -/// 'private'[opt] 'header' string-literal /// 'textual'[opt] 'header' string-literal -/// 'umbrella'[opt] 'header' string-literal +/// 'private' 'textual'[opt] 'header' string-literal +/// 'exclude' 'header' string-literal +/// 'umbrella' 'header' string-literal /// /// FIXME: Support 'private textual header'. void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, SourceLocation LeadingLoc) { - assert(Tok.is(MMToken::HeaderKeyword)); - consumeToken(); + // We've already consumed the first token. + ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; + if (LeadingToken == MMToken::PrivateKeyword) { + Role = ModuleMap::PrivateHeader; + // 'private' may optionally be followed by 'textual'. + if (Tok.is(MMToken::TextualKeyword)) { + LeadingToken = Tok.Kind; + consumeToken(); + } + } + if (LeadingToken == MMToken::TextualKeyword) + Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader); + + if (LeadingToken != MMToken::HeaderKeyword) { + if (!Tok.is(MMToken::HeaderKeyword)) { + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header) + << (LeadingToken == MMToken::PrivateKeyword ? "private" : + LeadingToken == MMToken::ExcludeKeyword ? "exclude" : + LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella"); + return; + } + consumeToken(); + } // Parse the header name. if (!Tok.is(MMToken::StringLiteral)) { @@ -1770,21 +1764,13 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, } else if (LeadingToken == MMToken::ExcludeKeyword) { Map.excludeHeader(ActiveModule, File); } else { - // Record this header. - ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; - if (LeadingToken == MMToken::PrivateKeyword) - Role = ModuleMap::PrivateHeader; - else if (LeadingToken == MMToken::TextualKeyword) - Role = ModuleMap::TextualHeader; - else - assert(LeadingToken == MMToken::HeaderKeyword); - // 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); + // Record this header. Map.addHeader(ActiveModule, File, Role); } } else if (LeadingToken != MMToken::ExcludeKeyword) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 1fd39faab7f..1d7efb81827 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4461,26 +4461,19 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case SUBMODULE_HEADER: { - // We lazily associate headers with their modules via the HeaderInfoTable. + case SUBMODULE_HEADER: + case SUBMODULE_EXCLUDED_HEADER: + case SUBMODULE_PRIVATE_HEADER: + // We lazily associate headers with their modules via the HeaderInfo table. // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead // of complete filenames or remove it entirely. - break; - } - - case SUBMODULE_EXCLUDED_HEADER: { - // We lazily associate headers with their modules via the HeaderInfoTable. - // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead - // of complete filenames or remove it entirely. - break; - } + break; - case SUBMODULE_PRIVATE_HEADER: { - // We lazily associate headers with their modules via the HeaderInfoTable. - // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead - // of complete filenames or remove it entirely. - break; - } + case SUBMODULE_TEXTUAL_HEADER: + case SUBMODULE_PRIVATE_TEXTUAL_HEADER: + // FIXME: Textual headers are not marked in the HeaderInfo table. Load + // them here. + break; case SUBMODULE_TOPHEADER: { CurrentModule->addTopHeaderFilename(Blob); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e39e5bb0222..000a7a9001f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2370,7 +2370,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { } // Enter the submodule description block. - Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/4); + Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5); // Write the abbreviations needed for the submodules block. using namespace llvm; @@ -2431,6 +2431,11 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbrev); Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name + unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev); + + Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name @@ -2504,40 +2509,25 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { } // Emit the headers. - for (unsigned I = 0, N = Mod->NormalHeaders.size(); I != N; ++I) { - Record.clear(); - Record.push_back(SUBMODULE_HEADER); - Stream.EmitRecordWithBlob(HeaderAbbrev, Record, - Mod->NormalHeaders[I]->getName()); - } - // Emit the excluded headers. - for (unsigned I = 0, N = Mod->ExcludedHeaders.size(); I != N; ++I) { - Record.clear(); - Record.push_back(SUBMODULE_EXCLUDED_HEADER); - Stream.EmitRecordWithBlob(ExcludedHeaderAbbrev, Record, - Mod->ExcludedHeaders[I]->getName()); - } - // Emit the textual headers. - for (unsigned I = 0, N = Mod->TextualHeaders.size(); I != N; ++I) { - Record.clear(); - Record.push_back(SUBMODULE_TEXTUAL_HEADER); - Stream.EmitRecordWithBlob(TextualHeaderAbbrev, Record, - Mod->TextualHeaders[I]->getName()); - } - // Emit the private headers. - for (unsigned I = 0, N = Mod->PrivateHeaders.size(); I != N; ++I) { - Record.clear(); - Record.push_back(SUBMODULE_PRIVATE_HEADER); - Stream.EmitRecordWithBlob(PrivateHeaderAbbrev, Record, - Mod->PrivateHeaders[I]->getName()); - } - ArrayRef<const FileEntry *> - TopHeaders = Mod->getTopHeaders(PP->getFileManager()); - for (unsigned I = 0, N = TopHeaders.size(); I != N; ++I) { + struct { + unsigned Kind; + unsigned Abbrev; + ArrayRef<const FileEntry*> Headers; + } HeaderLists[] = { + {SUBMODULE_HEADER, HeaderAbbrev, Mod->NormalHeaders}, + {SUBMODULE_TEXTUAL_HEADER, TextualHeaderAbbrev, Mod->TextualHeaders}, + {SUBMODULE_PRIVATE_HEADER, PrivateHeaderAbbrev, Mod->PrivateHeaders}, + {SUBMODULE_PRIVATE_TEXTUAL_HEADER, PrivateTextualHeaderAbbrev, + Mod->PrivateTextualHeaders}, + {SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Mod->ExcludedHeaders}, + {SUBMODULE_TOPHEADER, TopHeaderAbbrev, + Mod->getTopHeaders(PP->getFileManager())} + }; + for (auto &HL : HeaderLists) { Record.clear(); - Record.push_back(SUBMODULE_TOPHEADER); - Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, - TopHeaders[I]->getName()); + Record.push_back(HL.Kind); + for (auto *H : HL.Headers) + Stream.EmitRecordWithBlob(HL.Abbrev, Record, H->getName()); } // Emit the imports. |