/// \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;
};
}
#include <cassert>
namespace clang {
+class Module;
class Preprocessor;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
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.
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.
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
};
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;
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
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);
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);
}
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);
}
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.
// 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();
+}
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.
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)) {
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.
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);
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())
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;
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.
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.
///
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
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.
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);
}
}