ASTDumper.cpp revision 251662
1//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the AST dump methods, which dump out the 11// AST in a form that exposes type details and other fields. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/Attr.h" 17#include "clang/AST/CommentVisitor.h" 18#include "clang/AST/DeclCXX.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/DeclVisitor.h" 21#include "clang/AST/StmtVisitor.h" 22#include "clang/Basic/Module.h" 23#include "clang/Basic/SourceManager.h" 24#include "llvm/Support/raw_ostream.h" 25using namespace clang; 26using namespace clang::comments; 27 28//===----------------------------------------------------------------------===// 29// ASTDumper Visitor 30//===----------------------------------------------------------------------===// 31 32namespace { 33 // Colors used for various parts of the AST dump 34 35 struct TerminalColor { 36 raw_ostream::Colors Color; 37 bool Bold; 38 }; 39 40 // Decl kind names (VarDecl, FunctionDecl, etc) 41 static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true }; 42 // Attr names (CleanupAttr, GuardedByAttr, etc) 43 static const TerminalColor AttrColor = { raw_ostream::BLUE, true }; 44 // Statement names (DeclStmt, ImplicitCastExpr, etc) 45 static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true }; 46 // Comment names (FullComment, ParagraphComment, TextComment, etc) 47 static const TerminalColor CommentColor = { raw_ostream::YELLOW, true }; 48 49 // Type names (int, float, etc, plus user defined types) 50 static const TerminalColor TypeColor = { raw_ostream::GREEN, false }; 51 52 // Pointer address 53 static const TerminalColor AddressColor = { raw_ostream::YELLOW, false }; 54 // Source locations 55 static const TerminalColor LocationColor = { raw_ostream::YELLOW, false }; 56 57 // lvalue/xvalue 58 static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false }; 59 // bitfield/objcproperty/objcsubscript/vectorcomponent 60 static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false }; 61 62 // Null statements 63 static const TerminalColor NullColor = { raw_ostream::BLUE, false }; 64 65 // CastKind from CastExpr's 66 static const TerminalColor CastColor = { raw_ostream::RED, false }; 67 68 // Value of the statement 69 static const TerminalColor ValueColor = { raw_ostream::CYAN, true }; 70 // Decl names 71 static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; 72 73 // Indents ( `, -. | ) 74 static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; 75 76 class ASTDumper 77 : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, 78 public ConstCommentVisitor<ASTDumper> { 79 raw_ostream &OS; 80 const CommandTraits *Traits; 81 const SourceManager *SM; 82 bool IsFirstLine; 83 84 // Indicates whether more child are expected at the current tree depth 85 enum IndentType { IT_Child, IT_LastChild }; 86 87 /// Indents[i] indicates if another child exists at level i. 88 /// Used by Indent() to print the tree structure. 89 llvm::SmallVector<IndentType, 32> Indents; 90 91 /// Indicates that more children will be needed at this indent level. 92 /// If true, prevents lastChild() from marking the node as the last child. 93 /// This is used when there are multiple collections of children to be 94 /// dumped as well as during conditional node dumping. 95 bool MoreChildren; 96 97 /// Keep track of the last location we print out so that we can 98 /// print out deltas from then on out. 99 const char *LastLocFilename; 100 unsigned LastLocLine; 101 102 /// The \c FullComment parent of the comment being dumped. 103 const FullComment *FC; 104 105 bool ShowColors; 106 107 class IndentScope { 108 ASTDumper &Dumper; 109 // Preserve the Dumper's MoreChildren value from the previous IndentScope 110 bool MoreChildren; 111 public: 112 IndentScope(ASTDumper &Dumper) : Dumper(Dumper) { 113 MoreChildren = Dumper.hasMoreChildren(); 114 Dumper.setMoreChildren(false); 115 Dumper.indent(); 116 } 117 ~IndentScope() { 118 Dumper.setMoreChildren(MoreChildren); 119 Dumper.unindent(); 120 } 121 }; 122 123 class ColorScope { 124 ASTDumper &Dumper; 125 public: 126 ColorScope(ASTDumper &Dumper, TerminalColor Color) 127 : Dumper(Dumper) { 128 if (Dumper.ShowColors) 129 Dumper.OS.changeColor(Color.Color, Color.Bold); 130 } 131 ~ColorScope() { 132 if (Dumper.ShowColors) 133 Dumper.OS.resetColor(); 134 } 135 }; 136 137 public: 138 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 139 const SourceManager *SM) 140 : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false), 141 LastLocFilename(""), LastLocLine(~0U), FC(0), 142 ShowColors(SM && SM->getDiagnostics().getShowColors()) { } 143 144 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 145 const SourceManager *SM, bool ShowColors) 146 : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false), 147 LastLocFilename(""), LastLocLine(~0U), 148 ShowColors(ShowColors) { } 149 150 ~ASTDumper() { 151 OS << "\n"; 152 } 153 154 void dumpDecl(const Decl *D); 155 void dumpStmt(const Stmt *S); 156 void dumpFullComment(const FullComment *C); 157 158 // Formatting 159 void indent(); 160 void unindent(); 161 void lastChild(); 162 bool hasMoreChildren(); 163 void setMoreChildren(bool Value); 164 165 // Utilities 166 void dumpPointer(const void *Ptr); 167 void dumpSourceRange(SourceRange R); 168 void dumpLocation(SourceLocation Loc); 169 void dumpBareType(QualType T); 170 void dumpType(QualType T); 171 void dumpBareDeclRef(const Decl *Node); 172 void dumpDeclRef(const Decl *Node, const char *Label = 0); 173 void dumpName(const NamedDecl *D); 174 bool hasNodes(const DeclContext *DC); 175 void dumpDeclContext(const DeclContext *DC); 176 void dumpAttr(const Attr *A); 177 178 // C++ Utilities 179 void dumpAccessSpecifier(AccessSpecifier AS); 180 void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); 181 void dumpTemplateParameters(const TemplateParameterList *TPL); 182 void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); 183 void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A); 184 void dumpTemplateArgumentList(const TemplateArgumentList &TAL); 185 void dumpTemplateArgument(const TemplateArgument &A, 186 SourceRange R = SourceRange()); 187 188 // Decls 189 void VisitLabelDecl(const LabelDecl *D); 190 void VisitTypedefDecl(const TypedefDecl *D); 191 void VisitEnumDecl(const EnumDecl *D); 192 void VisitRecordDecl(const RecordDecl *D); 193 void VisitEnumConstantDecl(const EnumConstantDecl *D); 194 void VisitIndirectFieldDecl(const IndirectFieldDecl *D); 195 void VisitFunctionDecl(const FunctionDecl *D); 196 void VisitFieldDecl(const FieldDecl *D); 197 void VisitVarDecl(const VarDecl *D); 198 void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); 199 void VisitImportDecl(const ImportDecl *D); 200 201 // C++ Decls 202 void VisitNamespaceDecl(const NamespaceDecl *D); 203 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); 204 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 205 void VisitTypeAliasDecl(const TypeAliasDecl *D); 206 void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); 207 void VisitCXXRecordDecl(const CXXRecordDecl *D); 208 void VisitStaticAssertDecl(const StaticAssertDecl *D); 209 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 210 void VisitClassTemplateDecl(const ClassTemplateDecl *D); 211 void VisitClassTemplateSpecializationDecl( 212 const ClassTemplateSpecializationDecl *D); 213 void VisitClassTemplatePartialSpecializationDecl( 214 const ClassTemplatePartialSpecializationDecl *D); 215 void VisitClassScopeFunctionSpecializationDecl( 216 const ClassScopeFunctionSpecializationDecl *D); 217 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 218 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 219 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 220 void VisitUsingDecl(const UsingDecl *D); 221 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); 222 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); 223 void VisitUsingShadowDecl(const UsingShadowDecl *D); 224 void VisitLinkageSpecDecl(const LinkageSpecDecl *D); 225 void VisitAccessSpecDecl(const AccessSpecDecl *D); 226 void VisitFriendDecl(const FriendDecl *D); 227 228 // ObjC Decls 229 void VisitObjCIvarDecl(const ObjCIvarDecl *D); 230 void VisitObjCMethodDecl(const ObjCMethodDecl *D); 231 void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); 232 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); 233 void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); 234 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); 235 void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); 236 void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); 237 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 238 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 239 void VisitBlockDecl(const BlockDecl *D); 240 241 // Stmts. 242 void VisitStmt(const Stmt *Node); 243 void VisitDeclStmt(const DeclStmt *Node); 244 void VisitAttributedStmt(const AttributedStmt *Node); 245 void VisitLabelStmt(const LabelStmt *Node); 246 void VisitGotoStmt(const GotoStmt *Node); 247 248 // Exprs 249 void VisitExpr(const Expr *Node); 250 void VisitCastExpr(const CastExpr *Node); 251 void VisitDeclRefExpr(const DeclRefExpr *Node); 252 void VisitPredefinedExpr(const PredefinedExpr *Node); 253 void VisitCharacterLiteral(const CharacterLiteral *Node); 254 void VisitIntegerLiteral(const IntegerLiteral *Node); 255 void VisitFloatingLiteral(const FloatingLiteral *Node); 256 void VisitStringLiteral(const StringLiteral *Str); 257 void VisitUnaryOperator(const UnaryOperator *Node); 258 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); 259 void VisitMemberExpr(const MemberExpr *Node); 260 void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); 261 void VisitBinaryOperator(const BinaryOperator *Node); 262 void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); 263 void VisitAddrLabelExpr(const AddrLabelExpr *Node); 264 void VisitBlockExpr(const BlockExpr *Node); 265 void VisitOpaqueValueExpr(const OpaqueValueExpr *Node); 266 267 // C++ 268 void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); 269 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); 270 void VisitCXXThisExpr(const CXXThisExpr *Node); 271 void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); 272 void VisitCXXConstructExpr(const CXXConstructExpr *Node); 273 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); 274 void VisitExprWithCleanups(const ExprWithCleanups *Node); 275 void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); 276 void dumpCXXTemporary(const CXXTemporary *Temporary); 277 278 // ObjC 279 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); 280 void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); 281 void VisitObjCMessageExpr(const ObjCMessageExpr *Node); 282 void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); 283 void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); 284 void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); 285 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); 286 void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); 287 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); 288 void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); 289 290 // Comments. 291 const char *getCommandName(unsigned CommandID); 292 void dumpComment(const Comment *C); 293 294 // Inline comments. 295 void visitTextComment(const TextComment *C); 296 void visitInlineCommandComment(const InlineCommandComment *C); 297 void visitHTMLStartTagComment(const HTMLStartTagComment *C); 298 void visitHTMLEndTagComment(const HTMLEndTagComment *C); 299 300 // Block comments. 301 void visitBlockCommandComment(const BlockCommandComment *C); 302 void visitParamCommandComment(const ParamCommandComment *C); 303 void visitTParamCommandComment(const TParamCommandComment *C); 304 void visitVerbatimBlockComment(const VerbatimBlockComment *C); 305 void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); 306 void visitVerbatimLineComment(const VerbatimLineComment *C); 307 }; 308} 309 310//===----------------------------------------------------------------------===// 311// Utilities 312//===----------------------------------------------------------------------===// 313 314// Print out the appropriate tree structure using the Indents vector. 315// Example of tree and the Indents vector at each level. 316// A { } 317// |-B { IT_Child } 318// | `-C { IT_Child, IT_LastChild } 319// `-D { IT_LastChild } 320// |-E { IT_LastChild, IT_Child } 321// `-F { IT_LastChild, IT_LastChild } 322// Type non-last element, last element 323// IT_Child "| " "|-" 324// IT_LastChild " " "`-" 325void ASTDumper::indent() { 326 if (IsFirstLine) 327 IsFirstLine = false; 328 else 329 OS << "\n"; 330 331 ColorScope Color(*this, IndentColor); 332 for (llvm::SmallVector<IndentType, 32>::const_iterator I = Indents.begin(), 333 E = Indents.end(); 334 I != E; ++I) { 335 switch (*I) { 336 case IT_Child: 337 if (I == E - 1) 338 OS << "|-"; 339 else 340 OS << "| "; 341 continue; 342 case IT_LastChild: 343 if (I == E - 1) 344 OS << "`-"; 345 else 346 OS << " "; 347 continue; 348 } 349 llvm_unreachable("Invalid IndentType"); 350 } 351 Indents.push_back(IT_Child); 352} 353 354void ASTDumper::unindent() { 355 Indents.pop_back(); 356} 357 358// Call before each potential last child node is to be dumped. If MoreChildren 359// is false, then this is the last child, otherwise treat as a regular node. 360void ASTDumper::lastChild() { 361 if (!hasMoreChildren()) 362 Indents.back() = IT_LastChild; 363} 364 365// MoreChildren should be set before calling another function that may print 366// additional nodes to prevent conflicting final child nodes. 367bool ASTDumper::hasMoreChildren() { 368 return MoreChildren; 369} 370 371void ASTDumper::setMoreChildren(bool Value) { 372 MoreChildren = Value; 373} 374 375void ASTDumper::dumpPointer(const void *Ptr) { 376 ColorScope Color(*this, AddressColor); 377 OS << ' ' << Ptr; 378} 379 380void ASTDumper::dumpLocation(SourceLocation Loc) { 381 ColorScope Color(*this, LocationColor); 382 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 383 384 // The general format we print out is filename:line:col, but we drop pieces 385 // that haven't changed since the last loc printed. 386 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 387 388 if (PLoc.isInvalid()) { 389 OS << "<invalid sloc>"; 390 return; 391 } 392 393 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 394 OS << PLoc.getFilename() << ':' << PLoc.getLine() 395 << ':' << PLoc.getColumn(); 396 LastLocFilename = PLoc.getFilename(); 397 LastLocLine = PLoc.getLine(); 398 } else if (PLoc.getLine() != LastLocLine) { 399 OS << "line" << ':' << PLoc.getLine() 400 << ':' << PLoc.getColumn(); 401 LastLocLine = PLoc.getLine(); 402 } else { 403 OS << "col" << ':' << PLoc.getColumn(); 404 } 405} 406 407void ASTDumper::dumpSourceRange(SourceRange R) { 408 // Can't translate locations if a SourceManager isn't available. 409 if (!SM) 410 return; 411 412 OS << " <"; 413 dumpLocation(R.getBegin()); 414 if (R.getBegin() != R.getEnd()) { 415 OS << ", "; 416 dumpLocation(R.getEnd()); 417 } 418 OS << ">"; 419 420 // <t2.c:123:421[blah], t2.c:412:321> 421 422} 423 424void ASTDumper::dumpBareType(QualType T) { 425 ColorScope Color(*this, TypeColor); 426 427 SplitQualType T_split = T.split(); 428 OS << "'" << QualType::getAsString(T_split) << "'"; 429 430 if (!T.isNull()) { 431 // If the type is sugared, also dump a (shallow) desugared type. 432 SplitQualType D_split = T.getSplitDesugaredType(); 433 if (T_split != D_split) 434 OS << ":'" << QualType::getAsString(D_split) << "'"; 435 } 436} 437 438void ASTDumper::dumpType(QualType T) { 439 OS << ' '; 440 dumpBareType(T); 441} 442 443void ASTDumper::dumpBareDeclRef(const Decl *D) { 444 { 445 ColorScope Color(*this, DeclKindNameColor); 446 OS << D->getDeclKindName(); 447 } 448 dumpPointer(D); 449 450 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 451 ColorScope Color(*this, DeclNameColor); 452 OS << " '"; 453 ND->getDeclName().printName(OS); 454 OS << "'"; 455 } 456 457 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 458 dumpType(VD->getType()); 459} 460 461void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { 462 if (!D) 463 return; 464 465 IndentScope Indent(*this); 466 if (Label) 467 OS << Label << ' '; 468 dumpBareDeclRef(D); 469} 470 471void ASTDumper::dumpName(const NamedDecl *ND) { 472 if (ND->getDeclName()) { 473 ColorScope Color(*this, DeclNameColor); 474 OS << ' ' << ND->getNameAsString(); 475 } 476} 477 478bool ASTDumper::hasNodes(const DeclContext *DC) { 479 if (!DC) 480 return false; 481 482 return DC->decls_begin() != DC->decls_end(); 483} 484 485void ASTDumper::dumpDeclContext(const DeclContext *DC) { 486 if (!DC) 487 return; 488 for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 489 I != E; ++I) { 490 DeclContext::decl_iterator Next = I; 491 ++Next; 492 if (Next == E) 493 lastChild(); 494 dumpDecl(*I); 495 } 496} 497 498void ASTDumper::dumpAttr(const Attr *A) { 499 IndentScope Indent(*this); 500 { 501 ColorScope Color(*this, AttrColor); 502 switch (A->getKind()) { 503#define ATTR(X) case attr::X: OS << #X; break; 504#include "clang/Basic/AttrList.inc" 505 default: llvm_unreachable("unexpected attribute kind"); 506 } 507 OS << "Attr"; 508 } 509 dumpPointer(A); 510 dumpSourceRange(A->getRange()); 511#include "clang/AST/AttrDump.inc" 512} 513 514static Decl *getPreviousDeclImpl(...) { 515 return 0; 516} 517 518template<typename T> 519static const Decl *getPreviousDeclImpl(const Redeclarable<T> *D) { 520 return D->getPreviousDecl(); 521} 522 523/// Get the previous declaration in the redeclaration chain for a declaration. 524static const Decl *getPreviousDecl(const Decl *D) { 525 switch (D->getKind()) { 526#define DECL(DERIVED, BASE) \ 527 case Decl::DERIVED: \ 528 return getPreviousDeclImpl(cast<DERIVED##Decl>(D)); 529#define ABSTRACT_DECL(DECL) 530#include "clang/AST/DeclNodes.inc" 531 } 532 llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 533} 534 535//===----------------------------------------------------------------------===// 536// C++ Utilities 537//===----------------------------------------------------------------------===// 538 539void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { 540 switch (AS) { 541 case AS_none: 542 break; 543 case AS_public: 544 OS << "public"; 545 break; 546 case AS_protected: 547 OS << "protected"; 548 break; 549 case AS_private: 550 OS << "private"; 551 break; 552 } 553} 554 555void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { 556 IndentScope Indent(*this); 557 OS << "CXXCtorInitializer"; 558 if (Init->isAnyMemberInitializer()) { 559 OS << ' '; 560 dumpBareDeclRef(Init->getAnyMember()); 561 } else { 562 dumpType(QualType(Init->getBaseClass(), 0)); 563 } 564 dumpStmt(Init->getInit()); 565} 566 567void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { 568 if (!TPL) 569 return; 570 571 for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end(); 572 I != E; ++I) 573 dumpDecl(*I); 574} 575 576void ASTDumper::dumpTemplateArgumentListInfo( 577 const TemplateArgumentListInfo &TALI) { 578 for (unsigned i = 0, e = TALI.size(); i < e; ++i) { 579 if (i + 1 == e) 580 lastChild(); 581 dumpTemplateArgumentLoc(TALI[i]); 582 } 583} 584 585void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 586 dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 587} 588 589void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 590 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 591 dumpTemplateArgument(TAL[i]); 592} 593 594void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { 595 IndentScope Indent(*this); 596 OS << "TemplateArgument"; 597 if (R.isValid()) 598 dumpSourceRange(R); 599 600 switch (A.getKind()) { 601 case TemplateArgument::Null: 602 OS << " null"; 603 break; 604 case TemplateArgument::Type: 605 OS << " type"; 606 lastChild(); 607 dumpType(A.getAsType()); 608 break; 609 case TemplateArgument::Declaration: 610 OS << " decl"; 611 lastChild(); 612 dumpDeclRef(A.getAsDecl()); 613 break; 614 case TemplateArgument::NullPtr: 615 OS << " nullptr"; 616 break; 617 case TemplateArgument::Integral: 618 OS << " integral " << A.getAsIntegral(); 619 break; 620 case TemplateArgument::Template: 621 OS << " template "; 622 A.getAsTemplate().dump(OS); 623 break; 624 case TemplateArgument::TemplateExpansion: 625 OS << " template expansion"; 626 A.getAsTemplateOrTemplatePattern().dump(OS); 627 break; 628 case TemplateArgument::Expression: 629 OS << " expr"; 630 lastChild(); 631 dumpStmt(A.getAsExpr()); 632 break; 633 case TemplateArgument::Pack: 634 OS << " pack"; 635 for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); 636 I != E; ++I) { 637 if (I + 1 == E) 638 lastChild(); 639 dumpTemplateArgument(*I); 640 } 641 break; 642 } 643} 644 645//===----------------------------------------------------------------------===// 646// Decl dumping methods. 647//===----------------------------------------------------------------------===// 648 649void ASTDumper::dumpDecl(const Decl *D) { 650 IndentScope Indent(*this); 651 652 if (!D) { 653 ColorScope Color(*this, NullColor); 654 OS << "<<<NULL>>>"; 655 return; 656 } 657 658 { 659 ColorScope Color(*this, DeclKindNameColor); 660 OS << D->getDeclKindName() << "Decl"; 661 } 662 dumpPointer(D); 663 if (D->getLexicalDeclContext() != D->getDeclContext()) 664 OS << " parent " << cast<Decl>(D->getDeclContext()); 665 if (const Decl *Prev = getPreviousDecl(D)) 666 OS << " prev " << Prev; 667 dumpSourceRange(D->getSourceRange()); 668 669 bool HasAttrs = D->attr_begin() != D->attr_end(); 670 bool HasComment = D->getASTContext().getCommentForDecl(D, 0); 671 // Decls within functions are visited by the body 672 bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && 673 hasNodes(dyn_cast<DeclContext>(D)); 674 675 setMoreChildren(HasAttrs || HasComment || HasDeclContext); 676 ConstDeclVisitor<ASTDumper>::Visit(D); 677 678 setMoreChildren(HasComment || HasDeclContext); 679 for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); 680 I != E; ++I) { 681 if (I + 1 == E) 682 lastChild(); 683 dumpAttr(*I); 684 } 685 686 setMoreChildren(HasDeclContext); 687 lastChild(); 688 dumpFullComment(D->getASTContext().getCommentForDecl(D, 0)); 689 690 setMoreChildren(false); 691 if (HasDeclContext) 692 dumpDeclContext(cast<DeclContext>(D)); 693} 694 695void ASTDumper::VisitLabelDecl(const LabelDecl *D) { 696 dumpName(D); 697} 698 699void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 700 dumpName(D); 701 dumpType(D->getUnderlyingType()); 702 if (D->isModulePrivate()) 703 OS << " __module_private__"; 704} 705 706void ASTDumper::VisitEnumDecl(const EnumDecl *D) { 707 if (D->isScoped()) { 708 if (D->isScopedUsingClassTag()) 709 OS << " class"; 710 else 711 OS << " struct"; 712 } 713 dumpName(D); 714 if (D->isModulePrivate()) 715 OS << " __module_private__"; 716 if (D->isFixed()) 717 dumpType(D->getIntegerType()); 718} 719 720void ASTDumper::VisitRecordDecl(const RecordDecl *D) { 721 OS << ' ' << D->getKindName(); 722 dumpName(D); 723 if (D->isModulePrivate()) 724 OS << " __module_private__"; 725} 726 727void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 728 dumpName(D); 729 dumpType(D->getType()); 730 if (const Expr *Init = D->getInitExpr()) { 731 lastChild(); 732 dumpStmt(Init); 733 } 734} 735 736void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 737 dumpName(D); 738 dumpType(D->getType()); 739 for (IndirectFieldDecl::chain_iterator I = D->chain_begin(), 740 E = D->chain_end(); 741 I != E; ++I) { 742 if (I + 1 == E) 743 lastChild(); 744 dumpDeclRef(*I); 745 } 746} 747 748void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 749 dumpName(D); 750 dumpType(D->getType()); 751 752 StorageClass SC = D->getStorageClass(); 753 if (SC != SC_None) 754 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 755 if (D->isInlineSpecified()) 756 OS << " inline"; 757 if (D->isVirtualAsWritten()) 758 OS << " virtual"; 759 if (D->isModulePrivate()) 760 OS << " __module_private__"; 761 762 if (D->isPure()) 763 OS << " pure"; 764 else if (D->isDeletedAsWritten()) 765 OS << " delete"; 766 767 bool OldMoreChildren = hasMoreChildren(); 768 const FunctionTemplateSpecializationInfo *FTSI = 769 D->getTemplateSpecializationInfo(); 770 bool HasTemplateSpecialization = FTSI; 771 772 bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() != 773 D->getDeclsInPrototypeScope().end(); 774 775 bool HasFunctionDecls = D->param_begin() != D->param_end(); 776 777 const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D); 778 bool HasCtorInitializers = C && C->init_begin() != C->init_end(); 779 780 bool HasDeclarationBody = D->doesThisDeclarationHaveABody(); 781 782 setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls || 783 HasCtorInitializers || HasDeclarationBody); 784 if (HasTemplateSpecialization) { 785 lastChild(); 786 dumpTemplateArgumentList(*FTSI->TemplateArguments); 787 } 788 789 setMoreChildren(OldMoreChildren || HasFunctionDecls || 790 HasCtorInitializers || HasDeclarationBody); 791 for (ArrayRef<NamedDecl *>::iterator 792 I = D->getDeclsInPrototypeScope().begin(), 793 E = D->getDeclsInPrototypeScope().end(); I != E; ++I) { 794 if (I + 1 == E) 795 lastChild(); 796 dumpDecl(*I); 797 } 798 799 setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody); 800 for (FunctionDecl::param_const_iterator I = D->param_begin(), 801 E = D->param_end(); 802 I != E; ++I) { 803 if (I + 1 == E) 804 lastChild(); 805 dumpDecl(*I); 806 } 807 808 setMoreChildren(OldMoreChildren || HasDeclarationBody); 809 if (HasCtorInitializers) 810 for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 811 E = C->init_end(); 812 I != E; ++I) { 813 if (I + 1 == E) 814 lastChild(); 815 dumpCXXCtorInitializer(*I); 816 } 817 818 setMoreChildren(OldMoreChildren); 819 if (HasDeclarationBody) { 820 lastChild(); 821 dumpStmt(D->getBody()); 822 } 823} 824 825void ASTDumper::VisitFieldDecl(const FieldDecl *D) { 826 dumpName(D); 827 dumpType(D->getType()); 828 if (D->isMutable()) 829 OS << " mutable"; 830 if (D->isModulePrivate()) 831 OS << " __module_private__"; 832 833 bool OldMoreChildren = hasMoreChildren(); 834 bool IsBitField = D->isBitField(); 835 Expr *Init = D->getInClassInitializer(); 836 bool HasInit = Init; 837 838 setMoreChildren(OldMoreChildren || HasInit); 839 if (IsBitField) { 840 lastChild(); 841 dumpStmt(D->getBitWidth()); 842 } 843 setMoreChildren(OldMoreChildren); 844 if (HasInit) { 845 lastChild(); 846 dumpStmt(Init); 847 } 848} 849 850void ASTDumper::VisitVarDecl(const VarDecl *D) { 851 dumpName(D); 852 dumpType(D->getType()); 853 StorageClass SC = D->getStorageClass(); 854 if (SC != SC_None) 855 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 856 switch (D->getTLSKind()) { 857 case VarDecl::TLS_None: break; 858 case VarDecl::TLS_Static: OS << " tls"; break; 859 case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 860 } 861 if (D->isModulePrivate()) 862 OS << " __module_private__"; 863 if (D->isNRVOVariable()) 864 OS << " nrvo"; 865 if (D->hasInit()) { 866 lastChild(); 867 dumpStmt(D->getInit()); 868 } 869} 870 871void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 872 lastChild(); 873 dumpStmt(D->getAsmString()); 874} 875 876void ASTDumper::VisitImportDecl(const ImportDecl *D) { 877 OS << ' ' << D->getImportedModule()->getFullModuleName(); 878} 879 880//===----------------------------------------------------------------------===// 881// C++ Declarations 882//===----------------------------------------------------------------------===// 883 884void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 885 dumpName(D); 886 if (D->isInline()) 887 OS << " inline"; 888 if (!D->isOriginalNamespace()) 889 dumpDeclRef(D->getOriginalNamespace(), "original"); 890} 891 892void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 893 OS << ' '; 894 dumpBareDeclRef(D->getNominatedNamespace()); 895} 896 897void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 898 dumpName(D); 899 dumpDeclRef(D->getAliasedNamespace()); 900} 901 902void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 903 dumpName(D); 904 dumpType(D->getUnderlyingType()); 905} 906 907void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 908 dumpName(D); 909 dumpTemplateParameters(D->getTemplateParameters()); 910 dumpDecl(D->getTemplatedDecl()); 911} 912 913void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 914 VisitRecordDecl(D); 915 if (!D->isCompleteDefinition()) 916 return; 917 918 for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(), 919 E = D->bases_end(); 920 I != E; ++I) { 921 IndentScope Indent(*this); 922 if (I->isVirtual()) 923 OS << "virtual "; 924 dumpAccessSpecifier(I->getAccessSpecifier()); 925 dumpType(I->getType()); 926 if (I->isPackExpansion()) 927 OS << "..."; 928 } 929} 930 931void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 932 dumpStmt(D->getAssertExpr()); 933 lastChild(); 934 dumpStmt(D->getMessage()); 935} 936 937void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 938 dumpName(D); 939 dumpTemplateParameters(D->getTemplateParameters()); 940 dumpDecl(D->getTemplatedDecl()); 941 for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), 942 E = D->spec_end(); 943 I != E; ++I) { 944 FunctionTemplateDecl::spec_iterator Next = I; 945 ++Next; 946 if (Next == E) 947 lastChild(); 948 switch (I->getTemplateSpecializationKind()) { 949 case TSK_Undeclared: 950 case TSK_ImplicitInstantiation: 951 case TSK_ExplicitInstantiationDeclaration: 952 case TSK_ExplicitInstantiationDefinition: 953 if (D == D->getCanonicalDecl()) 954 dumpDecl(*I); 955 else 956 dumpDeclRef(*I); 957 break; 958 case TSK_ExplicitSpecialization: 959 dumpDeclRef(*I); 960 break; 961 } 962 } 963} 964 965void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 966 dumpName(D); 967 dumpTemplateParameters(D->getTemplateParameters()); 968 969 ClassTemplateDecl::spec_iterator I = D->spec_begin(); 970 ClassTemplateDecl::spec_iterator E = D->spec_end(); 971 if (I == E) 972 lastChild(); 973 dumpDecl(D->getTemplatedDecl()); 974 for (; I != E; ++I) { 975 ClassTemplateDecl::spec_iterator Next = I; 976 ++Next; 977 if (Next == E) 978 lastChild(); 979 switch (I->getTemplateSpecializationKind()) { 980 case TSK_Undeclared: 981 case TSK_ImplicitInstantiation: 982 if (D == D->getCanonicalDecl()) 983 dumpDecl(*I); 984 else 985 dumpDeclRef(*I); 986 break; 987 case TSK_ExplicitSpecialization: 988 case TSK_ExplicitInstantiationDeclaration: 989 case TSK_ExplicitInstantiationDefinition: 990 dumpDeclRef(*I); 991 break; 992 } 993 } 994} 995 996void ASTDumper::VisitClassTemplateSpecializationDecl( 997 const ClassTemplateSpecializationDecl *D) { 998 VisitCXXRecordDecl(D); 999 dumpTemplateArgumentList(D->getTemplateArgs()); 1000} 1001 1002void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1003 const ClassTemplatePartialSpecializationDecl *D) { 1004 VisitClassTemplateSpecializationDecl(D); 1005 dumpTemplateParameters(D->getTemplateParameters()); 1006} 1007 1008void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1009 const ClassScopeFunctionSpecializationDecl *D) { 1010 dumpDeclRef(D->getSpecialization()); 1011 if (D->hasExplicitTemplateArgs()) 1012 dumpTemplateArgumentListInfo(D->templateArgs()); 1013} 1014 1015void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1016 if (D->wasDeclaredWithTypename()) 1017 OS << " typename"; 1018 else 1019 OS << " class"; 1020 if (D->isParameterPack()) 1021 OS << " ..."; 1022 dumpName(D); 1023 if (D->hasDefaultArgument()) 1024 dumpType(D->getDefaultArgument()); 1025} 1026 1027void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1028 dumpType(D->getType()); 1029 if (D->isParameterPack()) 1030 OS << " ..."; 1031 dumpName(D); 1032 if (D->hasDefaultArgument()) 1033 dumpStmt(D->getDefaultArgument()); 1034} 1035 1036void ASTDumper::VisitTemplateTemplateParmDecl( 1037 const TemplateTemplateParmDecl *D) { 1038 if (D->isParameterPack()) 1039 OS << " ..."; 1040 dumpName(D); 1041 dumpTemplateParameters(D->getTemplateParameters()); 1042 if (D->hasDefaultArgument()) 1043 dumpTemplateArgumentLoc(D->getDefaultArgument()); 1044} 1045 1046void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1047 OS << ' '; 1048 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1049 OS << D->getNameAsString(); 1050} 1051 1052void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1053 const UnresolvedUsingTypenameDecl *D) { 1054 OS << ' '; 1055 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1056 OS << D->getNameAsString(); 1057} 1058 1059void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1060 OS << ' '; 1061 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1062 OS << D->getNameAsString(); 1063 dumpType(D->getType()); 1064} 1065 1066void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1067 OS << ' '; 1068 dumpBareDeclRef(D->getTargetDecl()); 1069} 1070 1071void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1072 switch (D->getLanguage()) { 1073 case LinkageSpecDecl::lang_c: OS << " C"; break; 1074 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1075 } 1076} 1077 1078void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1079 OS << ' '; 1080 dumpAccessSpecifier(D->getAccess()); 1081} 1082 1083void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1084 lastChild(); 1085 if (TypeSourceInfo *T = D->getFriendType()) 1086 dumpType(T->getType()); 1087 else 1088 dumpDecl(D->getFriendDecl()); 1089} 1090 1091//===----------------------------------------------------------------------===// 1092// Obj-C Declarations 1093//===----------------------------------------------------------------------===// 1094 1095void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1096 dumpName(D); 1097 dumpType(D->getType()); 1098 if (D->getSynthesize()) 1099 OS << " synthesize"; 1100 1101 switch (D->getAccessControl()) { 1102 case ObjCIvarDecl::None: 1103 OS << " none"; 1104 break; 1105 case ObjCIvarDecl::Private: 1106 OS << " private"; 1107 break; 1108 case ObjCIvarDecl::Protected: 1109 OS << " protected"; 1110 break; 1111 case ObjCIvarDecl::Public: 1112 OS << " public"; 1113 break; 1114 case ObjCIvarDecl::Package: 1115 OS << " package"; 1116 break; 1117 } 1118} 1119 1120void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1121 if (D->isInstanceMethod()) 1122 OS << " -"; 1123 else 1124 OS << " +"; 1125 dumpName(D); 1126 dumpType(D->getResultType()); 1127 1128 bool OldMoreChildren = hasMoreChildren(); 1129 bool IsVariadic = D->isVariadic(); 1130 bool HasBody = D->hasBody(); 1131 1132 setMoreChildren(OldMoreChildren || IsVariadic || HasBody); 1133 if (D->isThisDeclarationADefinition()) { 1134 lastChild(); 1135 dumpDeclContext(D); 1136 } else { 1137 for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1138 E = D->param_end(); 1139 I != E; ++I) { 1140 if (I + 1 == E) 1141 lastChild(); 1142 dumpDecl(*I); 1143 } 1144 } 1145 1146 setMoreChildren(OldMoreChildren || HasBody); 1147 if (IsVariadic) { 1148 lastChild(); 1149 IndentScope Indent(*this); 1150 OS << "..."; 1151 } 1152 1153 setMoreChildren(OldMoreChildren); 1154 if (HasBody) { 1155 lastChild(); 1156 dumpStmt(D->getBody()); 1157 } 1158} 1159 1160void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1161 dumpName(D); 1162 dumpDeclRef(D->getClassInterface()); 1163 if (D->protocol_begin() == D->protocol_end()) 1164 lastChild(); 1165 dumpDeclRef(D->getImplementation()); 1166 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1167 E = D->protocol_end(); 1168 I != E; ++I) { 1169 if (I + 1 == E) 1170 lastChild(); 1171 dumpDeclRef(*I); 1172 } 1173} 1174 1175void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1176 dumpName(D); 1177 dumpDeclRef(D->getClassInterface()); 1178 lastChild(); 1179 dumpDeclRef(D->getCategoryDecl()); 1180} 1181 1182void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1183 dumpName(D); 1184 for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), 1185 E = D->protocol_end(); 1186 I != E; ++I) { 1187 if (I + 1 == E) 1188 lastChild(); 1189 dumpDeclRef(*I); 1190 } 1191} 1192 1193void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1194 dumpName(D); 1195 dumpDeclRef(D->getSuperClass(), "super"); 1196 if (D->protocol_begin() == D->protocol_end()) 1197 lastChild(); 1198 dumpDeclRef(D->getImplementation()); 1199 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 1200 E = D->protocol_end(); 1201 I != E; ++I) { 1202 if (I + 1 == E) 1203 lastChild(); 1204 dumpDeclRef(*I); 1205 } 1206} 1207 1208void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1209 dumpName(D); 1210 dumpDeclRef(D->getSuperClass(), "super"); 1211 if (D->init_begin() == D->init_end()) 1212 lastChild(); 1213 dumpDeclRef(D->getClassInterface()); 1214 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1215 E = D->init_end(); 1216 I != E; ++I) { 1217 if (I + 1 == E) 1218 lastChild(); 1219 dumpCXXCtorInitializer(*I); 1220 } 1221} 1222 1223void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1224 dumpName(D); 1225 lastChild(); 1226 dumpDeclRef(D->getClassInterface()); 1227} 1228 1229void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1230 dumpName(D); 1231 dumpType(D->getType()); 1232 1233 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1234 OS << " required"; 1235 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1236 OS << " optional"; 1237 1238 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1239 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1240 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1241 OS << " readonly"; 1242 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1243 OS << " assign"; 1244 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1245 OS << " readwrite"; 1246 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1247 OS << " retain"; 1248 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1249 OS << " copy"; 1250 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1251 OS << " nonatomic"; 1252 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1253 OS << " atomic"; 1254 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1255 OS << " weak"; 1256 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1257 OS << " strong"; 1258 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1259 OS << " unsafe_unretained"; 1260 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { 1261 if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) 1262 lastChild(); 1263 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1264 } 1265 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { 1266 lastChild(); 1267 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1268 } 1269 } 1270} 1271 1272void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1273 dumpName(D->getPropertyDecl()); 1274 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1275 OS << " synthesize"; 1276 else 1277 OS << " dynamic"; 1278 dumpDeclRef(D->getPropertyDecl()); 1279 lastChild(); 1280 dumpDeclRef(D->getPropertyIvarDecl()); 1281} 1282 1283void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1284 for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); 1285 I != E; ++I) 1286 dumpDecl(*I); 1287 1288 if (D->isVariadic()) { 1289 IndentScope Indent(*this); 1290 OS << "..."; 1291 } 1292 1293 if (D->capturesCXXThis()) { 1294 IndentScope Indent(*this); 1295 OS << "capture this"; 1296 } 1297 for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end(); 1298 I != E; ++I) { 1299 IndentScope Indent(*this); 1300 OS << "capture"; 1301 if (I->isByRef()) 1302 OS << " byref"; 1303 if (I->isNested()) 1304 OS << " nested"; 1305 if (I->getVariable()) { 1306 OS << ' '; 1307 dumpBareDeclRef(I->getVariable()); 1308 } 1309 if (I->hasCopyExpr()) 1310 dumpStmt(I->getCopyExpr()); 1311 } 1312 lastChild(); 1313 dumpStmt(D->getBody()); 1314} 1315 1316//===----------------------------------------------------------------------===// 1317// Stmt dumping methods. 1318//===----------------------------------------------------------------------===// 1319 1320void ASTDumper::dumpStmt(const Stmt *S) { 1321 IndentScope Indent(*this); 1322 1323 if (!S) { 1324 ColorScope Color(*this, NullColor); 1325 OS << "<<<NULL>>>"; 1326 return; 1327 } 1328 1329 if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1330 VisitDeclStmt(DS); 1331 return; 1332 } 1333 1334 setMoreChildren(S->children()); 1335 ConstStmtVisitor<ASTDumper>::Visit(S); 1336 setMoreChildren(false); 1337 for (Stmt::const_child_range CI = S->children(); CI; ++CI) { 1338 Stmt::const_child_range Next = CI; 1339 ++Next; 1340 if (!Next) 1341 lastChild(); 1342 dumpStmt(*CI); 1343 } 1344} 1345 1346void ASTDumper::VisitStmt(const Stmt *Node) { 1347 { 1348 ColorScope Color(*this, StmtColor); 1349 OS << Node->getStmtClassName(); 1350 } 1351 dumpPointer(Node); 1352 dumpSourceRange(Node->getSourceRange()); 1353} 1354 1355void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1356 VisitStmt(Node); 1357 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1358 E = Node->decl_end(); 1359 I != E; ++I) { 1360 if (I + 1 == E) 1361 lastChild(); 1362 dumpDecl(*I); 1363 } 1364} 1365 1366void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1367 VisitStmt(Node); 1368 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1369 E = Node->getAttrs().end(); 1370 I != E; ++I) { 1371 if (I + 1 == E) 1372 lastChild(); 1373 dumpAttr(*I); 1374 } 1375} 1376 1377void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1378 VisitStmt(Node); 1379 OS << " '" << Node->getName() << "'"; 1380} 1381 1382void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1383 VisitStmt(Node); 1384 OS << " '" << Node->getLabel()->getName() << "'"; 1385 dumpPointer(Node->getLabel()); 1386} 1387 1388//===----------------------------------------------------------------------===// 1389// Expr dumping methods. 1390//===----------------------------------------------------------------------===// 1391 1392void ASTDumper::VisitExpr(const Expr *Node) { 1393 VisitStmt(Node); 1394 dumpType(Node->getType()); 1395 1396 { 1397 ColorScope Color(*this, ValueKindColor); 1398 switch (Node->getValueKind()) { 1399 case VK_RValue: 1400 break; 1401 case VK_LValue: 1402 OS << " lvalue"; 1403 break; 1404 case VK_XValue: 1405 OS << " xvalue"; 1406 break; 1407 } 1408 } 1409 1410 { 1411 ColorScope Color(*this, ObjectKindColor); 1412 switch (Node->getObjectKind()) { 1413 case OK_Ordinary: 1414 break; 1415 case OK_BitField: 1416 OS << " bitfield"; 1417 break; 1418 case OK_ObjCProperty: 1419 OS << " objcproperty"; 1420 break; 1421 case OK_ObjCSubscript: 1422 OS << " objcsubscript"; 1423 break; 1424 case OK_VectorComponent: 1425 OS << " vectorcomponent"; 1426 break; 1427 } 1428 } 1429} 1430 1431static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1432 if (Node->path_empty()) 1433 return; 1434 1435 OS << " ("; 1436 bool First = true; 1437 for (CastExpr::path_const_iterator I = Node->path_begin(), 1438 E = Node->path_end(); 1439 I != E; ++I) { 1440 const CXXBaseSpecifier *Base = *I; 1441 if (!First) 1442 OS << " -> "; 1443 1444 const CXXRecordDecl *RD = 1445 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1446 1447 if (Base->isVirtual()) 1448 OS << "virtual "; 1449 OS << RD->getName(); 1450 First = false; 1451 } 1452 1453 OS << ')'; 1454} 1455 1456void ASTDumper::VisitCastExpr(const CastExpr *Node) { 1457 VisitExpr(Node); 1458 OS << " <"; 1459 { 1460 ColorScope Color(*this, CastColor); 1461 OS << Node->getCastKindName(); 1462 } 1463 dumpBasePath(OS, Node); 1464 OS << ">"; 1465} 1466 1467void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1468 VisitExpr(Node); 1469 1470 OS << " "; 1471 dumpBareDeclRef(Node->getDecl()); 1472 if (Node->getDecl() != Node->getFoundDecl()) { 1473 OS << " ("; 1474 dumpBareDeclRef(Node->getFoundDecl()); 1475 OS << ")"; 1476 } 1477} 1478 1479void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1480 VisitExpr(Node); 1481 OS << " ("; 1482 if (!Node->requiresADL()) 1483 OS << "no "; 1484 OS << "ADL) = '" << Node->getName() << '\''; 1485 1486 UnresolvedLookupExpr::decls_iterator 1487 I = Node->decls_begin(), E = Node->decls_end(); 1488 if (I == E) 1489 OS << " empty"; 1490 for (; I != E; ++I) 1491 dumpPointer(*I); 1492} 1493 1494void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1495 VisitExpr(Node); 1496 1497 { 1498 ColorScope Color(*this, DeclKindNameColor); 1499 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1500 } 1501 OS << "='" << *Node->getDecl() << "'"; 1502 dumpPointer(Node->getDecl()); 1503 if (Node->isFreeIvar()) 1504 OS << " isFreeIvar"; 1505} 1506 1507void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1508 VisitExpr(Node); 1509 switch (Node->getIdentType()) { 1510 default: llvm_unreachable("unknown case"); 1511 case PredefinedExpr::Func: OS << " __func__"; break; 1512 case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 1513 case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break; 1514 case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 1515 } 1516} 1517 1518void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1519 VisitExpr(Node); 1520 ColorScope Color(*this, ValueColor); 1521 OS << " " << Node->getValue(); 1522} 1523 1524void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1525 VisitExpr(Node); 1526 1527 bool isSigned = Node->getType()->isSignedIntegerType(); 1528 ColorScope Color(*this, ValueColor); 1529 OS << " " << Node->getValue().toString(10, isSigned); 1530} 1531 1532void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1533 VisitExpr(Node); 1534 ColorScope Color(*this, ValueColor); 1535 OS << " " << Node->getValueAsApproximateDouble(); 1536} 1537 1538void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1539 VisitExpr(Str); 1540 ColorScope Color(*this, ValueColor); 1541 OS << " "; 1542 Str->outputString(OS); 1543} 1544 1545void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1546 VisitExpr(Node); 1547 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1548 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1549} 1550 1551void ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1552 const UnaryExprOrTypeTraitExpr *Node) { 1553 VisitExpr(Node); 1554 switch(Node->getKind()) { 1555 case UETT_SizeOf: 1556 OS << " sizeof"; 1557 break; 1558 case UETT_AlignOf: 1559 OS << " alignof"; 1560 break; 1561 case UETT_VecStep: 1562 OS << " vec_step"; 1563 break; 1564 } 1565 if (Node->isArgumentType()) 1566 dumpType(Node->getArgumentType()); 1567} 1568 1569void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1570 VisitExpr(Node); 1571 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1572 dumpPointer(Node->getMemberDecl()); 1573} 1574 1575void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1576 VisitExpr(Node); 1577 OS << " " << Node->getAccessor().getNameStart(); 1578} 1579 1580void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1581 VisitExpr(Node); 1582 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1583} 1584 1585void ASTDumper::VisitCompoundAssignOperator( 1586 const CompoundAssignOperator *Node) { 1587 VisitExpr(Node); 1588 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1589 << "' ComputeLHSTy="; 1590 dumpBareType(Node->getComputationLHSType()); 1591 OS << " ComputeResultTy="; 1592 dumpBareType(Node->getComputationResultType()); 1593} 1594 1595void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1596 VisitExpr(Node); 1597 dumpDecl(Node->getBlockDecl()); 1598} 1599 1600void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1601 VisitExpr(Node); 1602 1603 if (Expr *Source = Node->getSourceExpr()) { 1604 lastChild(); 1605 dumpStmt(Source); 1606 } 1607} 1608 1609// GNU extensions. 1610 1611void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1612 VisitExpr(Node); 1613 OS << " " << Node->getLabel()->getName(); 1614 dumpPointer(Node->getLabel()); 1615} 1616 1617//===----------------------------------------------------------------------===// 1618// C++ Expressions 1619//===----------------------------------------------------------------------===// 1620 1621void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1622 VisitExpr(Node); 1623 OS << " " << Node->getCastName() 1624 << "<" << Node->getTypeAsWritten().getAsString() << ">" 1625 << " <" << Node->getCastKindName(); 1626 dumpBasePath(OS, Node); 1627 OS << ">"; 1628} 1629 1630void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1631 VisitExpr(Node); 1632 OS << " " << (Node->getValue() ? "true" : "false"); 1633} 1634 1635void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1636 VisitExpr(Node); 1637 OS << " this"; 1638} 1639 1640void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1641 VisitExpr(Node); 1642 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1643 << " <" << Node->getCastKindName() << ">"; 1644} 1645 1646void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1647 VisitExpr(Node); 1648 CXXConstructorDecl *Ctor = Node->getConstructor(); 1649 dumpType(Ctor->getType()); 1650 if (Node->isElidable()) 1651 OS << " elidable"; 1652 if (Node->requiresZeroInitialization()) 1653 OS << " zeroing"; 1654} 1655 1656void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1657 VisitExpr(Node); 1658 OS << " "; 1659 dumpCXXTemporary(Node->getTemporary()); 1660} 1661 1662void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1663 VisitExpr(Node); 1664 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1665 dumpDeclRef(Node->getObject(i), "cleanup"); 1666} 1667 1668void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1669 OS << "(CXXTemporary"; 1670 dumpPointer(Temporary); 1671 OS << ")"; 1672} 1673 1674//===----------------------------------------------------------------------===// 1675// Obj-C Expressions 1676//===----------------------------------------------------------------------===// 1677 1678void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1679 VisitExpr(Node); 1680 OS << " selector=" << Node->getSelector().getAsString(); 1681 switch (Node->getReceiverKind()) { 1682 case ObjCMessageExpr::Instance: 1683 break; 1684 1685 case ObjCMessageExpr::Class: 1686 OS << " class="; 1687 dumpBareType(Node->getClassReceiver()); 1688 break; 1689 1690 case ObjCMessageExpr::SuperInstance: 1691 OS << " super (instance)"; 1692 break; 1693 1694 case ObjCMessageExpr::SuperClass: 1695 OS << " super (class)"; 1696 break; 1697 } 1698} 1699 1700void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1701 VisitExpr(Node); 1702 OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString(); 1703} 1704 1705void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1706 VisitStmt(Node); 1707 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1708 dumpDecl(CatchParam); 1709 else 1710 OS << " catch all"; 1711} 1712 1713void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1714 VisitExpr(Node); 1715 dumpType(Node->getEncodedType()); 1716} 1717 1718void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1719 VisitExpr(Node); 1720 1721 OS << " " << Node->getSelector().getAsString(); 1722} 1723 1724void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1725 VisitExpr(Node); 1726 1727 OS << ' ' << *Node->getProtocol(); 1728} 1729 1730void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1731 VisitExpr(Node); 1732 if (Node->isImplicitProperty()) { 1733 OS << " Kind=MethodRef Getter=\""; 1734 if (Node->getImplicitPropertyGetter()) 1735 OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 1736 else 1737 OS << "(null)"; 1738 1739 OS << "\" Setter=\""; 1740 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1741 OS << Setter->getSelector().getAsString(); 1742 else 1743 OS << "(null)"; 1744 OS << "\""; 1745 } else { 1746 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 1747 } 1748 1749 if (Node->isSuperReceiver()) 1750 OS << " super"; 1751 1752 OS << " Messaging="; 1753 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1754 OS << "Getter&Setter"; 1755 else if (Node->isMessagingGetter()) 1756 OS << "Getter"; 1757 else if (Node->isMessagingSetter()) 1758 OS << "Setter"; 1759} 1760 1761void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 1762 VisitExpr(Node); 1763 if (Node->isArraySubscriptRefExpr()) 1764 OS << " Kind=ArraySubscript GetterForArray=\""; 1765 else 1766 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1767 if (Node->getAtIndexMethodDecl()) 1768 OS << Node->getAtIndexMethodDecl()->getSelector().getAsString(); 1769 else 1770 OS << "(null)"; 1771 1772 if (Node->isArraySubscriptRefExpr()) 1773 OS << "\" SetterForArray=\""; 1774 else 1775 OS << "\" SetterForDictionary=\""; 1776 if (Node->setAtIndexMethodDecl()) 1777 OS << Node->setAtIndexMethodDecl()->getSelector().getAsString(); 1778 else 1779 OS << "(null)"; 1780} 1781 1782void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1783 VisitExpr(Node); 1784 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1785} 1786 1787//===----------------------------------------------------------------------===// 1788// Comments 1789//===----------------------------------------------------------------------===// 1790 1791const char *ASTDumper::getCommandName(unsigned CommandID) { 1792 if (Traits) 1793 return Traits->getCommandInfo(CommandID)->Name; 1794 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 1795 if (Info) 1796 return Info->Name; 1797 return "<not a builtin command>"; 1798} 1799 1800void ASTDumper::dumpFullComment(const FullComment *C) { 1801 if (!C) 1802 return; 1803 1804 FC = C; 1805 dumpComment(C); 1806 FC = 0; 1807} 1808 1809void ASTDumper::dumpComment(const Comment *C) { 1810 IndentScope Indent(*this); 1811 1812 if (!C) { 1813 ColorScope Color(*this, NullColor); 1814 OS << "<<<NULL>>>"; 1815 return; 1816 } 1817 1818 { 1819 ColorScope Color(*this, CommentColor); 1820 OS << C->getCommentKindName(); 1821 } 1822 dumpPointer(C); 1823 dumpSourceRange(C->getSourceRange()); 1824 ConstCommentVisitor<ASTDumper>::visit(C); 1825 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 1826 I != E; ++I) { 1827 if (I + 1 == E) 1828 lastChild(); 1829 dumpComment(*I); 1830 } 1831} 1832 1833void ASTDumper::visitTextComment(const TextComment *C) { 1834 OS << " Text=\"" << C->getText() << "\""; 1835} 1836 1837void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 1838 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 1839 switch (C->getRenderKind()) { 1840 case InlineCommandComment::RenderNormal: 1841 OS << " RenderNormal"; 1842 break; 1843 case InlineCommandComment::RenderBold: 1844 OS << " RenderBold"; 1845 break; 1846 case InlineCommandComment::RenderMonospaced: 1847 OS << " RenderMonospaced"; 1848 break; 1849 case InlineCommandComment::RenderEmphasized: 1850 OS << " RenderEmphasized"; 1851 break; 1852 } 1853 1854 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 1855 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 1856} 1857 1858void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 1859 OS << " Name=\"" << C->getTagName() << "\""; 1860 if (C->getNumAttrs() != 0) { 1861 OS << " Attrs: "; 1862 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 1863 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 1864 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 1865 } 1866 } 1867 if (C->isSelfClosing()) 1868 OS << " SelfClosing"; 1869} 1870 1871void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 1872 OS << " Name=\"" << C->getTagName() << "\""; 1873} 1874 1875void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 1876 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 1877 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 1878 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 1879} 1880 1881void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 1882 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 1883 1884 if (C->isDirectionExplicit()) 1885 OS << " explicitly"; 1886 else 1887 OS << " implicitly"; 1888 1889 if (C->hasParamName()) { 1890 if (C->isParamIndexValid()) 1891 OS << " Param=\"" << C->getParamName(FC) << "\""; 1892 else 1893 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 1894 } 1895 1896 if (C->isParamIndexValid()) 1897 OS << " ParamIndex=" << C->getParamIndex(); 1898} 1899 1900void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 1901 if (C->hasParamName()) { 1902 if (C->isPositionValid()) 1903 OS << " Param=\"" << C->getParamName(FC) << "\""; 1904 else 1905 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 1906 } 1907 1908 if (C->isPositionValid()) { 1909 OS << " Position=<"; 1910 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 1911 OS << C->getIndex(i); 1912 if (i != e - 1) 1913 OS << ", "; 1914 } 1915 OS << ">"; 1916 } 1917} 1918 1919void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 1920 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 1921 " CloseName=\"" << C->getCloseName() << "\""; 1922} 1923 1924void ASTDumper::visitVerbatimBlockLineComment( 1925 const VerbatimBlockLineComment *C) { 1926 OS << " Text=\"" << C->getText() << "\""; 1927} 1928 1929void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 1930 OS << " Text=\"" << C->getText() << "\""; 1931} 1932 1933//===----------------------------------------------------------------------===// 1934// Decl method implementations 1935//===----------------------------------------------------------------------===// 1936 1937void Decl::dump() const { 1938 dump(llvm::errs()); 1939} 1940 1941void Decl::dump(raw_ostream &OS) const { 1942 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 1943 &getASTContext().getSourceManager()); 1944 P.dumpDecl(this); 1945} 1946 1947void Decl::dumpColor() const { 1948 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 1949 &getASTContext().getSourceManager(), /*ShowColors*/true); 1950 P.dumpDecl(this); 1951} 1952//===----------------------------------------------------------------------===// 1953// Stmt method implementations 1954//===----------------------------------------------------------------------===// 1955 1956void Stmt::dump(SourceManager &SM) const { 1957 dump(llvm::errs(), SM); 1958} 1959 1960void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 1961 ASTDumper P(OS, 0, &SM); 1962 P.dumpStmt(this); 1963} 1964 1965void Stmt::dump() const { 1966 ASTDumper P(llvm::errs(), 0, 0); 1967 P.dumpStmt(this); 1968} 1969 1970void Stmt::dumpColor() const { 1971 ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true); 1972 P.dumpStmt(this); 1973} 1974 1975//===----------------------------------------------------------------------===// 1976// Comment method implementations 1977//===----------------------------------------------------------------------===// 1978 1979void Comment::dump() const { 1980 dump(llvm::errs(), 0, 0); 1981} 1982 1983void Comment::dump(const ASTContext &Context) const { 1984 dump(llvm::errs(), &Context.getCommentCommandTraits(), 1985 &Context.getSourceManager()); 1986} 1987 1988void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 1989 const SourceManager *SM) const { 1990 const FullComment *FC = dyn_cast<FullComment>(this); 1991 ASTDumper D(OS, Traits, SM); 1992 D.dumpFullComment(FC); 1993} 1994 1995void Comment::dumpColor() const { 1996 const FullComment *FC = dyn_cast<FullComment>(this); 1997 ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true); 1998 D.dumpFullComment(FC); 1999} 2000