diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp | 1144 |
1 files changed, 604 insertions, 540 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp index df7a2cb..ebf5e65 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TypeVisitor.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" @@ -90,24 +91,22 @@ namespace { class ASTDumper : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, - public ConstCommentVisitor<ASTDumper> { + public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> { raw_ostream &OS; const CommandTraits *Traits; const SourceManager *SM; - bool IsFirstLine; - // Indicates whether more child are expected at the current tree depth - enum IndentType { IT_Child, IT_LastChild }; + /// Pending[i] is an action to dump an entity at level i. + llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending; - /// Indents[i] indicates if another child exists at level i. - /// Used by Indent() to print the tree structure. - llvm::SmallVector<IndentType, 32> Indents; + /// Indicates whether we're at the top level. + bool TopLevel; - /// Indicates that more children will be needed at this indent level. - /// If true, prevents lastChild() from marking the node as the last child. - /// This is used when there are multiple collections of children to be - /// dumped as well as during conditional node dumping. - bool MoreChildren; + /// Indicates if we're handling the first child after entering a new depth. + bool FirstChild; + + /// Prefix for currently-being-dumped entity. + std::string Prefix; /// Keep track of the last location we print out so that we can /// print out deltas from then on out. @@ -119,21 +118,70 @@ namespace { bool ShowColors; - class IndentScope { - ASTDumper &Dumper; - // Preserve the Dumper's MoreChildren value from the previous IndentScope - bool MoreChildren; - public: - IndentScope(ASTDumper &Dumper) : Dumper(Dumper) { - MoreChildren = Dumper.hasMoreChildren(); - Dumper.setMoreChildren(false); - Dumper.indent(); + /// Dump a child of the current node. + template<typename Fn> void dumpChild(Fn doDumpChild) { + // If we're at the top level, there's nothing interesting to do; just + // run the dumper. + if (TopLevel) { + TopLevel = false; + doDumpChild(); + while (!Pending.empty()) { + Pending.back()(true); + Pending.pop_back(); + } + Prefix.clear(); + OS << "\n"; + TopLevel = true; + return; } - ~IndentScope() { - Dumper.setMoreChildren(MoreChildren); - Dumper.unindent(); + + const FullComment *OrigFC = FC; + auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) { + // Print out the appropriate tree structure and work out the prefix for + // children of this node. For instance: + // + // A Prefix = "" + // |-B Prefix = "| " + // | `-C Prefix = "| " + // `-D Prefix = " " + // |-E Prefix = " | " + // `-F Prefix = " " + // G Prefix = "" + // + // Note that the first level gets no prefix. + { + OS << '\n'; + ColorScope Color(*this, IndentColor); + OS << Prefix << (isLastChild ? '`' : '|') << '-'; + this->Prefix.push_back(isLastChild ? ' ' : '|'); + this->Prefix.push_back(' '); + } + + FirstChild = true; + unsigned Depth = Pending.size(); + + FC = OrigFC; + doDumpChild(); + + // If any children are left, they're the last at their nesting level. + // Dump those ones out now. + while (Depth < Pending.size()) { + Pending.back()(true); + this->Pending.pop_back(); + } + + // Restore the old prefix. + this->Prefix.resize(Prefix.size() - 2); + }; + + if (FirstChild) { + Pending.push_back(std::move(dumpWithIndent)); + } else { + Pending.back()(false); + Pending.back() = std::move(dumpWithIndent); } - }; + FirstChild = false; + } class ColorScope { ASTDumper &Dumper; @@ -149,78 +197,37 @@ namespace { } }; - class ChildDumper { - ASTDumper &Dumper; - - const Decl *Prev; - bool PrevRef; - public: - ChildDumper(ASTDumper &Dumper) : Dumper(Dumper), Prev(nullptr) {} - ~ChildDumper() { - if (Prev) { - Dumper.lastChild(); - dump(nullptr); - } - } - - // FIXME: This should take an arbitrary callable as the dumping action. - void dump(const Decl *D, bool Ref = false) { - if (Prev) { - if (PrevRef) - Dumper.dumpDeclRef(Prev); - else - Dumper.dumpDecl(Prev); - } - Prev = D; - PrevRef = Ref; - } - void dumpRef(const Decl *D) { dump(D, true); } - - // Give up ownership of the children of the node. By calling this, - // the caller takes back responsibility for calling lastChild(). - void release() { dump(nullptr); } - }; - public: ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM) - : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false), + : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true), LastLocFilename(""), LastLocLine(~0U), FC(nullptr), ShowColors(SM && SM->getDiagnostics().getShowColors()) { } ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM, bool ShowColors) - : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false), + : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true), LastLocFilename(""), LastLocLine(~0U), ShowColors(ShowColors) { } - ~ASTDumper() { - OS << "\n"; - } - void dumpDecl(const Decl *D); void dumpStmt(const Stmt *S); void dumpFullComment(const FullComment *C); - // Formatting - void indent(); - void unindent(); - void lastChild(); - bool hasMoreChildren(); - void setMoreChildren(bool Value); - // Utilities void dumpPointer(const void *Ptr); void dumpSourceRange(SourceRange R); void dumpLocation(SourceLocation Loc); - void dumpBareType(QualType T); + void dumpBareType(QualType T, bool Desugar = true); void dumpType(QualType 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); bool hasNodes(const DeclContext *DC); void dumpDeclContext(const DeclContext *DC); - void dumpLookups(const DeclContext *DC); + void dumpLookups(const DeclContext *DC, bool DumpDecls); void dumpAttr(const Attr *A); // C++ Utilities @@ -233,6 +240,175 @@ namespace { void dumpTemplateArgument(const TemplateArgument &A, SourceRange R = SourceRange()); + // Types + void VisitComplexType(const ComplexType *T) { + dumpTypeAsChild(T->getElementType()); + } + void VisitPointerType(const PointerType *T) { + dumpTypeAsChild(T->getPointeeType()); + } + void VisitBlockPointerType(const BlockPointerType *T) { + dumpTypeAsChild(T->getPointeeType()); + } + void VisitReferenceType(const ReferenceType *T) { + dumpTypeAsChild(T->getPointeeType()); + } + void VisitRValueReferenceType(const ReferenceType *T) { + if (T->isSpelledAsLValue()) + OS << " written as lvalue reference"; + VisitReferenceType(T); + } + void VisitMemberPointerType(const MemberPointerType *T) { + dumpTypeAsChild(T->getClass()); + dumpTypeAsChild(T->getPointeeType()); + } + void VisitArrayType(const ArrayType *T) { + switch (T->getSizeModifier()) { + case ArrayType::Normal: break; + case ArrayType::Static: OS << " static"; break; + case ArrayType::Star: OS << " *"; break; + } + OS << " " << T->getIndexTypeQualifiers().getAsString(); + dumpTypeAsChild(T->getElementType()); + } + void VisitConstantArrayType(const ConstantArrayType *T) { + OS << " " << T->getSize(); + VisitArrayType(T); + } + void VisitVariableArrayType(const VariableArrayType *T) { + OS << " "; + dumpSourceRange(T->getBracketsRange()); + VisitArrayType(T); + dumpStmt(T->getSizeExpr()); + } + void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { + VisitArrayType(T); + OS << " "; + dumpSourceRange(T->getBracketsRange()); + dumpStmt(T->getSizeExpr()); + } + void VisitDependentSizedExtVectorType( + const DependentSizedExtVectorType *T) { + OS << " "; + dumpLocation(T->getAttributeLoc()); + dumpTypeAsChild(T->getElementType()); + dumpStmt(T->getSizeExpr()); + } + void VisitVectorType(const VectorType *T) { + switch (T->getVectorKind()) { + case VectorType::GenericVector: break; + case VectorType::AltiVecVector: OS << " altivec"; break; + case VectorType::AltiVecPixel: OS << " altivec pixel"; break; + case VectorType::AltiVecBool: OS << " altivec bool"; break; + case VectorType::NeonVector: OS << " neon"; break; + case VectorType::NeonPolyVector: OS << " neon poly"; break; + } + OS << " " << T->getNumElements(); + dumpTypeAsChild(T->getElementType()); + } + void VisitFunctionType(const FunctionType *T) { + auto EI = T->getExtInfo(); + if (EI.getNoReturn()) OS << " noreturn"; + if (EI.getProducesResult()) OS << " produces_result"; + if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm(); + OS << " " << FunctionType::getNameForCallConv(EI.getCC()); + dumpTypeAsChild(T->getReturnType()); + } + void VisitFunctionProtoType(const FunctionProtoType *T) { + auto EPI = T->getExtProtoInfo(); + if (EPI.HasTrailingReturn) OS << " trailing_return"; + if (T->isConst()) OS << " const"; + if (T->isVolatile()) OS << " volatile"; + if (T->isRestrict()) OS << " restrict"; + switch (EPI.RefQualifier) { + case RQ_None: break; + case RQ_LValue: OS << " &"; break; + case RQ_RValue: OS << " &&"; break; + } + // FIXME: Exception specification. + // FIXME: Consumed parameters. + VisitFunctionType(T); + for (QualType PT : T->getParamTypes()) + dumpTypeAsChild(PT); + if (EPI.Variadic) + dumpChild([=] { OS << "..."; }); + } + void VisitUnresolvedUsingType(const UnresolvedUsingType *T) { + dumpDeclRef(T->getDecl()); + } + void VisitTypedefType(const TypedefType *T) { + dumpDeclRef(T->getDecl()); + } + void VisitTypeOfExprType(const TypeOfExprType *T) { + dumpStmt(T->getUnderlyingExpr()); + } + void VisitDecltypeType(const DecltypeType *T) { + dumpStmt(T->getUnderlyingExpr()); + } + void VisitUnaryTransformType(const UnaryTransformType *T) { + switch (T->getUTTKind()) { + case UnaryTransformType::EnumUnderlyingType: + OS << " underlying_type"; + break; + } + dumpTypeAsChild(T->getBaseType()); + } + void VisitTagType(const TagType *T) { + dumpDeclRef(T->getDecl()); + } + void VisitAttributedType(const AttributedType *T) { + // FIXME: AttrKind + dumpTypeAsChild(T->getModifiedType()); + } + void VisitTemplateTypeParmType(const TemplateTypeParmType *T) { + OS << " depth " << T->getDepth() << " index " << T->getIndex(); + if (T->isParameterPack()) OS << " pack"; + dumpDeclRef(T->getDecl()); + } + void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + dumpTypeAsChild(T->getReplacedParameter()); + } + void VisitSubstTemplateTypeParmPackType( + const SubstTemplateTypeParmPackType *T) { + dumpTypeAsChild(T->getReplacedParameter()); + dumpTemplateArgument(T->getArgumentPack()); + } + void VisitAutoType(const AutoType *T) { + if (T->isDecltypeAuto()) OS << " decltype(auto)"; + if (!T->isDeduced()) + OS << " undeduced"; + } + void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { + if (T->isTypeAlias()) OS << " alias"; + OS << " "; T->getTemplateName().dump(OS); + for (auto &Arg : *T) + dumpTemplateArgument(Arg); + if (T->isTypeAlias()) + dumpTypeAsChild(T->getAliasedType()); + } + void VisitInjectedClassNameType(const InjectedClassNameType *T) { + dumpDeclRef(T->getDecl()); + } + void VisitObjCInterfaceType(const ObjCInterfaceType *T) { + dumpDeclRef(T->getDecl()); + } + void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { + dumpTypeAsChild(T->getPointeeType()); + } + void VisitAtomicType(const AtomicType *T) { + dumpTypeAsChild(T->getValueType()); + } + void VisitAdjustedType(const AdjustedType *T) { + dumpTypeAsChild(T->getOriginalType()); + } + void VisitPackExpansionType(const PackExpansionType *T) { + if (auto N = T->getNumExpansions()) OS << " expansions " << *N; + if (!T->isSugared()) + dumpTypeAsChild(T->getPattern()); + } + // FIXME: ElaboratedType, DependentNameType, + // DependentTemplateSpecializationType, ObjCObjectType + // Decls void VisitLabelDecl(const LabelDecl *D); void VisitTypedefDecl(const TypedefDecl *D); @@ -255,8 +431,7 @@ namespace { void VisitCXXRecordDecl(const CXXRecordDecl *D); void VisitStaticAssertDecl(const StaticAssertDecl *D); template<typename SpecializationDecl> - void VisitTemplateDeclSpecialization(ChildDumper &Children, - const SpecializationDecl *D, + void VisitTemplateDeclSpecialization(const SpecializationDecl *D, bool DumpExplicitInst, bool DumpRefOnly); template<typename TemplateDecl> @@ -378,67 +553,6 @@ namespace { // Utilities //===----------------------------------------------------------------------===// -// Print out the appropriate tree structure using the Indents vector. -// Example of tree and the Indents vector at each level. -// A { } -// |-B { IT_Child } -// | `-C { IT_Child, IT_LastChild } -// `-D { IT_LastChild } -// |-E { IT_LastChild, IT_Child } -// `-F { IT_LastChild, IT_LastChild } -// Type non-last element, last element -// IT_Child "| " "|-" -// IT_LastChild " " "`-" -void ASTDumper::indent() { - if (IsFirstLine) - IsFirstLine = false; - else - OS << "\n"; - - ColorScope Color(*this, IndentColor); - for (SmallVectorImpl<IndentType>::const_iterator I = Indents.begin(), - E = Indents.end(); - I != E; ++I) { - switch (*I) { - case IT_Child: - if (I == E - 1) - OS << "|-"; - else - OS << "| "; - continue; - case IT_LastChild: - if (I == E - 1) - OS << "`-"; - else - OS << " "; - continue; - } - llvm_unreachable("Invalid IndentType"); - } - Indents.push_back(IT_Child); -} - -void ASTDumper::unindent() { - Indents.pop_back(); -} - -// Call before each potential last child node is to be dumped. If MoreChildren -// is false, then this is the last child, otherwise treat as a regular node. -void ASTDumper::lastChild() { - if (!hasMoreChildren()) - Indents.back() = IT_LastChild; -} - -// MoreChildren should be set before calling another function that may print -// additional nodes to prevent conflicting final child nodes. -bool ASTDumper::hasMoreChildren() { - return MoreChildren; -} - -void ASTDumper::setMoreChildren(bool Value) { - MoreChildren = Value; -} - void ASTDumper::dumpPointer(const void *Ptr) { ColorScope Color(*this, AddressColor); OS << ' ' << Ptr; @@ -491,13 +605,13 @@ void ASTDumper::dumpSourceRange(SourceRange R) { } -void ASTDumper::dumpBareType(QualType T) { +void ASTDumper::dumpBareType(QualType T, bool Desugar) { ColorScope Color(*this, TypeColor); - + SplitQualType T_split = T.split(); OS << "'" << QualType::getAsString(T_split) << "'"; - if (!T.isNull()) { + 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) @@ -510,6 +624,59 @@ void ASTDumper::dumpType(QualType T) { dumpBareType(T); } +void ASTDumper::dumpTypeAsChild(QualType T) { + SplitQualType SQT = T.split(); + if (!SQT.Quals.hasQualifiers()) + return dumpTypeAsChild(SQT.Ty); + + dumpChild([=] { + OS << "QualType"; + dumpPointer(T.getAsOpaquePtr()); + OS << " "; + dumpBareType(T, false); + OS << " " << T.split().Quals.getAsString(); + dumpTypeAsChild(T.split().Ty); + }); +} + +void ASTDumper::dumpTypeAsChild(const Type *T) { + dumpChild([=] { + if (!T) { + ColorScope Color(*this, NullColor); + OS << "<<<NULL>>>"; + return; + } + + { + ColorScope Color(*this, TypeColor); + OS << T->getTypeClassName() << "Type"; + } + dumpPointer(T); + OS << " "; + dumpBareType(QualType(T, 0), false); + + QualType SingleStepDesugar = + T->getLocallyUnqualifiedSingleStepDesugaredType(); + if (SingleStepDesugar != QualType(T, 0)) + OS << " sugar"; + if (T->isDependentType()) + OS << " dependent"; + else if (T->isInstantiationDependentType()) + OS << " instantiation_dependent"; + if (T->isVariablyModifiedType()) + OS << " variably_modified"; + if (T->containsUnexpandedParameterPack()) + OS << " contains_unexpanded_pack"; + if (T->isFromAST()) + OS << " imported"; + + TypeVisitor<ASTDumper>::Visit(T); + + if (SingleStepDesugar != QualType(T, 0)) + dumpTypeAsChild(SingleStepDesugar); + }); +} + void ASTDumper::dumpBareDeclRef(const Decl *D) { { ColorScope Color(*this, DeclKindNameColor); @@ -530,10 +697,11 @@ void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { if (!D) return; - IndentScope Indent(*this); - if (Label) - OS << Label << ' '; - dumpBareDeclRef(D); + dumpChild([=]{ + if (Label) + OS << Label << ' '; + dumpBareDeclRef(D); + }); } void ASTDumper::dumpName(const NamedDecl *ND) { @@ -555,86 +723,96 @@ void ASTDumper::dumpDeclContext(const DeclContext *DC) { if (!DC) return; - ChildDumper Children(*this); for (auto *D : DC->noload_decls()) - Children.dump(D); + dumpDecl(D); if (DC->hasExternalLexicalStorage()) { - Children.release(); - - lastChild(); - IndentScope Indent(*this); - ColorScope Color(*this, UndeserializedColor); - OS << "<undeserialized declarations>"; + dumpChild([=]{ + ColorScope Color(*this, UndeserializedColor); + OS << "<undeserialized declarations>"; + }); } } -void ASTDumper::dumpLookups(const DeclContext *DC) { - IndentScope Indent(*this); +void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { + dumpChild([=] { + OS << "StoredDeclsMap "; + dumpBareDeclRef(cast<Decl>(DC)); - OS << "StoredDeclsMap "; - dumpBareDeclRef(cast<Decl>(DC)); + const DeclContext *Primary = DC->getPrimaryContext(); + if (Primary != DC) { + OS << " primary"; + dumpPointer(cast<Decl>(Primary)); + } - const DeclContext *Primary = DC->getPrimaryContext(); - if (Primary != DC) { - OS << " primary"; - dumpPointer(cast<Decl>(Primary)); - } + bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); - bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); + DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(), + E = Primary->noload_lookups_end(); + while (I != E) { + DeclarationName Name = I.getLookupName(); + DeclContextLookupResult R = *I++; - DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(), - E = Primary->noload_lookups_end(); - while (I != E) { - DeclarationName Name = I.getLookupName(); - DeclContextLookupResult R = *I++; - if (I == E && !HasUndeserializedLookups) - lastChild(); + dumpChild([=] { + OS << "DeclarationName "; + { + ColorScope Color(*this, DeclNameColor); + OS << '\'' << Name << '\''; + } - IndentScope Indent(*this); - OS << "DeclarationName "; - { - ColorScope Color(*this, DeclNameColor); - OS << '\'' << Name << '\''; + for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); + RI != RE; ++RI) { + dumpChild([=] { + dumpBareDeclRef(*RI); + + if ((*RI)->isHidden()) + OS << " hidden"; + + // If requested, dump the redecl chain for this lookup. + if (DumpDecls) { + // Dump earliest decl first. + std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) { + if (Decl *Prev = D->getPreviousDecl()) + DumpWithPrev(Prev); + dumpDecl(D); + }; + DumpWithPrev(*RI); + } + }); + } + }); } - for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); - RI != RE; ++RI) { - if (RI + 1 == RE) - lastChild(); - dumpDeclRef(*RI); - if ((*RI)->isHidden()) - OS << " hidden"; + if (HasUndeserializedLookups) { + dumpChild([=] { + ColorScope Color(*this, UndeserializedColor); + OS << "<undeserialized lookups>"; + }); } - } - - if (HasUndeserializedLookups) { - lastChild(); - IndentScope Indent(*this); - ColorScope Color(*this, UndeserializedColor); - OS << "<undeserialized lookups>"; - } + }); } void ASTDumper::dumpAttr(const Attr *A) { - IndentScope Indent(*this); - { - ColorScope Color(*this, AttrColor); + dumpChild([=] { + { + ColorScope Color(*this, AttrColor); - switch (A->getKind()) { + switch (A->getKind()) { #define ATTR(X) case attr::X: OS << #X; break; #include "clang/Basic/AttrList.inc" - default: llvm_unreachable("unexpected attribute kind"); + default: + llvm_unreachable("unexpected attribute kind"); + } + OS << "Attr"; } - OS << "Attr"; - } - dumpPointer(A); - dumpSourceRange(A->getRange()); - if (A->isInherited()) - OS << " Inherited"; - if (A->isImplicit()) - OS << " Implicit"; + dumpPointer(A); + dumpSourceRange(A->getRange()); + if (A->isInherited()) + OS << " Inherited"; + if (A->isImplicit()) + OS << " Implicit"; #include "clang/AST/AttrDump.inc" + }); } static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} @@ -687,15 +865,20 @@ void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { } void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { - IndentScope Indent(*this); - OS << "CXXCtorInitializer"; - if (Init->isAnyMemberInitializer()) { - OS << ' '; - dumpBareDeclRef(Init->getAnyMember()); - } else { - dumpType(QualType(Init->getBaseClass(), 0)); - } - dumpStmt(Init->getInit()); + dumpChild([=] { + OS << "CXXCtorInitializer"; + if (Init->isAnyMemberInitializer()) { + OS << ' '; + dumpBareDeclRef(Init->getAnyMember()); + } else if (Init->isBaseInitializer()) { + dumpType(QualType(Init->getBaseClass(), 0)); + } else if (Init->isDelegatingInitializer()) { + dumpType(Init->getTypeSourceInfo()->getType()); + } else { + llvm_unreachable("Unknown initializer type"); + } + dumpStmt(Init->getInit()); + }); } void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { @@ -709,11 +892,8 @@ void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { void ASTDumper::dumpTemplateArgumentListInfo( const TemplateArgumentListInfo &TALI) { - for (unsigned i = 0, e = TALI.size(); i < e; ++i) { - if (i + 1 == e) - lastChild(); + for (unsigned i = 0, e = TALI.size(); i < e; ++i) dumpTemplateArgumentLoc(TALI[i]); - } } void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { @@ -726,54 +906,49 @@ void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { } void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { - IndentScope Indent(*this); - OS << "TemplateArgument"; - if (R.isValid()) - dumpSourceRange(R); - - switch (A.getKind()) { - case TemplateArgument::Null: - OS << " null"; - break; - case TemplateArgument::Type: - OS << " type"; - lastChild(); - dumpType(A.getAsType()); - break; - case TemplateArgument::Declaration: - OS << " decl"; - lastChild(); - dumpDeclRef(A.getAsDecl()); - break; - case TemplateArgument::NullPtr: - OS << " nullptr"; - break; - case TemplateArgument::Integral: - OS << " integral " << A.getAsIntegral(); - break; - case TemplateArgument::Template: - OS << " template "; - A.getAsTemplate().dump(OS); - break; - case TemplateArgument::TemplateExpansion: - OS << " template expansion"; - A.getAsTemplateOrTemplatePattern().dump(OS); - break; - case TemplateArgument::Expression: - OS << " expr"; - lastChild(); - dumpStmt(A.getAsExpr()); - break; - case TemplateArgument::Pack: - OS << " pack"; - for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); - dumpTemplateArgument(*I); + dumpChild([=] { + OS << "TemplateArgument"; + if (R.isValid()) + dumpSourceRange(R); + + switch (A.getKind()) { + case TemplateArgument::Null: + OS << " null"; + break; + case TemplateArgument::Type: + OS << " type"; + dumpType(A.getAsType()); + break; + case TemplateArgument::Declaration: + OS << " decl"; + dumpDeclRef(A.getAsDecl()); + break; + case TemplateArgument::NullPtr: + OS << " nullptr"; + break; + case TemplateArgument::Integral: + OS << " integral " << A.getAsIntegral(); + break; + case TemplateArgument::Template: + OS << " template "; + A.getAsTemplate().dump(OS); + break; + case TemplateArgument::TemplateExpansion: + OS << " template expansion"; + A.getAsTemplateOrTemplatePattern().dump(OS); + break; + case TemplateArgument::Expression: + OS << " expr"; + dumpStmt(A.getAsExpr()); + break; + case TemplateArgument::Pack: + OS << " pack"; + for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); + I != E; ++I) + dumpTemplateArgument(*I); + break; } - break; - } + }); } //===----------------------------------------------------------------------===// @@ -781,64 +956,57 @@ void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { //===----------------------------------------------------------------------===// void ASTDumper::dumpDecl(const Decl *D) { - IndentScope Indent(*this); + dumpChild([=] { + if (!D) { + ColorScope Color(*this, NullColor); + OS << "<<<NULL>>>"; + return; + } - if (!D) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; - return; - } + { + ColorScope Color(*this, DeclKindNameColor); + OS << D->getDeclKindName() << "Decl"; + } + dumpPointer(D); + if (D->getLexicalDeclContext() != D->getDeclContext()) + OS << " parent " << cast<Decl>(D->getDeclContext()); + dumpPreviousDecl(OS, D); + dumpSourceRange(D->getSourceRange()); + OS << ' '; + dumpLocation(D->getLocation()); + if (Module *M = D->getOwningModule()) + OS << " in " << M->getFullModuleName(); + if (const NamedDecl *ND = dyn_cast<NamedDecl>(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<FunctionDecl>(D)) + if (FD->isConstexpr()) + OS << " constexpr"; - { - ColorScope Color(*this, DeclKindNameColor); - OS << D->getDeclKindName() << "Decl"; - } - dumpPointer(D); - if (D->getLexicalDeclContext() != D->getDeclContext()) - OS << " parent " << cast<Decl>(D->getDeclContext()); - dumpPreviousDecl(OS, D); - dumpSourceRange(D->getSourceRange()); - OS << ' '; - dumpLocation(D->getLocation()); - if (Module *M = D->getOwningModule()) - OS << " in " << M->getFullModuleName(); - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - if (ND->isHidden()) - OS << " hidden"; - if (D->isImplicit()) - OS << " implicit"; - if (D->isUsed()) - OS << " used"; - else if (D->isReferenced()) - OS << " referenced"; - if (D->isInvalidDecl()) - OS << " invalid"; - - bool HasAttrs = D->hasAttrs(); - const FullComment *Comment = - D->getASTContext().getLocalCommentForDeclUncached(D); - // Decls within functions are visited by the body - bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && - hasNodes(dyn_cast<DeclContext>(D)); - - setMoreChildren(HasAttrs || Comment || HasDeclContext); - ConstDeclVisitor<ASTDumper>::Visit(D); - - setMoreChildren(Comment || HasDeclContext); - for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); - dumpAttr(*I); - } - setMoreChildren(HasDeclContext); - lastChild(); - dumpFullComment(Comment); + ConstDeclVisitor<ASTDumper>::Visit(D); - setMoreChildren(false); - if (HasDeclContext) - dumpDeclContext(cast<DeclContext>(D)); + for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E; + ++I) + dumpAttr(*I); + + if (const FullComment *Comment = + D->getASTContext().getLocalCommentForDeclUncached(D)) + dumpFullComment(Comment); + + // Decls within functions are visited by the body. + if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && + hasNodes(dyn_cast<DeclContext>(D))) + dumpDeclContext(cast<DeclContext>(D)); + }); } void ASTDumper::VisitLabelDecl(const LabelDecl *D) { @@ -878,19 +1046,16 @@ void ASTDumper::VisitRecordDecl(const RecordDecl *D) { void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { dumpName(D); dumpType(D->getType()); - if (const Expr *Init = D->getInitExpr()) { - lastChild(); + if (const Expr *Init = D->getInitExpr()) dumpStmt(Init); - } } void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { dumpName(D); dumpType(D->getType()); - ChildDumper Children(*this); for (auto *Child : D->chain()) - Children.dumpRef(Child); + dumpDeclRef(Child); } void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { @@ -914,73 +1079,39 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - switch (EPI.ExceptionSpecType) { + switch (EPI.ExceptionSpec.Type) { default: break; case EST_Unevaluated: - OS << " noexcept-unevaluated " << EPI.ExceptionSpecDecl; + OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; break; case EST_Uninstantiated: - OS << " noexcept-uninstantiated " << EPI.ExceptionSpecTemplate; + OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; break; } } - bool OldMoreChildren = hasMoreChildren(); - const FunctionTemplateSpecializationInfo *FTSI = - D->getTemplateSpecializationInfo(); - bool HasTemplateSpecialization = FTSI; - - bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() != - D->getDeclsInPrototypeScope().end(); - - bool HasFunctionDecls = D->param_begin() != D->param_end(); - - const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D); - bool HasCtorInitializers = C && C->init_begin() != C->init_end(); - - bool HasDeclarationBody = D->doesThisDeclarationHaveABody(); - - setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls || - HasCtorInitializers || HasDeclarationBody); - if (HasTemplateSpecialization) { - lastChild(); + if (const FunctionTemplateSpecializationInfo *FTSI = + D->getTemplateSpecializationInfo()) dumpTemplateArgumentList(*FTSI->TemplateArguments); - } - setMoreChildren(OldMoreChildren || HasFunctionDecls || - HasCtorInitializers || HasDeclarationBody); for (ArrayRef<NamedDecl *>::iterator I = D->getDeclsInPrototypeScope().begin(), - E = D->getDeclsInPrototypeScope().end(); I != E; ++I) { - if (I + 1 == E) - lastChild(); + E = D->getDeclsInPrototypeScope().end(); I != E; ++I) dumpDecl(*I); - } - setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody); for (FunctionDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpDecl(*I); - } - - setMoreChildren(OldMoreChildren || HasDeclarationBody); - if (HasCtorInitializers) + + if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), E = C->init_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpCXXCtorInitializer(*I); - } - setMoreChildren(OldMoreChildren); - if (HasDeclarationBody) { - lastChild(); + if (D->doesThisDeclarationHaveABody()) dumpStmt(D->getBody()); - } } void ASTDumper::VisitFieldDecl(const FieldDecl *D) { @@ -991,21 +1122,10 @@ void ASTDumper::VisitFieldDecl(const FieldDecl *D) { if (D->isModulePrivate()) OS << " __module_private__"; - bool OldMoreChildren = hasMoreChildren(); - bool IsBitField = D->isBitField(); - Expr *Init = D->getInClassInitializer(); - bool HasInit = Init; - - setMoreChildren(OldMoreChildren || HasInit); - if (IsBitField) { - lastChild(); + if (D->isBitField()) dumpStmt(D->getBitWidth()); - } - setMoreChildren(OldMoreChildren); - if (HasInit) { - lastChild(); + if (Expr *Init = D->getInClassInitializer()) dumpStmt(Init); - } } void ASTDumper::VisitVarDecl(const VarDecl *D) { @@ -1029,13 +1149,11 @@ void ASTDumper::VisitVarDecl(const VarDecl *D) { case VarDecl::CallInit: OS << " callinit"; break; case VarDecl::ListInit: OS << " listinit"; break; } - lastChild(); dumpStmt(D->getInit()); } } void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { - lastChild(); dumpStmt(D->getAsmString()); } @@ -1082,25 +1200,24 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { return; for (const auto &I : D->bases()) { - IndentScope Indent(*this); - if (I.isVirtual()) - OS << "virtual "; - dumpAccessSpecifier(I.getAccessSpecifier()); - dumpType(I.getType()); - if (I.isPackExpansion()) - OS << "..."; + dumpChild([=] { + if (I.isVirtual()) + OS << "virtual "; + dumpAccessSpecifier(I.getAccessSpecifier()); + dumpType(I.getType()); + if (I.isPackExpansion()) + OS << "..."; + }); } } void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { dumpStmt(D->getAssertExpr()); - lastChild(); dumpStmt(D->getMessage()); } template<typename SpecializationDecl> -void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children, - const SpecializationDecl *D, +void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, bool DumpExplicitInst, bool DumpRefOnly) { bool DumpedAny = false; @@ -1125,7 +1242,10 @@ void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children, // Fall through. case TSK_Undeclared: case TSK_ImplicitInstantiation: - Children.dump(Redecl, DumpRefOnly); + if (DumpRefOnly) + dumpDeclRef(Redecl); + else + dumpDecl(Redecl); DumpedAny = true; break; case TSK_ExplicitSpecialization: @@ -1135,7 +1255,7 @@ void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children, // Ensure we dump at least one decl for each specialization. if (!DumpedAny) - Children.dumpRef(D); + dumpDeclRef(D); } template<typename TemplateDecl> @@ -1144,11 +1264,10 @@ void ASTDumper::VisitTemplateDecl(const TemplateDecl *D, dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); - ChildDumper Children(*this); - Children.dump(D->getTemplatedDecl()); + dumpDecl(D->getTemplatedDecl()); for (auto *Child : D->specializations()) - VisitTemplateDeclSpecialization(Children, Child, DumpExplicitInst, + VisitTemplateDeclSpecialization(Child, DumpExplicitInst, !D->isCanonicalDecl()); } @@ -1206,10 +1325,8 @@ void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { if (D->isParameterPack()) OS << " ..."; dumpName(D); - if (D->hasDefaultArgument()) { - lastChild(); + if (D->hasDefaultArgument()) dumpTemplateArgument(D->getDefaultArgument()); - } } void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { @@ -1217,10 +1334,8 @@ void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { if (D->isParameterPack()) OS << " ..."; dumpName(D); - if (D->hasDefaultArgument()) { - lastChild(); + if (D->hasDefaultArgument()) dumpTemplateArgument(D->getDefaultArgument()); - } } void ASTDumper::VisitTemplateTemplateParmDecl( @@ -1229,10 +1344,8 @@ void ASTDumper::VisitTemplateTemplateParmDecl( OS << " ..."; dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); - if (D->hasDefaultArgument()) { - lastChild(); + if (D->hasDefaultArgument()) dumpTemplateArgumentLoc(D->getDefaultArgument()); - } } void ASTDumper::VisitUsingDecl(const UsingDecl *D) { @@ -1273,7 +1386,6 @@ void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { } void ASTDumper::VisitFriendDecl(const FriendDecl *D) { - lastChild(); if (TypeSourceInfo *T = D->getFriendType()) dumpType(T->getType()); else @@ -1317,96 +1429,66 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { dumpName(D); dumpType(D->getReturnType()); - bool OldMoreChildren = hasMoreChildren(); - bool IsVariadic = D->isVariadic(); - bool HasBody = D->hasBody(); - - setMoreChildren(OldMoreChildren || IsVariadic || HasBody); if (D->isThisDeclarationADefinition()) { - lastChild(); dumpDeclContext(D); } else { for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpDecl(*I); - } } - setMoreChildren(OldMoreChildren || HasBody); - if (IsVariadic) { - lastChild(); - IndentScope Indent(*this); - OS << "..."; - } + if (D->isVariadic()) + dumpChild([=] { OS << "..."; }); - setMoreChildren(OldMoreChildren); - if (HasBody) { - lastChild(); + if (D->hasBody()) dumpStmt(D->getBody()); - } } void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { dumpName(D); dumpDeclRef(D->getClassInterface()); - if (D->protocol_begin() == D->protocol_end()) - lastChild(); dumpDeclRef(D->getImplementation()); for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), E = D->protocol_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpDeclRef(*I); - } } void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { dumpName(D); dumpDeclRef(D->getClassInterface()); - lastChild(); dumpDeclRef(D->getCategoryDecl()); } void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { dumpName(D); - ChildDumper Children(*this); for (auto *Child : D->protocols()) - Children.dumpRef(Child); + dumpDeclRef(Child); } void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { dumpName(D); dumpDeclRef(D->getSuperClass(), "super"); - ChildDumper Children(*this); - Children.dumpRef(D->getImplementation()); + dumpDeclRef(D->getImplementation()); for (auto *Child : D->protocols()) - Children.dumpRef(Child); + dumpDeclRef(Child); } void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { dumpName(D); dumpDeclRef(D->getSuperClass(), "super"); - if (D->init_begin() == D->init_end()) - lastChild(); dumpDeclRef(D->getClassInterface()); for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), E = D->init_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpCXXCtorInitializer(*I); - } } void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { dumpName(D); - lastChild(); dumpDeclRef(D->getClassInterface()); } @@ -1441,15 +1523,10 @@ void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { OS << " strong"; if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) OS << " unsafe_unretained"; - if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { - if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) - lastChild(); + if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) dumpDeclRef(D->getGetterMethodDecl(), "getter"); - } - if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { - lastChild(); + if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) dumpDeclRef(D->getSetterMethodDecl(), "setter"); - } } } @@ -1460,7 +1537,6 @@ void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { else OS << " dynamic"; dumpDeclRef(D->getPropertyDecl()); - lastChild(); dumpDeclRef(D->getPropertyIvarDecl()); } @@ -1468,30 +1544,27 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) { for (auto I : D->params()) dumpDecl(I); - if (D->isVariadic()) { - IndentScope Indent(*this); - OS << "..."; - } + if (D->isVariadic()) + dumpChild([=]{ OS << "..."; }); + + if (D->capturesCXXThis()) + dumpChild([=]{ OS << "capture this"; }); - if (D->capturesCXXThis()) { - IndentScope Indent(*this); - OS << "capture this"; - } for (const auto &I : D->captures()) { - IndentScope Indent(*this); - OS << "capture"; - if (I.isByRef()) - OS << " byref"; - if (I.isNested()) - OS << " nested"; - if (I.getVariable()) { - OS << ' '; - dumpBareDeclRef(I.getVariable()); - } - if (I.hasCopyExpr()) - dumpStmt(I.getCopyExpr()); + dumpChild([=] { + OS << "capture"; + if (I.isByRef()) + OS << " byref"; + if (I.isNested()) + OS << " nested"; + if (I.getVariable()) { + OS << ' '; + dumpBareDeclRef(I.getVariable()); + } + if (I.hasCopyExpr()) + dumpStmt(I.getCopyExpr()); + }); } - lastChild(); dumpStmt(D->getBody()); } @@ -1500,29 +1573,23 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) { //===----------------------------------------------------------------------===// void ASTDumper::dumpStmt(const Stmt *S) { - IndentScope Indent(*this); + dumpChild([=] { + if (!S) { + ColorScope Color(*this, NullColor); + OS << "<<<NULL>>>"; + return; + } - if (!S) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; - return; - } + if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { + VisitDeclStmt(DS); + return; + } - if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { - VisitDeclStmt(DS); - return; - } + ConstStmtVisitor<ASTDumper>::Visit(S); - setMoreChildren(!S->children().empty()); - ConstStmtVisitor<ASTDumper>::Visit(S); - setMoreChildren(false); - for (Stmt::const_child_range CI = S->children(); CI; ++CI) { - Stmt::const_child_range Next = CI; - ++Next; - if (!Next) - lastChild(); - dumpStmt(*CI); - } + for (Stmt::const_child_range CI = S->children(); CI; ++CI) + dumpStmt(*CI); + }); } void ASTDumper::VisitStmt(const Stmt *Node) { @@ -1538,22 +1605,16 @@ void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { VisitStmt(Node); for (DeclStmt::const_decl_iterator I = Node->decl_begin(), E = Node->decl_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpDecl(*I); - } } void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { VisitStmt(Node); for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), E = Node->getAttrs().end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); + I != E; ++I) dumpAttr(*I); - } } void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { @@ -1693,15 +1754,7 @@ void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { VisitExpr(Node); - switch (Node->getIdentType()) { - default: llvm_unreachable("unknown case"); - case PredefinedExpr::Func: OS << " __func__"; break; - case PredefinedExpr::Function: OS << " __FUNCTION__"; break; - case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break; - case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break; - case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; - case PredefinedExpr::FuncSig: OS << " __FUNCSIG__"; break; - } + OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType()); } void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { @@ -1734,12 +1787,10 @@ void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { VisitExpr(ILE); if (auto *Filler = ILE->getArrayFiller()) { - if (!ILE->getNumInits()) - lastChild(); - IndentScope Indent(*this); - OS << "array filler"; - lastChild(); - dumpStmt(Filler); + dumpChild([=] { + OS << "array filler"; + dumpStmt(Filler); + }); } if (auto *Field = ILE->getInitializedFieldInUnion()) { OS << " field "; @@ -1805,10 +1856,8 @@ void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { VisitExpr(Node); - if (Expr *Source = Node->getSourceExpr()) { - lastChild(); + if (Expr *Source = Node->getSourceExpr()) dumpStmt(Source); - } } // GNU extensions. @@ -2024,27 +2073,24 @@ void ASTDumper::dumpFullComment(const FullComment *C) { } void ASTDumper::dumpComment(const Comment *C) { - IndentScope Indent(*this); - - if (!C) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; - return; - } + dumpChild([=] { + if (!C) { + ColorScope Color(*this, NullColor); + OS << "<<<NULL>>>"; + return; + } - { - ColorScope Color(*this, CommentColor); - OS << C->getCommentKindName(); - } - dumpPointer(C); - dumpSourceRange(C->getSourceRange()); - ConstCommentVisitor<ASTDumper>::visit(C); - for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); - I != E; ++I) { - if (I + 1 == E) - lastChild(); - dumpComment(*I); - } + { + ColorScope Color(*this, CommentColor); + OS << C->getCommentKindName(); + } + dumpPointer(C); + dumpSourceRange(C->getSourceRange()); + ConstCommentVisitor<ASTDumper>::visit(C); + for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); + I != E; ++I) + dumpComment(*I); + }); } void ASTDumper::visitTextComment(const TextComment *C) { @@ -2148,6 +2194,23 @@ void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { } //===----------------------------------------------------------------------===// +// Type method implementations +//===----------------------------------------------------------------------===// + +void QualType::dump(const char *msg) const { + if (msg) + llvm::errs() << msg << ": "; + dump(); +} + +LLVM_DUMP_METHOD void QualType::dump() const { + ASTDumper Dumper(llvm::errs(), nullptr, nullptr); + Dumper.dumpTypeAsChild(*this); +} + +LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); } + +//===----------------------------------------------------------------------===// // Decl method implementations //===----------------------------------------------------------------------===// @@ -2169,13 +2232,14 @@ LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { dumpLookups(llvm::errs()); } -LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS) const { +LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, + bool DumpDecls) const { const DeclContext *DC = this; while (!DC->isTranslationUnit()) DC = DC->getParent(); ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); - P.dumpLookups(this); + P.dumpLookups(this, DumpDecls); } //===----------------------------------------------------------------------===// |