diff --git a/clang/include/clang/Lex/ExternalPreprocessorSource.h b/clang/include/clang/Lex/ExternalPreprocessorSource.h index 2f9231dc9f22..a795a8565d02 100644 --- a/clang/include/clang/Lex/ExternalPreprocessorSource.h +++ b/clang/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/clang/include/clang/Lex/MacroInfo.h b/clang/include/clang/Lex/MacroInfo.h index 0dde8f2fdff6..6d2de9b95278 100644 --- a/clang/include/clang/Lex/MacroInfo.h +++ b/clang/include/clang/Lex/MacroInfo.h @@ -23,6 +23,7 @@ #include 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 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(this + 1)); } public: - static ModuleMacro *create(Preprocessor &PP, unsigned OwningModuleID, + static ModuleMacro *create(Preprocessor &PP, Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, ArrayRef 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/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 239bfa036fe8..a4fd42b5530d 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -364,12 +364,86 @@ class Preprocessor : public RefCountedBase { }; SmallVector 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 OverriddenMacros; + }; + + llvm::PointerUnion State; + + ExtInfo &getExtInfo(Preprocessor &PP) { + auto *Ext = State.dyn_cast(); + if (!Ext) { + Ext = new (PP.getPreprocessorAllocator()) + ExtInfo(State.get()); + State = Ext; + } + return *Ext; + } + + public: + MacroState() : MacroState(nullptr) {} + MacroState(MacroDirective *MD) : State(MD) {} + MacroDirective *getLatest() const { + if (auto *Ext = State.dyn_cast()) + return Ext->MD; + return State.get(); + } + void setLatest(MacroDirective *MD) { + if (auto *Ext = State.dyn_cast()) + 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 getOverriddenMacros() const { + if (auto *Ext = State.dyn_cast()) + return Ext->OverriddenMacros; + return None; + } + }; + + typedef llvm::DenseMap 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 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 BuildingSubmoduleStack; + + void EnterSubmodule(Module *M); + void LeaveSubmodule(); + /// The set of known macros exported from modules. llvm::FoldingSet 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 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 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_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 + 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/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 6507f8e4b667..a2737d5f3707 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/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/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp index 55e0049e5e53..d7f483192f15 100644 --- a/clang/lib/Lex/MacroInfo.cpp +++ b/clang/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 Overrides) { void *Mem = PP.getPreprocessorAllocator().Allocate( sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(), llvm::alignOf()); - return new (Mem) ModuleMacro(OwningModuleID, II, Macro, Overrides); + return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides); } diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index a50c8a829353..c22b05922189 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/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/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index fb5e2b05808c..33f5ff07f034 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/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(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(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(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/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 6753bf3fff1a..883f2d5ff3bc 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/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(MD) && - cast(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 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/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 51a038ac728f..6f2e390fc033 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/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/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index eeeb8511b213..eb029c18c331 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/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/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7d8ccbfdb7a6..8b918326204d 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/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/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index bdeeae0a51c2..59191f22e846 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 &Result) { - assert(!isa(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(MD)) { - SubmoduleID DefModuleID = DefMD->getInfo()->getOwningModuleID(); - assert(DefModuleID && "imported macro has no owning module"); - Result.push_back(DefModuleID); - } else if (auto *UndefMD = dyn_cast(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 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"); + // Write out any exported module macros. + if (IsModule) { + auto Leafs = PP.getLeafModuleMacros(Name); + SmallVector Worklist(Leafs.begin(), Leafs.end()); + llvm::DenseMap Visits; + while (!Worklist.empty()) { + auto *Macro = Worklist.pop_back_val(); - 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(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( + getSubmoduleID(Macro->getOwningModule())); + ModuleMacroRecord.push_back(getMacroID(Macro->getMacroInfo())); + for (auto *M : Macro->overrides()) + ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule())); - // Emit a record indicating this submodule exports this macro. - ModuleMacroRecord.push_back(ModID); - if (DefMacroDirective *DefMD = dyn_cast(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(); - 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); } }