summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTWriter.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
commitb8b2ed6529f176db7832d1e2a69fae55fa336bc8 (patch)
tree5f28e2ae2097fd91edda3c0900da7a321e32dabe /clang/lib/Serialization/ASTWriter.cpp
parent1ef49218b31145c6b0d1d1095a4be2103c93e4ce (diff)
downloadbcm5719-llvm-b8b2ed6529f176db7832d1e2a69fae55fa336bc8.tar.gz
bcm5719-llvm-b8b2ed6529f176db7832d1e2a69fae55fa336bc8.zip
[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. llvm-svn: 235614
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp132
1 files changed, 24 insertions, 108 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index bdeeae0a51c..59191f22e84 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1993,69 +1993,6 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
return false;
}
-static void addOverriddenSubmodules(ASTWriter &Writer, const Preprocessor &PP,
- MacroDirective *MD,
- SmallVectorImpl<uint64_t> &Result) {
- assert(!isa<VisibilityMacroDirective>(MD) &&
- "only #define and #undef can override");
-
- if (MD->isImported()) {
- auto ModIDs = MD->getOverriddenModules();
- Result.insert(Result.end(), ModIDs.begin(), ModIDs.end());
- return;
- }
-
- unsigned Start = Result.size();
-
- SubmoduleID ModID = Writer.inferSubmoduleIDFromLocation(MD->getLocation());
- for (MD = MD->getPrevious(); MD; MD = MD->getPrevious()) {
- if (shouldIgnoreMacro(MD, /*IsModule*/true, PP))
- break;
-
- // If this is a definition from a submodule import, that submodule's
- // definition is overridden by the definition or undefinition that we
- // started with.
- if (MD->isImported()) {
- if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
- SubmoduleID DefModuleID = DefMD->getInfo()->getOwningModuleID();
- assert(DefModuleID && "imported macro has no owning module");
- Result.push_back(DefModuleID);
- } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
- // If we override a #undef, we override anything that #undef overrides.
- // We don't need to override it, since an active #undef doesn't affect
- // the meaning of a macro.
- // FIXME: Overriding the #undef directly might be simpler.
- auto Overrides = UndefMD->getOverriddenModules();
- Result.insert(Result.end(), Overrides.begin(), Overrides.end());
- }
- }
-
- // Stop once we leave the original macro's submodule.
- //
- // Either this submodule #included another submodule of the same
- // module or it just happened to be built after the other module.
- // In the former case, we override the submodule's macro.
- //
- // FIXME: In the latter case, we shouldn't do so, but we can't tell
- // these cases apart.
- //
- // FIXME: We can leave this submodule and re-enter it if it #includes a
- // header within a different submodule of the same module. In such cases
- // the overrides list will be incomplete.
- SubmoduleID DirectiveModuleID =
- Writer.inferSubmoduleIDFromLocation(MD->getLocation());
- if (DirectiveModuleID != ModID) {
- if (DirectiveModuleID && !MD->isImported())
- Result.push_back(DirectiveModuleID);
- break;
- }
- }
-
- // Weed out any duplicate overrides.
- std::sort(Result.begin() + Start, Result.end());
- Result.erase(std::unique(Result.begin() + Start, Result.end()), Result.end());
-}
-
/// \brief Writes the block containing the serialized form of the
/// preprocessor.
///
@@ -2093,7 +2030,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
I = PP.macro_begin(/*IncludeExternalMacros=*/false),
E = PP.macro_end(/*IncludeExternalMacros=*/false);
I != E; ++I) {
- MacroDirectives.push_back(std::make_pair(I->first, I->second));
+ MacroDirectives.push_back(std::make_pair(I->first, I->second.getLatest()));
}
// Sort the set of macro definitions that need to be serialized by the
@@ -2117,18 +2054,6 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
Name->isFromAST() && !Name->hasChangedSinceDeserialization())
continue;
- // State of this macro within each submodule.
- enum class SubmoduleMacroState {
- /// We've seen nothing about this macro.
- None,
- /// We've seen a public visibility directive.
- Public,
- /// We've either exported a macro for this module or found that the
- /// module's definition of this macro is private.
- Done
- };
- llvm::DenseMap<SubmoduleID, SubmoduleMacroState> State;
-
auto StartOffset = Stream.GetCurrentBitNo();
// Emit the macro directives in reverse source order.
@@ -2157,39 +2082,30 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
Record.push_back(Overrides.size());
Record.append(Overrides.begin(), Overrides.end());
}
+ }
- // If this is the final definition in some module, and it's not
- // module-private, add a module macro record for it.
- if (IsModule) {
- SubmoduleID ModID =
- MD->isImported() ? MD->getOwningModuleID()
- : inferSubmoduleIDFromLocation(MD->getLocation());
- assert(ModID && "found macro in no submodule");
-
- auto &S = State[ModID];
- if (S == SubmoduleMacroState::Done) {
- // We've already handled the final macro from this submodule, or seen
- // a private visibility directive.
- } else 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 (S == SubmoduleMacroState::None)
- S = VisMD->isPublic() ? SubmoduleMacroState::Public
- : SubmoduleMacroState::Done;
- } else {
- S = SubmoduleMacroState::Done;
-
- // Emit a record indicating this submodule exports this macro.
- ModuleMacroRecord.push_back(ModID);
- if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
- ModuleMacroRecord.push_back(getMacroID(DefMD->getInfo()));
- else
- ModuleMacroRecord.push_back(0);
- addOverriddenSubmodules(*this, PP, MD, ModuleMacroRecord);
-
- Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
- ModuleMacroRecord.clear();
- }
+ // Write out any exported module macros.
+ if (IsModule) {
+ auto Leafs = PP.getLeafModuleMacros(Name);
+ SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
+ llvm::DenseMap<ModuleMacro*, unsigned> Visits;
+ while (!Worklist.empty()) {
+ auto *Macro = Worklist.pop_back_val();
+
+ // Emit a record indicating this submodule exports this macro.
+ ModuleMacroRecord.push_back(
+ getSubmoduleID(Macro->getOwningModule()));
+ ModuleMacroRecord.push_back(getMacroID(Macro->getMacroInfo()));
+ for (auto *M : Macro->overrides())
+ ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
+
+ Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
+ ModuleMacroRecord.clear();
+
+ // Enqueue overridden macros once we've visited all their ancestors.
+ for (auto *M : Macro->overrides())
+ if (++Visits[M] == M->getNumOverridingMacros())
+ Worklist.push_back(M);
}
}
OpenPOWER on IntegriCloud