Index: include/clang/AST/TextNodeDumper.h =================================================================== --- include/clang/AST/TextNodeDumper.h +++ include/clang/AST/TextNodeDumper.h @@ -0,0 +1,54 @@ +//===--- TextNodeDumper.h - Printing of AST nodes -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements AST dumping of components of individual AST nodes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H +#define LLVM_CLANG_AST_TEXTNODEDUMPER_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTDumperUtils.h" +#include "clang/AST/ExprCXX.h" + +namespace clang { + +class TextNodeDumper { + raw_ostream &OS; + const bool ShowColors; + + /// Keep track of the last location we print out so that we can + /// print out deltas from then on out. + const char *LastLocFilename = ""; + unsigned LastLocLine = ~0U; + + const SourceManager *SM; + + /// The policy to use for printing; can be defaulted. + PrintingPolicy PrintPolicy; + +public: + TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM, + const PrintingPolicy &PrintPolicy); + + void dumpPointer(const void *Ptr); + void dumpLocation(SourceLocation Loc); + void dumpSourceRange(SourceRange R); + void dumpBareType(QualType T, bool Desugar = true); + void dumpType(QualType T); + void dumpBareDeclRef(const Decl *D); + void dumpName(const NamedDecl *ND); + void dumpAccessSpecifier(AccessSpecifier AS); + void dumpCXXTemporary(const CXXTemporary *Temporary); +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H Index: lib/AST/ASTDumper.cpp =================================================================== --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -23,6 +23,7 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TextNodeDumper.h" #include "clang/AST/TypeVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/Module.h" @@ -44,10 +45,10 @@ public TypeVisitor { TextTreeStructure TreeStructure; + TextNodeDumper NodeDumper; raw_ostream &OS; const CommandTraits *Traits; - const SourceManager *SM; /// The policy to use for printing; can be defaulted. PrintingPolicy PrintPolicy; @@ -56,11 +57,6 @@ /// not already been loaded. bool Deserialize = false; - /// Keep track of the last location we print out so that we can - /// print out deltas from then on out. - const char *LastLocFilename = ""; - unsigned LastLocLine = ~0U; - const bool ShowColors; /// Dump a child of the current node. @@ -80,7 +76,8 @@ ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM, bool ShowColors, const PrintingPolicy &PrintPolicy) - : TreeStructure(OS, ShowColors), OS(OS), Traits(Traits), SM(SM), + : TreeStructure(OS, ShowColors), + NodeDumper(OS, ShowColors, SM, PrintPolicy), OS(OS), Traits(Traits), PrintPolicy(PrintPolicy), ShowColors(ShowColors) {} void setDeserialize(bool D) { Deserialize = D; } @@ -90,23 +87,17 @@ void dumpFullComment(const FullComment *C); // Utilities - void dumpPointer(const void *Ptr); - void dumpSourceRange(SourceRange R); - void dumpLocation(SourceLocation Loc); - void dumpBareType(QualType T, bool Desugar = true); - void dumpType(QualType T); + void dumpType(QualType T) { NodeDumper.dumpType(T); } void dumpTypeAsChild(QualType T); void dumpTypeAsChild(const Type *T); - void dumpBareDeclRef(const Decl *Node); void dumpDeclRef(const Decl *Node, const char *Label = nullptr); - void dumpName(const NamedDecl *D); + void dumpBareDeclRef(const Decl *Node) { NodeDumper.dumpBareDeclRef(Node); } bool hasNodes(const DeclContext *DC); void dumpDeclContext(const DeclContext *DC); void dumpLookups(const DeclContext *DC, bool DumpDecls); void dumpAttr(const Attr *A); // C++ Utilities - void dumpAccessSpecifier(AccessSpecifier AS); void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); void dumpTemplateParameters(const TemplateParameterList *TPL); void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); @@ -155,7 +146,7 @@ } void VisitVariableArrayType(const VariableArrayType *T) { OS << " "; - dumpSourceRange(T->getBracketsRange()); + NodeDumper.dumpSourceRange(T->getBracketsRange()); VisitArrayType(T); dumpStmt(T->getSizeExpr()); } @@ -167,14 +158,14 @@ } OS << " " << T->getIndexTypeQualifiers().getAsString(); OS << " "; - dumpSourceRange(T->getBracketsRange()); + NodeDumper.dumpSourceRange(T->getBracketsRange()); dumpTypeAsChild(T->getElementType()); dumpStmt(T->getSizeExpr()); } void VisitDependentSizedExtVectorType( const DependentSizedExtVectorType *T) { OS << " "; - dumpLocation(T->getAttributeLoc()); + NodeDumper.dumpLocation(T->getAttributeLoc()); dumpTypeAsChild(T->getElementType()); dumpStmt(T->getSizeExpr()); } @@ -426,7 +417,6 @@ void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); void VisitExprWithCleanups(const ExprWithCleanups *Node); void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); - void dumpCXXTemporary(const CXXTemporary *Temporary); void VisitLambdaExpr(const LambdaExpr *Node) { VisitExpr(Node); dumpDecl(Node->getLambdaClass()); @@ -480,77 +470,6 @@ // Utilities //===----------------------------------------------------------------------===// -void ASTDumper::dumpPointer(const void *Ptr) { - ColorScope Color(OS, ShowColors, AddressColor); - OS << ' ' << Ptr; -} - -void ASTDumper::dumpLocation(SourceLocation Loc) { - if (!SM) - return; - - ColorScope Color(OS, ShowColors, LocationColor); - SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); - - // The general format we print out is filename:line:col, but we drop pieces - // that haven't changed since the last loc printed. - PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); - - if (PLoc.isInvalid()) { - OS << ""; - return; - } - - if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { - OS << PLoc.getFilename() << ':' << PLoc.getLine() - << ':' << PLoc.getColumn(); - LastLocFilename = PLoc.getFilename(); - LastLocLine = PLoc.getLine(); - } else if (PLoc.getLine() != LastLocLine) { - OS << "line" << ':' << PLoc.getLine() - << ':' << PLoc.getColumn(); - LastLocLine = PLoc.getLine(); - } else { - OS << "col" << ':' << PLoc.getColumn(); - } -} - -void ASTDumper::dumpSourceRange(SourceRange R) { - // Can't translate locations if a SourceManager isn't available. - if (!SM) - return; - - OS << " <"; - dumpLocation(R.getBegin()); - if (R.getBegin() != R.getEnd()) { - OS << ", "; - dumpLocation(R.getEnd()); - } - OS << ">"; - - // - -} - -void ASTDumper::dumpBareType(QualType T, bool Desugar) { - ColorScope Color(OS, ShowColors, TypeColor); - - SplitQualType T_split = T.split(); - OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; - - if (Desugar && !T.isNull()) { - // If the type is sugared, also dump a (shallow) desugared type. - SplitQualType D_split = T.getSplitDesugaredType(); - if (T_split != D_split) - OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; - } -} - -void ASTDumper::dumpType(QualType T) { - OS << ' '; - dumpBareType(T); -} - void ASTDumper::dumpTypeAsChild(QualType T) { SplitQualType SQT = T.split(); if (!SQT.Quals.hasQualifiers()) @@ -558,9 +477,9 @@ dumpChild([=] { OS << "QualType"; - dumpPointer(T.getAsOpaquePtr()); + NodeDumper.dumpPointer(T.getAsOpaquePtr()); OS << " "; - dumpBareType(T, false); + NodeDumper.dumpBareType(T, false); OS << " " << T.split().Quals.getAsString(); dumpTypeAsChild(T.split().Ty); }); @@ -578,7 +497,7 @@ ColorScope Color(OS, ShowColors, TypeColor); OS << "LocInfo Type"; } - dumpPointer(T); + NodeDumper.dumpPointer(T); dumpTypeAsChild(LIT->getTypeSourceInfo()->getType()); return; } @@ -587,9 +506,9 @@ ColorScope Color(OS, ShowColors, TypeColor); OS << T->getTypeClassName() << "Type"; } - dumpPointer(T); + NodeDumper.dumpPointer(T); OS << " "; - dumpBareType(QualType(T, 0), false); + NodeDumper.dumpBareType(QualType(T, 0), false); QualType SingleStepDesugar = T->getLocallyUnqualifiedSingleStepDesugaredType(); @@ -613,28 +532,6 @@ }); } -void ASTDumper::dumpBareDeclRef(const Decl *D) { - if (!D) { - ColorScope Color(OS, ShowColors, NullColor); - OS << "<<>>"; - return; - } - - { - ColorScope Color(OS, ShowColors, DeclKindNameColor); - OS << D->getDeclKindName(); - } - dumpPointer(D); - - if (const NamedDecl *ND = dyn_cast(D)) { - ColorScope Color(OS, ShowColors, DeclNameColor); - OS << " '" << ND->getDeclName() << '\''; - } - - if (const ValueDecl *VD = dyn_cast(D)) - dumpType(VD->getType()); -} - void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { if (!D) return; @@ -646,13 +543,6 @@ }); } -void ASTDumper::dumpName(const NamedDecl *ND) { - if (ND->getDeclName()) { - ColorScope Color(OS, ShowColors, DeclNameColor); - OS << ' ' << ND->getNameAsString(); - } -} - bool ASTDumper::hasNodes(const DeclContext *DC) { if (!DC) return false; @@ -680,12 +570,12 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { dumpChild([=] { OS << "StoredDeclsMap "; - dumpBareDeclRef(cast(DC)); + NodeDumper.dumpBareDeclRef(cast(DC)); const DeclContext *Primary = DC->getPrimaryContext(); if (Primary != DC) { OS << " primary"; - dumpPointer(cast(Primary)); + NodeDumper.dumpPointer(cast(Primary)); } bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); @@ -707,7 +597,7 @@ for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI) { dumpChild([=] { - dumpBareDeclRef(*RI); + NodeDumper.dumpBareDeclRef(*RI); if ((*RI)->isHidden()) OS << " hidden"; @@ -747,8 +637,8 @@ } OS << "Attr"; } - dumpPointer(A); - dumpSourceRange(A->getRange()); + NodeDumper.dumpPointer(A); + NodeDumper.dumpSourceRange(A->getRange()); if (A->isInherited()) OS << " Inherited"; if (A->isImplicit()) @@ -790,32 +680,16 @@ // C++ Utilities //===----------------------------------------------------------------------===// -void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { - switch (AS) { - case AS_none: - break; - case AS_public: - OS << "public"; - break; - case AS_protected: - OS << "protected"; - break; - case AS_private: - OS << "private"; - break; - } -} - void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { dumpChild([=] { OS << "CXXCtorInitializer"; if (Init->isAnyMemberInitializer()) { OS << ' '; - dumpBareDeclRef(Init->getAnyMember()); + NodeDumper.dumpBareDeclRef(Init->getAnyMember()); } else if (Init->isBaseInitializer()) { - dumpType(QualType(Init->getBaseClass(), 0)); + NodeDumper.dumpType(QualType(Init->getBaseClass(), 0)); } else if (Init->isDelegatingInitializer()) { - dumpType(Init->getTypeSourceInfo()->getType()); + NodeDumper.dumpType(Init->getTypeSourceInfo()->getType()); } else { llvm_unreachable("Unknown initializer type"); } @@ -851,7 +725,7 @@ dumpChild([=] { OS << "TemplateArgument"; if (R.isValid()) - dumpSourceRange(R); + NodeDumper.dumpSourceRange(R); switch (A.getKind()) { case TemplateArgument::Null: @@ -859,7 +733,7 @@ break; case TemplateArgument::Type: OS << " type"; - dumpType(A.getAsType()); + NodeDumper.dumpType(A.getAsType()); break; case TemplateArgument::Declaration: OS << " decl"; @@ -921,13 +795,13 @@ ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << D->getDeclKindName() << "Decl"; } - dumpPointer(D); + NodeDumper.dumpPointer(D); if (D->getLexicalDeclContext() != D->getDeclContext()) OS << " parent " << cast(D->getDeclContext()); dumpPreviousDecl(OS, D); - dumpSourceRange(D->getSourceRange()); + NodeDumper.dumpSourceRange(D->getSourceRange()); OS << ' '; - dumpLocation(D->getLocation()); + NodeDumper.dumpLocation(D->getLocation()); if (D->isFromASTFile()) OS << " imported"; if (Module *M = D->getOwningModule()) @@ -969,13 +843,11 @@ }); } -void ASTDumper::VisitLabelDecl(const LabelDecl *D) { - dumpName(D); -} +void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); } void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { - dumpName(D); - dumpType(D->getUnderlyingType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getUnderlyingType()); if (D->isModulePrivate()) OS << " __module_private__"; dumpTypeAsChild(D->getUnderlyingType()); @@ -988,16 +860,16 @@ else OS << " struct"; } - dumpName(D); + NodeDumper.dumpName(D); if (D->isModulePrivate()) OS << " __module_private__"; if (D->isFixed()) - dumpType(D->getIntegerType()); + NodeDumper.dumpType(D->getIntegerType()); } void ASTDumper::VisitRecordDecl(const RecordDecl *D) { OS << ' ' << D->getKindName(); - dumpName(D); + NodeDumper.dumpName(D); if (D->isModulePrivate()) OS << " __module_private__"; if (D->isCompleteDefinition()) @@ -1005,23 +877,23 @@ } void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (const Expr *Init = D->getInitExpr()) dumpStmt(Init); } void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); for (auto *Child : D->chain()) dumpDeclRef(Child); } void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); StorageClass SC = D->getStorageClass(); if (SC != SC_None) @@ -1102,8 +974,8 @@ } void ASTDumper::VisitFieldDecl(const FieldDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (D->isMutable()) OS << " mutable"; if (D->isModulePrivate()) @@ -1116,8 +988,8 @@ } void ASTDumper::VisitVarDecl(const VarDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); StorageClass SC = D->getStorageClass(); if (SC != SC_None) OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); @@ -1151,8 +1023,8 @@ } void ASTDumper::VisitBindingDecl(const BindingDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (auto *E = D->getBinding()) dumpStmt(E); } @@ -1199,8 +1071,8 @@ } void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); OS << " combiner"; dumpStmt(D->getCombiner()); if (auto *Initializer = D->getInitializer()) { @@ -1233,15 +1105,15 @@ OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } - dumpPointer(C); - dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); + NodeDumper.dumpPointer(C); + NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); }); } } void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); dumpStmt(D->getInit()); } @@ -1250,7 +1122,7 @@ //===----------------------------------------------------------------------===// void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); if (D->isInline()) OS << " inline"; if (!D->isOriginalNamespace()) @@ -1259,22 +1131,22 @@ void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { OS << ' '; - dumpBareDeclRef(D->getNominatedNamespace()); + NodeDumper.dumpBareDeclRef(D->getNominatedNamespace()); } void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpDeclRef(D->getAliasedNamespace()); } void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { - dumpName(D); - dumpType(D->getUnderlyingType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getUnderlyingType()); dumpTypeAsChild(D->getUnderlyingType()); } void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); dumpDecl(D->getTemplatedDecl()); } @@ -1410,8 +1282,8 @@ dumpChild([=] { if (I.isVirtual()) OS << "virtual "; - dumpAccessSpecifier(I.getAccessSpecifier()); - dumpType(I.getType()); + NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier()); + NodeDumper.dumpType(I.getType()); if (I.isPackExpansion()) OS << "..."; }); @@ -1468,7 +1340,7 @@ template void ASTDumper::VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) { - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); dumpDecl(D->getTemplatedDecl()); @@ -1513,7 +1385,7 @@ } void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); } @@ -1537,7 +1409,7 @@ OS << " depth " << D->getDepth() << " index " << D->getIndex(); if (D->isParameterPack()) OS << " ..."; - dumpName(D); + NodeDumper.dumpName(D); if (D->hasDefaultArgument()) dumpTemplateArgument(D->getDefaultArgument()); if (auto *From = D->getDefaultArgStorage().getInheritedFrom()) @@ -1546,11 +1418,11 @@ } void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { - dumpType(D->getType()); + NodeDumper.dumpType(D->getType()); OS << " depth " << D->getDepth() << " index " << D->getIndex(); if (D->isParameterPack()) OS << " ..."; - dumpName(D); + NodeDumper.dumpName(D); if (D->hasDefaultArgument()) dumpTemplateArgument(D->getDefaultArgument()); if (auto *From = D->getDefaultArgStorage().getInheritedFrom()) @@ -1563,7 +1435,7 @@ OS << " depth " << D->getDepth() << " index " << D->getIndex(); if (D->isParameterPack()) OS << " ..."; - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); if (D->hasDefaultArgument()) dumpTemplateArgumentLoc(D->getDefaultArgument()); @@ -1592,12 +1464,12 @@ if (D->getQualifier()) D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); OS << D->getNameAsString(); - dumpType(D->getType()); + NodeDumper.dumpType(D->getType()); } void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { OS << ' '; - dumpBareDeclRef(D->getTargetDecl()); + NodeDumper.dumpBareDeclRef(D->getTargetDecl()); if (auto *TD = dyn_cast(D->getUnderlyingDecl())) dumpTypeAsChild(TD->getTypeForDecl()); } @@ -1609,21 +1481,21 @@ dumpChild([=] { OS << "target "; - dumpBareDeclRef(D->getTargetDecl()); + NodeDumper.dumpBareDeclRef(D->getTargetDecl()); }); dumpChild([=] { OS << "nominated "; - dumpBareDeclRef(D->getNominatedBaseClass()); + NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass()); OS << ' '; - dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); + NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); }); dumpChild([=] { OS << "constructed "; - dumpBareDeclRef(D->getConstructedBaseClass()); + NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass()); OS << ' '; - dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); + NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); }); } @@ -1636,12 +1508,12 @@ void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { OS << ' '; - dumpAccessSpecifier(D->getAccess()); + NodeDumper.dumpAccessSpecifier(D->getAccess()); } void ASTDumper::VisitFriendDecl(const FriendDecl *D) { if (TypeSourceInfo *T = D->getFriendType()) - dumpType(T->getType()); + NodeDumper.dumpType(T->getType()); else dumpDecl(D->getFriendDecl()); } @@ -1651,8 +1523,8 @@ //===----------------------------------------------------------------------===// void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (D->getSynthesize()) OS << " synthesize"; @@ -1680,8 +1552,8 @@ OS << " -"; else OS << " +"; - dumpName(D); - dumpType(D->getReturnType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getReturnType()); if (D->isThisDeclarationADefinition()) { dumpDeclContext(D); @@ -1698,7 +1570,7 @@ } void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); switch (D->getVariance()) { case ObjCTypeParamVariance::Invariant: break; @@ -1714,11 +1586,11 @@ if (D->hasExplicitBound()) OS << " bounded"; - dumpType(D->getUnderlyingType()); + NodeDumper.dumpType(D->getUnderlyingType()); } void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpDeclRef(D->getClassInterface()); dumpObjCTypeParamList(D->getTypeParamList()); dumpDeclRef(D->getImplementation()); @@ -1729,20 +1601,20 @@ } void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpDeclRef(D->getClassInterface()); dumpDeclRef(D->getCategoryDecl()); } void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); for (auto *Child : D->protocols()) dumpDeclRef(Child); } void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpObjCTypeParamList(D->getTypeParamListAsWritten()); dumpDeclRef(D->getSuperClass(), "super"); @@ -1752,7 +1624,7 @@ } void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpDeclRef(D->getSuperClass(), "super"); dumpDeclRef(D->getClassInterface()); for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), @@ -1762,13 +1634,13 @@ } void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpDeclRef(D->getClassInterface()); } void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) OS << " required"; @@ -1807,7 +1679,7 @@ } void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { - dumpName(D->getPropertyDecl()); + NodeDumper.dumpName(D->getPropertyDecl()); if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) OS << " synthesize"; else @@ -1835,7 +1707,7 @@ OS << " nested"; if (I.getVariable()) { OS << ' '; - dumpBareDeclRef(I.getVariable()); + NodeDumper.dumpBareDeclRef(I.getVariable()); } if (I.hasCopyExpr()) dumpStmt(I.getCopyExpr()); @@ -1873,8 +1745,8 @@ ColorScope Color(OS, ShowColors, StmtColor); OS << Node->getStmtClassName(); } - dumpPointer(Node); - dumpSourceRange(Node->getSourceRange()); + NodeDumper.dumpPointer(Node); + NodeDumper.dumpSourceRange(Node->getSourceRange()); } void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { @@ -1925,7 +1797,7 @@ void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { VisitStmt(Node); OS << " '" << Node->getLabel()->getName() << "'"; - dumpPointer(Node->getLabel()); + NodeDumper.dumpPointer(Node->getLabel()); } void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { @@ -1964,8 +1836,8 @@ OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } - dumpPointer(C); - dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); + NodeDumper.dumpPointer(C); + NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); if (C->isImplicit()) OS << " "; for (auto *S : C->children()) @@ -1980,7 +1852,7 @@ void ASTDumper::VisitExpr(const Expr *Node) { VisitStmt(Node); - dumpType(Node->getType()); + NodeDumper.dumpType(Node->getType()); { ColorScope Color(OS, ShowColors, ValueKindColor); @@ -2063,10 +1935,10 @@ VisitExpr(Node); OS << " "; - dumpBareDeclRef(Node->getDecl()); + NodeDumper.dumpBareDeclRef(Node->getDecl()); if (Node->getDecl() != Node->getFoundDecl()) { OS << " ("; - dumpBareDeclRef(Node->getFoundDecl()); + NodeDumper.dumpBareDeclRef(Node->getFoundDecl()); OS << ")"; } } @@ -2083,7 +1955,7 @@ if (I == E) OS << " empty"; for (; I != E; ++I) - dumpPointer(*I); + NodeDumper.dumpPointer(*I); } void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { @@ -2094,7 +1966,7 @@ OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; } OS << "='" << *Node->getDecl() << "'"; - dumpPointer(Node->getDecl()); + NodeDumper.dumpPointer(Node->getDecl()); if (Node->isFreeIvar()) OS << " isFreeIvar"; } @@ -2148,7 +2020,7 @@ } if (auto *Field = ILE->getInitializedFieldInUnion()) { OS << " field "; - dumpBareDeclRef(Field); + NodeDumper.dumpBareDeclRef(Field); } } @@ -2181,13 +2053,13 @@ break; } if (Node->isArgumentType()) - dumpType(Node->getArgumentType()); + NodeDumper.dumpType(Node->getArgumentType()); } void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { VisitExpr(Node); OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); - dumpPointer(Node->getMemberDecl()); + NodeDumper.dumpPointer(Node->getMemberDecl()); } void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { @@ -2205,9 +2077,9 @@ VisitExpr(Node); OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "' ComputeLHSTy="; - dumpBareType(Node->getComputationLHSType()); + NodeDumper.dumpBareType(Node->getComputationLHSType()); OS << " ComputeResultTy="; - dumpBareType(Node->getComputationResultType()); + NodeDumper.dumpBareType(Node->getComputationResultType()); } void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { @@ -2233,7 +2105,7 @@ dumpChild([=] { if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) { OS << "case "; - dumpType(TSI->getType()); + NodeDumper.dumpType(TSI->getType()); } else { OS << "default"; } @@ -2253,7 +2125,7 @@ void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { VisitExpr(Node); OS << " " << Node->getLabel()->getName(); - dumpPointer(Node->getLabel()); + NodeDumper.dumpPointer(Node->getLabel()); } //===----------------------------------------------------------------------===// @@ -2288,7 +2160,7 @@ void ASTDumper::VisitCXXUnresolvedConstructExpr( const CXXUnresolvedConstructExpr *Node) { VisitExpr(Node); - dumpType(Node->getTypeAsWritten()); + NodeDumper.dumpType(Node->getTypeAsWritten()); if (Node->isListInitialization()) OS << " list"; } @@ -2296,7 +2168,7 @@ void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { VisitExpr(Node); CXXConstructorDecl *Ctor = Node->getConstructor(); - dumpType(Ctor->getType()); + NodeDumper.dumpType(Ctor->getType()); if (Node->isElidable()) OS << " elidable"; if (Node->isListInitialization()) @@ -2310,7 +2182,7 @@ void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { VisitExpr(Node); OS << " "; - dumpCXXTemporary(Node->getTemporary()); + NodeDumper.dumpCXXTemporary(Node->getTemporary()); } void ASTDumper::VisitCXXNewExpr(const CXXNewExpr *Node) { @@ -2321,7 +2193,7 @@ OS << " array"; if (Node->getOperatorNew()) { OS << ' '; - dumpBareDeclRef(Node->getOperatorNew()); + NodeDumper.dumpBareDeclRef(Node->getOperatorNew()); } // We could dump the deallocation function used in case of error, but it's // usually not that interesting. @@ -2335,7 +2207,7 @@ OS << " array"; if (Node->getOperatorDelete()) { OS << ' '; - dumpBareDeclRef(Node->getOperatorDelete()); + NodeDumper.dumpBareDeclRef(Node->getOperatorDelete()); } } @@ -2344,7 +2216,7 @@ VisitExpr(Node); if (const ValueDecl *VD = Node->getExtendingDecl()) { OS << " extended by "; - dumpBareDeclRef(VD); + NodeDumper.dumpBareDeclRef(VD); } } @@ -2354,16 +2226,10 @@ dumpDeclRef(Node->getObject(i), "cleanup"); } -void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { - OS << "(CXXTemporary"; - dumpPointer(Temporary); - OS << ")"; -} - void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { VisitExpr(Node); - dumpPointer(Node->getPack()); - dumpName(Node->getPack()); + NodeDumper.dumpPointer(Node->getPack()); + NodeDumper.dumpName(Node->getPack()); if (Node->isPartiallySubstituted()) for (const auto &A : Node->getPartialArguments()) dumpTemplateArgument(A); @@ -2389,7 +2255,7 @@ case ObjCMessageExpr::Class: OS << " class="; - dumpBareType(Node->getClassReceiver()); + NodeDumper.dumpBareType(Node->getClassReceiver()); break; case ObjCMessageExpr::SuperInstance: @@ -2420,7 +2286,7 @@ void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { VisitExpr(Node); - dumpType(Node->getEncodedType()); + NodeDumper.dumpType(Node->getEncodedType()); } void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { @@ -2524,8 +2390,8 @@ ColorScope Color(OS, ShowColors, CommentColor); OS << C->getCommentKindName(); } - dumpPointer(C); - dumpSourceRange(C->getSourceRange()); + NodeDumper.dumpPointer(C); + NodeDumper.dumpSourceRange(C->getSourceRange()); ConstCommentVisitor::visit(C, FC); for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); I != E; ++I) Index: lib/AST/CMakeLists.txt =================================================================== --- lib/AST/CMakeLists.txt +++ lib/AST/CMakeLists.txt @@ -69,6 +69,7 @@ StmtViz.cpp TemplateBase.cpp TemplateName.cpp + TextNodeDumper.cpp Type.cpp TypeLoc.cpp TypePrinter.cpp Index: lib/AST/TextNodeDumper.cpp =================================================================== --- lib/AST/TextNodeDumper.cpp +++ lib/AST/TextNodeDumper.cpp @@ -0,0 +1,141 @@ +//===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements AST dumping of components of individual AST nodes. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/TextNodeDumper.h" + +using namespace clang; + +TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors, + const SourceManager *SM, + const PrintingPolicy &PrintPolicy) + : OS(OS), ShowColors(ShowColors), SM(SM), PrintPolicy(PrintPolicy) {} + +void TextNodeDumper::dumpPointer(const void *Ptr) { + ColorScope Color(OS, ShowColors, AddressColor); + OS << ' ' << Ptr; +} + +void TextNodeDumper::dumpLocation(SourceLocation Loc) { + if (!SM) + return; + + ColorScope Color(OS, ShowColors, LocationColor); + SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); + + // The general format we print out is filename:line:col, but we drop pieces + // that haven't changed since the last loc printed. + PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); + + if (PLoc.isInvalid()) { + OS << ""; + return; + } + + if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { + OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':' + << PLoc.getColumn(); + LastLocFilename = PLoc.getFilename(); + LastLocLine = PLoc.getLine(); + } else if (PLoc.getLine() != LastLocLine) { + OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); + LastLocLine = PLoc.getLine(); + } else { + OS << "col" << ':' << PLoc.getColumn(); + } +} + +void TextNodeDumper::dumpSourceRange(SourceRange R) { + // Can't translate locations if a SourceManager isn't available. + if (!SM) + return; + + OS << " <"; + dumpLocation(R.getBegin()); + if (R.getBegin() != R.getEnd()) { + OS << ", "; + dumpLocation(R.getEnd()); + } + OS << ">"; + + // +} + +void TextNodeDumper::dumpBareType(QualType T, bool Desugar) { + ColorScope Color(OS, ShowColors, TypeColor); + + SplitQualType T_split = T.split(); + OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; + + if (Desugar && !T.isNull()) { + // If the type is sugared, also dump a (shallow) desugared type. + SplitQualType D_split = T.getSplitDesugaredType(); + if (T_split != D_split) + OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; + } +} + +void TextNodeDumper::dumpType(QualType T) { + OS << ' '; + dumpBareType(T); +} + +void TextNodeDumper::dumpBareDeclRef(const Decl *D) { + if (!D) { + ColorScope Color(OS, ShowColors, NullColor); + OS << "<<>>"; + return; + } + + { + ColorScope Color(OS, ShowColors, DeclKindNameColor); + OS << D->getDeclKindName(); + } + dumpPointer(D); + + if (const NamedDecl *ND = dyn_cast(D)) { + ColorScope Color(OS, ShowColors, DeclNameColor); + OS << " '" << ND->getDeclName() << '\''; + } + + if (const ValueDecl *VD = dyn_cast(D)) + dumpType(VD->getType()); +} + +void TextNodeDumper::dumpName(const NamedDecl *ND) { + if (ND->getDeclName()) { + ColorScope Color(OS, ShowColors, DeclNameColor); + OS << ' ' << ND->getNameAsString(); + } +} + +void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) { + switch (AS) { + case AS_none: + break; + case AS_public: + OS << "public"; + break; + case AS_protected: + OS << "protected"; + break; + case AS_private: + OS << "private"; + break; + } +} + +void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { + OS << "(CXXTemporary"; + dumpPointer(Temporary); + OS << ")"; +}