summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/PPLexerChange.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-05-01 21:22:17 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-05-01 21:22:17 +0000
commitee977933f7df9cef13cc06ac7fa3e4a22b72e41f (patch)
treea22ff47a085710049d757d9056439c018e405181 /clang/lib/Lex/PPLexerChange.cpp
parentf9b517c1596a7f13c4b2be68c0ff5db1b1d96afb (diff)
downloadbcm5719-llvm-ee977933f7df9cef13cc06ac7fa3e4a22b72e41f.tar.gz
bcm5719-llvm-ee977933f7df9cef13cc06ac7fa3e4a22b72e41f.zip
[modules] Add -fmodules-local-submodule-visibility flag.
This flag specifies that the normal visibility rules should be used even for local submodules (submodules of the currently-being-built module). Thus names will only be visible if a header / module that declares them has actually been included / imported, and not merely because a submodule that happened to be built earlier declared those names. This also removes the need to modularize bottom-up: textually-included headers will be included into every submodule that includes them, since their include guards will not leak between modules. So far, this only governs visibility of macros, not of declarations, so is not ready for real use yet. llvm-svn: 236350
Diffstat (limited to 'clang/lib/Lex/PPLexerChange.cpp')
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp69
1 files changed, 52 insertions, 17 deletions
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index 6766fdfcd07..c506aa7f6f0 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -612,16 +612,25 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) {
// Save the current state for future imports.
BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M, ImportLoc));
-
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.
- for (auto &M : Macros) {
- BuildingSubmoduleInfo::SavedMacroInfo SMI;
- SMI.Latest = M.second.getLatest();
- auto O = M.second.getOverriddenMacros();
- SMI.Overridden.insert(SMI.Overridden.end(), O.begin(), O.end());
- Info.Macros.insert(std::make_pair(M.first, SMI));
+ Info.Macros.swap(Macros);
+ // Save our visible modules set. This is guaranteed to clear the set.
+ if (getLangOpts().ModulesLocalVisibility)
+ Info.VisibleModules = std::move(VisibleModules);
+
+ // Determine the set of starting macros for this submodule.
+ // FIXME: If we re-enter a submodule, should we restore its MacroDirectives?
+ auto &StartingMacros = (getLangOpts().ModulesLocalVisibility &&
+ BuildingSubmoduleStack.size() > 1)
+ ? BuildingSubmoduleStack[0].Macros
+ : Info.Macros;
+
+ // Restore to the starting state.
+ // FIXME: Do this lazily, when each macro name is first referenced.
+ for (auto &Macro : StartingMacros) {
+ MacroState MS(Macro.second.getLatest());
+ MS.setOverriddenMacros(*this, MS.getOverriddenMacros());
+ Macros.insert(std::make_pair(Macro.first, std::move(MS)));
}
}
@@ -631,19 +640,35 @@ void Preprocessor::LeaveSubmodule() {
// Create ModuleMacros for any macros defined in this submodule.
for (auto &Macro : Macros) {
auto *II = const_cast<IdentifierInfo*>(Macro.first);
- auto SavedInfo = Info.Macros.lookup(II);
+ auto &OuterInfo = Info.Macros[II];
+
+ // Find the starting point for the MacroDirective chain in this submodule.
+ auto *OldMD = OuterInfo.getLatest();
+ if (getLangOpts().ModulesLocalVisibility &&
+ BuildingSubmoduleStack.size() > 1) {
+ auto &PredefMacros = BuildingSubmoduleStack[0].Macros;
+ auto PredefMacroIt = PredefMacros.find(Macro.first);
+ if (PredefMacroIt == PredefMacros.end())
+ OldMD = nullptr;
+ else
+ OldMD = PredefMacroIt->second.getLatest();
+ }
// 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 != SavedInfo.Latest;
+ for (auto *MD = Macro.second.getLatest(); MD != OldMD;
MD = MD->getPrevious()) {
assert(MD && "broken macro directive chain");
// Skip macros defined in other submodules we #included along the way.
- Module *Mod = getModuleContainingLocation(MD->getLocation());
- if (Mod != Info.M)
- continue;
+ // There's no point doing this if we're tracking local submodule
+ // visibiltiy, since there can be no such directives in our list.
+ if (!getLangOpts().ModulesLocalVisibility) {
+ Module *Mod = getModuleContainingLocation(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
@@ -667,11 +692,21 @@ void Preprocessor::LeaveSubmodule() {
}
}
- // Restore the macro's overrides list.
- Macro.second.setOverriddenMacros(SavedInfo.Overridden);
+ // Maintain a single macro directive chain if we're not tracking
+ // per-submodule macro visibility.
+ if (!getLangOpts().ModulesLocalVisibility)
+ OuterInfo.setLatest(Macro.second.getLatest());
}
- makeModuleVisible(Info.M, Info.ImportLoc);
+ // Put back the old macros.
+ std::swap(Info.Macros, Macros);
+
+ if (getLangOpts().ModulesLocalVisibility)
+ VisibleModules = std::move(Info.VisibleModules);
+
+ // A nested #include makes the included submodule visible.
+ if (BuildingSubmoduleStack.size() > 1)
+ makeModuleVisible(Info.M, Info.ImportLoc);
BuildingSubmoduleStack.pop_back();
}
OpenPOWER on IntegriCloud