diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index b1cb00ec59029e69098f27eb316e055acaa26273..015957204bdfff72aef65f75baeb05d77eb6c2f4 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -1444,6 +1444,7 @@ public: void DumpToken(const Token &Tok, bool DumpFlags = false) const; void DumpLocation(SourceLocation Loc) const; void DumpMacro(const MacroInfo &MI) const; + void dumpMacroInfo(const IdentifierInfo *II); /// \brief Given a location that specifies the start of a /// token, return a new location that specifies a character within the token. diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index 7581fe3cd7a6e55c6dcece4ef3c1d56cc655ec26..109b6c12b89b7e4a365f44d3feb8819617800144 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -219,10 +219,8 @@ void MacroDirective::dump() const { Out << " prev " << Prev; if (IsFromPCH) Out << " from_pch"; - if (IsPublic) - Out << " public"; - else if (isa<VisibilityMacroDirective>(this)) - Out << " private"; + if (isa<VisibilityMacroDirective>(this)) + Out << (IsPublic ? " public" : " private"); if (auto *DMD = dyn_cast<DefMacroDirective>(this)) { if (auto *Info = DMD->getInfo()) { diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 0aff712abbc209dec04dbc19d3195a632ce877ae..98f90bb7e2038d78b5d09eb77ab06a5c3e96be0e 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -194,6 +194,70 @@ void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II, Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro; } +void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) { + ArrayRef<ModuleMacro*> Leaf; + auto LeafIt = LeafModuleMacros.find(II); + if (LeafIt != LeafModuleMacros.end()) + Leaf = LeafIt->second; + const MacroState *State = nullptr; + auto Pos = Macros.find(II); + if (Pos != Macros.end()) + State = &Pos->second; + + llvm::errs() << "MacroState " << State << " " << II->getNameStart(); + if (State && State->isAmbiguous(*this, II)) + llvm::errs() << " ambiguous"; + if (!State->getOverriddenMacros().empty()) { + llvm::errs() << " overrides"; + for (auto *O : State->getOverriddenMacros()) + llvm::errs() << " " << O->getOwningModule()->getFullModuleName(); + } + llvm::errs() << "\n"; + + // Dump local macro directives. + for (auto *MD = State ? State->getLatest() : nullptr; MD; + MD = MD->getPrevious()) { + llvm::errs() << " "; + MD->dump(); + } + + // Dump module macros. + llvm::DenseSet<ModuleMacro*> Active; + for (auto *MM : State ? State->getActiveModuleMacros(*this, II) : None) + Active.insert(MM); + llvm::DenseSet<ModuleMacro*> Visited; + llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf.begin(), Leaf.end()); + while (!Worklist.empty()) { + auto *MM = Worklist.pop_back_val(); + llvm::errs() << " ModuleMacro " << MM << " " + << MM->getOwningModule()->getFullModuleName(); + if (!MM->getMacroInfo()) + llvm::errs() << " undef"; + + if (Active.count(MM)) + llvm::errs() << " active"; + else if (MM->getOwningModule()->NameVisibility < Module::MacrosVisible) + llvm::errs() << " hidden"; + else + llvm::errs() << " overridden"; + + if (!MM->overrides().empty()) { + llvm::errs() << " overrides"; + for (auto *O : MM->overrides()) { + llvm::errs() << " " << O->getOwningModule()->getFullModuleName(); + if (Visited.insert(O).second) + Worklist.push_back(O); + } + } + llvm::errs() << "\n"; + if (auto *MI = MM->getMacroInfo()) { + llvm::errs() << " "; + MI->dump(); + llvm::errs() << "\n"; + } + } +} + /// RegisterBuiltinMacro - Register the specified identifier in the identifier /// table and mark it as a builtin macro to be expanded. static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 7093182239be5547e45379e41f9fdc558500485f..6facf4c80bf5ad144f0c04bec6dbd76792b013a6 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -875,6 +875,14 @@ struct PragmaDebugHandler : public PragmaHandler { llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error"); } else if (II->isStr("llvm_unreachable")) { llvm_unreachable("#pragma clang __debug llvm_unreachable"); + } else if (II->isStr("macro")) { + Token MacroName; + PP.LexUnexpandedToken(MacroName); + auto *MacroII = MacroName.getIdentifierInfo(); + if (MacroII) + PP.dumpMacroInfo(MacroII); + else + PP.Diag(MacroName, diag::warn_pragma_diagnostic_invalid); } else if (II->isStr("overflow_stack")) { DebugOverflowStack(); } else if (II->isStr("handle_crash")) {