summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-11-15 04:24:58 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-11-15 04:24:58 +0000
commitce587f5eb96477e4c357e49b7d55aa175485b367 (patch)
tree13772f05719330d7fbed0723840e40e106203120 /clang/lib
parent6519801a6e773eda9e64a7e573ed062965f1e6c5 (diff)
downloadbcm5719-llvm-ce587f5eb96477e4c357e49b7d55aa175485b367.tar.gz
bcm5719-llvm-ce587f5eb96477e4c357e49b7d55aa175485b367.zip
When we hit a #include directive that maps to a module import, emit a token
representing the module import rather than making the module immediately visible. This serves two goals: * It avoids making declarations in the module visible prematurely, if we walk past the #include during a tentative parse, for instance, and * It gives a diagnostic (although, admittedly, not a very nice one) if a header with a corresponding module is included anywhere other than at the top level. llvm-svn: 194782
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Frontend/PrintPreprocessedOutput.cpp5
-rw-r--r--clang/lib/Lex/PPDirectives.cpp23
-rw-r--r--clang/lib/Parse/Parser.cpp19
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
4 files changed, 44 insertions, 9 deletions
diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
index 3545d70744f..55a66d87f8b 100644
--- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -657,6 +657,11 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
// -traditional-cpp the lexer keeps /all/ whitespace, including comments.
SourceLocation StartLoc = Tok.getLocation();
Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
+ } else if (Tok.is(tok::annot_module_include)) {
+ // PrintPPOutputPPCallbacks::InclusionDirective handles producing
+ // appropriate output here. Ignore this token entirely.
+ PP.Lex(Tok);
+ continue;
} else if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
OS << II->getName();
} else if (Tok.isLiteral() && !Tok.needsCleaning() &&
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 9ba65a57a84..86c508fe9b1 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1603,10 +1603,9 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
"@import " + PathString.str().str() + ";");
}
- // Load the module.
- // If this was an #__include_macros directive, only make macros visible.
- Module::NameVisibilityKind Visibility
- = (IncludeKind == 3)? Module::MacrosVisible : Module::AllVisible;
+ // Load the module. Only make macros visible. We'll make the declarations
+ // visible when the parser gets here.
+ Module::NameVisibilityKind Visibility = Module::MacrosVisible;
ModuleLoadResult Imported
= TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,
/*IsIncludeDirective=*/true);
@@ -1626,7 +1625,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
}
return;
}
-
+
// If this header isn't part of the module we're building, we're done.
if (!BuildingImportedModule && Imported) {
if (Callbacks) {
@@ -1634,6 +1633,20 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FilenameRange, File,
SearchPath, RelativePath, Imported);
}
+
+ if (IncludeKind != 3) {
+ // Let the parser know that we hit a module import, and it should
+ // make the module visible.
+ // FIXME: Produce this as the current token directly, rather than
+ // allocating a new token for it.
+ Token *Tok = new Token[1];
+ Tok[0].startToken();
+ Tok[0].setKind(tok::annot_module_include);
+ Tok[0].setLocation(HashLoc);
+ Tok[0].setAnnotationEndLoc(End);
+ Tok[0].setAnnotationValue(Imported);
+ EnterTokenStream(Tok, 1, true, true);
+ }
return;
}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 84aad4101fb..c6eac18aa49 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -566,19 +566,30 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
ConsumeToken();
- while (Tok.is(tok::annot_pragma_unused))
+ Result = DeclGroupPtrTy();
+ switch (Tok.getKind()) {
+ case tok::annot_pragma_unused:
HandlePragmaUnused();
+ return false;
- Result = DeclGroupPtrTy();
- if (Tok.is(tok::eof)) {
+ case tok::annot_module_include:
+ Actions.ActOnModuleInclude(Tok.getLocation(),
+ reinterpret_cast<Module *>(
+ Tok.getAnnotationValue()));
+ ConsumeToken();
+ return false;
+
+ case tok::eof:
// Late template parsing can begin.
if (getLangOpts().DelayedTemplateParsing)
Actions.SetLateTemplateParser(LateTemplateParserCallback, this);
if (!PP.isIncrementalProcessingEnabled())
Actions.ActOnEndOfTranslationUnit();
//else don't tell Sema that we ended parsing: more input might come.
-
return true;
+
+ default:
+ break;
}
ParsedAttributesWithRange attrs(AttrFactory);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 211e8587d16..f5507791e7f 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12913,6 +12913,12 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc,
return Import;
}
+void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
+ // FIXME: Should we synthesize an ImportDecl here?
+ PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc,
+ /*Complain=*/true);
+}
+
void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) {
// Create the implicit import declaration.
TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
OpenPOWER on IntegriCloud