summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h3
-rw-r--r--include/clang/Lex/MacroInfo.h23
-rw-r--r--include/clang/Lex/Preprocessor.h97
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp3
-rw-r--r--lib/Lex/MacroInfo.cpp4
-rw-r--r--lib/Lex/PPDirectives.cpp2
-rw-r--r--lib/Lex/PPLexerChange.cpp63
-rw-r--r--lib/Lex/PPMacroExpansion.cpp73
-rw-r--r--lib/Lex/Preprocessor.cpp2
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--lib/Serialization/ASTReader.cpp7
-rw-r--r--lib/Serialization/ASTWriter.cpp132
12 files changed, 263 insertions, 148 deletions
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index 2f9231dc9f..a795a8565d 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -32,6 +32,9 @@ public:
/// \brief Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
+
+ /// \brief Map a module ID to a module.
+ virtual Module *getModule(unsigned ModuleID) = 0;
};
}
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 0dde8f2fdf..6d2de9b952 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -23,6 +23,7 @@
#include <cassert>
namespace clang {
+class Module;
class Preprocessor;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
@@ -590,8 +591,8 @@ class ModuleMacro : public llvm::FoldingSetNode {
IdentifierInfo *II;
/// The body of the #define, or nullptr if this is a #undef.
MacroInfo *Macro;
- /// The ID of the module that exports this macro.
- unsigned OwningModuleID;
+ /// The module that exports this macro.
+ Module *OwningModule;
/// The number of module macros that override this one.
unsigned NumOverriddenBy;
/// The number of modules whose macros are directly overridden by this one.
@@ -600,30 +601,30 @@ class ModuleMacro : public llvm::FoldingSetNode {
friend class Preprocessor;
- ModuleMacro(unsigned OwningModuleID, IdentifierInfo *II, MacroInfo *Macro,
+ ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides)
- : II(II), Macro(Macro), OwningModuleID(OwningModuleID),
+ : II(II), Macro(Macro), OwningModule(OwningModule),
NumOverriddenBy(0), NumOverrides(Overrides.size()) {
std::copy(Overrides.begin(), Overrides.end(),
reinterpret_cast<ModuleMacro **>(this + 1));
}
public:
- static ModuleMacro *create(Preprocessor &PP, unsigned OwningModuleID,
+ static ModuleMacro *create(Preprocessor &PP, Module *OwningModule,
IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides);
void Profile(llvm::FoldingSetNodeID &ID) const {
- return Profile(ID, OwningModuleID, II);
+ return Profile(ID, OwningModule, II);
}
- static void Profile(llvm::FoldingSetNodeID &ID, unsigned OwningModuleID,
+ static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
IdentifierInfo *II) {
- ID.AddInteger(OwningModuleID);
+ ID.AddPointer(OwningModule);
ID.AddPointer(II);
}
/// Get the ID of the module that exports this macro.
- unsigned getOwningModuleID() const { return OwningModuleID; }
+ Module *getOwningModule() const { return OwningModule; }
/// Get definition for this exported #define, or nullptr if this
/// represents a #undef.
@@ -642,6 +643,10 @@ public:
return llvm::make_range(overrides_begin(), overrides_end());
}
/// \}
+
+ /// Get the number of macros that override this one.
+ unsigned getNumOverridingMacros() const { return NumOverriddenBy; }
+
};
} // end namespace clang
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 239bfa036f..a4fd42b553 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -364,12 +364,86 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
+ /// The state of a macro for an identifier.
+ class MacroState {
+ struct ExtInfo {
+ ExtInfo(MacroDirective *MD) : MD(MD) {}
+
+ // The most recent macro directive for this identifier.
+ MacroDirective *MD;
+ // The module macros that are overridden by this macro.
+ SmallVector<ModuleMacro*, 4> OverriddenMacros;
+ };
+
+ llvm::PointerUnion<MacroDirective *, ExtInfo *> State;
+
+ ExtInfo &getExtInfo(Preprocessor &PP) {
+ auto *Ext = State.dyn_cast<ExtInfo*>();
+ if (!Ext) {
+ Ext = new (PP.getPreprocessorAllocator())
+ ExtInfo(State.get<MacroDirective *>());
+ State = Ext;
+ }
+ return *Ext;
+ }
+
+ public:
+ MacroState() : MacroState(nullptr) {}
+ MacroState(MacroDirective *MD) : State(MD) {}
+ MacroDirective *getLatest() const {
+ if (auto *Ext = State.dyn_cast<ExtInfo*>())
+ return Ext->MD;
+ return State.get<MacroDirective*>();
+ }
+ void setLatest(MacroDirective *MD) {
+ if (auto *Ext = State.dyn_cast<ExtInfo*>())
+ Ext->MD = MD;
+ else
+ State = MD;
+ }
+
+ MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
+ SourceManager &SourceMgr) const {
+ return getLatest()->findDirectiveAtLoc(Loc, SourceMgr);
+ }
+
+ void addOverriddenMacro(Preprocessor &PP, ModuleMacro *MM) {
+ getExtInfo(PP).OverriddenMacros.push_back(MM);
+ }
+ ArrayRef<ModuleMacro*> getOverriddenMacros() const {
+ if (auto *Ext = State.dyn_cast<ExtInfo*>())
+ return Ext->OverriddenMacros;
+ return None;
+ }
+ };
+
+ typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
+
/// For each IdentifierInfo that was associated with a macro, we
/// keep a mapping to the history of all macro definitions and #undefs in
/// the reverse order (the latest one is in the head of the list).
- llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
+ MacroMap Macros;
+
friend class ASTReader;
+ /// \brief Information about a submodule that we're currently building.
+ struct BuildingSubmoduleInfo {
+ BuildingSubmoduleInfo(Module *M) : M(M) {}
+
+ // The module that we are building.
+ Module *M;
+ // The macros that were visible before we entered the module.
+ MacroMap Macros;
+
+ // FIXME: VisibleModules?
+ // FIXME: CounterValue?
+ // FIXME: PragmaPushMacroInfo?
+ };
+ SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
+
+ void EnterSubmodule(Module *M);
+ void LeaveSubmodule();
+
/// The set of known macros exported from modules.
llvm::FoldingSet<ModuleMacro> ModuleMacros;
@@ -656,19 +730,30 @@ public:
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
/// \brief Register an exported macro for a module and identifier.
- ModuleMacro *addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
- MacroInfo *Macro,
+ ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
- ModuleMacro *getModuleMacro(unsigned ModuleID, IdentifierInfo *II);
+ ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II);
+
+ /// \brief Get the list of leaf (non-overridden) module macros for a name.
+ ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
+ auto I = LeafModuleMacros.find(II);
+ if (I != LeafModuleMacros.end())
+ return I->second;
+ return None;
+ }
/// \{
/// Iterators for the macro history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
- typedef llvm::DenseMap<const IdentifierInfo *,
- MacroDirective*>::const_iterator macro_iterator;
+ typedef MacroMap::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+ llvm::iterator_range<macro_iterator>
+ macros(bool IncludeExternalMacros = true) const {
+ return llvm::make_range(macro_begin(IncludeExternalMacros),
+ macro_end(IncludeExternalMacros));
+ }
/// \}
/// \brief Return the name of the macro defined before \p Loc that has
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 6507f8e4b6..a2737d5f37 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -687,7 +687,8 @@ static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
I != E; ++I) {
if (I->first->hasMacroDefinition())
- MacrosByID.push_back(id_macro_pair(I->first, I->second->getMacroInfo()));
+ MacrosByID.push_back(
+ id_macro_pair(I->first, I->second.getLatest()->getMacroInfo()));
}
llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 55e0049e5e..d7f483192f 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -235,11 +235,11 @@ void MacroDirective::dump() const {
Out << "\n";
}
-ModuleMacro *ModuleMacro::create(Preprocessor &PP, unsigned OwningModuleID,
+ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule,
IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides) {
void *Mem = PP.getPreprocessorAllocator().Allocate(
sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
llvm::alignOf<ModuleMacro>());
- return new (Mem) ModuleMacro(OwningModuleID, II, Macro, Overrides);
+ return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index a50c8a8293..c22b059221 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1787,6 +1787,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
assert(!CurSubmodule && "should not have marked this as a module yet");
CurSubmodule = BuildingModule.getModule();
+ EnterSubmodule(CurSubmodule);
+
EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
CurSubmodule);
}
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();
+}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 6753bf3fff..883f2d5ff3 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -37,33 +37,73 @@ MacroDirective *
Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const {
assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
- macro_iterator Pos = Macros.find(II);
+ auto Pos = Macros.find(II);
assert(Pos != Macros.end() && "Identifier macro info is missing!");
- return Pos->second;
+ return Pos->second.getLatest();
}
void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
assert(MD && "MacroDirective should be non-zero!");
assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
- MacroDirective *&StoredMD = Macros[II];
- MD->setPrevious(StoredMD);
- StoredMD = MD;
- // Setup the identifier as having associated macro history.
+ MacroState &StoredMD = Macros[II];
+ auto *OldMD = StoredMD.getLatest();
+ MD->setPrevious(OldMD);
+ StoredMD.setLatest(MD);
+
+ // Set up the identifier as having associated macro history.
II->setHasMacroDefinition(true);
if (!MD->isDefined())
II->setHasMacroDefinition(false);
- bool isImportedMacro = isa<DefMacroDirective>(MD) &&
- cast<DefMacroDirective>(MD)->isImported();
- if (II->isFromAST() && !isImportedMacro)
+ if (II->isFromAST() && !MD->isImported())
II->setChangedSinceDeserialization();
+
+ // Accumulate any overridden imported macros.
+ if (!MD->isImported() && getCurrentModule()) {
+ Module *OwningMod = getModuleForLocation(MD->getLocation());
+ if (!OwningMod)
+ return;
+
+ for (auto *PrevMD = OldMD; PrevMD; PrevMD = PrevMD->getPrevious()) {
+ // FIXME: Store a ModuleMacro * on an imported directive.
+ Module *DirectiveMod = getModuleForLocation(PrevMD->getLocation());
+ Module *PrevOwningMod =
+ PrevMD->isImported()
+ ? getExternalSource()->getModule(PrevMD->getOwningModuleID())
+ : DirectiveMod;
+ auto *MM = getModuleMacro(PrevOwningMod, II);
+ if (!MM) {
+ // We're still within the module defining the previous macro. We don't
+ // override it.
+ assert(!PrevMD->isImported() &&
+ "imported macro with no corresponding ModuleMacro");
+ break;
+ }
+ StoredMD.addOverriddenMacro(*this, MM);
+
+ // 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.
+ if (DirectiveMod != OwningMod || !PrevMD->isImported())
+ break;
+ }
+ }
}
void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
MacroDirective *MD) {
assert(II && MD);
- MacroDirective *&StoredMD = Macros[II];
- assert(!StoredMD &&
+ MacroState &StoredMD = Macros[II];
+ assert(!StoredMD.getLatest() &&
"the macro history was modified before initializing it from a pch");
StoredMD = MD;
// Setup the identifier as having associated macro history.
@@ -72,12 +112,12 @@ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
II->setHasMacroDefinition(false);
}
-ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II,
MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides,
bool &New) {
llvm::FoldingSetNodeID ID;
- ModuleMacro::Profile(ID, ModuleID, II);
+ ModuleMacro::Profile(ID, Mod, II);
void *InsertPos;
if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
@@ -85,7 +125,7 @@ ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
return MM;
}
- auto *MM = ModuleMacro::create(*this, ModuleID, II, Macro, Overrides);
+ auto *MM = ModuleMacro::create(*this, Mod, II, Macro, Overrides);
ModuleMacros.InsertNode(MM, InsertPos);
// Each overridden macro is now overridden by one more macro.
@@ -112,10 +152,9 @@ ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
return MM;
}
-ModuleMacro *Preprocessor::getModuleMacro(unsigned ModuleID,
- IdentifierInfo *II) {
+ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) {
llvm::FoldingSetNodeID ID;
- ModuleMacro::Profile(ID, ModuleID, II);
+ ModuleMacro::Profile(ID, Mod, II);
void *InsertPos;
return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 51a038ac72..6f2e390fc0 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -322,7 +322,7 @@ StringRef Preprocessor::getLastMacroWithSpelling(
for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
I != E; ++I) {
const MacroDirective::DefInfo
- Def = I->second->findDirectiveAtLoc(Loc, SourceMgr);
+ Def = I->second.findDirectiveAtLoc(Loc, SourceMgr);
if (!Def || !Def.getMacroInfo())
continue;
if (!Def.getMacroInfo()->isObjectLike())
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index eeeb8511b2..eb029c18c3 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3037,7 +3037,7 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
MEnd = PP.macro_end();
M != MEnd; ++M) {
if (IncludeUndefined || M->first->hasMacroDefinition()) {
- if (MacroInfo *MI = M->second->getMacroInfo())
+ if (MacroInfo *MI = M->second.getLatest()->getMacroInfo())
if (MI->isUsedForHeaderGuard())
continue;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 7d8ccbfdb7..8b91832620 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1807,17 +1807,18 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
for (auto &MMI : ModuleMacros) {
Overrides.clear();
for (unsigned ModID : MMI.Overrides) {
- auto *Macro = PP.getModuleMacro(ModID, II);
+ Module *Mod = getSubmodule(ModID);
+ auto *Macro = PP.getModuleMacro(Mod, II);
assert(Macro && "missing definition for overridden macro");
Overrides.push_back(Macro);
}
bool Inserted = false;
- PP.addModuleMacro(MMI.SubModID, II, MMI.MI, Overrides, Inserted);
+ Module *Owner = getSubmodule(MMI.getSubmoduleID());
+ PP.addModuleMacro(Owner, II, MMI.MI, Overrides, Inserted);
if (!Inserted)
continue;
- Module *Owner = getSubmodule(MMI.getSubmoduleID());
if (Owner->NameVisibility == Module::Hidden) {
// Macros in the owning module are hidden. Just remember this macro to
// install if we make this module visible.
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index bdeeae0a51..59191f22e8 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/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);
}
}