1249261Sdim//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim// 10249261Sdim// This file implements the AST dump methods, which dump out the 11249261Sdim// AST in a form that exposes type details and other fields. 12249261Sdim// 13249261Sdim//===----------------------------------------------------------------------===// 14249261Sdim 15249261Sdim#include "clang/AST/ASTContext.h" 16249261Sdim#include "clang/AST/Attr.h" 17249261Sdim#include "clang/AST/CommentVisitor.h" 18249261Sdim#include "clang/AST/DeclCXX.h" 19263508Sdim#include "clang/AST/DeclLookups.h" 20249261Sdim#include "clang/AST/DeclObjC.h" 21249261Sdim#include "clang/AST/DeclVisitor.h" 22249261Sdim#include "clang/AST/StmtVisitor.h" 23249261Sdim#include "clang/Basic/Module.h" 24249261Sdim#include "clang/Basic/SourceManager.h" 25249261Sdim#include "llvm/Support/raw_ostream.h" 26249261Sdimusing namespace clang; 27249261Sdimusing namespace clang::comments; 28249261Sdim 29249261Sdim//===----------------------------------------------------------------------===// 30249261Sdim// ASTDumper Visitor 31249261Sdim//===----------------------------------------------------------------------===// 32249261Sdim 33249261Sdimnamespace { 34249261Sdim // Colors used for various parts of the AST dump 35266715Sdim // Do not use bold yellow for any text. It is hard to read on white screens. 36249261Sdim 37249261Sdim struct TerminalColor { 38249261Sdim raw_ostream::Colors Color; 39249261Sdim bool Bold; 40249261Sdim }; 41249261Sdim 42266715Sdim // Red - CastColor 43266715Sdim // Green - TypeColor 44266715Sdim // Bold Green - DeclKindNameColor, UndeserializedColor 45266715Sdim // Yellow - AddressColor, LocationColor 46266715Sdim // Blue - CommentColor, NullColor, IndentColor 47266715Sdim // Bold Blue - AttrColor 48266715Sdim // Bold Magenta - StmtColor 49266715Sdim // Cyan - ValueKindColor, ObjectKindColor 50266715Sdim // Bold Cyan - ValueColor, DeclNameColor 51266715Sdim 52249261Sdim // Decl kind names (VarDecl, FunctionDecl, etc) 53249261Sdim static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true }; 54249261Sdim // Attr names (CleanupAttr, GuardedByAttr, etc) 55249261Sdim static const TerminalColor AttrColor = { raw_ostream::BLUE, true }; 56249261Sdim // Statement names (DeclStmt, ImplicitCastExpr, etc) 57249261Sdim static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true }; 58249261Sdim // Comment names (FullComment, ParagraphComment, TextComment, etc) 59266715Sdim static const TerminalColor CommentColor = { raw_ostream::BLUE, false }; 60249261Sdim 61249261Sdim // Type names (int, float, etc, plus user defined types) 62249261Sdim static const TerminalColor TypeColor = { raw_ostream::GREEN, false }; 63249261Sdim 64249261Sdim // Pointer address 65249261Sdim static const TerminalColor AddressColor = { raw_ostream::YELLOW, false }; 66249261Sdim // Source locations 67249261Sdim static const TerminalColor LocationColor = { raw_ostream::YELLOW, false }; 68249261Sdim 69249261Sdim // lvalue/xvalue 70249261Sdim static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false }; 71249261Sdim // bitfield/objcproperty/objcsubscript/vectorcomponent 72249261Sdim static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false }; 73249261Sdim 74249261Sdim // Null statements 75249261Sdim static const TerminalColor NullColor = { raw_ostream::BLUE, false }; 76249261Sdim 77263508Sdim // Undeserialized entities 78263508Sdim static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true }; 79263508Sdim 80249261Sdim // CastKind from CastExpr's 81249261Sdim static const TerminalColor CastColor = { raw_ostream::RED, false }; 82249261Sdim 83249261Sdim // Value of the statement 84249261Sdim static const TerminalColor ValueColor = { raw_ostream::CYAN, true }; 85249261Sdim // Decl names 86249261Sdim static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; 87249261Sdim 88249261Sdim // Indents ( `, -. | ) 89249261Sdim static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; 90249261Sdim 91249261Sdim class ASTDumper 92249261Sdim : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, 93249261Sdim public ConstCommentVisitor<ASTDumper> { 94249261Sdim raw_ostream &OS; 95249261Sdim const CommandTraits *Traits; 96249261Sdim const SourceManager *SM; 97249261Sdim bool IsFirstLine; 98249261Sdim 99249261Sdim // Indicates whether more child are expected at the current tree depth 100249261Sdim enum IndentType { IT_Child, IT_LastChild }; 101249261Sdim 102249261Sdim /// Indents[i] indicates if another child exists at level i. 103249261Sdim /// Used by Indent() to print the tree structure. 104249261Sdim llvm::SmallVector<IndentType, 32> Indents; 105249261Sdim 106249261Sdim /// Indicates that more children will be needed at this indent level. 107249261Sdim /// If true, prevents lastChild() from marking the node as the last child. 108249261Sdim /// This is used when there are multiple collections of children to be 109249261Sdim /// dumped as well as during conditional node dumping. 110249261Sdim bool MoreChildren; 111249261Sdim 112249261Sdim /// Keep track of the last location we print out so that we can 113249261Sdim /// print out deltas from then on out. 114249261Sdim const char *LastLocFilename; 115249261Sdim unsigned LastLocLine; 116249261Sdim 117249261Sdim /// The \c FullComment parent of the comment being dumped. 118249261Sdim const FullComment *FC; 119249261Sdim 120249261Sdim bool ShowColors; 121249261Sdim 122249261Sdim class IndentScope { 123249261Sdim ASTDumper &Dumper; 124249261Sdim // Preserve the Dumper's MoreChildren value from the previous IndentScope 125249261Sdim bool MoreChildren; 126249261Sdim public: 127249261Sdim IndentScope(ASTDumper &Dumper) : Dumper(Dumper) { 128249261Sdim MoreChildren = Dumper.hasMoreChildren(); 129249261Sdim Dumper.setMoreChildren(false); 130249261Sdim Dumper.indent(); 131249261Sdim } 132249261Sdim ~IndentScope() { 133249261Sdim Dumper.setMoreChildren(MoreChildren); 134249261Sdim Dumper.unindent(); 135249261Sdim } 136249261Sdim }; 137249261Sdim 138249261Sdim class ColorScope { 139249261Sdim ASTDumper &Dumper; 140249261Sdim public: 141249261Sdim ColorScope(ASTDumper &Dumper, TerminalColor Color) 142249261Sdim : Dumper(Dumper) { 143249261Sdim if (Dumper.ShowColors) 144249261Sdim Dumper.OS.changeColor(Color.Color, Color.Bold); 145249261Sdim } 146249261Sdim ~ColorScope() { 147249261Sdim if (Dumper.ShowColors) 148249261Sdim Dumper.OS.resetColor(); 149249261Sdim } 150249261Sdim }; 151249261Sdim 152249261Sdim public: 153249261Sdim ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 154249261Sdim const SourceManager *SM) 155249261Sdim : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false), 156249261Sdim LastLocFilename(""), LastLocLine(~0U), FC(0), 157249261Sdim ShowColors(SM && SM->getDiagnostics().getShowColors()) { } 158249261Sdim 159249261Sdim ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 160249261Sdim const SourceManager *SM, bool ShowColors) 161249261Sdim : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false), 162249261Sdim LastLocFilename(""), LastLocLine(~0U), 163249261Sdim ShowColors(ShowColors) { } 164249261Sdim 165249261Sdim ~ASTDumper() { 166249261Sdim OS << "\n"; 167249261Sdim } 168249261Sdim 169249261Sdim void dumpDecl(const Decl *D); 170249261Sdim void dumpStmt(const Stmt *S); 171249261Sdim void dumpFullComment(const FullComment *C); 172249261Sdim 173249261Sdim // Formatting 174249261Sdim void indent(); 175249261Sdim void unindent(); 176249261Sdim void lastChild(); 177249261Sdim bool hasMoreChildren(); 178249261Sdim void setMoreChildren(bool Value); 179249261Sdim 180249261Sdim // Utilities 181249261Sdim void dumpPointer(const void *Ptr); 182249261Sdim void dumpSourceRange(SourceRange R); 183249261Sdim void dumpLocation(SourceLocation Loc); 184249261Sdim void dumpBareType(QualType T); 185249261Sdim void dumpType(QualType T); 186249261Sdim void dumpBareDeclRef(const Decl *Node); 187249261Sdim void dumpDeclRef(const Decl *Node, const char *Label = 0); 188249261Sdim void dumpName(const NamedDecl *D); 189249261Sdim bool hasNodes(const DeclContext *DC); 190249261Sdim void dumpDeclContext(const DeclContext *DC); 191263508Sdim void dumpLookups(const DeclContext *DC); 192249261Sdim void dumpAttr(const Attr *A); 193249261Sdim 194249261Sdim // C++ Utilities 195249261Sdim void dumpAccessSpecifier(AccessSpecifier AS); 196249261Sdim void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); 197249261Sdim void dumpTemplateParameters(const TemplateParameterList *TPL); 198249261Sdim void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); 199249261Sdim void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A); 200249261Sdim void dumpTemplateArgumentList(const TemplateArgumentList &TAL); 201249261Sdim void dumpTemplateArgument(const TemplateArgument &A, 202249261Sdim SourceRange R = SourceRange()); 203249261Sdim 204249261Sdim // Decls 205249261Sdim void VisitLabelDecl(const LabelDecl *D); 206249261Sdim void VisitTypedefDecl(const TypedefDecl *D); 207249261Sdim void VisitEnumDecl(const EnumDecl *D); 208249261Sdim void VisitRecordDecl(const RecordDecl *D); 209249261Sdim void VisitEnumConstantDecl(const EnumConstantDecl *D); 210249261Sdim void VisitIndirectFieldDecl(const IndirectFieldDecl *D); 211249261Sdim void VisitFunctionDecl(const FunctionDecl *D); 212249261Sdim void VisitFieldDecl(const FieldDecl *D); 213249261Sdim void VisitVarDecl(const VarDecl *D); 214249261Sdim void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); 215249261Sdim void VisitImportDecl(const ImportDecl *D); 216249261Sdim 217249261Sdim // C++ Decls 218249261Sdim void VisitNamespaceDecl(const NamespaceDecl *D); 219249261Sdim void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); 220249261Sdim void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 221249261Sdim void VisitTypeAliasDecl(const TypeAliasDecl *D); 222249261Sdim void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); 223249261Sdim void VisitCXXRecordDecl(const CXXRecordDecl *D); 224249261Sdim void VisitStaticAssertDecl(const StaticAssertDecl *D); 225249261Sdim void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 226249261Sdim void VisitClassTemplateDecl(const ClassTemplateDecl *D); 227249261Sdim void VisitClassTemplateSpecializationDecl( 228249261Sdim const ClassTemplateSpecializationDecl *D); 229249261Sdim void VisitClassTemplatePartialSpecializationDecl( 230249261Sdim const ClassTemplatePartialSpecializationDecl *D); 231249261Sdim void VisitClassScopeFunctionSpecializationDecl( 232249261Sdim const ClassScopeFunctionSpecializationDecl *D); 233263508Sdim void VisitVarTemplateDecl(const VarTemplateDecl *D); 234263508Sdim void VisitVarTemplateSpecializationDecl( 235263508Sdim const VarTemplateSpecializationDecl *D); 236263508Sdim void VisitVarTemplatePartialSpecializationDecl( 237263508Sdim const VarTemplatePartialSpecializationDecl *D); 238249261Sdim void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 239249261Sdim void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 240249261Sdim void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 241249261Sdim void VisitUsingDecl(const UsingDecl *D); 242249261Sdim void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); 243249261Sdim void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); 244249261Sdim void VisitUsingShadowDecl(const UsingShadowDecl *D); 245249261Sdim void VisitLinkageSpecDecl(const LinkageSpecDecl *D); 246249261Sdim void VisitAccessSpecDecl(const AccessSpecDecl *D); 247249261Sdim void VisitFriendDecl(const FriendDecl *D); 248249261Sdim 249249261Sdim // ObjC Decls 250249261Sdim void VisitObjCIvarDecl(const ObjCIvarDecl *D); 251249261Sdim void VisitObjCMethodDecl(const ObjCMethodDecl *D); 252249261Sdim void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); 253249261Sdim void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); 254249261Sdim void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); 255249261Sdim void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); 256249261Sdim void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); 257249261Sdim void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); 258249261Sdim void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 259249261Sdim void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 260249261Sdim void VisitBlockDecl(const BlockDecl *D); 261249261Sdim 262249261Sdim // Stmts. 263249261Sdim void VisitStmt(const Stmt *Node); 264249261Sdim void VisitDeclStmt(const DeclStmt *Node); 265249261Sdim void VisitAttributedStmt(const AttributedStmt *Node); 266249261Sdim void VisitLabelStmt(const LabelStmt *Node); 267249261Sdim void VisitGotoStmt(const GotoStmt *Node); 268263508Sdim void VisitCXXCatchStmt(const CXXCatchStmt *Node); 269249261Sdim 270249261Sdim // Exprs 271249261Sdim void VisitExpr(const Expr *Node); 272249261Sdim void VisitCastExpr(const CastExpr *Node); 273249261Sdim void VisitDeclRefExpr(const DeclRefExpr *Node); 274249261Sdim void VisitPredefinedExpr(const PredefinedExpr *Node); 275249261Sdim void VisitCharacterLiteral(const CharacterLiteral *Node); 276249261Sdim void VisitIntegerLiteral(const IntegerLiteral *Node); 277249261Sdim void VisitFloatingLiteral(const FloatingLiteral *Node); 278249261Sdim void VisitStringLiteral(const StringLiteral *Str); 279249261Sdim void VisitUnaryOperator(const UnaryOperator *Node); 280249261Sdim void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); 281249261Sdim void VisitMemberExpr(const MemberExpr *Node); 282249261Sdim void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); 283249261Sdim void VisitBinaryOperator(const BinaryOperator *Node); 284249261Sdim void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); 285249261Sdim void VisitAddrLabelExpr(const AddrLabelExpr *Node); 286249261Sdim void VisitBlockExpr(const BlockExpr *Node); 287249261Sdim void VisitOpaqueValueExpr(const OpaqueValueExpr *Node); 288249261Sdim 289249261Sdim // C++ 290249261Sdim void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); 291249261Sdim void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); 292249261Sdim void VisitCXXThisExpr(const CXXThisExpr *Node); 293249261Sdim void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); 294249261Sdim void VisitCXXConstructExpr(const CXXConstructExpr *Node); 295249261Sdim void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); 296263508Sdim void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); 297249261Sdim void VisitExprWithCleanups(const ExprWithCleanups *Node); 298249261Sdim void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); 299249261Sdim void dumpCXXTemporary(const CXXTemporary *Temporary); 300263508Sdim void VisitLambdaExpr(const LambdaExpr *Node) { 301263508Sdim VisitExpr(Node); 302263508Sdim dumpDecl(Node->getLambdaClass()); 303263508Sdim } 304249261Sdim 305249261Sdim // ObjC 306249261Sdim void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); 307249261Sdim void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); 308249261Sdim void VisitObjCMessageExpr(const ObjCMessageExpr *Node); 309249261Sdim void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); 310249261Sdim void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); 311249261Sdim void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); 312249261Sdim void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); 313249261Sdim void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); 314249261Sdim void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); 315249261Sdim void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); 316249261Sdim 317249261Sdim // Comments. 318249261Sdim const char *getCommandName(unsigned CommandID); 319249261Sdim void dumpComment(const Comment *C); 320249261Sdim 321249261Sdim // Inline comments. 322249261Sdim void visitTextComment(const TextComment *C); 323249261Sdim void visitInlineCommandComment(const InlineCommandComment *C); 324249261Sdim void visitHTMLStartTagComment(const HTMLStartTagComment *C); 325249261Sdim void visitHTMLEndTagComment(const HTMLEndTagComment *C); 326249261Sdim 327249261Sdim // Block comments. 328249261Sdim void visitBlockCommandComment(const BlockCommandComment *C); 329249261Sdim void visitParamCommandComment(const ParamCommandComment *C); 330249261Sdim void visitTParamCommandComment(const TParamCommandComment *C); 331249261Sdim void visitVerbatimBlockComment(const VerbatimBlockComment *C); 332249261Sdim void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); 333249261Sdim void visitVerbatimLineComment(const VerbatimLineComment *C); 334249261Sdim }; 335249261Sdim} 336249261Sdim 337249261Sdim//===----------------------------------------------------------------------===// 338249261Sdim// Utilities 339249261Sdim//===----------------------------------------------------------------------===// 340249261Sdim 341249261Sdim// Print out the appropriate tree structure using the Indents vector. 342249261Sdim// Example of tree and the Indents vector at each level. 343249261Sdim// A { } 344249261Sdim// |-B { IT_Child } 345249261Sdim// | `-C { IT_Child, IT_LastChild } 346249261Sdim// `-D { IT_LastChild } 347249261Sdim// |-E { IT_LastChild, IT_Child } 348249261Sdim// `-F { IT_LastChild, IT_LastChild } 349249261Sdim// Type non-last element, last element 350249261Sdim// IT_Child "| " "|-" 351249261Sdim// IT_LastChild " " "`-" 352249261Sdimvoid ASTDumper::indent() { 353249261Sdim if (IsFirstLine) 354249261Sdim IsFirstLine = false; 355249261Sdim else 356249261Sdim OS << "\n"; 357249261Sdim 358249261Sdim ColorScope Color(*this, IndentColor); 359263508Sdim for (SmallVectorImpl<IndentType>::const_iterator I = Indents.begin(), 360263508Sdim E = Indents.end(); 361249261Sdim I != E; ++I) { 362249261Sdim switch (*I) { 363249261Sdim case IT_Child: 364249261Sdim if (I == E - 1) 365249261Sdim OS << "|-"; 366249261Sdim else 367249261Sdim OS << "| "; 368249261Sdim continue; 369249261Sdim case IT_LastChild: 370249261Sdim if (I == E - 1) 371249261Sdim OS << "`-"; 372249261Sdim else 373249261Sdim OS << " "; 374249261Sdim continue; 375249261Sdim } 376249261Sdim llvm_unreachable("Invalid IndentType"); 377249261Sdim } 378249261Sdim Indents.push_back(IT_Child); 379249261Sdim} 380249261Sdim 381249261Sdimvoid ASTDumper::unindent() { 382249261Sdim Indents.pop_back(); 383249261Sdim} 384249261Sdim 385249261Sdim// Call before each potential last child node is to be dumped. If MoreChildren 386249261Sdim// is false, then this is the last child, otherwise treat as a regular node. 387249261Sdimvoid ASTDumper::lastChild() { 388249261Sdim if (!hasMoreChildren()) 389249261Sdim Indents.back() = IT_LastChild; 390249261Sdim} 391249261Sdim 392249261Sdim// MoreChildren should be set before calling another function that may print 393249261Sdim// additional nodes to prevent conflicting final child nodes. 394249261Sdimbool ASTDumper::hasMoreChildren() { 395249261Sdim return MoreChildren; 396249261Sdim} 397249261Sdim 398249261Sdimvoid ASTDumper::setMoreChildren(bool Value) { 399249261Sdim MoreChildren = Value; 400249261Sdim} 401249261Sdim 402249261Sdimvoid ASTDumper::dumpPointer(const void *Ptr) { 403249261Sdim ColorScope Color(*this, AddressColor); 404249261Sdim OS << ' ' << Ptr; 405249261Sdim} 406249261Sdim 407249261Sdimvoid ASTDumper::dumpLocation(SourceLocation Loc) { 408249261Sdim ColorScope Color(*this, LocationColor); 409249261Sdim SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 410249261Sdim 411249261Sdim // The general format we print out is filename:line:col, but we drop pieces 412249261Sdim // that haven't changed since the last loc printed. 413249261Sdim PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 414249261Sdim 415249261Sdim if (PLoc.isInvalid()) { 416249261Sdim OS << "<invalid sloc>"; 417249261Sdim return; 418249261Sdim } 419249261Sdim 420249261Sdim if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 421249261Sdim OS << PLoc.getFilename() << ':' << PLoc.getLine() 422249261Sdim << ':' << PLoc.getColumn(); 423249261Sdim LastLocFilename = PLoc.getFilename(); 424249261Sdim LastLocLine = PLoc.getLine(); 425249261Sdim } else if (PLoc.getLine() != LastLocLine) { 426249261Sdim OS << "line" << ':' << PLoc.getLine() 427249261Sdim << ':' << PLoc.getColumn(); 428249261Sdim LastLocLine = PLoc.getLine(); 429249261Sdim } else { 430249261Sdim OS << "col" << ':' << PLoc.getColumn(); 431249261Sdim } 432249261Sdim} 433249261Sdim 434249261Sdimvoid ASTDumper::dumpSourceRange(SourceRange R) { 435249261Sdim // Can't translate locations if a SourceManager isn't available. 436249261Sdim if (!SM) 437249261Sdim return; 438249261Sdim 439249261Sdim OS << " <"; 440249261Sdim dumpLocation(R.getBegin()); 441249261Sdim if (R.getBegin() != R.getEnd()) { 442249261Sdim OS << ", "; 443249261Sdim dumpLocation(R.getEnd()); 444249261Sdim } 445249261Sdim OS << ">"; 446249261Sdim 447249261Sdim // <t2.c:123:421[blah], t2.c:412:321> 448249261Sdim 449249261Sdim} 450249261Sdim 451249261Sdimvoid ASTDumper::dumpBareType(QualType T) { 452249261Sdim ColorScope Color(*this, TypeColor); 453249261Sdim 454249261Sdim SplitQualType T_split = T.split(); 455249261Sdim OS << "'" << QualType::getAsString(T_split) << "'"; 456249261Sdim 457249261Sdim if (!T.isNull()) { 458249261Sdim // If the type is sugared, also dump a (shallow) desugared type. 459249261Sdim SplitQualType D_split = T.getSplitDesugaredType(); 460249261Sdim if (T_split != D_split) 461249261Sdim OS << ":'" << QualType::getAsString(D_split) << "'"; 462249261Sdim } 463249261Sdim} 464249261Sdim 465249261Sdimvoid ASTDumper::dumpType(QualType T) { 466249261Sdim OS << ' '; 467249261Sdim dumpBareType(T); 468249261Sdim} 469249261Sdim 470249261Sdimvoid ASTDumper::dumpBareDeclRef(const Decl *D) { 471249261Sdim { 472249261Sdim ColorScope Color(*this, DeclKindNameColor); 473249261Sdim OS << D->getDeclKindName(); 474249261Sdim } 475249261Sdim dumpPointer(D); 476249261Sdim 477249261Sdim if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 478249261Sdim ColorScope Color(*this, DeclNameColor); 479263508Sdim OS << " '" << ND->getDeclName() << '\''; 480249261Sdim } 481249261Sdim 482249261Sdim if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 483249261Sdim dumpType(VD->getType()); 484249261Sdim} 485249261Sdim 486249261Sdimvoid ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { 487249261Sdim if (!D) 488249261Sdim return; 489249261Sdim 490249261Sdim IndentScope Indent(*this); 491249261Sdim if (Label) 492249261Sdim OS << Label << ' '; 493249261Sdim dumpBareDeclRef(D); 494249261Sdim} 495249261Sdim 496249261Sdimvoid ASTDumper::dumpName(const NamedDecl *ND) { 497249261Sdim if (ND->getDeclName()) { 498249261Sdim ColorScope Color(*this, DeclNameColor); 499249261Sdim OS << ' ' << ND->getNameAsString(); 500249261Sdim } 501249261Sdim} 502249261Sdim 503249261Sdimbool ASTDumper::hasNodes(const DeclContext *DC) { 504249261Sdim if (!DC) 505249261Sdim return false; 506249261Sdim 507263508Sdim return DC->hasExternalLexicalStorage() || 508263508Sdim DC->noload_decls_begin() != DC->noload_decls_end(); 509249261Sdim} 510249261Sdim 511249261Sdimvoid ASTDumper::dumpDeclContext(const DeclContext *DC) { 512249261Sdim if (!DC) 513249261Sdim return; 514263508Sdim bool HasUndeserializedDecls = DC->hasExternalLexicalStorage(); 515263508Sdim for (DeclContext::decl_iterator I = DC->noload_decls_begin(), 516263508Sdim E = DC->noload_decls_end(); 517249261Sdim I != E; ++I) { 518249261Sdim DeclContext::decl_iterator Next = I; 519249261Sdim ++Next; 520263508Sdim if (Next == E && !HasUndeserializedDecls) 521249261Sdim lastChild(); 522249261Sdim dumpDecl(*I); 523249261Sdim } 524263508Sdim if (HasUndeserializedDecls) { 525263508Sdim lastChild(); 526263508Sdim IndentScope Indent(*this); 527263508Sdim ColorScope Color(*this, UndeserializedColor); 528263508Sdim OS << "<undeserialized declarations>"; 529263508Sdim } 530249261Sdim} 531249261Sdim 532263508Sdimvoid ASTDumper::dumpLookups(const DeclContext *DC) { 533263508Sdim IndentScope Indent(*this); 534263508Sdim 535263508Sdim OS << "StoredDeclsMap "; 536263508Sdim dumpBareDeclRef(cast<Decl>(DC)); 537263508Sdim 538263508Sdim const DeclContext *Primary = DC->getPrimaryContext(); 539263508Sdim if (Primary != DC) { 540263508Sdim OS << " primary"; 541263508Sdim dumpPointer(cast<Decl>(Primary)); 542263508Sdim } 543263508Sdim 544263508Sdim bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); 545263508Sdim 546263508Sdim DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(), 547263508Sdim E = Primary->noload_lookups_end(); 548263508Sdim while (I != E) { 549263508Sdim DeclarationName Name = I.getLookupName(); 550263508Sdim DeclContextLookupResult R = *I++; 551263508Sdim if (I == E && !HasUndeserializedLookups) 552263508Sdim lastChild(); 553263508Sdim 554263508Sdim IndentScope Indent(*this); 555263508Sdim OS << "DeclarationName "; 556263508Sdim { 557263508Sdim ColorScope Color(*this, DeclNameColor); 558263508Sdim OS << '\'' << Name << '\''; 559263508Sdim } 560263508Sdim 561263508Sdim for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); 562263508Sdim RI != RE; ++RI) { 563263508Sdim if (RI + 1 == RE) 564263508Sdim lastChild(); 565263508Sdim dumpDeclRef(*RI); 566263508Sdim if ((*RI)->isHidden()) 567263508Sdim OS << " hidden"; 568263508Sdim } 569263508Sdim } 570263508Sdim 571263508Sdim if (HasUndeserializedLookups) { 572263508Sdim lastChild(); 573263508Sdim IndentScope Indent(*this); 574263508Sdim ColorScope Color(*this, UndeserializedColor); 575263508Sdim OS << "<undeserialized lookups>"; 576263508Sdim } 577263508Sdim} 578263508Sdim 579249261Sdimvoid ASTDumper::dumpAttr(const Attr *A) { 580249261Sdim IndentScope Indent(*this); 581249261Sdim { 582249261Sdim ColorScope Color(*this, AttrColor); 583249261Sdim switch (A->getKind()) { 584249261Sdim#define ATTR(X) case attr::X: OS << #X; break; 585249261Sdim#include "clang/Basic/AttrList.inc" 586249261Sdim default: llvm_unreachable("unexpected attribute kind"); 587249261Sdim } 588249261Sdim OS << "Attr"; 589249261Sdim } 590249261Sdim dumpPointer(A); 591249261Sdim dumpSourceRange(A->getRange()); 592249261Sdim#include "clang/AST/AttrDump.inc" 593249261Sdim} 594249261Sdim 595263508Sdimstatic void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 596263508Sdim 597263508Sdimtemplate<typename T> 598263508Sdimstatic void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 599263508Sdim const T *First = D->getFirstDecl(); 600263508Sdim if (First != D) 601263508Sdim OS << " first " << First; 602249261Sdim} 603249261Sdim 604249261Sdimtemplate<typename T> 605263508Sdimstatic void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 606263508Sdim const T *Prev = D->getPreviousDecl(); 607263508Sdim if (Prev) 608263508Sdim OS << " prev " << Prev; 609249261Sdim} 610249261Sdim 611263508Sdim/// Dump the previous declaration in the redeclaration chain for a declaration, 612263508Sdim/// if any. 613263508Sdimstatic void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 614249261Sdim switch (D->getKind()) { 615249261Sdim#define DECL(DERIVED, BASE) \ 616249261Sdim case Decl::DERIVED: \ 617263508Sdim return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 618249261Sdim#define ABSTRACT_DECL(DECL) 619249261Sdim#include "clang/AST/DeclNodes.inc" 620249261Sdim } 621249261Sdim llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 622249261Sdim} 623249261Sdim 624249261Sdim//===----------------------------------------------------------------------===// 625249261Sdim// C++ Utilities 626249261Sdim//===----------------------------------------------------------------------===// 627249261Sdim 628249261Sdimvoid ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { 629249261Sdim switch (AS) { 630249261Sdim case AS_none: 631249261Sdim break; 632249261Sdim case AS_public: 633249261Sdim OS << "public"; 634249261Sdim break; 635249261Sdim case AS_protected: 636249261Sdim OS << "protected"; 637249261Sdim break; 638249261Sdim case AS_private: 639249261Sdim OS << "private"; 640249261Sdim break; 641249261Sdim } 642249261Sdim} 643249261Sdim 644249261Sdimvoid ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { 645249261Sdim IndentScope Indent(*this); 646249261Sdim OS << "CXXCtorInitializer"; 647249261Sdim if (Init->isAnyMemberInitializer()) { 648249261Sdim OS << ' '; 649249261Sdim dumpBareDeclRef(Init->getAnyMember()); 650249261Sdim } else { 651249261Sdim dumpType(QualType(Init->getBaseClass(), 0)); 652249261Sdim } 653249261Sdim dumpStmt(Init->getInit()); 654249261Sdim} 655249261Sdim 656249261Sdimvoid ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { 657249261Sdim if (!TPL) 658249261Sdim return; 659249261Sdim 660249261Sdim for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end(); 661249261Sdim I != E; ++I) 662249261Sdim dumpDecl(*I); 663249261Sdim} 664249261Sdim 665249261Sdimvoid ASTDumper::dumpTemplateArgumentListInfo( 666249261Sdim const TemplateArgumentListInfo &TALI) { 667249261Sdim for (unsigned i = 0, e = TALI.size(); i < e; ++i) { 668249261Sdim if (i + 1 == e) 669249261Sdim lastChild(); 670249261Sdim dumpTemplateArgumentLoc(TALI[i]); 671249261Sdim } 672249261Sdim} 673249261Sdim 674249261Sdimvoid ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 675249261Sdim dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 676249261Sdim} 677249261Sdim 678249261Sdimvoid ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 679249261Sdim for (unsigned i = 0, e = TAL.size(); i < e; ++i) 680249261Sdim dumpTemplateArgument(TAL[i]); 681249261Sdim} 682249261Sdim 683249261Sdimvoid ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { 684249261Sdim IndentScope Indent(*this); 685249261Sdim OS << "TemplateArgument"; 686249261Sdim if (R.isValid()) 687249261Sdim dumpSourceRange(R); 688249261Sdim 689249261Sdim switch (A.getKind()) { 690249261Sdim case TemplateArgument::Null: 691249261Sdim OS << " null"; 692249261Sdim break; 693249261Sdim case TemplateArgument::Type: 694249261Sdim OS << " type"; 695249261Sdim lastChild(); 696249261Sdim dumpType(A.getAsType()); 697249261Sdim break; 698249261Sdim case TemplateArgument::Declaration: 699249261Sdim OS << " decl"; 700249261Sdim lastChild(); 701249261Sdim dumpDeclRef(A.getAsDecl()); 702249261Sdim break; 703249261Sdim case TemplateArgument::NullPtr: 704249261Sdim OS << " nullptr"; 705249261Sdim break; 706249261Sdim case TemplateArgument::Integral: 707249261Sdim OS << " integral " << A.getAsIntegral(); 708249261Sdim break; 709249261Sdim case TemplateArgument::Template: 710249261Sdim OS << " template "; 711249261Sdim A.getAsTemplate().dump(OS); 712249261Sdim break; 713249261Sdim case TemplateArgument::TemplateExpansion: 714249261Sdim OS << " template expansion"; 715249261Sdim A.getAsTemplateOrTemplatePattern().dump(OS); 716249261Sdim break; 717249261Sdim case TemplateArgument::Expression: 718249261Sdim OS << " expr"; 719249261Sdim lastChild(); 720249261Sdim dumpStmt(A.getAsExpr()); 721249261Sdim break; 722249261Sdim case TemplateArgument::Pack: 723249261Sdim OS << " pack"; 724249261Sdim for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); 725249261Sdim I != E; ++I) { 726249261Sdim if (I + 1 == E) 727249261Sdim lastChild(); 728249261Sdim dumpTemplateArgument(*I); 729249261Sdim } 730249261Sdim break; 731249261Sdim } 732249261Sdim} 733249261Sdim 734249261Sdim//===----------------------------------------------------------------------===// 735249261Sdim// Decl dumping methods. 736249261Sdim//===----------------------------------------------------------------------===// 737249261Sdim 738249261Sdimvoid ASTDumper::dumpDecl(const Decl *D) { 739249261Sdim IndentScope Indent(*this); 740249261Sdim 741249261Sdim if (!D) { 742249261Sdim ColorScope Color(*this, NullColor); 743249261Sdim OS << "<<<NULL>>>"; 744249261Sdim return; 745249261Sdim } 746249261Sdim 747249261Sdim { 748249261Sdim ColorScope Color(*this, DeclKindNameColor); 749249261Sdim OS << D->getDeclKindName() << "Decl"; 750249261Sdim } 751249261Sdim dumpPointer(D); 752249261Sdim if (D->getLexicalDeclContext() != D->getDeclContext()) 753249261Sdim OS << " parent " << cast<Decl>(D->getDeclContext()); 754263508Sdim dumpPreviousDecl(OS, D); 755249261Sdim dumpSourceRange(D->getSourceRange()); 756263508Sdim if (Module *M = D->getOwningModule()) 757263508Sdim OS << " in " << M->getFullModuleName(); 758263508Sdim if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 759263508Sdim if (ND->isHidden()) 760263508Sdim OS << " hidden"; 761249261Sdim 762249261Sdim bool HasAttrs = D->attr_begin() != D->attr_end(); 763263508Sdim const FullComment *Comment = 764263508Sdim D->getASTContext().getLocalCommentForDeclUncached(D); 765249261Sdim // Decls within functions are visited by the body 766249261Sdim bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && 767249261Sdim hasNodes(dyn_cast<DeclContext>(D)); 768249261Sdim 769263508Sdim setMoreChildren(HasAttrs || Comment || HasDeclContext); 770249261Sdim ConstDeclVisitor<ASTDumper>::Visit(D); 771249261Sdim 772263508Sdim setMoreChildren(Comment || HasDeclContext); 773249261Sdim for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); 774249261Sdim I != E; ++I) { 775249261Sdim if (I + 1 == E) 776249261Sdim lastChild(); 777249261Sdim dumpAttr(*I); 778249261Sdim } 779249261Sdim 780249261Sdim setMoreChildren(HasDeclContext); 781249261Sdim lastChild(); 782263508Sdim dumpFullComment(Comment); 783249261Sdim 784263508Sdim if (D->isInvalidDecl()) 785263508Sdim OS << " invalid"; 786263508Sdim 787249261Sdim setMoreChildren(false); 788249261Sdim if (HasDeclContext) 789249261Sdim dumpDeclContext(cast<DeclContext>(D)); 790249261Sdim} 791249261Sdim 792249261Sdimvoid ASTDumper::VisitLabelDecl(const LabelDecl *D) { 793249261Sdim dumpName(D); 794249261Sdim} 795249261Sdim 796249261Sdimvoid ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 797249261Sdim dumpName(D); 798249261Sdim dumpType(D->getUnderlyingType()); 799249261Sdim if (D->isModulePrivate()) 800249261Sdim OS << " __module_private__"; 801249261Sdim} 802249261Sdim 803249261Sdimvoid ASTDumper::VisitEnumDecl(const EnumDecl *D) { 804249261Sdim if (D->isScoped()) { 805249261Sdim if (D->isScopedUsingClassTag()) 806249261Sdim OS << " class"; 807249261Sdim else 808249261Sdim OS << " struct"; 809249261Sdim } 810249261Sdim dumpName(D); 811249261Sdim if (D->isModulePrivate()) 812249261Sdim OS << " __module_private__"; 813249261Sdim if (D->isFixed()) 814249261Sdim dumpType(D->getIntegerType()); 815249261Sdim} 816249261Sdim 817249261Sdimvoid ASTDumper::VisitRecordDecl(const RecordDecl *D) { 818249261Sdim OS << ' ' << D->getKindName(); 819249261Sdim dumpName(D); 820249261Sdim if (D->isModulePrivate()) 821249261Sdim OS << " __module_private__"; 822263508Sdim if (D->isCompleteDefinition()) 823263508Sdim OS << " definition"; 824249261Sdim} 825249261Sdim 826249261Sdimvoid ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 827249261Sdim dumpName(D); 828249261Sdim dumpType(D->getType()); 829249261Sdim if (const Expr *Init = D->getInitExpr()) { 830249261Sdim lastChild(); 831249261Sdim dumpStmt(Init); 832249261Sdim } 833249261Sdim} 834249261Sdim 835249261Sdimvoid ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 836249261Sdim dumpName(D); 837249261Sdim dumpType(D->getType()); 838249261Sdim for (IndirectFieldDecl::chain_iterator I = D->chain_begin(), 839249261Sdim E = D->chain_end(); 840249261Sdim I != E; ++I) { 841249261Sdim if (I + 1 == E) 842249261Sdim lastChild(); 843249261Sdim dumpDeclRef(*I); 844249261Sdim } 845249261Sdim} 846249261Sdim 847249261Sdimvoid ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 848249261Sdim dumpName(D); 849249261Sdim dumpType(D->getType()); 850249261Sdim 851249261Sdim StorageClass SC = D->getStorageClass(); 852249261Sdim if (SC != SC_None) 853249261Sdim OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 854249261Sdim if (D->isInlineSpecified()) 855249261Sdim OS << " inline"; 856249261Sdim if (D->isVirtualAsWritten()) 857249261Sdim OS << " virtual"; 858249261Sdim if (D->isModulePrivate()) 859249261Sdim OS << " __module_private__"; 860249261Sdim 861249261Sdim if (D->isPure()) 862249261Sdim OS << " pure"; 863249261Sdim else if (D->isDeletedAsWritten()) 864249261Sdim OS << " delete"; 865249261Sdim 866263508Sdim if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { 867263508Sdim FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 868263508Sdim switch (EPI.ExceptionSpecType) { 869263508Sdim default: break; 870263508Sdim case EST_Unevaluated: 871263508Sdim OS << " noexcept-unevaluated " << EPI.ExceptionSpecDecl; 872263508Sdim break; 873263508Sdim case EST_Uninstantiated: 874263508Sdim OS << " noexcept-uninstantiated " << EPI.ExceptionSpecTemplate; 875263508Sdim break; 876263508Sdim } 877263508Sdim } 878263508Sdim 879249261Sdim bool OldMoreChildren = hasMoreChildren(); 880249261Sdim const FunctionTemplateSpecializationInfo *FTSI = 881249261Sdim D->getTemplateSpecializationInfo(); 882249261Sdim bool HasTemplateSpecialization = FTSI; 883249261Sdim 884249261Sdim bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() != 885249261Sdim D->getDeclsInPrototypeScope().end(); 886249261Sdim 887249261Sdim bool HasFunctionDecls = D->param_begin() != D->param_end(); 888249261Sdim 889249261Sdim const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D); 890249261Sdim bool HasCtorInitializers = C && C->init_begin() != C->init_end(); 891249261Sdim 892249261Sdim bool HasDeclarationBody = D->doesThisDeclarationHaveABody(); 893249261Sdim 894249261Sdim setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls || 895249261Sdim HasCtorInitializers || HasDeclarationBody); 896249261Sdim if (HasTemplateSpecialization) { 897249261Sdim lastChild(); 898249261Sdim dumpTemplateArgumentList(*FTSI->TemplateArguments); 899249261Sdim } 900249261Sdim 901249261Sdim setMoreChildren(OldMoreChildren || HasFunctionDecls || 902249261Sdim HasCtorInitializers || HasDeclarationBody); 903249261Sdim for (ArrayRef<NamedDecl *>::iterator 904249261Sdim I = D->getDeclsInPrototypeScope().begin(), 905249261Sdim E = D->getDeclsInPrototypeScope().end(); I != E; ++I) { 906249261Sdim if (I + 1 == E) 907249261Sdim lastChild(); 908249261Sdim dumpDecl(*I); 909249261Sdim } 910249261Sdim 911249261Sdim setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody); 912249261Sdim for (FunctionDecl::param_const_iterator I = D->param_begin(), 913249261Sdim E = D->param_end(); 914249261Sdim I != E; ++I) { 915249261Sdim if (I + 1 == E) 916249261Sdim lastChild(); 917249261Sdim dumpDecl(*I); 918249261Sdim } 919249261Sdim 920249261Sdim setMoreChildren(OldMoreChildren || HasDeclarationBody); 921249261Sdim if (HasCtorInitializers) 922249261Sdim for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 923249261Sdim E = C->init_end(); 924249261Sdim I != E; ++I) { 925249261Sdim if (I + 1 == E) 926249261Sdim lastChild(); 927249261Sdim dumpCXXCtorInitializer(*I); 928249261Sdim } 929249261Sdim 930249261Sdim setMoreChildren(OldMoreChildren); 931249261Sdim if (HasDeclarationBody) { 932249261Sdim lastChild(); 933249261Sdim dumpStmt(D->getBody()); 934249261Sdim } 935249261Sdim} 936249261Sdim 937249261Sdimvoid ASTDumper::VisitFieldDecl(const FieldDecl *D) { 938249261Sdim dumpName(D); 939249261Sdim dumpType(D->getType()); 940249261Sdim if (D->isMutable()) 941249261Sdim OS << " mutable"; 942249261Sdim if (D->isModulePrivate()) 943249261Sdim OS << " __module_private__"; 944249261Sdim 945249261Sdim bool OldMoreChildren = hasMoreChildren(); 946249261Sdim bool IsBitField = D->isBitField(); 947249261Sdim Expr *Init = D->getInClassInitializer(); 948249261Sdim bool HasInit = Init; 949249261Sdim 950249261Sdim setMoreChildren(OldMoreChildren || HasInit); 951249261Sdim if (IsBitField) { 952249261Sdim lastChild(); 953249261Sdim dumpStmt(D->getBitWidth()); 954249261Sdim } 955249261Sdim setMoreChildren(OldMoreChildren); 956249261Sdim if (HasInit) { 957249261Sdim lastChild(); 958249261Sdim dumpStmt(Init); 959249261Sdim } 960249261Sdim} 961249261Sdim 962249261Sdimvoid ASTDumper::VisitVarDecl(const VarDecl *D) { 963249261Sdim dumpName(D); 964249261Sdim dumpType(D->getType()); 965249261Sdim StorageClass SC = D->getStorageClass(); 966249261Sdim if (SC != SC_None) 967249261Sdim OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 968251662Sdim switch (D->getTLSKind()) { 969251662Sdim case VarDecl::TLS_None: break; 970251662Sdim case VarDecl::TLS_Static: OS << " tls"; break; 971251662Sdim case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 972251662Sdim } 973249261Sdim if (D->isModulePrivate()) 974249261Sdim OS << " __module_private__"; 975249261Sdim if (D->isNRVOVariable()) 976249261Sdim OS << " nrvo"; 977249261Sdim if (D->hasInit()) { 978249261Sdim lastChild(); 979249261Sdim dumpStmt(D->getInit()); 980249261Sdim } 981249261Sdim} 982249261Sdim 983249261Sdimvoid ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 984249261Sdim lastChild(); 985249261Sdim dumpStmt(D->getAsmString()); 986249261Sdim} 987249261Sdim 988249261Sdimvoid ASTDumper::VisitImportDecl(const ImportDecl *D) { 989249261Sdim OS << ' ' << D->getImportedModule()->getFullModuleName(); 990249261Sdim} 991249261Sdim 992249261Sdim//===----------------------------------------------------------------------===// 993249261Sdim// C++ Declarations 994249261Sdim//===----------------------------------------------------------------------===// 995249261Sdim 996249261Sdimvoid ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 997249261Sdim dumpName(D); 998249261Sdim if (D->isInline()) 999249261Sdim OS << " inline"; 1000249261Sdim if (!D->isOriginalNamespace()) 1001249261Sdim dumpDeclRef(D->getOriginalNamespace(), "original"); 1002249261Sdim} 1003249261Sdim 1004249261Sdimvoid ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1005249261Sdim OS << ' '; 1006249261Sdim dumpBareDeclRef(D->getNominatedNamespace()); 1007249261Sdim} 1008249261Sdim 1009249261Sdimvoid ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1010249261Sdim dumpName(D); 1011249261Sdim dumpDeclRef(D->getAliasedNamespace()); 1012249261Sdim} 1013249261Sdim 1014249261Sdimvoid ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1015249261Sdim dumpName(D); 1016249261Sdim dumpType(D->getUnderlyingType()); 1017249261Sdim} 1018249261Sdim 1019249261Sdimvoid ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 1020249261Sdim dumpName(D); 1021249261Sdim dumpTemplateParameters(D->getTemplateParameters()); 1022249261Sdim dumpDecl(D->getTemplatedDecl()); 1023249261Sdim} 1024249261Sdim 1025249261Sdimvoid ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1026249261Sdim VisitRecordDecl(D); 1027249261Sdim if (!D->isCompleteDefinition()) 1028249261Sdim return; 1029249261Sdim 1030249261Sdim for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(), 1031249261Sdim E = D->bases_end(); 1032249261Sdim I != E; ++I) { 1033249261Sdim IndentScope Indent(*this); 1034249261Sdim if (I->isVirtual()) 1035249261Sdim OS << "virtual "; 1036249261Sdim dumpAccessSpecifier(I->getAccessSpecifier()); 1037249261Sdim dumpType(I->getType()); 1038249261Sdim if (I->isPackExpansion()) 1039249261Sdim OS << "..."; 1040249261Sdim } 1041249261Sdim} 1042249261Sdim 1043249261Sdimvoid ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 1044249261Sdim dumpStmt(D->getAssertExpr()); 1045249261Sdim lastChild(); 1046249261Sdim dumpStmt(D->getMessage()); 1047249261Sdim} 1048249261Sdim 1049249261Sdimvoid ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1050249261Sdim dumpName(D); 1051249261Sdim dumpTemplateParameters(D->getTemplateParameters()); 1052249261Sdim dumpDecl(D->getTemplatedDecl()); 1053249261Sdim for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), 1054249261Sdim E = D->spec_end(); 1055249261Sdim I != E; ++I) { 1056249261Sdim FunctionTemplateDecl::spec_iterator Next = I; 1057249261Sdim ++Next; 1058249261Sdim if (Next == E) 1059249261Sdim lastChild(); 1060249261Sdim switch (I->getTemplateSpecializationKind()) { 1061249261Sdim case TSK_Undeclared: 1062249261Sdim case TSK_ImplicitInstantiation: 1063249261Sdim case TSK_ExplicitInstantiationDeclaration: 1064249261Sdim case TSK_ExplicitInstantiationDefinition: 1065249261Sdim if (D == D->getCanonicalDecl()) 1066249261Sdim dumpDecl(*I); 1067249261Sdim else 1068249261Sdim dumpDeclRef(*I); 1069249261Sdim break; 1070249261Sdim case TSK_ExplicitSpecialization: 1071249261Sdim dumpDeclRef(*I); 1072249261Sdim break; 1073249261Sdim } 1074249261Sdim } 1075249261Sdim} 1076249261Sdim 1077249261Sdimvoid ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1078249261Sdim dumpName(D); 1079249261Sdim dumpTemplateParameters(D->getTemplateParameters()); 1080249261Sdim 1081249261Sdim ClassTemplateDecl::spec_iterator I = D->spec_begin(); 1082249261Sdim ClassTemplateDecl::spec_iterator E = D->spec_end(); 1083249261Sdim if (I == E) 1084249261Sdim lastChild(); 1085249261Sdim dumpDecl(D->getTemplatedDecl()); 1086249261Sdim for (; I != E; ++I) { 1087249261Sdim ClassTemplateDecl::spec_iterator Next = I; 1088249261Sdim ++Next; 1089249261Sdim if (Next == E) 1090249261Sdim lastChild(); 1091249261Sdim switch (I->getTemplateSpecializationKind()) { 1092249261Sdim case TSK_Undeclared: 1093249261Sdim case TSK_ImplicitInstantiation: 1094249261Sdim if (D == D->getCanonicalDecl()) 1095249261Sdim dumpDecl(*I); 1096249261Sdim else 1097249261Sdim dumpDeclRef(*I); 1098249261Sdim break; 1099249261Sdim case TSK_ExplicitSpecialization: 1100249261Sdim case TSK_ExplicitInstantiationDeclaration: 1101249261Sdim case TSK_ExplicitInstantiationDefinition: 1102249261Sdim dumpDeclRef(*I); 1103249261Sdim break; 1104249261Sdim } 1105249261Sdim } 1106249261Sdim} 1107249261Sdim 1108249261Sdimvoid ASTDumper::VisitClassTemplateSpecializationDecl( 1109249261Sdim const ClassTemplateSpecializationDecl *D) { 1110249261Sdim VisitCXXRecordDecl(D); 1111249261Sdim dumpTemplateArgumentList(D->getTemplateArgs()); 1112249261Sdim} 1113249261Sdim 1114249261Sdimvoid ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1115249261Sdim const ClassTemplatePartialSpecializationDecl *D) { 1116249261Sdim VisitClassTemplateSpecializationDecl(D); 1117249261Sdim dumpTemplateParameters(D->getTemplateParameters()); 1118249261Sdim} 1119249261Sdim 1120249261Sdimvoid ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1121249261Sdim const ClassScopeFunctionSpecializationDecl *D) { 1122249261Sdim dumpDeclRef(D->getSpecialization()); 1123249261Sdim if (D->hasExplicitTemplateArgs()) 1124249261Sdim dumpTemplateArgumentListInfo(D->templateArgs()); 1125249261Sdim} 1126249261Sdim 1127263508Sdimvoid ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1128263508Sdim dumpName(D); 1129263508Sdim dumpTemplateParameters(D->getTemplateParameters()); 1130263508Sdim 1131263508Sdim VarTemplateDecl::spec_iterator I = D->spec_begin(); 1132263508Sdim VarTemplateDecl::spec_iterator E = D->spec_end(); 1133263508Sdim if (I == E) 1134263508Sdim lastChild(); 1135263508Sdim dumpDecl(D->getTemplatedDecl()); 1136263508Sdim for (; I != E; ++I) { 1137263508Sdim VarTemplateDecl::spec_iterator Next = I; 1138263508Sdim ++Next; 1139263508Sdim if (Next == E) 1140263508Sdim lastChild(); 1141263508Sdim switch (I->getTemplateSpecializationKind()) { 1142263508Sdim case TSK_Undeclared: 1143263508Sdim case TSK_ImplicitInstantiation: 1144263508Sdim if (D == D->getCanonicalDecl()) 1145263508Sdim dumpDecl(*I); 1146263508Sdim else 1147263508Sdim dumpDeclRef(*I); 1148263508Sdim break; 1149263508Sdim case TSK_ExplicitSpecialization: 1150263508Sdim case TSK_ExplicitInstantiationDeclaration: 1151263508Sdim case TSK_ExplicitInstantiationDefinition: 1152263508Sdim dumpDeclRef(*I); 1153263508Sdim break; 1154263508Sdim } 1155263508Sdim } 1156263508Sdim} 1157263508Sdim 1158263508Sdimvoid ASTDumper::VisitVarTemplateSpecializationDecl( 1159263508Sdim const VarTemplateSpecializationDecl *D) { 1160263508Sdim dumpTemplateArgumentList(D->getTemplateArgs()); 1161263508Sdim VisitVarDecl(D); 1162263508Sdim} 1163263508Sdim 1164263508Sdimvoid ASTDumper::VisitVarTemplatePartialSpecializationDecl( 1165263508Sdim const VarTemplatePartialSpecializationDecl *D) { 1166263508Sdim dumpTemplateParameters(D->getTemplateParameters()); 1167263508Sdim VisitVarTemplateSpecializationDecl(D); 1168263508Sdim} 1169263508Sdim 1170249261Sdimvoid ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1171249261Sdim if (D->wasDeclaredWithTypename()) 1172249261Sdim OS << " typename"; 1173249261Sdim else 1174249261Sdim OS << " class"; 1175249261Sdim if (D->isParameterPack()) 1176249261Sdim OS << " ..."; 1177249261Sdim dumpName(D); 1178249261Sdim if (D->hasDefaultArgument()) 1179249261Sdim dumpType(D->getDefaultArgument()); 1180249261Sdim} 1181249261Sdim 1182249261Sdimvoid ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1183249261Sdim dumpType(D->getType()); 1184249261Sdim if (D->isParameterPack()) 1185249261Sdim OS << " ..."; 1186249261Sdim dumpName(D); 1187249261Sdim if (D->hasDefaultArgument()) 1188249261Sdim dumpStmt(D->getDefaultArgument()); 1189249261Sdim} 1190249261Sdim 1191249261Sdimvoid ASTDumper::VisitTemplateTemplateParmDecl( 1192249261Sdim const TemplateTemplateParmDecl *D) { 1193249261Sdim if (D->isParameterPack()) 1194249261Sdim OS << " ..."; 1195249261Sdim dumpName(D); 1196249261Sdim dumpTemplateParameters(D->getTemplateParameters()); 1197249261Sdim if (D->hasDefaultArgument()) 1198249261Sdim dumpTemplateArgumentLoc(D->getDefaultArgument()); 1199249261Sdim} 1200249261Sdim 1201249261Sdimvoid ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1202249261Sdim OS << ' '; 1203249261Sdim D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1204249261Sdim OS << D->getNameAsString(); 1205249261Sdim} 1206249261Sdim 1207249261Sdimvoid ASTDumper::VisitUnresolvedUsingTypenameDecl( 1208249261Sdim const UnresolvedUsingTypenameDecl *D) { 1209249261Sdim OS << ' '; 1210249261Sdim D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1211249261Sdim OS << D->getNameAsString(); 1212249261Sdim} 1213249261Sdim 1214249261Sdimvoid ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1215249261Sdim OS << ' '; 1216249261Sdim D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1217249261Sdim OS << D->getNameAsString(); 1218249261Sdim dumpType(D->getType()); 1219249261Sdim} 1220249261Sdim 1221249261Sdimvoid ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1222249261Sdim OS << ' '; 1223249261Sdim dumpBareDeclRef(D->getTargetDecl()); 1224249261Sdim} 1225249261Sdim 1226249261Sdimvoid ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1227249261Sdim switch (D->getLanguage()) { 1228249261Sdim case LinkageSpecDecl::lang_c: OS << " C"; break; 1229249261Sdim case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1230249261Sdim } 1231249261Sdim} 1232249261Sdim 1233249261Sdimvoid ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1234249261Sdim OS << ' '; 1235249261Sdim dumpAccessSpecifier(D->getAccess()); 1236249261Sdim} 1237249261Sdim 1238249261Sdimvoid ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1239249261Sdim lastChild(); 1240249261Sdim if (TypeSourceInfo *T = D->getFriendType()) 1241249261Sdim dumpType(T->getType()); 1242249261Sdim else 1243249261Sdim dumpDecl(D->getFriendDecl()); 1244249261Sdim} 1245249261Sdim 1246249261Sdim//===----------------------------------------------------------------------===// 1247249261Sdim// Obj-C Declarations 1248249261Sdim//===----------------------------------------------------------------------===// 1249249261Sdim 1250249261Sdimvoid ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1251249261Sdim dumpName(D); 1252249261Sdim dumpType(D->getType()); 1253249261Sdim if (D->getSynthesize()) 1254249261Sdim OS << " synthesize"; 1255263508Sdim if (D->getBackingIvarReferencedInAccessor()) 1256263508Sdim OS << " BackingIvarReferencedInAccessor"; 1257249261Sdim 1258249261Sdim switch (D->getAccessControl()) { 1259249261Sdim case ObjCIvarDecl::None: 1260249261Sdim OS << " none"; 1261249261Sdim break; 1262249261Sdim case ObjCIvarDecl::Private: 1263249261Sdim OS << " private"; 1264249261Sdim break; 1265249261Sdim case ObjCIvarDecl::Protected: 1266249261Sdim OS << " protected"; 1267249261Sdim break; 1268249261Sdim case ObjCIvarDecl::Public: 1269249261Sdim OS << " public"; 1270249261Sdim break; 1271249261Sdim case ObjCIvarDecl::Package: 1272249261Sdim OS << " package"; 1273249261Sdim break; 1274249261Sdim } 1275249261Sdim} 1276249261Sdim 1277249261Sdimvoid ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1278249261Sdim if (D->isInstanceMethod()) 1279249261Sdim OS << " -"; 1280249261Sdim else 1281249261Sdim OS << " +"; 1282249261Sdim dumpName(D); 1283249261Sdim dumpType(D->getResultType()); 1284249261Sdim 1285249261Sdim bool OldMoreChildren = hasMoreChildren(); 1286249261Sdim bool IsVariadic = D->isVariadic(); 1287249261Sdim bool HasBody = D->hasBody(); 1288249261Sdim 1289249261Sdim setMoreChildren(OldMoreChildren || IsVariadic || HasBody); 1290249261Sdim if (D->isThisDeclarationADefinition()) { 1291249261Sdim lastChild(); 1292249261Sdim dumpDeclContext(D); 1293249261Sdim } else { 1294249261Sdim for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1295249261Sdim E = D->param_end(); 1296249261Sdim I != E; ++I) { 1297249261Sdim if (I + 1 == E) 1298249261Sdim lastChild(); 1299249261Sdim dumpDecl(*I); 1300249261Sdim } 1301249261Sdim } 1302249261Sdim 1303249261Sdim setMoreChildren(OldMoreChildren || HasBody); 1304249261Sdim if (IsVariadic) { 1305249261Sdim lastChild(); 1306249261Sdim IndentScope Indent(*this); 1307249261Sdim OS << "..."; 1308249261Sdim } 1309249261Sdim 1310249261Sdim setMoreChildren(OldMoreChildren); 1311249261Sdim if (HasBody) { 1312249261Sdim lastChild(); 1313249261Sdim dumpStmt(D->getBody()); 1314249261Sdim } 1315249261Sdim} 1316249261Sdim 1317249261Sdimvoid ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1318249261Sdim dumpName(D); 1319249261Sdim dumpDeclRef(D->getClassInterface()); 1320249261Sdim if (D->protocol_begin() == D->protocol_end()) 1321249261Sdim lastChild(); 1322249261Sdim dumpDeclRef(D->getImplementation()); 1323249261Sdim for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1324249261Sdim E = D->protocol_end(); 1325249261Sdim I != E; ++I) { 1326249261Sdim if (I + 1 == E) 1327249261Sdim lastChild(); 1328249261Sdim dumpDeclRef(*I); 1329249261Sdim } 1330249261Sdim} 1331249261Sdim 1332249261Sdimvoid ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1333249261Sdim dumpName(D); 1334249261Sdim dumpDeclRef(D->getClassInterface()); 1335249261Sdim lastChild(); 1336249261Sdim dumpDeclRef(D->getCategoryDecl()); 1337249261Sdim} 1338249261Sdim 1339249261Sdimvoid ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1340249261Sdim dumpName(D); 1341249261Sdim for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), 1342249261Sdim E = D->protocol_end(); 1343249261Sdim I != E; ++I) { 1344249261Sdim if (I + 1 == E) 1345249261Sdim lastChild(); 1346249261Sdim dumpDeclRef(*I); 1347249261Sdim } 1348249261Sdim} 1349249261Sdim 1350249261Sdimvoid ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1351249261Sdim dumpName(D); 1352249261Sdim dumpDeclRef(D->getSuperClass(), "super"); 1353249261Sdim if (D->protocol_begin() == D->protocol_end()) 1354249261Sdim lastChild(); 1355249261Sdim dumpDeclRef(D->getImplementation()); 1356249261Sdim for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 1357249261Sdim E = D->protocol_end(); 1358249261Sdim I != E; ++I) { 1359249261Sdim if (I + 1 == E) 1360249261Sdim lastChild(); 1361249261Sdim dumpDeclRef(*I); 1362249261Sdim } 1363249261Sdim} 1364249261Sdim 1365249261Sdimvoid ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1366249261Sdim dumpName(D); 1367249261Sdim dumpDeclRef(D->getSuperClass(), "super"); 1368249261Sdim if (D->init_begin() == D->init_end()) 1369249261Sdim lastChild(); 1370249261Sdim dumpDeclRef(D->getClassInterface()); 1371249261Sdim for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1372249261Sdim E = D->init_end(); 1373249261Sdim I != E; ++I) { 1374249261Sdim if (I + 1 == E) 1375249261Sdim lastChild(); 1376249261Sdim dumpCXXCtorInitializer(*I); 1377249261Sdim } 1378249261Sdim} 1379249261Sdim 1380249261Sdimvoid ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1381249261Sdim dumpName(D); 1382249261Sdim lastChild(); 1383249261Sdim dumpDeclRef(D->getClassInterface()); 1384249261Sdim} 1385249261Sdim 1386249261Sdimvoid ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1387249261Sdim dumpName(D); 1388249261Sdim dumpType(D->getType()); 1389249261Sdim 1390249261Sdim if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1391249261Sdim OS << " required"; 1392249261Sdim else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1393249261Sdim OS << " optional"; 1394249261Sdim 1395249261Sdim ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1396249261Sdim if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1397249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1398249261Sdim OS << " readonly"; 1399249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1400249261Sdim OS << " assign"; 1401249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1402249261Sdim OS << " readwrite"; 1403249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1404249261Sdim OS << " retain"; 1405249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1406249261Sdim OS << " copy"; 1407249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1408249261Sdim OS << " nonatomic"; 1409249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1410249261Sdim OS << " atomic"; 1411249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1412249261Sdim OS << " weak"; 1413249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1414249261Sdim OS << " strong"; 1415249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1416249261Sdim OS << " unsafe_unretained"; 1417249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { 1418249261Sdim if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) 1419249261Sdim lastChild(); 1420249261Sdim dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1421249261Sdim } 1422249261Sdim if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { 1423249261Sdim lastChild(); 1424249261Sdim dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1425249261Sdim } 1426249261Sdim } 1427249261Sdim} 1428249261Sdim 1429249261Sdimvoid ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1430249261Sdim dumpName(D->getPropertyDecl()); 1431249261Sdim if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1432249261Sdim OS << " synthesize"; 1433249261Sdim else 1434249261Sdim OS << " dynamic"; 1435249261Sdim dumpDeclRef(D->getPropertyDecl()); 1436249261Sdim lastChild(); 1437249261Sdim dumpDeclRef(D->getPropertyIvarDecl()); 1438249261Sdim} 1439249261Sdim 1440249261Sdimvoid ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1441249261Sdim for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); 1442249261Sdim I != E; ++I) 1443249261Sdim dumpDecl(*I); 1444249261Sdim 1445249261Sdim if (D->isVariadic()) { 1446249261Sdim IndentScope Indent(*this); 1447249261Sdim OS << "..."; 1448249261Sdim } 1449249261Sdim 1450249261Sdim if (D->capturesCXXThis()) { 1451249261Sdim IndentScope Indent(*this); 1452249261Sdim OS << "capture this"; 1453249261Sdim } 1454249261Sdim for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end(); 1455249261Sdim I != E; ++I) { 1456249261Sdim IndentScope Indent(*this); 1457249261Sdim OS << "capture"; 1458249261Sdim if (I->isByRef()) 1459249261Sdim OS << " byref"; 1460249261Sdim if (I->isNested()) 1461249261Sdim OS << " nested"; 1462249261Sdim if (I->getVariable()) { 1463249261Sdim OS << ' '; 1464249261Sdim dumpBareDeclRef(I->getVariable()); 1465249261Sdim } 1466249261Sdim if (I->hasCopyExpr()) 1467249261Sdim dumpStmt(I->getCopyExpr()); 1468249261Sdim } 1469249261Sdim lastChild(); 1470249261Sdim dumpStmt(D->getBody()); 1471249261Sdim} 1472249261Sdim 1473249261Sdim//===----------------------------------------------------------------------===// 1474249261Sdim// Stmt dumping methods. 1475249261Sdim//===----------------------------------------------------------------------===// 1476249261Sdim 1477249261Sdimvoid ASTDumper::dumpStmt(const Stmt *S) { 1478249261Sdim IndentScope Indent(*this); 1479249261Sdim 1480249261Sdim if (!S) { 1481249261Sdim ColorScope Color(*this, NullColor); 1482249261Sdim OS << "<<<NULL>>>"; 1483249261Sdim return; 1484249261Sdim } 1485249261Sdim 1486249261Sdim if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1487249261Sdim VisitDeclStmt(DS); 1488249261Sdim return; 1489249261Sdim } 1490249261Sdim 1491263508Sdim setMoreChildren(!S->children().empty()); 1492249261Sdim ConstStmtVisitor<ASTDumper>::Visit(S); 1493249261Sdim setMoreChildren(false); 1494249261Sdim for (Stmt::const_child_range CI = S->children(); CI; ++CI) { 1495249261Sdim Stmt::const_child_range Next = CI; 1496249261Sdim ++Next; 1497249261Sdim if (!Next) 1498249261Sdim lastChild(); 1499249261Sdim dumpStmt(*CI); 1500249261Sdim } 1501249261Sdim} 1502249261Sdim 1503249261Sdimvoid ASTDumper::VisitStmt(const Stmt *Node) { 1504249261Sdim { 1505249261Sdim ColorScope Color(*this, StmtColor); 1506249261Sdim OS << Node->getStmtClassName(); 1507249261Sdim } 1508249261Sdim dumpPointer(Node); 1509249261Sdim dumpSourceRange(Node->getSourceRange()); 1510249261Sdim} 1511249261Sdim 1512249261Sdimvoid ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1513249261Sdim VisitStmt(Node); 1514249261Sdim for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1515249261Sdim E = Node->decl_end(); 1516249261Sdim I != E; ++I) { 1517249261Sdim if (I + 1 == E) 1518249261Sdim lastChild(); 1519249261Sdim dumpDecl(*I); 1520249261Sdim } 1521249261Sdim} 1522249261Sdim 1523249261Sdimvoid ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1524249261Sdim VisitStmt(Node); 1525249261Sdim for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1526249261Sdim E = Node->getAttrs().end(); 1527249261Sdim I != E; ++I) { 1528249261Sdim if (I + 1 == E) 1529249261Sdim lastChild(); 1530249261Sdim dumpAttr(*I); 1531249261Sdim } 1532249261Sdim} 1533249261Sdim 1534249261Sdimvoid ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1535249261Sdim VisitStmt(Node); 1536249261Sdim OS << " '" << Node->getName() << "'"; 1537249261Sdim} 1538249261Sdim 1539249261Sdimvoid ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1540249261Sdim VisitStmt(Node); 1541249261Sdim OS << " '" << Node->getLabel()->getName() << "'"; 1542249261Sdim dumpPointer(Node->getLabel()); 1543249261Sdim} 1544249261Sdim 1545263508Sdimvoid ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1546263508Sdim VisitStmt(Node); 1547263508Sdim dumpDecl(Node->getExceptionDecl()); 1548263508Sdim} 1549263508Sdim 1550249261Sdim//===----------------------------------------------------------------------===// 1551249261Sdim// Expr dumping methods. 1552249261Sdim//===----------------------------------------------------------------------===// 1553249261Sdim 1554249261Sdimvoid ASTDumper::VisitExpr(const Expr *Node) { 1555249261Sdim VisitStmt(Node); 1556249261Sdim dumpType(Node->getType()); 1557249261Sdim 1558249261Sdim { 1559249261Sdim ColorScope Color(*this, ValueKindColor); 1560249261Sdim switch (Node->getValueKind()) { 1561249261Sdim case VK_RValue: 1562249261Sdim break; 1563249261Sdim case VK_LValue: 1564249261Sdim OS << " lvalue"; 1565249261Sdim break; 1566249261Sdim case VK_XValue: 1567249261Sdim OS << " xvalue"; 1568249261Sdim break; 1569249261Sdim } 1570249261Sdim } 1571249261Sdim 1572249261Sdim { 1573249261Sdim ColorScope Color(*this, ObjectKindColor); 1574249261Sdim switch (Node->getObjectKind()) { 1575249261Sdim case OK_Ordinary: 1576249261Sdim break; 1577249261Sdim case OK_BitField: 1578249261Sdim OS << " bitfield"; 1579249261Sdim break; 1580249261Sdim case OK_ObjCProperty: 1581249261Sdim OS << " objcproperty"; 1582249261Sdim break; 1583249261Sdim case OK_ObjCSubscript: 1584249261Sdim OS << " objcsubscript"; 1585249261Sdim break; 1586249261Sdim case OK_VectorComponent: 1587249261Sdim OS << " vectorcomponent"; 1588249261Sdim break; 1589249261Sdim } 1590249261Sdim } 1591249261Sdim} 1592249261Sdim 1593249261Sdimstatic void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1594249261Sdim if (Node->path_empty()) 1595249261Sdim return; 1596249261Sdim 1597249261Sdim OS << " ("; 1598249261Sdim bool First = true; 1599249261Sdim for (CastExpr::path_const_iterator I = Node->path_begin(), 1600249261Sdim E = Node->path_end(); 1601249261Sdim I != E; ++I) { 1602249261Sdim const CXXBaseSpecifier *Base = *I; 1603249261Sdim if (!First) 1604249261Sdim OS << " -> "; 1605249261Sdim 1606249261Sdim const CXXRecordDecl *RD = 1607249261Sdim cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1608249261Sdim 1609249261Sdim if (Base->isVirtual()) 1610249261Sdim OS << "virtual "; 1611249261Sdim OS << RD->getName(); 1612249261Sdim First = false; 1613249261Sdim } 1614249261Sdim 1615249261Sdim OS << ')'; 1616249261Sdim} 1617249261Sdim 1618249261Sdimvoid ASTDumper::VisitCastExpr(const CastExpr *Node) { 1619249261Sdim VisitExpr(Node); 1620249261Sdim OS << " <"; 1621249261Sdim { 1622249261Sdim ColorScope Color(*this, CastColor); 1623249261Sdim OS << Node->getCastKindName(); 1624249261Sdim } 1625249261Sdim dumpBasePath(OS, Node); 1626249261Sdim OS << ">"; 1627249261Sdim} 1628249261Sdim 1629249261Sdimvoid ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1630249261Sdim VisitExpr(Node); 1631249261Sdim 1632249261Sdim OS << " "; 1633249261Sdim dumpBareDeclRef(Node->getDecl()); 1634249261Sdim if (Node->getDecl() != Node->getFoundDecl()) { 1635249261Sdim OS << " ("; 1636249261Sdim dumpBareDeclRef(Node->getFoundDecl()); 1637249261Sdim OS << ")"; 1638249261Sdim } 1639249261Sdim} 1640249261Sdim 1641249261Sdimvoid ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1642249261Sdim VisitExpr(Node); 1643249261Sdim OS << " ("; 1644249261Sdim if (!Node->requiresADL()) 1645249261Sdim OS << "no "; 1646249261Sdim OS << "ADL) = '" << Node->getName() << '\''; 1647249261Sdim 1648249261Sdim UnresolvedLookupExpr::decls_iterator 1649249261Sdim I = Node->decls_begin(), E = Node->decls_end(); 1650249261Sdim if (I == E) 1651249261Sdim OS << " empty"; 1652249261Sdim for (; I != E; ++I) 1653249261Sdim dumpPointer(*I); 1654249261Sdim} 1655249261Sdim 1656249261Sdimvoid ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1657249261Sdim VisitExpr(Node); 1658249261Sdim 1659249261Sdim { 1660249261Sdim ColorScope Color(*this, DeclKindNameColor); 1661249261Sdim OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1662249261Sdim } 1663249261Sdim OS << "='" << *Node->getDecl() << "'"; 1664249261Sdim dumpPointer(Node->getDecl()); 1665249261Sdim if (Node->isFreeIvar()) 1666249261Sdim OS << " isFreeIvar"; 1667249261Sdim} 1668249261Sdim 1669249261Sdimvoid ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1670249261Sdim VisitExpr(Node); 1671249261Sdim switch (Node->getIdentType()) { 1672249261Sdim default: llvm_unreachable("unknown case"); 1673249261Sdim case PredefinedExpr::Func: OS << " __func__"; break; 1674249261Sdim case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 1675263508Sdim case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break; 1676249261Sdim case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break; 1677249261Sdim case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 1678249261Sdim } 1679249261Sdim} 1680249261Sdim 1681249261Sdimvoid ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1682249261Sdim VisitExpr(Node); 1683249261Sdim ColorScope Color(*this, ValueColor); 1684249261Sdim OS << " " << Node->getValue(); 1685249261Sdim} 1686249261Sdim 1687249261Sdimvoid ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1688249261Sdim VisitExpr(Node); 1689249261Sdim 1690249261Sdim bool isSigned = Node->getType()->isSignedIntegerType(); 1691249261Sdim ColorScope Color(*this, ValueColor); 1692249261Sdim OS << " " << Node->getValue().toString(10, isSigned); 1693249261Sdim} 1694249261Sdim 1695249261Sdimvoid ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1696249261Sdim VisitExpr(Node); 1697249261Sdim ColorScope Color(*this, ValueColor); 1698249261Sdim OS << " " << Node->getValueAsApproximateDouble(); 1699249261Sdim} 1700249261Sdim 1701249261Sdimvoid ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1702249261Sdim VisitExpr(Str); 1703249261Sdim ColorScope Color(*this, ValueColor); 1704249261Sdim OS << " "; 1705249261Sdim Str->outputString(OS); 1706249261Sdim} 1707249261Sdim 1708249261Sdimvoid ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1709249261Sdim VisitExpr(Node); 1710249261Sdim OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1711249261Sdim << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1712249261Sdim} 1713249261Sdim 1714249261Sdimvoid ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1715249261Sdim const UnaryExprOrTypeTraitExpr *Node) { 1716249261Sdim VisitExpr(Node); 1717249261Sdim switch(Node->getKind()) { 1718249261Sdim case UETT_SizeOf: 1719249261Sdim OS << " sizeof"; 1720249261Sdim break; 1721249261Sdim case UETT_AlignOf: 1722249261Sdim OS << " alignof"; 1723249261Sdim break; 1724249261Sdim case UETT_VecStep: 1725249261Sdim OS << " vec_step"; 1726249261Sdim break; 1727249261Sdim } 1728249261Sdim if (Node->isArgumentType()) 1729249261Sdim dumpType(Node->getArgumentType()); 1730249261Sdim} 1731249261Sdim 1732249261Sdimvoid ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1733249261Sdim VisitExpr(Node); 1734249261Sdim OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1735249261Sdim dumpPointer(Node->getMemberDecl()); 1736249261Sdim} 1737249261Sdim 1738249261Sdimvoid ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1739249261Sdim VisitExpr(Node); 1740249261Sdim OS << " " << Node->getAccessor().getNameStart(); 1741249261Sdim} 1742249261Sdim 1743249261Sdimvoid ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1744249261Sdim VisitExpr(Node); 1745249261Sdim OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1746249261Sdim} 1747249261Sdim 1748249261Sdimvoid ASTDumper::VisitCompoundAssignOperator( 1749249261Sdim const CompoundAssignOperator *Node) { 1750249261Sdim VisitExpr(Node); 1751249261Sdim OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1752249261Sdim << "' ComputeLHSTy="; 1753249261Sdim dumpBareType(Node->getComputationLHSType()); 1754249261Sdim OS << " ComputeResultTy="; 1755249261Sdim dumpBareType(Node->getComputationResultType()); 1756249261Sdim} 1757249261Sdim 1758249261Sdimvoid ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1759249261Sdim VisitExpr(Node); 1760249261Sdim dumpDecl(Node->getBlockDecl()); 1761249261Sdim} 1762249261Sdim 1763249261Sdimvoid ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1764249261Sdim VisitExpr(Node); 1765249261Sdim 1766249261Sdim if (Expr *Source = Node->getSourceExpr()) { 1767249261Sdim lastChild(); 1768249261Sdim dumpStmt(Source); 1769249261Sdim } 1770249261Sdim} 1771249261Sdim 1772249261Sdim// GNU extensions. 1773249261Sdim 1774249261Sdimvoid ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1775249261Sdim VisitExpr(Node); 1776249261Sdim OS << " " << Node->getLabel()->getName(); 1777249261Sdim dumpPointer(Node->getLabel()); 1778249261Sdim} 1779249261Sdim 1780249261Sdim//===----------------------------------------------------------------------===// 1781249261Sdim// C++ Expressions 1782249261Sdim//===----------------------------------------------------------------------===// 1783249261Sdim 1784249261Sdimvoid ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1785249261Sdim VisitExpr(Node); 1786249261Sdim OS << " " << Node->getCastName() 1787249261Sdim << "<" << Node->getTypeAsWritten().getAsString() << ">" 1788249261Sdim << " <" << Node->getCastKindName(); 1789249261Sdim dumpBasePath(OS, Node); 1790249261Sdim OS << ">"; 1791249261Sdim} 1792249261Sdim 1793249261Sdimvoid ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1794249261Sdim VisitExpr(Node); 1795249261Sdim OS << " " << (Node->getValue() ? "true" : "false"); 1796249261Sdim} 1797249261Sdim 1798249261Sdimvoid ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1799249261Sdim VisitExpr(Node); 1800249261Sdim OS << " this"; 1801249261Sdim} 1802249261Sdim 1803249261Sdimvoid ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1804249261Sdim VisitExpr(Node); 1805249261Sdim OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1806249261Sdim << " <" << Node->getCastKindName() << ">"; 1807249261Sdim} 1808249261Sdim 1809249261Sdimvoid ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1810249261Sdim VisitExpr(Node); 1811249261Sdim CXXConstructorDecl *Ctor = Node->getConstructor(); 1812249261Sdim dumpType(Ctor->getType()); 1813249261Sdim if (Node->isElidable()) 1814249261Sdim OS << " elidable"; 1815249261Sdim if (Node->requiresZeroInitialization()) 1816249261Sdim OS << " zeroing"; 1817249261Sdim} 1818249261Sdim 1819249261Sdimvoid ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1820249261Sdim VisitExpr(Node); 1821249261Sdim OS << " "; 1822249261Sdim dumpCXXTemporary(Node->getTemporary()); 1823249261Sdim} 1824249261Sdim 1825263508Sdimvoid 1826263508SdimASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { 1827263508Sdim VisitExpr(Node); 1828263508Sdim if (const ValueDecl *VD = Node->getExtendingDecl()) { 1829263508Sdim OS << " extended by "; 1830263508Sdim dumpBareDeclRef(VD); 1831263508Sdim } 1832263508Sdim} 1833263508Sdim 1834249261Sdimvoid ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1835249261Sdim VisitExpr(Node); 1836249261Sdim for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1837249261Sdim dumpDeclRef(Node->getObject(i), "cleanup"); 1838249261Sdim} 1839249261Sdim 1840249261Sdimvoid ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1841249261Sdim OS << "(CXXTemporary"; 1842249261Sdim dumpPointer(Temporary); 1843249261Sdim OS << ")"; 1844249261Sdim} 1845249261Sdim 1846249261Sdim//===----------------------------------------------------------------------===// 1847249261Sdim// Obj-C Expressions 1848249261Sdim//===----------------------------------------------------------------------===// 1849249261Sdim 1850249261Sdimvoid ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1851249261Sdim VisitExpr(Node); 1852249261Sdim OS << " selector=" << Node->getSelector().getAsString(); 1853249261Sdim switch (Node->getReceiverKind()) { 1854249261Sdim case ObjCMessageExpr::Instance: 1855249261Sdim break; 1856249261Sdim 1857249261Sdim case ObjCMessageExpr::Class: 1858249261Sdim OS << " class="; 1859249261Sdim dumpBareType(Node->getClassReceiver()); 1860249261Sdim break; 1861249261Sdim 1862249261Sdim case ObjCMessageExpr::SuperInstance: 1863249261Sdim OS << " super (instance)"; 1864249261Sdim break; 1865249261Sdim 1866249261Sdim case ObjCMessageExpr::SuperClass: 1867249261Sdim OS << " super (class)"; 1868249261Sdim break; 1869249261Sdim } 1870249261Sdim} 1871249261Sdim 1872249261Sdimvoid ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1873249261Sdim VisitExpr(Node); 1874249261Sdim OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString(); 1875249261Sdim} 1876249261Sdim 1877249261Sdimvoid ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1878249261Sdim VisitStmt(Node); 1879249261Sdim if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1880249261Sdim dumpDecl(CatchParam); 1881249261Sdim else 1882249261Sdim OS << " catch all"; 1883249261Sdim} 1884249261Sdim 1885249261Sdimvoid ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1886249261Sdim VisitExpr(Node); 1887249261Sdim dumpType(Node->getEncodedType()); 1888249261Sdim} 1889249261Sdim 1890249261Sdimvoid ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1891249261Sdim VisitExpr(Node); 1892249261Sdim 1893249261Sdim OS << " " << Node->getSelector().getAsString(); 1894249261Sdim} 1895249261Sdim 1896249261Sdimvoid ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1897249261Sdim VisitExpr(Node); 1898249261Sdim 1899249261Sdim OS << ' ' << *Node->getProtocol(); 1900249261Sdim} 1901249261Sdim 1902249261Sdimvoid ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1903249261Sdim VisitExpr(Node); 1904249261Sdim if (Node->isImplicitProperty()) { 1905249261Sdim OS << " Kind=MethodRef Getter=\""; 1906249261Sdim if (Node->getImplicitPropertyGetter()) 1907249261Sdim OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 1908249261Sdim else 1909249261Sdim OS << "(null)"; 1910249261Sdim 1911249261Sdim OS << "\" Setter=\""; 1912249261Sdim if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1913249261Sdim OS << Setter->getSelector().getAsString(); 1914249261Sdim else 1915249261Sdim OS << "(null)"; 1916249261Sdim OS << "\""; 1917249261Sdim } else { 1918249261Sdim OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 1919249261Sdim } 1920249261Sdim 1921249261Sdim if (Node->isSuperReceiver()) 1922249261Sdim OS << " super"; 1923249261Sdim 1924249261Sdim OS << " Messaging="; 1925249261Sdim if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1926249261Sdim OS << "Getter&Setter"; 1927249261Sdim else if (Node->isMessagingGetter()) 1928249261Sdim OS << "Getter"; 1929249261Sdim else if (Node->isMessagingSetter()) 1930249261Sdim OS << "Setter"; 1931249261Sdim} 1932249261Sdim 1933249261Sdimvoid ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 1934249261Sdim VisitExpr(Node); 1935249261Sdim if (Node->isArraySubscriptRefExpr()) 1936249261Sdim OS << " Kind=ArraySubscript GetterForArray=\""; 1937249261Sdim else 1938249261Sdim OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1939249261Sdim if (Node->getAtIndexMethodDecl()) 1940249261Sdim OS << Node->getAtIndexMethodDecl()->getSelector().getAsString(); 1941249261Sdim else 1942249261Sdim OS << "(null)"; 1943249261Sdim 1944249261Sdim if (Node->isArraySubscriptRefExpr()) 1945249261Sdim OS << "\" SetterForArray=\""; 1946249261Sdim else 1947249261Sdim OS << "\" SetterForDictionary=\""; 1948249261Sdim if (Node->setAtIndexMethodDecl()) 1949249261Sdim OS << Node->setAtIndexMethodDecl()->getSelector().getAsString(); 1950249261Sdim else 1951249261Sdim OS << "(null)"; 1952249261Sdim} 1953249261Sdim 1954249261Sdimvoid ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1955249261Sdim VisitExpr(Node); 1956249261Sdim OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1957249261Sdim} 1958249261Sdim 1959249261Sdim//===----------------------------------------------------------------------===// 1960249261Sdim// Comments 1961249261Sdim//===----------------------------------------------------------------------===// 1962249261Sdim 1963249261Sdimconst char *ASTDumper::getCommandName(unsigned CommandID) { 1964249261Sdim if (Traits) 1965249261Sdim return Traits->getCommandInfo(CommandID)->Name; 1966249261Sdim const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 1967249261Sdim if (Info) 1968249261Sdim return Info->Name; 1969249261Sdim return "<not a builtin command>"; 1970249261Sdim} 1971249261Sdim 1972249261Sdimvoid ASTDumper::dumpFullComment(const FullComment *C) { 1973249261Sdim if (!C) 1974249261Sdim return; 1975249261Sdim 1976249261Sdim FC = C; 1977249261Sdim dumpComment(C); 1978249261Sdim FC = 0; 1979249261Sdim} 1980249261Sdim 1981249261Sdimvoid ASTDumper::dumpComment(const Comment *C) { 1982249261Sdim IndentScope Indent(*this); 1983249261Sdim 1984249261Sdim if (!C) { 1985249261Sdim ColorScope Color(*this, NullColor); 1986249261Sdim OS << "<<<NULL>>>"; 1987249261Sdim return; 1988249261Sdim } 1989249261Sdim 1990249261Sdim { 1991249261Sdim ColorScope Color(*this, CommentColor); 1992249261Sdim OS << C->getCommentKindName(); 1993249261Sdim } 1994249261Sdim dumpPointer(C); 1995249261Sdim dumpSourceRange(C->getSourceRange()); 1996249261Sdim ConstCommentVisitor<ASTDumper>::visit(C); 1997249261Sdim for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 1998249261Sdim I != E; ++I) { 1999249261Sdim if (I + 1 == E) 2000249261Sdim lastChild(); 2001249261Sdim dumpComment(*I); 2002249261Sdim } 2003249261Sdim} 2004249261Sdim 2005249261Sdimvoid ASTDumper::visitTextComment(const TextComment *C) { 2006249261Sdim OS << " Text=\"" << C->getText() << "\""; 2007249261Sdim} 2008249261Sdim 2009249261Sdimvoid ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 2010249261Sdim OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2011249261Sdim switch (C->getRenderKind()) { 2012249261Sdim case InlineCommandComment::RenderNormal: 2013249261Sdim OS << " RenderNormal"; 2014249261Sdim break; 2015249261Sdim case InlineCommandComment::RenderBold: 2016249261Sdim OS << " RenderBold"; 2017249261Sdim break; 2018249261Sdim case InlineCommandComment::RenderMonospaced: 2019249261Sdim OS << " RenderMonospaced"; 2020249261Sdim break; 2021249261Sdim case InlineCommandComment::RenderEmphasized: 2022249261Sdim OS << " RenderEmphasized"; 2023249261Sdim break; 2024249261Sdim } 2025249261Sdim 2026249261Sdim for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2027249261Sdim OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2028249261Sdim} 2029249261Sdim 2030249261Sdimvoid ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 2031249261Sdim OS << " Name=\"" << C->getTagName() << "\""; 2032249261Sdim if (C->getNumAttrs() != 0) { 2033249261Sdim OS << " Attrs: "; 2034249261Sdim for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 2035249261Sdim const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 2036249261Sdim OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 2037249261Sdim } 2038249261Sdim } 2039249261Sdim if (C->isSelfClosing()) 2040249261Sdim OS << " SelfClosing"; 2041249261Sdim} 2042249261Sdim 2043249261Sdimvoid ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 2044249261Sdim OS << " Name=\"" << C->getTagName() << "\""; 2045249261Sdim} 2046249261Sdim 2047249261Sdimvoid ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 2048249261Sdim OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2049249261Sdim for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2050249261Sdim OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2051249261Sdim} 2052249261Sdim 2053249261Sdimvoid ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 2054249261Sdim OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 2055249261Sdim 2056249261Sdim if (C->isDirectionExplicit()) 2057249261Sdim OS << " explicitly"; 2058249261Sdim else 2059249261Sdim OS << " implicitly"; 2060249261Sdim 2061249261Sdim if (C->hasParamName()) { 2062249261Sdim if (C->isParamIndexValid()) 2063249261Sdim OS << " Param=\"" << C->getParamName(FC) << "\""; 2064249261Sdim else 2065249261Sdim OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2066249261Sdim } 2067249261Sdim 2068249261Sdim if (C->isParamIndexValid()) 2069249261Sdim OS << " ParamIndex=" << C->getParamIndex(); 2070249261Sdim} 2071249261Sdim 2072249261Sdimvoid ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 2073249261Sdim if (C->hasParamName()) { 2074249261Sdim if (C->isPositionValid()) 2075249261Sdim OS << " Param=\"" << C->getParamName(FC) << "\""; 2076249261Sdim else 2077249261Sdim OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2078249261Sdim } 2079249261Sdim 2080249261Sdim if (C->isPositionValid()) { 2081249261Sdim OS << " Position=<"; 2082249261Sdim for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 2083249261Sdim OS << C->getIndex(i); 2084249261Sdim if (i != e - 1) 2085249261Sdim OS << ", "; 2086249261Sdim } 2087249261Sdim OS << ">"; 2088249261Sdim } 2089249261Sdim} 2090249261Sdim 2091249261Sdimvoid ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 2092249261Sdim OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 2093249261Sdim " CloseName=\"" << C->getCloseName() << "\""; 2094249261Sdim} 2095249261Sdim 2096249261Sdimvoid ASTDumper::visitVerbatimBlockLineComment( 2097249261Sdim const VerbatimBlockLineComment *C) { 2098249261Sdim OS << " Text=\"" << C->getText() << "\""; 2099249261Sdim} 2100249261Sdim 2101249261Sdimvoid ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 2102249261Sdim OS << " Text=\"" << C->getText() << "\""; 2103249261Sdim} 2104249261Sdim 2105249261Sdim//===----------------------------------------------------------------------===// 2106249261Sdim// Decl method implementations 2107249261Sdim//===----------------------------------------------------------------------===// 2108249261Sdim 2109249261Sdimvoid Decl::dump() const { 2110249261Sdim dump(llvm::errs()); 2111249261Sdim} 2112249261Sdim 2113249261Sdimvoid Decl::dump(raw_ostream &OS) const { 2114249261Sdim ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 2115249261Sdim &getASTContext().getSourceManager()); 2116249261Sdim P.dumpDecl(this); 2117249261Sdim} 2118249261Sdim 2119249261Sdimvoid Decl::dumpColor() const { 2120249261Sdim ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 2121249261Sdim &getASTContext().getSourceManager(), /*ShowColors*/true); 2122249261Sdim P.dumpDecl(this); 2123249261Sdim} 2124263508Sdim 2125263508Sdimvoid DeclContext::dumpLookups() const { 2126263508Sdim dumpLookups(llvm::errs()); 2127263508Sdim} 2128263508Sdim 2129263508Sdimvoid DeclContext::dumpLookups(raw_ostream &OS) const { 2130263508Sdim const DeclContext *DC = this; 2131263508Sdim while (!DC->isTranslationUnit()) 2132263508Sdim DC = DC->getParent(); 2133263508Sdim ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 2134263508Sdim ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); 2135263508Sdim P.dumpLookups(this); 2136263508Sdim} 2137263508Sdim 2138249261Sdim//===----------------------------------------------------------------------===// 2139249261Sdim// Stmt method implementations 2140249261Sdim//===----------------------------------------------------------------------===// 2141249261Sdim 2142249261Sdimvoid Stmt::dump(SourceManager &SM) const { 2143249261Sdim dump(llvm::errs(), SM); 2144249261Sdim} 2145249261Sdim 2146249261Sdimvoid Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 2147249261Sdim ASTDumper P(OS, 0, &SM); 2148249261Sdim P.dumpStmt(this); 2149249261Sdim} 2150249261Sdim 2151249261Sdimvoid Stmt::dump() const { 2152249261Sdim ASTDumper P(llvm::errs(), 0, 0); 2153249261Sdim P.dumpStmt(this); 2154249261Sdim} 2155249261Sdim 2156249261Sdimvoid Stmt::dumpColor() const { 2157249261Sdim ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true); 2158249261Sdim P.dumpStmt(this); 2159249261Sdim} 2160249261Sdim 2161249261Sdim//===----------------------------------------------------------------------===// 2162249261Sdim// Comment method implementations 2163249261Sdim//===----------------------------------------------------------------------===// 2164249261Sdim 2165249261Sdimvoid Comment::dump() const { 2166249261Sdim dump(llvm::errs(), 0, 0); 2167249261Sdim} 2168249261Sdim 2169249261Sdimvoid Comment::dump(const ASTContext &Context) const { 2170249261Sdim dump(llvm::errs(), &Context.getCommentCommandTraits(), 2171249261Sdim &Context.getSourceManager()); 2172249261Sdim} 2173249261Sdim 2174249261Sdimvoid Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 2175249261Sdim const SourceManager *SM) const { 2176249261Sdim const FullComment *FC = dyn_cast<FullComment>(this); 2177249261Sdim ASTDumper D(OS, Traits, SM); 2178249261Sdim D.dumpFullComment(FC); 2179249261Sdim} 2180249261Sdim 2181249261Sdimvoid Comment::dumpColor() const { 2182249261Sdim const FullComment *FC = dyn_cast<FullComment>(this); 2183249261Sdim ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true); 2184249261Sdim D.dumpFullComment(FC); 2185249261Sdim} 2186