summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-10-22 23:50:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-10-22 23:50:56 +0000
commit306d892076c831131ebe47125b1dfe41f736e1b0 (patch)
treef6cbaae79943965a27b80f55cecf03b3a6d81ec9 /clang/lib/Lex
parent1fd051bfe8f4013f1bd973b28fd2b3f23ad7b7a5 (diff)
downloadbcm5719-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.cpp47
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp3
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();
OpenPOWER on IntegriCloud