Index: include/clang/AST/TextNodeDumper.h =================================================================== --- include/clang/AST/TextNodeDumper.h +++ include/clang/AST/TextNodeDumper.h @@ -165,6 +165,8 @@ void Visit(QualType T); + void Visit(const Decl *D); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); Index: lib/AST/ASTDumper.cpp =================================================================== --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -435,35 +435,6 @@ }); } -static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} - -template -static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable *D) { - const T *First = D->getFirstDecl(); - if (First != D) - OS << " first " << First; -} - -template -static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable *D) { - const T *Prev = D->getPreviousDecl(); - if (Prev) - OS << " prev " << Prev; -} - -/// Dump the previous declaration in the redeclaration chain for a declaration, -/// if any. -static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { - switch (D->getKind()) { -#define DECL(DERIVED, BASE) \ - case Decl::DERIVED: \ - return dumpPreviousDeclImpl(OS, cast(D)); -#define ABSTRACT_DECL(DECL) -#include "clang/AST/DeclNodes.inc" - } - llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); -} - //===----------------------------------------------------------------------===// // C++ Utilities //===----------------------------------------------------------------------===// @@ -536,46 +507,9 @@ void ASTDumper::dumpDecl(const Decl *D) { dumpChild([=] { - if (!D) { - ColorScope Color(OS, ShowColors, NullColor); - OS << "<<>>"; + NodeDumper.Visit(D); + if (!D) return; - } - - { - ColorScope Color(OS, ShowColors, DeclKindNameColor); - OS << D->getDeclKindName() << "Decl"; - } - NodeDumper.dumpPointer(D); - if (D->getLexicalDeclContext() != D->getDeclContext()) - OS << " parent " << cast(D->getDeclContext()); - dumpPreviousDecl(OS, D); - NodeDumper.dumpSourceRange(D->getSourceRange()); - OS << ' '; - NodeDumper.dumpLocation(D->getLocation()); - if (D->isFromASTFile()) - OS << " imported"; - if (Module *M = D->getOwningModule()) - OS << " in " << M->getFullModuleName(); - if (auto *ND = dyn_cast(D)) - for (Module *M : D->getASTContext().getModulesWithMergedDefinition( - const_cast(ND))) - dumpChild([=] { OS << "also in " << M->getFullModuleName(); }); - if (const NamedDecl *ND = dyn_cast(D)) - if (ND->isHidden()) - OS << " hidden"; - if (D->isImplicit()) - OS << " implicit"; - if (D->isUsed()) - OS << " used"; - else if (D->isThisDeclarationReferenced()) - OS << " referenced"; - if (D->isInvalidDecl()) - OS << " invalid"; - if (const FunctionDecl *FD = dyn_cast(D)) - if (FD->isConstexpr()) - OS << " constexpr"; - ConstDeclVisitor::Visit(D); Index: lib/AST/TextNodeDumper.cpp =================================================================== --- lib/AST/TextNodeDumper.cpp +++ lib/AST/TextNodeDumper.cpp @@ -12,11 +12,42 @@ //===----------------------------------------------------------------------===// #include "clang/AST/TextNodeDumper.h" +#include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/LocInfoType.h" using namespace clang; +static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} + +template +static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable *D) { + const T *First = D->getFirstDecl(); + if (First != D) + OS << " first " << First; +} + +template +static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable *D) { + const T *Prev = D->getPreviousDecl(); + if (Prev) + OS << " prev " << Prev; +} + +/// Dump the previous declaration in the redeclaration chain for a declaration, +/// if any. +static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { + switch (D->getKind()) { +#define DECL(DERIVED, BASE) \ + case Decl::DERIVED: \ + return dumpPreviousDeclImpl(OS, cast(D)); +#define ABSTRACT_DECL(DECL) +#include "clang/AST/DeclNodes.inc" + } + llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); +} + TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM, const PrintingPolicy &PrintPolicy, @@ -183,6 +214,50 @@ OS << " " << T.split().Quals.getAsString(); } +void TextNodeDumper::Visit(const Decl *D) { + if (!D) { + ColorScope Color(OS, ShowColors, NullColor); + OS << "<<>>"; + return; + } + + { + ColorScope Color(OS, ShowColors, DeclKindNameColor); + OS << D->getDeclKindName() << "Decl"; + } + dumpPointer(D); + if (D->getLexicalDeclContext() != D->getDeclContext()) + OS << " parent " << cast(D->getDeclContext()); + dumpPreviousDecl(OS, D); + dumpSourceRange(D->getSourceRange()); + OS << ' '; + dumpLocation(D->getLocation()); + if (D->isFromASTFile()) + OS << " imported"; + if (Module *M = D->getOwningModule()) + OS << " in " << M->getFullModuleName(); + if (auto *ND = dyn_cast(D)) + for (Module *M : D->getASTContext().getModulesWithMergedDefinition( + const_cast(ND))) + AddChild([=] { OS << "also in " << M->getFullModuleName(); }); + if (const NamedDecl *ND = dyn_cast(D)) + if (ND->isHidden()) + OS << " hidden"; + if (D->isImplicit()) + OS << " implicit"; + + if (D->isUsed()) + OS << " used"; + else if (D->isThisDeclarationReferenced()) + OS << " referenced"; + + if (D->isInvalidDecl()) + OS << " invalid"; + if (const FunctionDecl *FD = dyn_cast(D)) + if (FD->isConstexpr()) + OS << " constexpr"; +} + void TextNodeDumper::dumpPointer(const void *Ptr) { ColorScope Color(OS, ShowColors, AddressColor); OS << ' ' << Ptr;