summaryrefslogtreecommitdiff
path: root/lib/Lex/PPLexerChange.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-04-23 18:18:26 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-04-23 18:18:26 +0000
commiteacc7339437e06b76df1f8b653c5a4dfb2566eda (patch)
tree58fe5177235e26c8049d04f5910eb1b219acaa50 /lib/Lex/PPLexerChange.cpp
parent9e7eb7e6324af09ffac26146a8dc9c792f49c0e3 (diff)
[modules] Determine the set of macros exported by a submodule at the end of that submodule.
Previously we'd defer this determination until writing the AST, which doesn't allow us to use this information when building other submodules of the same module. This change also allows us to use a uniform mechanism for writing module macro records, independent of whether they are local or imported. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235614 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/PPLexerChange.cpp')
-rw-r--r--lib/Lex/PPLexerChange.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index fb5e2b0580..33f5ff07f0 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -400,6 +400,9 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
Result.setAnnotationEndLoc(Result.getLocation());
Result.setAnnotationValue(CurSubmodule);
+
+ // We're done with this submodule.
+ LeaveSubmodule();
}
// We're done with the #included file.
@@ -605,3 +608,63 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
// preprocessor directive mode), so just return EOF as our token.
assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");
}
+
+void Preprocessor::EnterSubmodule(Module *M) {
+ // Save the current state for future imports.
+ BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M));
+
+ auto &Info = BuildingSubmoduleStack.back();
+ // Copy across our macros and start the submodule with the current state.
+ // FIXME: We should start each submodule with just the predefined macros.
+ Info.Macros = Macros;
+}
+
+void Preprocessor::LeaveSubmodule() {
+ auto &Info = BuildingSubmoduleStack.back();
+
+ // Create ModuleMacros for any macros defined in this submodule.
+ for (auto &Macro : Macros) {
+ auto *II = const_cast<IdentifierInfo*>(Macro.first);
+ MacroState State = Info.Macros.lookup(II);
+
+ // This module may have exported a new macro. If so, create a ModuleMacro
+ // representing that fact.
+ bool ExplicitlyPublic = false;
+ for (auto *MD = Macro.second.getLatest(); MD != State.getLatest();
+ MD = MD->getPrevious()) {
+ // Skip macros defined in other submodules we #included along the way.
+ Module *Mod = getModuleForLocation(MD->getLocation());
+ if (Mod != Info.M)
+ continue;
+
+ if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+ // The latest visibility directive for a name in a submodule affects
+ // all the directives that come before it.
+ if (VisMD->isPublic())
+ ExplicitlyPublic = true;
+ else if (!ExplicitlyPublic)
+ // Private with no following public directive: not exported.
+ break;
+ } else {
+ MacroInfo *Def = nullptr;
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+ Def = DefMD->getInfo();
+
+ // FIXME: Issue a warning if multiple headers for the same submodule
+ // define a macro, rather than silently ignoring all but the first.
+ bool IsNew;
+ addModuleMacro(Info.M, II, Def, Macro.second.getOverriddenMacros(),
+ IsNew);
+ break;
+ }
+ }
+
+ // Update the macro to refer to the latest directive in the chain.
+ State.setLatest(Macro.second.getLatest());
+
+ // Restore the old macro state.
+ Macro.second = State;
+ }
+
+ BuildingSubmoduleStack.pop_back();
+}