diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-22 23:50:56 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-22 23:50:56 +0000 |
commit | 306d892076c831131ebe47125b1dfe41f736e1b0 (patch) | |
tree | f6cbaae79943965a27b80f55cecf03b3a6d81ec9 /clang/lib/Lex | |
parent | 1fd051bfe8f4013f1bd973b28fd2b3f23ad7b7a5 (diff) | |
download | bcm5719-llvm-306d892076c831131ebe47125b1dfe41f736e1b0.tar.gz bcm5719-llvm-306d892076c831131ebe47125b1dfe41f736e1b0.zip |
[modules] Add support for 'textual header' directives.
This allows a module to specify that it logically contains a file, but that
said file is non-modular and intended for textual inclusion. This allows
layering checks to work properly in the presence of such files.
llvm-svn: 220448
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 47 | ||||
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 3 |
2 files changed, 42 insertions, 8 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 5885f423bbe..f5fc111631a 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -315,9 +315,16 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, - Module *RequestingModule) { + Module *RequestingModule, + bool IncludeTextualHeaders) { HeadersMap::iterator Known = findKnownHeader(File); + auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { + if (!IncludeTextualHeaders && R.getRole() == ModuleMap::TextualHeader) + return ModuleMap::KnownHeader(); + return R; + }; + if (Known != Headers.end()) { ModuleMap::KnownHeader Result = KnownHeader(); @@ -336,7 +343,7 @@ ModuleMap::findModuleForHeader(const FileEntry *File, // If 'File' is part of 'RequestingModule', 'RequestingModule' is the // module we are looking for. if (I->getModule() == RequestingModule) - return *I; + return MakeResult(*I); // If uses need to be specified explicitly, we are only allowed to return // modules that are explicitly used by the requesting module. @@ -349,10 +356,11 @@ ModuleMap::findModuleForHeader(const FileEntry *File, // are going to get. // FIXME: If we have a RequestingModule, we should prefer the header from // that module. - if (I->getRole() == ModuleMap::NormalHeader) + if (I->getRole() == ModuleMap::NormalHeader || + I->getRole() == ModuleMap::TextualHeader) break; } - return Result; + return MakeResult(Result); } SmallVector<const DirectoryEntry *, 2> SkippedDirs; @@ -422,9 +430,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File, if (!Result->isAvailable()) return KnownHeader(); - return Headers[File].back(); + return MakeResult(Headers[File].back()); } - + return KnownHeader(); } @@ -785,6 +793,8 @@ void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, ModuleHeaderRole Role) { if (Role == ExcludedHeader) { Mod->ExcludedHeaders.push_back(Header); + } else if (Role == TextualHeader) { + Mod->TextualHeaders.push_back(Header); } else { if (Role == PrivateHeader) Mod->PrivateHeaders.push_back(Header); @@ -946,6 +956,7 @@ namespace clang { RequiresKeyword, Star, StringLiteral, + TextualKeyword, LBrace, RBrace, LSquare, @@ -1096,6 +1107,7 @@ retry: .Case("module", MMToken::ModuleKeyword) .Case("private", MMToken::PrivateKeyword) .Case("requires", MMToken::RequiresKeyword) + .Case("textual", MMToken::TextualKeyword) .Case("umbrella", MMToken::UmbrellaKeyword) .Case("use", MMToken::UseKeyword) .Default(MMToken::Identifier); @@ -1463,6 +1475,17 @@ 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"; + } + break; + } + case MMToken::UmbrellaKeyword: { SourceLocation UmbrellaLoc = consumeToken(); if (Tok.is(MMToken::HeaderKeyword)) @@ -1650,8 +1673,12 @@ static void appendSubframeworkPaths(Module *Mod, /// \brief Parse a header declaration. /// /// header-declaration: -/// 'umbrella'[opt] 'header' string-literal /// 'exclude'[opt] 'header' string-literal +/// 'private'[opt] 'header' string-literal +/// 'textual'[opt] 'header' string-literal +/// 'umbrella'[opt] 'header' string-literal +/// +/// FIXME: Support 'private textual header'. void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, SourceLocation LeadingLoc) { assert(Tok.is(MMToken::HeaderKeyword)); @@ -1747,6 +1774,8 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, Role = ModuleMap::ExcludedHeader; else if (LeadingToken == MMToken::PrivateKeyword) Role = ModuleMap::PrivateHeader; + else if (LeadingToken == MMToken::TextualKeyword) + Role = ModuleMap::TextualHeader; else assert(LeadingToken == MMToken::HeaderKeyword); @@ -1839,6 +1868,7 @@ void ModuleMapParser::parseExportDecl() { ModuleId ParsedModuleId; bool Wildcard = false; do { + // FIXME: Support string-literal module names here. if (Tok.is(MMToken::Identifier)) { ParsedModuleId.push_back(std::make_pair(Tok.getString(), Tok.getLocation())); @@ -1936,6 +1966,7 @@ void ModuleMapParser::parseConfigMacros() { } // If we don't have an identifier, we're done. + // FIXME: Support macros with the same name as a keyword here. if (!Tok.is(MMToken::Identifier)) return; @@ -1952,6 +1983,7 @@ void ModuleMapParser::parseConfigMacros() { consumeToken(); // We expect to see a macro name here. + // FIXME: Support macros with the same name as a keyword here. if (!Tok.is(MMToken::Identifier)) { Diags.Report(Tok.getLocation(), diag::err_mmap_expected_config_macro); break; @@ -2117,6 +2149,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { } consumeToken(); + // FIXME: Support string-literal module names here. if (!Tok.is(MMToken::Identifier)) { Diags.Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name); break; diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index f0d3d67acae..33256ec5b68 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -519,7 +519,8 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { continue; // If it's not part of a module and not unknown, complain. - if (!ModMap.findModuleForHeader(File) && + if (!ModMap.findModuleForHeader(File, nullptr, + /*IncludeTextualHeaders*/true) && !ModMap.isHeaderInUnavailableModule(File)) { Diag(StartLoc, diag::warn_forgotten_module_header) << File->getName() << Mod->getFullModuleName(); |