From a105ad12e67f7f30cc6fe34e645a676a43801b70 Mon Sep 17 00:00:00 2001 From: Richard Smith <richard-llvm@metafoo.co.uk> Date: Thu, 30 Apr 2015 23:10:40 +0000 Subject: [PATCH] [modules] Add a mechanism to dump information about a macro. Wire this up to "#pragma clang __debug macro <name>". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236280 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/Preprocessor.h | 1 + lib/Lex/MacroInfo.cpp | 6 +-- lib/Lex/PPMacroExpansion.cpp | 64 ++++++++++++++++++++++++++++++++ lib/Lex/Pragma.cpp | 8 ++++ 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index b1cb00ec590..015957204bd 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 7581fe3cd7a..109b6c12b89 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 0aff712abbc..98f90bb7e20 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 7093182239b..6facf4c80bf 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")) { -- GitLab