ASTDumper.cpp revision 296417
138032Speter//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===// 238032Speter// 338032Speter// The LLVM Compiler Infrastructure 438032Speter// 538032Speter// This file is distributed under the University of Illinois Open Source 638032Speter// License. See LICENSE.TXT for details. 738032Speter// 838032Speter//===----------------------------------------------------------------------===// 938032Speter// 1038032Speter// This file implements the AST dump methods, which dump out the 1138032Speter// AST in a form that exposes type details and other fields. 1238032Speter// 1338032Speter//===----------------------------------------------------------------------===// 1438032Speter 1538032Speter#include "clang/AST/ASTContext.h" 1638032Speter#include "clang/AST/Attr.h" 1738032Speter#include "clang/AST/CommentVisitor.h" 1838032Speter#include "clang/AST/DeclCXX.h" 1938032Speter#include "clang/AST/DeclLookups.h" 2038032Speter#include "clang/AST/DeclObjC.h" 2138032Speter#include "clang/AST/DeclVisitor.h" 2238032Speter#include "clang/AST/StmtVisitor.h" 2338032Speter#include "clang/AST/TypeVisitor.h" 2438032Speter#include "clang/Basic/Builtins.h" 2538032Speter#include "clang/Basic/Module.h" 2638032Speter#include "clang/Basic/SourceManager.h" 2738032Speter#include "clang/Sema/LocInfoType.h" 2838032Speter#include "llvm/Support/raw_ostream.h" 2938032Speterusing namespace clang; 3038032Speterusing namespace clang::comments; 3138032Speter 3238032Speter//===----------------------------------------------------------------------===// 3338032Speter// ASTDumper Visitor 3438032Speter//===----------------------------------------------------------------------===// 3538032Speter 3638032Speternamespace { 3738032Speter // Colors used for various parts of the AST dump 3838032Speter // Do not use bold yellow for any text. It is hard to read on white screens. 3938032Speter 4038032Speter struct TerminalColor { 4138032Speter raw_ostream::Colors Color; 4238032Speter bool Bold; 4338032Speter }; 4438032Speter 4538032Speter // Red - CastColor 4638032Speter // Green - TypeColor 4738032Speter // Bold Green - DeclKindNameColor, UndeserializedColor 4838032Speter // Yellow - AddressColor, LocationColor 4938032Speter // Blue - CommentColor, NullColor, IndentColor 5038032Speter // Bold Blue - AttrColor 5138032Speter // Bold Magenta - StmtColor 5238032Speter // Cyan - ValueKindColor, ObjectKindColor 5338032Speter // Bold Cyan - ValueColor, DeclNameColor 5438032Speter 5538032Speter // Decl kind names (VarDecl, FunctionDecl, etc) 5638032Speter static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true }; 5738032Speter // Attr names (CleanupAttr, GuardedByAttr, etc) 5838032Speter static const TerminalColor AttrColor = { raw_ostream::BLUE, true }; 5938032Speter // Statement names (DeclStmt, ImplicitCastExpr, etc) 6038032Speter static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true }; 6138032Speter // Comment names (FullComment, ParagraphComment, TextComment, etc) 6238032Speter static const TerminalColor CommentColor = { raw_ostream::BLUE, false }; 6338032Speter 6438032Speter // Type names (int, float, etc, plus user defined types) 6538032Speter static const TerminalColor TypeColor = { raw_ostream::GREEN, false }; 6638032Speter 6738032Speter // Pointer address 6838032Speter static const TerminalColor AddressColor = { raw_ostream::YELLOW, false }; 6938032Speter // Source locations 7038032Speter static const TerminalColor LocationColor = { raw_ostream::YELLOW, false }; 7138032Speter 7238032Speter // lvalue/xvalue 7338032Speter static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false }; 7438032Speter // bitfield/objcproperty/objcsubscript/vectorcomponent 7538032Speter static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false }; 7638032Speter 7738032Speter // Null statements 7838032Speter static const TerminalColor NullColor = { raw_ostream::BLUE, false }; 7938032Speter 8038032Speter // Undeserialized entities 8138032Speter static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true }; 8238032Speter 8338032Speter // CastKind from CastExpr's 8438032Speter static const TerminalColor CastColor = { raw_ostream::RED, false }; 8538032Speter 8638032Speter // Value of the statement 8738032Speter static const TerminalColor ValueColor = { raw_ostream::CYAN, true }; 8838032Speter // Decl names 8938032Speter static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; 9038032Speter 9138032Speter // Indents ( `, -. | ) 9238032Speter static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; 9338032Speter 9438032Speter class ASTDumper 9538032Speter : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, 9638032Speter public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> { 9738032Speter raw_ostream &OS; 9838032Speter const CommandTraits *Traits; 9938032Speter const SourceManager *SM; 10038032Speter 10138032Speter /// Pending[i] is an action to dump an entity at level i. 10238032Speter llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending; 10338032Speter 10438032Speter /// Indicates whether we're at the top level. 10538032Speter bool TopLevel; 10638032Speter 10738032Speter /// Indicates if we're handling the first child after entering a new depth. 10838032Speter bool FirstChild; 10938032Speter 11038032Speter /// Prefix for currently-being-dumped entity. 11138032Speter std::string Prefix; 11238032Speter 11338032Speter /// Keep track of the last location we print out so that we can 11438032Speter /// print out deltas from then on out. 11538032Speter const char *LastLocFilename; 11638032Speter unsigned LastLocLine; 11738032Speter 11838032Speter /// The \c FullComment parent of the comment being dumped. 11938032Speter const FullComment *FC; 12038032Speter 12138032Speter bool ShowColors; 12238032Speter 12338032Speter /// Dump a child of the current node. 12438032Speter template<typename Fn> void dumpChild(Fn doDumpChild) { 12538032Speter // If we're at the top level, there's nothing interesting to do; just 12638032Speter // run the dumper. 12738032Speter if (TopLevel) { 12838032Speter TopLevel = false; 12938032Speter doDumpChild(); 13038032Speter while (!Pending.empty()) { 13138032Speter Pending.back()(true); 13238032Speter Pending.pop_back(); 13338032Speter } 13438032Speter Prefix.clear(); 13538032Speter OS << "\n"; 13638032Speter TopLevel = true; 13738032Speter return; 13838032Speter } 13938032Speter 14038032Speter const FullComment *OrigFC = FC; 14138032Speter auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) { 14238032Speter // Print out the appropriate tree structure and work out the prefix for 14338032Speter // children of this node. For instance: 14438032Speter // 14538032Speter // A Prefix = "" 14638032Speter // |-B Prefix = "| " 14738032Speter // | `-C Prefix = "| " 14838032Speter // `-D Prefix = " " 14938032Speter // |-E Prefix = " | " 15038032Speter // `-F Prefix = " " 15138032Speter // G Prefix = "" 15238032Speter // 15338032Speter // Note that the first level gets no prefix. 15438032Speter { 15538032Speter OS << '\n'; 15638032Speter ColorScope Color(*this, IndentColor); 15738032Speter OS << Prefix << (isLastChild ? '`' : '|') << '-'; 15838032Speter this->Prefix.push_back(isLastChild ? ' ' : '|'); 15938032Speter this->Prefix.push_back(' '); 16038032Speter } 16138032Speter 16238032Speter FirstChild = true; 16338032Speter unsigned Depth = Pending.size(); 16438032Speter 16538032Speter FC = OrigFC; 16638032Speter doDumpChild(); 16738032Speter 16838032Speter // If any children are left, they're the last at their nesting level. 16938032Speter // Dump those ones out now. 17038032Speter while (Depth < Pending.size()) { 17138032Speter Pending.back()(true); 17238032Speter this->Pending.pop_back(); 17338032Speter } 17438032Speter 17538032Speter // Restore the old prefix. 17638032Speter this->Prefix.resize(Prefix.size() - 2); 17738032Speter }; 17838032Speter 17938032Speter if (FirstChild) { 18038032Speter Pending.push_back(std::move(dumpWithIndent)); 18138032Speter } else { 18238032Speter Pending.back()(false); 18338032Speter Pending.back() = std::move(dumpWithIndent); 18438032Speter } 18538032Speter FirstChild = false; 18638032Speter } 18738032Speter 18838032Speter class ColorScope { 18938032Speter ASTDumper &Dumper; 19038032Speter public: 19138032Speter ColorScope(ASTDumper &Dumper, TerminalColor Color) 19238032Speter : Dumper(Dumper) { 19338032Speter if (Dumper.ShowColors) 19438032Speter Dumper.OS.changeColor(Color.Color, Color.Bold); 19538032Speter } 19638032Speter ~ColorScope() { 19738032Speter if (Dumper.ShowColors) 19838032Speter Dumper.OS.resetColor(); 19938032Speter } 20038032Speter }; 20138032Speter 20238032Speter public: 20338032Speter ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 20438032Speter const SourceManager *SM) 20538032Speter : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true), 20638032Speter LastLocFilename(""), LastLocLine(~0U), FC(nullptr), 20738032Speter ShowColors(SM && SM->getDiagnostics().getShowColors()) { } 20838032Speter 20938032Speter ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 21038032Speter const SourceManager *SM, bool ShowColors) 21138032Speter : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true), 21238032Speter LastLocFilename(""), LastLocLine(~0U), 21338032Speter ShowColors(ShowColors) { } 21438032Speter 21538032Speter void dumpDecl(const Decl *D); 21638032Speter void dumpStmt(const Stmt *S); 21738032Speter void dumpFullComment(const FullComment *C); 21838032Speter 21938032Speter // Utilities 22038032Speter void dumpPointer(const void *Ptr); 22138032Speter void dumpSourceRange(SourceRange R); 22238032Speter void dumpLocation(SourceLocation Loc); 22338032Speter void dumpBareType(QualType T, bool Desugar = true); 22438032Speter void dumpType(QualType T); 22538032Speter void dumpTypeAsChild(QualType T); 22638032Speter void dumpTypeAsChild(const Type *T); 22738032Speter void dumpBareDeclRef(const Decl *Node); 22838032Speter void dumpDeclRef(const Decl *Node, const char *Label = nullptr); 22938032Speter void dumpName(const NamedDecl *D); 23038032Speter bool hasNodes(const DeclContext *DC); 23138032Speter void dumpDeclContext(const DeclContext *DC); 23238032Speter void dumpLookups(const DeclContext *DC, bool DumpDecls); 23338032Speter void dumpAttr(const Attr *A); 23438032Speter 23538032Speter // C++ Utilities 23638032Speter void dumpAccessSpecifier(AccessSpecifier AS); 23738032Speter void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); 23838032Speter void dumpTemplateParameters(const TemplateParameterList *TPL); 23938032Speter void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); 24038032Speter void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A); 24138032Speter void dumpTemplateArgumentList(const TemplateArgumentList &TAL); 24238032Speter void dumpTemplateArgument(const TemplateArgument &A, 24338032Speter SourceRange R = SourceRange()); 24438032Speter 24538032Speter // Objective-C utilities. 24638032Speter void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams); 24738032Speter 24838032Speter // Types 24938032Speter void VisitComplexType(const ComplexType *T) { 25038032Speter dumpTypeAsChild(T->getElementType()); 25138032Speter } 25238032Speter void VisitPointerType(const PointerType *T) { 25338032Speter dumpTypeAsChild(T->getPointeeType()); 25438032Speter } 25538032Speter void VisitBlockPointerType(const BlockPointerType *T) { 25638032Speter dumpTypeAsChild(T->getPointeeType()); 25738032Speter } 25838032Speter void VisitReferenceType(const ReferenceType *T) { 25938032Speter dumpTypeAsChild(T->getPointeeType()); 26038032Speter } 26138032Speter void VisitRValueReferenceType(const ReferenceType *T) { 26238032Speter if (T->isSpelledAsLValue()) 26338032Speter OS << " written as lvalue reference"; 26438032Speter VisitReferenceType(T); 26538032Speter } 26638032Speter void VisitMemberPointerType(const MemberPointerType *T) { 26738032Speter dumpTypeAsChild(T->getClass()); 26838032Speter dumpTypeAsChild(T->getPointeeType()); 26938032Speter } 27038032Speter void VisitArrayType(const ArrayType *T) { 27138032Speter switch (T->getSizeModifier()) { 27238032Speter case ArrayType::Normal: break; 27338032Speter case ArrayType::Static: OS << " static"; break; 27438032Speter case ArrayType::Star: OS << " *"; break; 27538032Speter } 27638032Speter OS << " " << T->getIndexTypeQualifiers().getAsString(); 27738032Speter dumpTypeAsChild(T->getElementType()); 27838032Speter } 27938032Speter void VisitConstantArrayType(const ConstantArrayType *T) { 28038032Speter OS << " " << T->getSize(); 28138032Speter VisitArrayType(T); 28238032Speter } 28338032Speter void VisitVariableArrayType(const VariableArrayType *T) { 28438032Speter OS << " "; 28538032Speter dumpSourceRange(T->getBracketsRange()); 28638032Speter VisitArrayType(T); 28738032Speter dumpStmt(T->getSizeExpr()); 28838032Speter } 28938032Speter void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 29038032Speter VisitArrayType(T); 29138032Speter OS << " "; 29238032Speter dumpSourceRange(T->getBracketsRange()); 29338032Speter dumpStmt(T->getSizeExpr()); 29438032Speter } 29538032Speter void VisitDependentSizedExtVectorType( 29638032Speter const DependentSizedExtVectorType *T) { 29738032Speter OS << " "; 29838032Speter dumpLocation(T->getAttributeLoc()); 29938032Speter dumpTypeAsChild(T->getElementType()); 30038032Speter dumpStmt(T->getSizeExpr()); 30138032Speter } 30238032Speter void VisitVectorType(const VectorType *T) { 30338032Speter switch (T->getVectorKind()) { 30438032Speter case VectorType::GenericVector: break; 30538032Speter case VectorType::AltiVecVector: OS << " altivec"; break; 30638032Speter case VectorType::AltiVecPixel: OS << " altivec pixel"; break; 30738032Speter case VectorType::AltiVecBool: OS << " altivec bool"; break; 30838032Speter case VectorType::NeonVector: OS << " neon"; break; 30938032Speter case VectorType::NeonPolyVector: OS << " neon poly"; break; 31038032Speter } 31138032Speter OS << " " << T->getNumElements(); 31238032Speter dumpTypeAsChild(T->getElementType()); 31338032Speter } 31438032Speter void VisitFunctionType(const FunctionType *T) { 31538032Speter auto EI = T->getExtInfo(); 31638032Speter if (EI.getNoReturn()) OS << " noreturn"; 31738032Speter if (EI.getProducesResult()) OS << " produces_result"; 31838032Speter if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm(); 31938032Speter OS << " " << FunctionType::getNameForCallConv(EI.getCC()); 32038032Speter dumpTypeAsChild(T->getReturnType()); 32138032Speter } 32238032Speter void VisitFunctionProtoType(const FunctionProtoType *T) { 32338032Speter auto EPI = T->getExtProtoInfo(); 32438032Speter if (EPI.HasTrailingReturn) OS << " trailing_return"; 32538032Speter if (T->isConst()) OS << " const"; 32638032Speter if (T->isVolatile()) OS << " volatile"; 32738032Speter if (T->isRestrict()) OS << " restrict"; 32838032Speter switch (EPI.RefQualifier) { 32938032Speter case RQ_None: break; 33038032Speter case RQ_LValue: OS << " &"; break; 33138032Speter case RQ_RValue: OS << " &&"; break; 33238032Speter } 33338032Speter // FIXME: Exception specification. 33438032Speter // FIXME: Consumed parameters. 33538032Speter VisitFunctionType(T); 33638032Speter for (QualType PT : T->getParamTypes()) 33738032Speter dumpTypeAsChild(PT); 33838032Speter if (EPI.Variadic) 33938032Speter dumpChild([=] { OS << "..."; }); 34038032Speter } 34138032Speter void VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 34238032Speter dumpDeclRef(T->getDecl()); 34338032Speter } 34438032Speter void VisitTypedefType(const TypedefType *T) { 34538032Speter dumpDeclRef(T->getDecl()); 34638032Speter } 34738032Speter void VisitTypeOfExprType(const TypeOfExprType *T) { 34838032Speter dumpStmt(T->getUnderlyingExpr()); 34938032Speter } 35038032Speter void VisitDecltypeType(const DecltypeType *T) { 35138032Speter dumpStmt(T->getUnderlyingExpr()); 35238032Speter } 35338032Speter void VisitUnaryTransformType(const UnaryTransformType *T) { 35438032Speter switch (T->getUTTKind()) { 35538032Speter case UnaryTransformType::EnumUnderlyingType: 35638032Speter OS << " underlying_type"; 35738032Speter break; 35838032Speter } 35938032Speter dumpTypeAsChild(T->getBaseType()); 36038032Speter } 36138032Speter void VisitTagType(const TagType *T) { 36238032Speter dumpDeclRef(T->getDecl()); 36338032Speter } 36438032Speter void VisitAttributedType(const AttributedType *T) { 36538032Speter // FIXME: AttrKind 36638032Speter dumpTypeAsChild(T->getModifiedType()); 36738032Speter } 36838032Speter void VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 36938032Speter OS << " depth " << T->getDepth() << " index " << T->getIndex(); 37038032Speter if (T->isParameterPack()) OS << " pack"; 37138032Speter dumpDeclRef(T->getDecl()); 37238032Speter } 37338032Speter void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { 37438032Speter dumpTypeAsChild(T->getReplacedParameter()); 37538032Speter } 37638032Speter void VisitSubstTemplateTypeParmPackType( 37738032Speter const SubstTemplateTypeParmPackType *T) { 37838032Speter dumpTypeAsChild(T->getReplacedParameter()); 37938032Speter dumpTemplateArgument(T->getArgumentPack()); 38038032Speter } 38138032Speter void VisitAutoType(const AutoType *T) { 38238032Speter if (T->isDecltypeAuto()) OS << " decltype(auto)"; 38338032Speter if (!T->isDeduced()) 38438032Speter OS << " undeduced"; 38538032Speter } 38638032Speter void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { 38738032Speter if (T->isTypeAlias()) OS << " alias"; 38838032Speter OS << " "; T->getTemplateName().dump(OS); 38938032Speter for (auto &Arg : *T) 39038032Speter dumpTemplateArgument(Arg); 39138032Speter if (T->isTypeAlias()) 39238032Speter dumpTypeAsChild(T->getAliasedType()); 39338032Speter } 39438032Speter void VisitInjectedClassNameType(const InjectedClassNameType *T) { 39538032Speter dumpDeclRef(T->getDecl()); 39638032Speter } 39738032Speter void VisitObjCInterfaceType(const ObjCInterfaceType *T) { 39838032Speter dumpDeclRef(T->getDecl()); 39938032Speter } 40038032Speter void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 40138032Speter dumpTypeAsChild(T->getPointeeType()); 40238032Speter } 40338032Speter void VisitAtomicType(const AtomicType *T) { 40438032Speter dumpTypeAsChild(T->getValueType()); 40538032Speter } 40638032Speter void VisitAdjustedType(const AdjustedType *T) { 40738032Speter dumpTypeAsChild(T->getOriginalType()); 40838032Speter } 40938032Speter void VisitPackExpansionType(const PackExpansionType *T) { 41038032Speter if (auto N = T->getNumExpansions()) OS << " expansions " << *N; 41138032Speter if (!T->isSugared()) 41238032Speter dumpTypeAsChild(T->getPattern()); 41338032Speter } 41438032Speter // FIXME: ElaboratedType, DependentNameType, 41538032Speter // DependentTemplateSpecializationType, ObjCObjectType 41638032Speter 41738032Speter // Decls 41838032Speter void VisitLabelDecl(const LabelDecl *D); 41938032Speter void VisitTypedefDecl(const TypedefDecl *D); 42038032Speter void VisitEnumDecl(const EnumDecl *D); 42138032Speter void VisitRecordDecl(const RecordDecl *D); 42238032Speter void VisitEnumConstantDecl(const EnumConstantDecl *D); 42338032Speter void VisitIndirectFieldDecl(const IndirectFieldDecl *D); 42438032Speter void VisitFunctionDecl(const FunctionDecl *D); 42538032Speter void VisitFieldDecl(const FieldDecl *D); 42638032Speter void VisitVarDecl(const VarDecl *D); 42738032Speter void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); 42838032Speter void VisitImportDecl(const ImportDecl *D); 42938032Speter 43038032Speter // C++ Decls 43138032Speter void VisitNamespaceDecl(const NamespaceDecl *D); 43238032Speter void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); 43338032Speter void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 43438032Speter void VisitTypeAliasDecl(const TypeAliasDecl *D); 43538032Speter void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); 43638032Speter void VisitCXXRecordDecl(const CXXRecordDecl *D); 43738032Speter void VisitStaticAssertDecl(const StaticAssertDecl *D); 43838032Speter template<typename SpecializationDecl> 43938032Speter void VisitTemplateDeclSpecialization(const SpecializationDecl *D, 44038032Speter bool DumpExplicitInst, 44138032Speter bool DumpRefOnly); 44238032Speter template<typename TemplateDecl> 44338032Speter void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); 44438032Speter void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 44538032Speter void VisitClassTemplateDecl(const ClassTemplateDecl *D); 44638032Speter void VisitClassTemplateSpecializationDecl( 44738032Speter const ClassTemplateSpecializationDecl *D); 44838032Speter void VisitClassTemplatePartialSpecializationDecl( 44938032Speter const ClassTemplatePartialSpecializationDecl *D); 45038032Speter void VisitClassScopeFunctionSpecializationDecl( 45138032Speter const ClassScopeFunctionSpecializationDecl *D); 45238032Speter void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D); 45338032Speter void VisitVarTemplateDecl(const VarTemplateDecl *D); 45438032Speter void VisitVarTemplateSpecializationDecl( 45538032Speter const VarTemplateSpecializationDecl *D); 45638032Speter void VisitVarTemplatePartialSpecializationDecl( 45738032Speter const VarTemplatePartialSpecializationDecl *D); 45838032Speter void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 45938032Speter void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 46038032Speter void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 46138032Speter void VisitUsingDecl(const UsingDecl *D); 46238032Speter void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); 46338032Speter void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); 46438032Speter void VisitUsingShadowDecl(const UsingShadowDecl *D); 46538032Speter void VisitLinkageSpecDecl(const LinkageSpecDecl *D); 46638032Speter void VisitAccessSpecDecl(const AccessSpecDecl *D); 46738032Speter void VisitFriendDecl(const FriendDecl *D); 46838032Speter 46938032Speter // ObjC Decls 47038032Speter void VisitObjCIvarDecl(const ObjCIvarDecl *D); 47138032Speter void VisitObjCMethodDecl(const ObjCMethodDecl *D); 47238032Speter void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); 47338032Speter void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); 47438032Speter void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); 47538032Speter void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); 47638032Speter void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); 47738032Speter void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); 47838032Speter void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); 47938032Speter void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 48038032Speter void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 48138032Speter void VisitBlockDecl(const BlockDecl *D); 48238032Speter 48338032Speter // Stmts. 48438032Speter void VisitStmt(const Stmt *Node); 48538032Speter void VisitDeclStmt(const DeclStmt *Node); 48638032Speter void VisitAttributedStmt(const AttributedStmt *Node); 48738032Speter void VisitLabelStmt(const LabelStmt *Node); 48838032Speter void VisitGotoStmt(const GotoStmt *Node); 48938032Speter void VisitCXXCatchStmt(const CXXCatchStmt *Node); 49038032Speter 49138032Speter // Exprs 49238032Speter void VisitExpr(const Expr *Node); 49338032Speter void VisitCastExpr(const CastExpr *Node); 49438032Speter void VisitDeclRefExpr(const DeclRefExpr *Node); 49538032Speter void VisitPredefinedExpr(const PredefinedExpr *Node); 49638032Speter void VisitCharacterLiteral(const CharacterLiteral *Node); 49738032Speter void VisitIntegerLiteral(const IntegerLiteral *Node); 49838032Speter void VisitFloatingLiteral(const FloatingLiteral *Node); 49938032Speter void VisitStringLiteral(const StringLiteral *Str); 50038032Speter void VisitInitListExpr(const InitListExpr *ILE); 50138032Speter void VisitUnaryOperator(const UnaryOperator *Node); 50238032Speter void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); 50338032Speter void VisitMemberExpr(const MemberExpr *Node); 50438032Speter void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); 50538032Speter void VisitBinaryOperator(const BinaryOperator *Node); 50638032Speter void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); 50738032Speter void VisitAddrLabelExpr(const AddrLabelExpr *Node); 50838032Speter void VisitBlockExpr(const BlockExpr *Node); 50938032Speter void VisitOpaqueValueExpr(const OpaqueValueExpr *Node); 51038032Speter 51138032Speter // C++ 51238032Speter void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); 51338032Speter void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); 51438032Speter void VisitCXXThisExpr(const CXXThisExpr *Node); 51538032Speter void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); 51638032Speter void VisitCXXConstructExpr(const CXXConstructExpr *Node); 51738032Speter void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); 51838032Speter void VisitCXXNewExpr(const CXXNewExpr *Node); 51938032Speter void VisitCXXDeleteExpr(const CXXDeleteExpr *Node); 52038032Speter void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); 52138032Speter void VisitExprWithCleanups(const ExprWithCleanups *Node); 52238032Speter void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); 52338032Speter void dumpCXXTemporary(const CXXTemporary *Temporary); 52438032Speter void VisitLambdaExpr(const LambdaExpr *Node) { 52538032Speter VisitExpr(Node); 52638032Speter dumpDecl(Node->getLambdaClass()); 52738032Speter } 52838032Speter void VisitSizeOfPackExpr(const SizeOfPackExpr *Node); 52938032Speter 53038032Speter // ObjC 53138032Speter void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); 53238032Speter void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); 53338032Speter void VisitObjCMessageExpr(const ObjCMessageExpr *Node); 53438032Speter void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); 53538032Speter void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); 53638032Speter void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); 53738032Speter void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); 53838032Speter void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); 53938032Speter void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); 54038032Speter void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); 54138032Speter 54238032Speter // Comments. 54338032Speter const char *getCommandName(unsigned CommandID); 54438032Speter void dumpComment(const Comment *C); 54538032Speter 54638032Speter // Inline comments. 54738032Speter void visitTextComment(const TextComment *C); 54838032Speter void visitInlineCommandComment(const InlineCommandComment *C); 54938032Speter void visitHTMLStartTagComment(const HTMLStartTagComment *C); 55038032Speter void visitHTMLEndTagComment(const HTMLEndTagComment *C); 55138032Speter 55238032Speter // Block comments. 55338032Speter void visitBlockCommandComment(const BlockCommandComment *C); 55438032Speter void visitParamCommandComment(const ParamCommandComment *C); 55538032Speter void visitTParamCommandComment(const TParamCommandComment *C); 55638032Speter void visitVerbatimBlockComment(const VerbatimBlockComment *C); 55738032Speter void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); 55838032Speter void visitVerbatimLineComment(const VerbatimLineComment *C); 55938032Speter }; 56038032Speter} 56138032Speter 56238032Speter//===----------------------------------------------------------------------===// 56338032Speter// Utilities 56438032Speter//===----------------------------------------------------------------------===// 56538032Speter 56638032Spetervoid ASTDumper::dumpPointer(const void *Ptr) { 56738032Speter ColorScope Color(*this, AddressColor); 56838032Speter OS << ' ' << Ptr; 56938032Speter} 57038032Speter 57138032Spetervoid ASTDumper::dumpLocation(SourceLocation Loc) { 57238032Speter if (!SM) 57338032Speter return; 57438032Speter 57538032Speter ColorScope Color(*this, LocationColor); 57638032Speter SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 57738032Speter 57838032Speter // The general format we print out is filename:line:col, but we drop pieces 57938032Speter // that haven't changed since the last loc printed. 58038032Speter PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 58138032Speter 58238032Speter if (PLoc.isInvalid()) { 58338032Speter OS << "<invalid sloc>"; 58438032Speter return; 58538032Speter } 58638032Speter 58738032Speter if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 58838032Speter OS << PLoc.getFilename() << ':' << PLoc.getLine() 58938032Speter << ':' << PLoc.getColumn(); 59038032Speter LastLocFilename = PLoc.getFilename(); 59138032Speter LastLocLine = PLoc.getLine(); 59238032Speter } else if (PLoc.getLine() != LastLocLine) { 59338032Speter OS << "line" << ':' << PLoc.getLine() 59438032Speter << ':' << PLoc.getColumn(); 59538032Speter LastLocLine = PLoc.getLine(); 59638032Speter } else { 59738032Speter OS << "col" << ':' << PLoc.getColumn(); 59838032Speter } 59938032Speter} 60038032Speter 60138032Spetervoid ASTDumper::dumpSourceRange(SourceRange R) { 60238032Speter // Can't translate locations if a SourceManager isn't available. 60338032Speter if (!SM) 60438032Speter return; 60538032Speter 60638032Speter OS << " <"; 60738032Speter dumpLocation(R.getBegin()); 60838032Speter if (R.getBegin() != R.getEnd()) { 60938032Speter OS << ", "; 61038032Speter dumpLocation(R.getEnd()); 61138032Speter } 61238032Speter OS << ">"; 61338032Speter 61438032Speter // <t2.c:123:421[blah], t2.c:412:321> 61538032Speter 61638032Speter} 61738032Speter 61838032Spetervoid ASTDumper::dumpBareType(QualType T, bool Desugar) { 61938032Speter ColorScope Color(*this, TypeColor); 62038032Speter 62138032Speter SplitQualType T_split = T.split(); 62238032Speter OS << "'" << QualType::getAsString(T_split) << "'"; 62338032Speter 62438032Speter if (Desugar && !T.isNull()) { 62538032Speter // If the type is sugared, also dump a (shallow) desugared type. 62638032Speter SplitQualType D_split = T.getSplitDesugaredType(); 62738032Speter if (T_split != D_split) 62838032Speter OS << ":'" << QualType::getAsString(D_split) << "'"; 62938032Speter } 63038032Speter} 63138032Speter 63238032Spetervoid ASTDumper::dumpType(QualType T) { 63338032Speter OS << ' '; 63438032Speter dumpBareType(T); 63538032Speter} 63638032Speter 63738032Spetervoid ASTDumper::dumpTypeAsChild(QualType T) { 63838032Speter SplitQualType SQT = T.split(); 63938032Speter if (!SQT.Quals.hasQualifiers()) 64038032Speter return dumpTypeAsChild(SQT.Ty); 64138032Speter 64238032Speter dumpChild([=] { 64338032Speter OS << "QualType"; 64438032Speter dumpPointer(T.getAsOpaquePtr()); 64538032Speter OS << " "; 64638032Speter dumpBareType(T, false); 64738032Speter OS << " " << T.split().Quals.getAsString(); 64838032Speter dumpTypeAsChild(T.split().Ty); 64938032Speter }); 65038032Speter} 65138032Speter 65238032Spetervoid ASTDumper::dumpTypeAsChild(const Type *T) { 65338032Speter dumpChild([=] { 65438032Speter if (!T) { 65538032Speter ColorScope Color(*this, NullColor); 65638032Speter OS << "<<<NULL>>>"; 65738032Speter return; 65838032Speter } 65938032Speter if (const LocInfoType *LIT = llvm::dyn_cast<LocInfoType>(T)) { 66038032Speter { 66138032Speter ColorScope Color(*this, TypeColor); 66238032Speter OS << "LocInfo Type"; 66338032Speter } 66438032Speter dumpPointer(T); 66538032Speter dumpTypeAsChild(LIT->getTypeSourceInfo()->getType()); 66638032Speter return; 66738032Speter } 66838032Speter 66938032Speter { 67038032Speter ColorScope Color(*this, TypeColor); 67138032Speter OS << T->getTypeClassName() << "Type"; 67238032Speter } 67338032Speter dumpPointer(T); 67438032Speter OS << " "; 67538032Speter dumpBareType(QualType(T, 0), false); 67638032Speter 67738032Speter QualType SingleStepDesugar = 67838032Speter T->getLocallyUnqualifiedSingleStepDesugaredType(); 67938032Speter if (SingleStepDesugar != QualType(T, 0)) 68038032Speter OS << " sugar"; 68138032Speter if (T->isDependentType()) 68238032Speter OS << " dependent"; 68338032Speter else if (T->isInstantiationDependentType()) 68438032Speter OS << " instantiation_dependent"; 68538032Speter if (T->isVariablyModifiedType()) 68638032Speter OS << " variably_modified"; 68738032Speter if (T->containsUnexpandedParameterPack()) 68838032Speter OS << " contains_unexpanded_pack"; 68938032Speter if (T->isFromAST()) 69038032Speter OS << " imported"; 69138032Speter 69238032Speter TypeVisitor<ASTDumper>::Visit(T); 69338032Speter 69438032Speter if (SingleStepDesugar != QualType(T, 0)) 69538032Speter dumpTypeAsChild(SingleStepDesugar); 69638032Speter }); 69738032Speter} 69838032Speter 69938032Spetervoid ASTDumper::dumpBareDeclRef(const Decl *D) { 70038032Speter { 70138032Speter ColorScope Color(*this, DeclKindNameColor); 70238032Speter OS << D->getDeclKindName(); 70338032Speter } 70438032Speter dumpPointer(D); 70538032Speter 70638032Speter if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 70738032Speter ColorScope Color(*this, DeclNameColor); 70838032Speter OS << " '" << ND->getDeclName() << '\''; 70938032Speter } 71038032Speter 71138032Speter if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 71238032Speter dumpType(VD->getType()); 71338032Speter} 71438032Speter 71538032Spetervoid ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { 71638032Speter if (!D) 71738032Speter return; 71838032Speter 71938032Speter dumpChild([=]{ 72038032Speter if (Label) 72138032Speter OS << Label << ' '; 72238032Speter dumpBareDeclRef(D); 72338032Speter }); 72438032Speter} 72538032Speter 72638032Spetervoid ASTDumper::dumpName(const NamedDecl *ND) { 72738032Speter if (ND->getDeclName()) { 72838032Speter ColorScope Color(*this, DeclNameColor); 72938032Speter OS << ' ' << ND->getNameAsString(); 73038032Speter } 73138032Speter} 73238032Speter 73338032Speterbool ASTDumper::hasNodes(const DeclContext *DC) { 73438032Speter if (!DC) 73538032Speter return false; 73638032Speter 73738032Speter return DC->hasExternalLexicalStorage() || 73838032Speter DC->noload_decls_begin() != DC->noload_decls_end(); 73938032Speter} 74038032Speter 74138032Spetervoid ASTDumper::dumpDeclContext(const DeclContext *DC) { 74238032Speter if (!DC) 74338032Speter return; 74438032Speter 74538032Speter for (auto *D : DC->noload_decls()) 74638032Speter dumpDecl(D); 74738032Speter 74838032Speter if (DC->hasExternalLexicalStorage()) { 74938032Speter dumpChild([=]{ 75038032Speter ColorScope Color(*this, UndeserializedColor); 75138032Speter OS << "<undeserialized declarations>"; 75238032Speter }); 75338032Speter } 75438032Speter} 75538032Speter 75638032Spetervoid ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { 75738032Speter dumpChild([=] { 75838032Speter OS << "StoredDeclsMap "; 75938032Speter dumpBareDeclRef(cast<Decl>(DC)); 76038032Speter 76138032Speter const DeclContext *Primary = DC->getPrimaryContext(); 76238032Speter if (Primary != DC) { 76338032Speter OS << " primary"; 76438032Speter dumpPointer(cast<Decl>(Primary)); 76538032Speter } 76638032Speter 76738032Speter bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); 76838032Speter 76938032Speter DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(), 77038032Speter E = Primary->noload_lookups_end(); 77138032Speter while (I != E) { 77238032Speter DeclarationName Name = I.getLookupName(); 77338032Speter DeclContextLookupResult R = *I++; 77438032Speter 77538032Speter dumpChild([=] { 77638032Speter OS << "DeclarationName "; 77738032Speter { 77838032Speter ColorScope Color(*this, DeclNameColor); 77938032Speter OS << '\'' << Name << '\''; 78038032Speter } 78138032Speter 78238032Speter for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); 78338032Speter RI != RE; ++RI) { 78438032Speter dumpChild([=] { 78538032Speter dumpBareDeclRef(*RI); 78638032Speter 78738032Speter if ((*RI)->isHidden()) 78838032Speter OS << " hidden"; 78938032Speter 79038032Speter // If requested, dump the redecl chain for this lookup. 79138032Speter if (DumpDecls) { 79238032Speter // Dump earliest decl first. 79338032Speter std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) { 79438032Speter if (Decl *Prev = D->getPreviousDecl()) 79538032Speter DumpWithPrev(Prev); 79638032Speter dumpDecl(D); 79738032Speter }; 79838032Speter DumpWithPrev(*RI); 79938032Speter } 80038032Speter }); 80138032Speter } 80238032Speter }); 80338032Speter } 80438032Speter 80538032Speter if (HasUndeserializedLookups) { 80638032Speter dumpChild([=] { 80738032Speter ColorScope Color(*this, UndeserializedColor); 80838032Speter OS << "<undeserialized lookups>"; 80938032Speter }); 81038032Speter } 81138032Speter }); 81238032Speter} 81338032Speter 81438032Spetervoid ASTDumper::dumpAttr(const Attr *A) { 81538032Speter dumpChild([=] { 81638032Speter { 81738032Speter ColorScope Color(*this, AttrColor); 81838032Speter 81938032Speter switch (A->getKind()) { 82038032Speter#define ATTR(X) case attr::X: OS << #X; break; 82138032Speter#include "clang/Basic/AttrList.inc" 82238032Speter default: 82338032Speter llvm_unreachable("unexpected attribute kind"); 82438032Speter } 82538032Speter OS << "Attr"; 82638032Speter } 82738032Speter dumpPointer(A); 82838032Speter dumpSourceRange(A->getRange()); 82938032Speter if (A->isInherited()) 83038032Speter OS << " Inherited"; 83138032Speter if (A->isImplicit()) 83238032Speter OS << " Implicit"; 83338032Speter#include "clang/AST/AttrDump.inc" 83438032Speter }); 83538032Speter} 83638032Speter 83738032Speterstatic void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 83838032Speter 83938032Spetertemplate<typename T> 84038032Speterstatic void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 84138032Speter const T *First = D->getFirstDecl(); 84238032Speter if (First != D) 84338032Speter OS << " first " << First; 84438032Speter} 84538032Speter 84638032Spetertemplate<typename T> 84738032Speterstatic void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 84838032Speter const T *Prev = D->getPreviousDecl(); 84938032Speter if (Prev) 85038032Speter OS << " prev " << Prev; 85138032Speter} 85238032Speter 85338032Speter/// Dump the previous declaration in the redeclaration chain for a declaration, 85438032Speter/// if any. 85538032Speterstatic void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 85638032Speter switch (D->getKind()) { 85738032Speter#define DECL(DERIVED, BASE) \ 85838032Speter case Decl::DERIVED: \ 85938032Speter return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 86038032Speter#define ABSTRACT_DECL(DECL) 86138032Speter#include "clang/AST/DeclNodes.inc" 86238032Speter } 86338032Speter llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 86438032Speter} 86538032Speter 86638032Speter//===----------------------------------------------------------------------===// 86738032Speter// C++ Utilities 86838032Speter//===----------------------------------------------------------------------===// 86938032Speter 87038032Spetervoid ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { 87138032Speter switch (AS) { 87238032Speter case AS_none: 87338032Speter break; 87438032Speter case AS_public: 87538032Speter OS << "public"; 87638032Speter break; 87738032Speter case AS_protected: 87838032Speter OS << "protected"; 87938032Speter break; 88038032Speter case AS_private: 88138032Speter OS << "private"; 88238032Speter break; 88338032Speter } 88438032Speter} 88538032Speter 88638032Spetervoid ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { 88738032Speter dumpChild([=] { 88838032Speter OS << "CXXCtorInitializer"; 88938032Speter if (Init->isAnyMemberInitializer()) { 89038032Speter OS << ' '; 89138032Speter dumpBareDeclRef(Init->getAnyMember()); 89238032Speter } else if (Init->isBaseInitializer()) { 89338032Speter dumpType(QualType(Init->getBaseClass(), 0)); 89438032Speter } else if (Init->isDelegatingInitializer()) { 89538032Speter dumpType(Init->getTypeSourceInfo()->getType()); 89638032Speter } else { 89738032Speter llvm_unreachable("Unknown initializer type"); 89838032Speter } 89938032Speter dumpStmt(Init->getInit()); 90038032Speter }); 90138032Speter} 90238032Speter 90338032Spetervoid ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { 90438032Speter if (!TPL) 90538032Speter return; 90638032Speter 90738032Speter for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end(); 90838032Speter I != E; ++I) 90938032Speter dumpDecl(*I); 91038032Speter} 91138032Speter 91238032Spetervoid ASTDumper::dumpTemplateArgumentListInfo( 91338032Speter const TemplateArgumentListInfo &TALI) { 91438032Speter for (unsigned i = 0, e = TALI.size(); i < e; ++i) 91538032Speter dumpTemplateArgumentLoc(TALI[i]); 91638032Speter} 91738032Speter 91838032Spetervoid ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 91938032Speter dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 92038032Speter} 92138032Speter 92238032Spetervoid ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 92338032Speter for (unsigned i = 0, e = TAL.size(); i < e; ++i) 92438032Speter dumpTemplateArgument(TAL[i]); 92538032Speter} 92638032Speter 92738032Spetervoid ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { 92838032Speter dumpChild([=] { 92938032Speter OS << "TemplateArgument"; 93038032Speter if (R.isValid()) 93138032Speter dumpSourceRange(R); 93238032Speter 93338032Speter switch (A.getKind()) { 93438032Speter case TemplateArgument::Null: 93538032Speter OS << " null"; 93638032Speter break; 93738032Speter case TemplateArgument::Type: 93838032Speter OS << " type"; 93938032Speter dumpType(A.getAsType()); 94038032Speter break; 94138032Speter case TemplateArgument::Declaration: 94238032Speter OS << " decl"; 94338032Speter dumpDeclRef(A.getAsDecl()); 94438032Speter break; 94538032Speter case TemplateArgument::NullPtr: 94638032Speter OS << " nullptr"; 94738032Speter break; 94838032Speter case TemplateArgument::Integral: 94938032Speter OS << " integral " << A.getAsIntegral(); 95038032Speter break; 95138032Speter case TemplateArgument::Template: 95238032Speter OS << " template "; 95338032Speter A.getAsTemplate().dump(OS); 95438032Speter break; 95538032Speter case TemplateArgument::TemplateExpansion: 95638032Speter OS << " template expansion"; 95738032Speter A.getAsTemplateOrTemplatePattern().dump(OS); 95838032Speter break; 95938032Speter case TemplateArgument::Expression: 96038032Speter OS << " expr"; 96138032Speter dumpStmt(A.getAsExpr()); 96238032Speter break; 96338032Speter case TemplateArgument::Pack: 96438032Speter OS << " pack"; 96538032Speter for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); 96638032Speter I != E; ++I) 96738032Speter dumpTemplateArgument(*I); 96838032Speter break; 96938032Speter } 97038032Speter }); 97138032Speter} 97238032Speter 97338032Speter//===----------------------------------------------------------------------===// 97438032Speter// Objective-C Utilities 97538032Speter//===----------------------------------------------------------------------===// 97638032Spetervoid ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) { 97738032Speter if (!typeParams) 97838032Speter return; 97938032Speter 98038032Speter for (auto typeParam : *typeParams) { 98138032Speter dumpDecl(typeParam); 98238032Speter } 98338032Speter} 98438032Speter 98538032Speter//===----------------------------------------------------------------------===// 98638032Speter// Decl dumping methods. 98738032Speter//===----------------------------------------------------------------------===// 98838032Speter 98938032Spetervoid ASTDumper::dumpDecl(const Decl *D) { 99038032Speter dumpChild([=] { 99138032Speter if (!D) { 99238032Speter ColorScope Color(*this, NullColor); 99338032Speter OS << "<<<NULL>>>"; 99438032Speter return; 99538032Speter } 99638032Speter 99738032Speter { 99838032Speter ColorScope Color(*this, DeclKindNameColor); 99938032Speter OS << D->getDeclKindName() << "Decl"; 100038032Speter } 100138032Speter dumpPointer(D); 100238032Speter if (D->getLexicalDeclContext() != D->getDeclContext()) 100338032Speter OS << " parent " << cast<Decl>(D->getDeclContext()); 100438032Speter dumpPreviousDecl(OS, D); 100538032Speter dumpSourceRange(D->getSourceRange()); 100638032Speter OS << ' '; 100738032Speter dumpLocation(D->getLocation()); 100838032Speter if (Module *M = D->getImportedOwningModule()) 100938032Speter OS << " in " << M->getFullModuleName(); 101038032Speter else if (Module *M = D->getLocalOwningModule()) 101138032Speter OS << " in (local) " << M->getFullModuleName(); 101238032Speter if (auto *ND = dyn_cast<NamedDecl>(D)) 101338032Speter for (Module *M : D->getASTContext().getModulesWithMergedDefinition( 101438032Speter const_cast<NamedDecl *>(ND))) 101538032Speter dumpChild([=] { OS << "also in " << M->getFullModuleName(); }); 101638032Speter if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 101738032Speter if (ND->isHidden()) 101838032Speter OS << " hidden"; 101938032Speter if (D->isImplicit()) 102038032Speter OS << " implicit"; 102138032Speter if (D->isUsed()) 102238032Speter OS << " used"; 102338032Speter else if (D->isThisDeclarationReferenced()) 102438032Speter OS << " referenced"; 102538032Speter if (D->isInvalidDecl()) 102638032Speter OS << " invalid"; 102738032Speter if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 102838032Speter if (FD->isConstexpr()) 102938032Speter OS << " constexpr"; 103038032Speter 103138032Speter 103238032Speter ConstDeclVisitor<ASTDumper>::Visit(D); 103338032Speter 103438032Speter for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E; 103538032Speter ++I) 103638032Speter dumpAttr(*I); 103738032Speter 103838032Speter if (const FullComment *Comment = 103938032Speter D->getASTContext().getLocalCommentForDeclUncached(D)) 104038032Speter dumpFullComment(Comment); 104138032Speter 104238032Speter // Decls within functions are visited by the body. 104338032Speter if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && 104438032Speter hasNodes(dyn_cast<DeclContext>(D))) 104538032Speter dumpDeclContext(cast<DeclContext>(D)); 104638032Speter }); 104738032Speter} 104838032Speter 104938032Spetervoid ASTDumper::VisitLabelDecl(const LabelDecl *D) { 105038032Speter dumpName(D); 105138032Speter} 105238032Speter 105338032Spetervoid ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 105438032Speter dumpName(D); 105538032Speter dumpType(D->getUnderlyingType()); 105638032Speter if (D->isModulePrivate()) 105738032Speter OS << " __module_private__"; 105838032Speter dumpTypeAsChild(D->getUnderlyingType()); 105938032Speter} 106038032Speter 106138032Spetervoid ASTDumper::VisitEnumDecl(const EnumDecl *D) { 106238032Speter if (D->isScoped()) { 106338032Speter if (D->isScopedUsingClassTag()) 106438032Speter OS << " class"; 106538032Speter else 106638032Speter OS << " struct"; 106738032Speter } 106838032Speter dumpName(D); 106938032Speter if (D->isModulePrivate()) 107038032Speter OS << " __module_private__"; 107138032Speter if (D->isFixed()) 107238032Speter dumpType(D->getIntegerType()); 107338032Speter} 107438032Speter 107538032Spetervoid ASTDumper::VisitRecordDecl(const RecordDecl *D) { 107638032Speter OS << ' ' << D->getKindName(); 107738032Speter dumpName(D); 107838032Speter if (D->isModulePrivate()) 107938032Speter OS << " __module_private__"; 108038032Speter if (D->isCompleteDefinition()) 108138032Speter OS << " definition"; 108238032Speter} 108338032Speter 108438032Spetervoid ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 108538032Speter dumpName(D); 108638032Speter dumpType(D->getType()); 108738032Speter if (const Expr *Init = D->getInitExpr()) 108838032Speter dumpStmt(Init); 108938032Speter} 109038032Speter 109138032Spetervoid ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 109238032Speter dumpName(D); 109338032Speter dumpType(D->getType()); 109438032Speter 109538032Speter for (auto *Child : D->chain()) 109638032Speter dumpDeclRef(Child); 109738032Speter} 109838032Speter 109938032Spetervoid ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 110038032Speter dumpName(D); 110138032Speter dumpType(D->getType()); 110238032Speter 110338032Speter StorageClass SC = D->getStorageClass(); 110438032Speter if (SC != SC_None) 110538032Speter OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 110638032Speter if (D->isInlineSpecified()) 110738032Speter OS << " inline"; 110838032Speter if (D->isVirtualAsWritten()) 110938032Speter OS << " virtual"; 111038032Speter if (D->isModulePrivate()) 111138032Speter OS << " __module_private__"; 111238032Speter 111338032Speter if (D->isPure()) 111438032Speter OS << " pure"; 111538032Speter else if (D->isDeletedAsWritten()) 111638032Speter OS << " delete"; 111738032Speter 111838032Speter if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { 111938032Speter FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 112038032Speter switch (EPI.ExceptionSpec.Type) { 112138032Speter default: break; 112238032Speter case EST_Unevaluated: 112338032Speter OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; 112438032Speter break; 112538032Speter case EST_Uninstantiated: 112638032Speter OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; 112738032Speter break; 112838032Speter } 112938032Speter } 113038032Speter 113138032Speter if (const FunctionTemplateSpecializationInfo *FTSI = 113238032Speter D->getTemplateSpecializationInfo()) 113338032Speter dumpTemplateArgumentList(*FTSI->TemplateArguments); 113438032Speter 113538032Speter for (ArrayRef<NamedDecl *>::iterator 113638032Speter I = D->getDeclsInPrototypeScope().begin(), 113738032Speter E = D->getDeclsInPrototypeScope().end(); I != E; ++I) 113838032Speter dumpDecl(*I); 113938032Speter 114038032Speter if (!D->param_begin() && D->getNumParams()) 114138032Speter dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; }); 114238032Speter else 114338032Speter for (FunctionDecl::param_const_iterator I = D->param_begin(), 114438032Speter E = D->param_end(); 114538032Speter I != E; ++I) 114638032Speter dumpDecl(*I); 114738032Speter 114838032Speter if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) 114938032Speter for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 115038032Speter E = C->init_end(); 115138032Speter I != E; ++I) 115238032Speter dumpCXXCtorInitializer(*I); 115338032Speter 115438032Speter if (D->doesThisDeclarationHaveABody()) 115538032Speter dumpStmt(D->getBody()); 115638032Speter} 115738032Speter 115838032Spetervoid ASTDumper::VisitFieldDecl(const FieldDecl *D) { 115938032Speter dumpName(D); 116038032Speter dumpType(D->getType()); 116138032Speter if (D->isMutable()) 116238032Speter OS << " mutable"; 116338032Speter if (D->isModulePrivate()) 116438032Speter OS << " __module_private__"; 116538032Speter 116638032Speter if (D->isBitField()) 116738032Speter dumpStmt(D->getBitWidth()); 116838032Speter if (Expr *Init = D->getInClassInitializer()) 116938032Speter dumpStmt(Init); 117038032Speter} 117138032Speter 117238032Spetervoid ASTDumper::VisitVarDecl(const VarDecl *D) { 117338032Speter dumpName(D); 117438032Speter dumpType(D->getType()); 117538032Speter StorageClass SC = D->getStorageClass(); 117638032Speter if (SC != SC_None) 117738032Speter OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 117838032Speter switch (D->getTLSKind()) { 117938032Speter case VarDecl::TLS_None: break; 118038032Speter case VarDecl::TLS_Static: OS << " tls"; break; 118138032Speter case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 118238032Speter } 118338032Speter if (D->isModulePrivate()) 118438032Speter OS << " __module_private__"; 118538032Speter if (D->isNRVOVariable()) 118638032Speter OS << " nrvo"; 118738032Speter if (D->hasInit()) { 118838032Speter switch (D->getInitStyle()) { 118938032Speter case VarDecl::CInit: OS << " cinit"; break; 119038032Speter case VarDecl::CallInit: OS << " callinit"; break; 119138032Speter case VarDecl::ListInit: OS << " listinit"; break; 119238032Speter } 119338032Speter dumpStmt(D->getInit()); 119438032Speter } 119538032Speter} 119638032Speter 119738032Spetervoid ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 119838032Speter dumpStmt(D->getAsmString()); 119938032Speter} 120038032Speter 120138032Spetervoid ASTDumper::VisitImportDecl(const ImportDecl *D) { 120238032Speter OS << ' ' << D->getImportedModule()->getFullModuleName(); 120338032Speter} 120438032Speter 120538032Speter//===----------------------------------------------------------------------===// 120638032Speter// C++ Declarations 120738032Speter//===----------------------------------------------------------------------===// 120838032Speter 120938032Spetervoid ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 121038032Speter dumpName(D); 121138032Speter if (D->isInline()) 121238032Speter OS << " inline"; 121338032Speter if (!D->isOriginalNamespace()) 121438032Speter dumpDeclRef(D->getOriginalNamespace(), "original"); 121538032Speter} 121638032Speter 121738032Spetervoid ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 121838032Speter OS << ' '; 121938032Speter dumpBareDeclRef(D->getNominatedNamespace()); 122038032Speter} 122138032Speter 122238032Spetervoid ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 122338032Speter dumpName(D); 122438032Speter dumpDeclRef(D->getAliasedNamespace()); 122538032Speter} 122638032Speter 122738032Spetervoid ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 122838032Speter dumpName(D); 122938032Speter dumpType(D->getUnderlyingType()); 123038032Speter dumpTypeAsChild(D->getUnderlyingType()); 123138032Speter} 123238032Speter 123338032Spetervoid ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 123438032Speter dumpName(D); 123538032Speter dumpTemplateParameters(D->getTemplateParameters()); 123638032Speter dumpDecl(D->getTemplatedDecl()); 123738032Speter} 123838032Speter 123938032Spetervoid ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 124038032Speter VisitRecordDecl(D); 124138032Speter if (!D->isCompleteDefinition()) 124238032Speter return; 124338032Speter 124438032Speter for (const auto &I : D->bases()) { 124538032Speter dumpChild([=] { 124638032Speter if (I.isVirtual()) 124738032Speter OS << "virtual "; 124838032Speter dumpAccessSpecifier(I.getAccessSpecifier()); 124938032Speter dumpType(I.getType()); 125038032Speter if (I.isPackExpansion()) 125138032Speter OS << "..."; 125238032Speter }); 125338032Speter } 125438032Speter} 125538032Speter 125638032Spetervoid ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 125738032Speter dumpStmt(D->getAssertExpr()); 125838032Speter dumpStmt(D->getMessage()); 125938032Speter} 126038032Speter 126138032Spetertemplate<typename SpecializationDecl> 126238032Spetervoid ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, 126338032Speter bool DumpExplicitInst, 126438032Speter bool DumpRefOnly) { 126538032Speter bool DumpedAny = false; 126638032Speter for (auto *RedeclWithBadType : D->redecls()) { 126738032Speter // FIXME: The redecls() range sometimes has elements of a less-specific 126838032Speter // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives 126938032Speter // us TagDecls, and should give CXXRecordDecls). 127038032Speter auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); 127138032Speter if (!Redecl) { 127238032Speter // Found the injected-class-name for a class template. This will be dumped 127338032Speter // as part of its surrounding class so we don't need to dump it here. 127438032Speter assert(isa<CXXRecordDecl>(RedeclWithBadType) && 127538032Speter "expected an injected-class-name"); 127638032Speter continue; 127738032Speter } 127838032Speter 127938032Speter switch (Redecl->getTemplateSpecializationKind()) { 128038032Speter case TSK_ExplicitInstantiationDeclaration: 128138032Speter case TSK_ExplicitInstantiationDefinition: 128238032Speter if (!DumpExplicitInst) 128338032Speter break; 128438032Speter // Fall through. 128538032Speter case TSK_Undeclared: 128638032Speter case TSK_ImplicitInstantiation: 128738032Speter if (DumpRefOnly) 128838032Speter dumpDeclRef(Redecl); 128938032Speter else 129038032Speter dumpDecl(Redecl); 129138032Speter DumpedAny = true; 129238032Speter break; 129338032Speter case TSK_ExplicitSpecialization: 129438032Speter break; 129538032Speter } 129638032Speter } 129738032Speter 129838032Speter // Ensure we dump at least one decl for each specialization. 129938032Speter if (!DumpedAny) 130038032Speter dumpDeclRef(D); 130138032Speter} 130238032Speter 130338032Spetertemplate<typename TemplateDecl> 130438032Spetervoid ASTDumper::VisitTemplateDecl(const TemplateDecl *D, 130538032Speter bool DumpExplicitInst) { 130638032Speter dumpName(D); 130738032Speter dumpTemplateParameters(D->getTemplateParameters()); 130838032Speter 130938032Speter dumpDecl(D->getTemplatedDecl()); 131038032Speter 131138032Speter for (auto *Child : D->specializations()) 131238032Speter VisitTemplateDeclSpecialization(Child, DumpExplicitInst, 131338032Speter !D->isCanonicalDecl()); 131438032Speter} 131538032Speter 131638032Spetervoid ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 131738032Speter // FIXME: We don't add a declaration of a function template specialization 131838032Speter // to its context when it's explicitly instantiated, so dump explicit 131938032Speter // instantiations when we dump the template itself. 132038032Speter VisitTemplateDecl(D, true); 132138032Speter} 132238032Speter 132338032Spetervoid ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 132438032Speter VisitTemplateDecl(D, false); 132538032Speter} 132638032Speter 132738032Spetervoid ASTDumper::VisitClassTemplateSpecializationDecl( 132838032Speter const ClassTemplateSpecializationDecl *D) { 132938032Speter VisitCXXRecordDecl(D); 133038032Speter dumpTemplateArgumentList(D->getTemplateArgs()); 133138032Speter} 133238032Speter 133338032Spetervoid ASTDumper::VisitClassTemplatePartialSpecializationDecl( 133438032Speter const ClassTemplatePartialSpecializationDecl *D) { 133538032Speter VisitClassTemplateSpecializationDecl(D); 133638032Speter dumpTemplateParameters(D->getTemplateParameters()); 133738032Speter} 133838032Speter 133938032Spetervoid ASTDumper::VisitClassScopeFunctionSpecializationDecl( 134038032Speter const ClassScopeFunctionSpecializationDecl *D) { 134138032Speter dumpDeclRef(D->getSpecialization()); 134238032Speter if (D->hasExplicitTemplateArgs()) 134338032Speter dumpTemplateArgumentListInfo(D->templateArgs()); 134438032Speter} 134538032Speter 134638032Spetervoid ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 134738032Speter VisitTemplateDecl(D, false); 134838032Speter} 134938032Speter 135038032Spetervoid ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { 135138032Speter dumpName(D); 135238032Speter dumpTemplateParameters(D->getTemplateParameters()); 135338032Speter} 135438032Speter 135538032Spetervoid ASTDumper::VisitVarTemplateSpecializationDecl( 135638032Speter const VarTemplateSpecializationDecl *D) { 135738032Speter dumpTemplateArgumentList(D->getTemplateArgs()); 135838032Speter VisitVarDecl(D); 135938032Speter} 136038032Speter 136138032Spetervoid ASTDumper::VisitVarTemplatePartialSpecializationDecl( 136238032Speter const VarTemplatePartialSpecializationDecl *D) { 136338032Speter dumpTemplateParameters(D->getTemplateParameters()); 136438032Speter VisitVarTemplateSpecializationDecl(D); 136538032Speter} 136638032Speter 136738032Spetervoid ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 136838032Speter if (D->wasDeclaredWithTypename()) 136938032Speter OS << " typename"; 137038032Speter else 137138032Speter OS << " class"; 137238032Speter if (D->isParameterPack()) 137338032Speter OS << " ..."; 137438032Speter dumpName(D); 137538032Speter if (D->hasDefaultArgument()) 137638032Speter dumpTemplateArgument(D->getDefaultArgument()); 137738032Speter} 137838032Speter 137938032Spetervoid ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 138038032Speter dumpType(D->getType()); 138138032Speter if (D->isParameterPack()) 138238032Speter OS << " ..."; 138338032Speter dumpName(D); 138438032Speter if (D->hasDefaultArgument()) 138538032Speter dumpTemplateArgument(D->getDefaultArgument()); 138638032Speter} 138738032Speter 138838032Spetervoid ASTDumper::VisitTemplateTemplateParmDecl( 138938032Speter const TemplateTemplateParmDecl *D) { 139038032Speter if (D->isParameterPack()) 139138032Speter OS << " ..."; 139238032Speter dumpName(D); 139338032Speter dumpTemplateParameters(D->getTemplateParameters()); 139438032Speter if (D->hasDefaultArgument()) 139538032Speter dumpTemplateArgumentLoc(D->getDefaultArgument()); 139638032Speter} 139738032Speter 139838032Spetervoid ASTDumper::VisitUsingDecl(const UsingDecl *D) { 139938032Speter OS << ' '; 140038032Speter if (D->getQualifier()) 140138032Speter D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 140238032Speter OS << D->getNameAsString(); 140338032Speter} 140438032Speter 140538032Spetervoid ASTDumper::VisitUnresolvedUsingTypenameDecl( 140638032Speter const UnresolvedUsingTypenameDecl *D) { 140738032Speter OS << ' '; 140838032Speter if (D->getQualifier()) 140938032Speter D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 141038032Speter OS << D->getNameAsString(); 141138032Speter} 141238032Speter 141338032Spetervoid ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 141438032Speter OS << ' '; 141538032Speter if (D->getQualifier()) 141638032Speter D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 141738032Speter OS << D->getNameAsString(); 141838032Speter dumpType(D->getType()); 141938032Speter} 142038032Speter 142138032Spetervoid ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 142238032Speter OS << ' '; 142338032Speter dumpBareDeclRef(D->getTargetDecl()); 142438032Speter if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl())) 142538032Speter dumpTypeAsChild(TD->getTypeForDecl()); 142638032Speter} 142738032Speter 142838032Spetervoid ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 142938032Speter switch (D->getLanguage()) { 143038032Speter case LinkageSpecDecl::lang_c: OS << " C"; break; 143138032Speter case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 143238032Speter } 143338032Speter} 143438032Speter 143538032Spetervoid ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 143638032Speter OS << ' '; 143738032Speter dumpAccessSpecifier(D->getAccess()); 143838032Speter} 143938032Speter 144038032Spetervoid ASTDumper::VisitFriendDecl(const FriendDecl *D) { 144138032Speter if (TypeSourceInfo *T = D->getFriendType()) 144238032Speter dumpType(T->getType()); 144338032Speter else 144438032Speter dumpDecl(D->getFriendDecl()); 144538032Speter} 144638032Speter 144738032Speter//===----------------------------------------------------------------------===// 144838032Speter// Obj-C Declarations 144938032Speter//===----------------------------------------------------------------------===// 145038032Speter 145138032Spetervoid ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 145238032Speter dumpName(D); 145338032Speter dumpType(D->getType()); 145438032Speter if (D->getSynthesize()) 145538032Speter OS << " synthesize"; 145638032Speter 145738032Speter switch (D->getAccessControl()) { 145838032Speter case ObjCIvarDecl::None: 145938032Speter OS << " none"; 146038032Speter break; 146138032Speter case ObjCIvarDecl::Private: 146238032Speter OS << " private"; 146338032Speter break; 146438032Speter case ObjCIvarDecl::Protected: 146538032Speter OS << " protected"; 146638032Speter break; 146738032Speter case ObjCIvarDecl::Public: 146838032Speter OS << " public"; 146938032Speter break; 147038032Speter case ObjCIvarDecl::Package: 147138032Speter OS << " package"; 147238032Speter break; 147338032Speter } 147438032Speter} 147538032Speter 147638032Spetervoid ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 147738032Speter if (D->isInstanceMethod()) 147838032Speter OS << " -"; 147938032Speter else 148038032Speter OS << " +"; 148138032Speter dumpName(D); 148238032Speter dumpType(D->getReturnType()); 148338032Speter 148438032Speter if (D->isThisDeclarationADefinition()) { 148538032Speter dumpDeclContext(D); 148638032Speter } else { 148738032Speter for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 148838032Speter E = D->param_end(); 148938032Speter I != E; ++I) 149038032Speter dumpDecl(*I); 149138032Speter } 149238032Speter 149338032Speter if (D->isVariadic()) 149438032Speter dumpChild([=] { OS << "..."; }); 149538032Speter 149638032Speter if (D->hasBody()) 149738032Speter dumpStmt(D->getBody()); 149838032Speter} 149938032Speter 150038032Spetervoid ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { 1501 dumpName(D); 1502 switch (D->getVariance()) { 1503 case ObjCTypeParamVariance::Invariant: 1504 break; 1505 1506 case ObjCTypeParamVariance::Covariant: 1507 OS << " covariant"; 1508 break; 1509 1510 case ObjCTypeParamVariance::Contravariant: 1511 OS << " contravariant"; 1512 break; 1513 } 1514 1515 if (D->hasExplicitBound()) 1516 OS << " bounded"; 1517 dumpType(D->getUnderlyingType()); 1518} 1519 1520void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1521 dumpName(D); 1522 dumpDeclRef(D->getClassInterface()); 1523 dumpObjCTypeParamList(D->getTypeParamList()); 1524 dumpDeclRef(D->getImplementation()); 1525 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1526 E = D->protocol_end(); 1527 I != E; ++I) 1528 dumpDeclRef(*I); 1529} 1530 1531void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1532 dumpName(D); 1533 dumpDeclRef(D->getClassInterface()); 1534 dumpDeclRef(D->getCategoryDecl()); 1535} 1536 1537void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1538 dumpName(D); 1539 1540 for (auto *Child : D->protocols()) 1541 dumpDeclRef(Child); 1542} 1543 1544void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1545 dumpName(D); 1546 dumpObjCTypeParamList(D->getTypeParamListAsWritten()); 1547 dumpDeclRef(D->getSuperClass(), "super"); 1548 1549 dumpDeclRef(D->getImplementation()); 1550 for (auto *Child : D->protocols()) 1551 dumpDeclRef(Child); 1552} 1553 1554void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1555 dumpName(D); 1556 dumpDeclRef(D->getSuperClass(), "super"); 1557 dumpDeclRef(D->getClassInterface()); 1558 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1559 E = D->init_end(); 1560 I != E; ++I) 1561 dumpCXXCtorInitializer(*I); 1562} 1563 1564void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1565 dumpName(D); 1566 dumpDeclRef(D->getClassInterface()); 1567} 1568 1569void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1570 dumpName(D); 1571 dumpType(D->getType()); 1572 1573 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1574 OS << " required"; 1575 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1576 OS << " optional"; 1577 1578 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1579 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1580 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1581 OS << " readonly"; 1582 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1583 OS << " assign"; 1584 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1585 OS << " readwrite"; 1586 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1587 OS << " retain"; 1588 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1589 OS << " copy"; 1590 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1591 OS << " nonatomic"; 1592 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1593 OS << " atomic"; 1594 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1595 OS << " weak"; 1596 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1597 OS << " strong"; 1598 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1599 OS << " unsafe_unretained"; 1600 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) 1601 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1602 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) 1603 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1604 } 1605} 1606 1607void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1608 dumpName(D->getPropertyDecl()); 1609 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1610 OS << " synthesize"; 1611 else 1612 OS << " dynamic"; 1613 dumpDeclRef(D->getPropertyDecl()); 1614 dumpDeclRef(D->getPropertyIvarDecl()); 1615} 1616 1617void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1618 for (auto I : D->params()) 1619 dumpDecl(I); 1620 1621 if (D->isVariadic()) 1622 dumpChild([=]{ OS << "..."; }); 1623 1624 if (D->capturesCXXThis()) 1625 dumpChild([=]{ OS << "capture this"; }); 1626 1627 for (const auto &I : D->captures()) { 1628 dumpChild([=] { 1629 OS << "capture"; 1630 if (I.isByRef()) 1631 OS << " byref"; 1632 if (I.isNested()) 1633 OS << " nested"; 1634 if (I.getVariable()) { 1635 OS << ' '; 1636 dumpBareDeclRef(I.getVariable()); 1637 } 1638 if (I.hasCopyExpr()) 1639 dumpStmt(I.getCopyExpr()); 1640 }); 1641 } 1642 dumpStmt(D->getBody()); 1643} 1644 1645//===----------------------------------------------------------------------===// 1646// Stmt dumping methods. 1647//===----------------------------------------------------------------------===// 1648 1649void ASTDumper::dumpStmt(const Stmt *S) { 1650 dumpChild([=] { 1651 if (!S) { 1652 ColorScope Color(*this, NullColor); 1653 OS << "<<<NULL>>>"; 1654 return; 1655 } 1656 1657 if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1658 VisitDeclStmt(DS); 1659 return; 1660 } 1661 1662 ConstStmtVisitor<ASTDumper>::Visit(S); 1663 1664 for (const Stmt *SubStmt : S->children()) 1665 dumpStmt(SubStmt); 1666 }); 1667} 1668 1669void ASTDumper::VisitStmt(const Stmt *Node) { 1670 { 1671 ColorScope Color(*this, StmtColor); 1672 OS << Node->getStmtClassName(); 1673 } 1674 dumpPointer(Node); 1675 dumpSourceRange(Node->getSourceRange()); 1676} 1677 1678void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1679 VisitStmt(Node); 1680 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1681 E = Node->decl_end(); 1682 I != E; ++I) 1683 dumpDecl(*I); 1684} 1685 1686void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1687 VisitStmt(Node); 1688 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1689 E = Node->getAttrs().end(); 1690 I != E; ++I) 1691 dumpAttr(*I); 1692} 1693 1694void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1695 VisitStmt(Node); 1696 OS << " '" << Node->getName() << "'"; 1697} 1698 1699void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1700 VisitStmt(Node); 1701 OS << " '" << Node->getLabel()->getName() << "'"; 1702 dumpPointer(Node->getLabel()); 1703} 1704 1705void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1706 VisitStmt(Node); 1707 dumpDecl(Node->getExceptionDecl()); 1708} 1709 1710//===----------------------------------------------------------------------===// 1711// Expr dumping methods. 1712//===----------------------------------------------------------------------===// 1713 1714void ASTDumper::VisitExpr(const Expr *Node) { 1715 VisitStmt(Node); 1716 dumpType(Node->getType()); 1717 1718 { 1719 ColorScope Color(*this, ValueKindColor); 1720 switch (Node->getValueKind()) { 1721 case VK_RValue: 1722 break; 1723 case VK_LValue: 1724 OS << " lvalue"; 1725 break; 1726 case VK_XValue: 1727 OS << " xvalue"; 1728 break; 1729 } 1730 } 1731 1732 { 1733 ColorScope Color(*this, ObjectKindColor); 1734 switch (Node->getObjectKind()) { 1735 case OK_Ordinary: 1736 break; 1737 case OK_BitField: 1738 OS << " bitfield"; 1739 break; 1740 case OK_ObjCProperty: 1741 OS << " objcproperty"; 1742 break; 1743 case OK_ObjCSubscript: 1744 OS << " objcsubscript"; 1745 break; 1746 case OK_VectorComponent: 1747 OS << " vectorcomponent"; 1748 break; 1749 } 1750 } 1751} 1752 1753static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1754 if (Node->path_empty()) 1755 return; 1756 1757 OS << " ("; 1758 bool First = true; 1759 for (CastExpr::path_const_iterator I = Node->path_begin(), 1760 E = Node->path_end(); 1761 I != E; ++I) { 1762 const CXXBaseSpecifier *Base = *I; 1763 if (!First) 1764 OS << " -> "; 1765 1766 const CXXRecordDecl *RD = 1767 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1768 1769 if (Base->isVirtual()) 1770 OS << "virtual "; 1771 OS << RD->getName(); 1772 First = false; 1773 } 1774 1775 OS << ')'; 1776} 1777 1778void ASTDumper::VisitCastExpr(const CastExpr *Node) { 1779 VisitExpr(Node); 1780 OS << " <"; 1781 { 1782 ColorScope Color(*this, CastColor); 1783 OS << Node->getCastKindName(); 1784 } 1785 dumpBasePath(OS, Node); 1786 OS << ">"; 1787} 1788 1789void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1790 VisitExpr(Node); 1791 1792 OS << " "; 1793 dumpBareDeclRef(Node->getDecl()); 1794 if (Node->getDecl() != Node->getFoundDecl()) { 1795 OS << " ("; 1796 dumpBareDeclRef(Node->getFoundDecl()); 1797 OS << ")"; 1798 } 1799} 1800 1801void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1802 VisitExpr(Node); 1803 OS << " ("; 1804 if (!Node->requiresADL()) 1805 OS << "no "; 1806 OS << "ADL) = '" << Node->getName() << '\''; 1807 1808 UnresolvedLookupExpr::decls_iterator 1809 I = Node->decls_begin(), E = Node->decls_end(); 1810 if (I == E) 1811 OS << " empty"; 1812 for (; I != E; ++I) 1813 dumpPointer(*I); 1814} 1815 1816void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1817 VisitExpr(Node); 1818 1819 { 1820 ColorScope Color(*this, DeclKindNameColor); 1821 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1822 } 1823 OS << "='" << *Node->getDecl() << "'"; 1824 dumpPointer(Node->getDecl()); 1825 if (Node->isFreeIvar()) 1826 OS << " isFreeIvar"; 1827} 1828 1829void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1830 VisitExpr(Node); 1831 OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType()); 1832} 1833 1834void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1835 VisitExpr(Node); 1836 ColorScope Color(*this, ValueColor); 1837 OS << " " << Node->getValue(); 1838} 1839 1840void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1841 VisitExpr(Node); 1842 1843 bool isSigned = Node->getType()->isSignedIntegerType(); 1844 ColorScope Color(*this, ValueColor); 1845 OS << " " << Node->getValue().toString(10, isSigned); 1846} 1847 1848void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1849 VisitExpr(Node); 1850 ColorScope Color(*this, ValueColor); 1851 OS << " " << Node->getValueAsApproximateDouble(); 1852} 1853 1854void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1855 VisitExpr(Str); 1856 ColorScope Color(*this, ValueColor); 1857 OS << " "; 1858 Str->outputString(OS); 1859} 1860 1861void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { 1862 VisitExpr(ILE); 1863 if (auto *Filler = ILE->getArrayFiller()) { 1864 dumpChild([=] { 1865 OS << "array filler"; 1866 dumpStmt(Filler); 1867 }); 1868 } 1869 if (auto *Field = ILE->getInitializedFieldInUnion()) { 1870 OS << " field "; 1871 dumpBareDeclRef(Field); 1872 } 1873} 1874 1875void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1876 VisitExpr(Node); 1877 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1878 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1879} 1880 1881void ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1882 const UnaryExprOrTypeTraitExpr *Node) { 1883 VisitExpr(Node); 1884 switch(Node->getKind()) { 1885 case UETT_SizeOf: 1886 OS << " sizeof"; 1887 break; 1888 case UETT_AlignOf: 1889 OS << " alignof"; 1890 break; 1891 case UETT_VecStep: 1892 OS << " vec_step"; 1893 break; 1894 case UETT_OpenMPRequiredSimdAlign: 1895 OS << " __builtin_omp_required_simd_align"; 1896 break; 1897 } 1898 if (Node->isArgumentType()) 1899 dumpType(Node->getArgumentType()); 1900} 1901 1902void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1903 VisitExpr(Node); 1904 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1905 dumpPointer(Node->getMemberDecl()); 1906} 1907 1908void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1909 VisitExpr(Node); 1910 OS << " " << Node->getAccessor().getNameStart(); 1911} 1912 1913void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1914 VisitExpr(Node); 1915 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1916} 1917 1918void ASTDumper::VisitCompoundAssignOperator( 1919 const CompoundAssignOperator *Node) { 1920 VisitExpr(Node); 1921 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1922 << "' ComputeLHSTy="; 1923 dumpBareType(Node->getComputationLHSType()); 1924 OS << " ComputeResultTy="; 1925 dumpBareType(Node->getComputationResultType()); 1926} 1927 1928void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1929 VisitExpr(Node); 1930 dumpDecl(Node->getBlockDecl()); 1931} 1932 1933void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1934 VisitExpr(Node); 1935 1936 if (Expr *Source = Node->getSourceExpr()) 1937 dumpStmt(Source); 1938} 1939 1940// GNU extensions. 1941 1942void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1943 VisitExpr(Node); 1944 OS << " " << Node->getLabel()->getName(); 1945 dumpPointer(Node->getLabel()); 1946} 1947 1948//===----------------------------------------------------------------------===// 1949// C++ Expressions 1950//===----------------------------------------------------------------------===// 1951 1952void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1953 VisitExpr(Node); 1954 OS << " " << Node->getCastName() 1955 << "<" << Node->getTypeAsWritten().getAsString() << ">" 1956 << " <" << Node->getCastKindName(); 1957 dumpBasePath(OS, Node); 1958 OS << ">"; 1959} 1960 1961void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1962 VisitExpr(Node); 1963 OS << " " << (Node->getValue() ? "true" : "false"); 1964} 1965 1966void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1967 VisitExpr(Node); 1968 OS << " this"; 1969} 1970 1971void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1972 VisitExpr(Node); 1973 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1974 << " <" << Node->getCastKindName() << ">"; 1975} 1976 1977void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1978 VisitExpr(Node); 1979 CXXConstructorDecl *Ctor = Node->getConstructor(); 1980 dumpType(Ctor->getType()); 1981 if (Node->isElidable()) 1982 OS << " elidable"; 1983 if (Node->requiresZeroInitialization()) 1984 OS << " zeroing"; 1985} 1986 1987void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1988 VisitExpr(Node); 1989 OS << " "; 1990 dumpCXXTemporary(Node->getTemporary()); 1991} 1992 1993void ASTDumper::VisitCXXNewExpr(const CXXNewExpr *Node) { 1994 VisitExpr(Node); 1995 if (Node->isGlobalNew()) 1996 OS << " global"; 1997 if (Node->isArray()) 1998 OS << " array"; 1999 if (Node->getOperatorNew()) { 2000 OS << ' '; 2001 dumpBareDeclRef(Node->getOperatorNew()); 2002 } 2003 // We could dump the deallocation function used in case of error, but it's 2004 // usually not that interesting. 2005} 2006 2007void ASTDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) { 2008 VisitExpr(Node); 2009 if (Node->isGlobalDelete()) 2010 OS << " global"; 2011 if (Node->isArrayForm()) 2012 OS << " array"; 2013 if (Node->getOperatorDelete()) { 2014 OS << ' '; 2015 dumpBareDeclRef(Node->getOperatorDelete()); 2016 } 2017} 2018 2019void 2020ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { 2021 VisitExpr(Node); 2022 if (const ValueDecl *VD = Node->getExtendingDecl()) { 2023 OS << " extended by "; 2024 dumpBareDeclRef(VD); 2025 } 2026} 2027 2028void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 2029 VisitExpr(Node); 2030 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 2031 dumpDeclRef(Node->getObject(i), "cleanup"); 2032} 2033 2034void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 2035 OS << "(CXXTemporary"; 2036 dumpPointer(Temporary); 2037 OS << ")"; 2038} 2039 2040void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { 2041 VisitExpr(Node); 2042 dumpPointer(Node->getPack()); 2043 dumpName(Node->getPack()); 2044 if (Node->isPartiallySubstituted()) 2045 for (const auto &A : Node->getPartialArguments()) 2046 dumpTemplateArgument(A); 2047} 2048 2049 2050//===----------------------------------------------------------------------===// 2051// Obj-C Expressions 2052//===----------------------------------------------------------------------===// 2053 2054void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 2055 VisitExpr(Node); 2056 OS << " selector="; 2057 Node->getSelector().print(OS); 2058 switch (Node->getReceiverKind()) { 2059 case ObjCMessageExpr::Instance: 2060 break; 2061 2062 case ObjCMessageExpr::Class: 2063 OS << " class="; 2064 dumpBareType(Node->getClassReceiver()); 2065 break; 2066 2067 case ObjCMessageExpr::SuperInstance: 2068 OS << " super (instance)"; 2069 break; 2070 2071 case ObjCMessageExpr::SuperClass: 2072 OS << " super (class)"; 2073 break; 2074 } 2075} 2076 2077void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 2078 VisitExpr(Node); 2079 OS << " selector="; 2080 Node->getBoxingMethod()->getSelector().print(OS); 2081} 2082 2083void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 2084 VisitStmt(Node); 2085 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 2086 dumpDecl(CatchParam); 2087 else 2088 OS << " catch all"; 2089} 2090 2091void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 2092 VisitExpr(Node); 2093 dumpType(Node->getEncodedType()); 2094} 2095 2096void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 2097 VisitExpr(Node); 2098 2099 OS << " "; 2100 Node->getSelector().print(OS); 2101} 2102 2103void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 2104 VisitExpr(Node); 2105 2106 OS << ' ' << *Node->getProtocol(); 2107} 2108 2109void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 2110 VisitExpr(Node); 2111 if (Node->isImplicitProperty()) { 2112 OS << " Kind=MethodRef Getter=\""; 2113 if (Node->getImplicitPropertyGetter()) 2114 Node->getImplicitPropertyGetter()->getSelector().print(OS); 2115 else 2116 OS << "(null)"; 2117 2118 OS << "\" Setter=\""; 2119 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 2120 Setter->getSelector().print(OS); 2121 else 2122 OS << "(null)"; 2123 OS << "\""; 2124 } else { 2125 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 2126 } 2127 2128 if (Node->isSuperReceiver()) 2129 OS << " super"; 2130 2131 OS << " Messaging="; 2132 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 2133 OS << "Getter&Setter"; 2134 else if (Node->isMessagingGetter()) 2135 OS << "Getter"; 2136 else if (Node->isMessagingSetter()) 2137 OS << "Setter"; 2138} 2139 2140void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 2141 VisitExpr(Node); 2142 if (Node->isArraySubscriptRefExpr()) 2143 OS << " Kind=ArraySubscript GetterForArray=\""; 2144 else 2145 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 2146 if (Node->getAtIndexMethodDecl()) 2147 Node->getAtIndexMethodDecl()->getSelector().print(OS); 2148 else 2149 OS << "(null)"; 2150 2151 if (Node->isArraySubscriptRefExpr()) 2152 OS << "\" SetterForArray=\""; 2153 else 2154 OS << "\" SetterForDictionary=\""; 2155 if (Node->setAtIndexMethodDecl()) 2156 Node->setAtIndexMethodDecl()->getSelector().print(OS); 2157 else 2158 OS << "(null)"; 2159} 2160 2161void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 2162 VisitExpr(Node); 2163 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 2164} 2165 2166//===----------------------------------------------------------------------===// 2167// Comments 2168//===----------------------------------------------------------------------===// 2169 2170const char *ASTDumper::getCommandName(unsigned CommandID) { 2171 if (Traits) 2172 return Traits->getCommandInfo(CommandID)->Name; 2173 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 2174 if (Info) 2175 return Info->Name; 2176 return "<not a builtin command>"; 2177} 2178 2179void ASTDumper::dumpFullComment(const FullComment *C) { 2180 if (!C) 2181 return; 2182 2183 FC = C; 2184 dumpComment(C); 2185 FC = nullptr; 2186} 2187 2188void ASTDumper::dumpComment(const Comment *C) { 2189 dumpChild([=] { 2190 if (!C) { 2191 ColorScope Color(*this, NullColor); 2192 OS << "<<<NULL>>>"; 2193 return; 2194 } 2195 2196 { 2197 ColorScope Color(*this, CommentColor); 2198 OS << C->getCommentKindName(); 2199 } 2200 dumpPointer(C); 2201 dumpSourceRange(C->getSourceRange()); 2202 ConstCommentVisitor<ASTDumper>::visit(C); 2203 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 2204 I != E; ++I) 2205 dumpComment(*I); 2206 }); 2207} 2208 2209void ASTDumper::visitTextComment(const TextComment *C) { 2210 OS << " Text=\"" << C->getText() << "\""; 2211} 2212 2213void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 2214 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2215 switch (C->getRenderKind()) { 2216 case InlineCommandComment::RenderNormal: 2217 OS << " RenderNormal"; 2218 break; 2219 case InlineCommandComment::RenderBold: 2220 OS << " RenderBold"; 2221 break; 2222 case InlineCommandComment::RenderMonospaced: 2223 OS << " RenderMonospaced"; 2224 break; 2225 case InlineCommandComment::RenderEmphasized: 2226 OS << " RenderEmphasized"; 2227 break; 2228 } 2229 2230 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2231 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2232} 2233 2234void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 2235 OS << " Name=\"" << C->getTagName() << "\""; 2236 if (C->getNumAttrs() != 0) { 2237 OS << " Attrs: "; 2238 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 2239 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 2240 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 2241 } 2242 } 2243 if (C->isSelfClosing()) 2244 OS << " SelfClosing"; 2245} 2246 2247void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 2248 OS << " Name=\"" << C->getTagName() << "\""; 2249} 2250 2251void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 2252 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2253 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2254 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2255} 2256 2257void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 2258 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 2259 2260 if (C->isDirectionExplicit()) 2261 OS << " explicitly"; 2262 else 2263 OS << " implicitly"; 2264 2265 if (C->hasParamName()) { 2266 if (C->isParamIndexValid()) 2267 OS << " Param=\"" << C->getParamName(FC) << "\""; 2268 else 2269 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2270 } 2271 2272 if (C->isParamIndexValid() && !C->isVarArgParam()) 2273 OS << " ParamIndex=" << C->getParamIndex(); 2274} 2275 2276void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 2277 if (C->hasParamName()) { 2278 if (C->isPositionValid()) 2279 OS << " Param=\"" << C->getParamName(FC) << "\""; 2280 else 2281 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2282 } 2283 2284 if (C->isPositionValid()) { 2285 OS << " Position=<"; 2286 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 2287 OS << C->getIndex(i); 2288 if (i != e - 1) 2289 OS << ", "; 2290 } 2291 OS << ">"; 2292 } 2293} 2294 2295void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 2296 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 2297 " CloseName=\"" << C->getCloseName() << "\""; 2298} 2299 2300void ASTDumper::visitVerbatimBlockLineComment( 2301 const VerbatimBlockLineComment *C) { 2302 OS << " Text=\"" << C->getText() << "\""; 2303} 2304 2305void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 2306 OS << " Text=\"" << C->getText() << "\""; 2307} 2308 2309//===----------------------------------------------------------------------===// 2310// Type method implementations 2311//===----------------------------------------------------------------------===// 2312 2313void QualType::dump(const char *msg) const { 2314 if (msg) 2315 llvm::errs() << msg << ": "; 2316 dump(); 2317} 2318 2319LLVM_DUMP_METHOD void QualType::dump() const { 2320 ASTDumper Dumper(llvm::errs(), nullptr, nullptr); 2321 Dumper.dumpTypeAsChild(*this); 2322} 2323 2324LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); } 2325 2326//===----------------------------------------------------------------------===// 2327// Decl method implementations 2328//===----------------------------------------------------------------------===// 2329 2330LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } 2331 2332LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const { 2333 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 2334 &getASTContext().getSourceManager()); 2335 P.dumpDecl(this); 2336} 2337 2338LLVM_DUMP_METHOD void Decl::dumpColor() const { 2339 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 2340 &getASTContext().getSourceManager(), /*ShowColors*/true); 2341 P.dumpDecl(this); 2342} 2343 2344LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { 2345 dumpLookups(llvm::errs()); 2346} 2347 2348LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, 2349 bool DumpDecls) const { 2350 const DeclContext *DC = this; 2351 while (!DC->isTranslationUnit()) 2352 DC = DC->getParent(); 2353 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 2354 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); 2355 P.dumpLookups(this, DumpDecls); 2356} 2357 2358//===----------------------------------------------------------------------===// 2359// Stmt method implementations 2360//===----------------------------------------------------------------------===// 2361 2362LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { 2363 dump(llvm::errs(), SM); 2364} 2365 2366LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 2367 ASTDumper P(OS, nullptr, &SM); 2368 P.dumpStmt(this); 2369} 2370 2371LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const { 2372 ASTDumper P(OS, nullptr, nullptr); 2373 P.dumpStmt(this); 2374} 2375 2376LLVM_DUMP_METHOD void Stmt::dump() const { 2377 ASTDumper P(llvm::errs(), nullptr, nullptr); 2378 P.dumpStmt(this); 2379} 2380 2381LLVM_DUMP_METHOD void Stmt::dumpColor() const { 2382 ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 2383 P.dumpStmt(this); 2384} 2385 2386//===----------------------------------------------------------------------===// 2387// Comment method implementations 2388//===----------------------------------------------------------------------===// 2389 2390LLVM_DUMP_METHOD void Comment::dump() const { 2391 dump(llvm::errs(), nullptr, nullptr); 2392} 2393 2394LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { 2395 dump(llvm::errs(), &Context.getCommentCommandTraits(), 2396 &Context.getSourceManager()); 2397} 2398 2399void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 2400 const SourceManager *SM) const { 2401 const FullComment *FC = dyn_cast<FullComment>(this); 2402 ASTDumper D(OS, Traits, SM); 2403 D.dumpFullComment(FC); 2404} 2405 2406LLVM_DUMP_METHOD void Comment::dumpColor() const { 2407 const FullComment *FC = dyn_cast<FullComment>(this); 2408 ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 2409 D.dumpFullComment(FC); 2410} 2411