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" 25 using namespace clang; 26 using namespace clang::comments; 27 28 //===----------------------------------------------------------------------===// 29 // ASTDumper Visitor 30 //===----------------------------------------------------------------------===// 31 32 namespace { 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 " " "`-" 325 void 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 354 void 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. 360 void 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. 367 bool ASTDumper::hasMoreChildren() { 368 return MoreChildren; 369 } 370 371 void ASTDumper::setMoreChildren(bool Value) { 372 MoreChildren = Value; 373 } 374 375 void ASTDumper::dumpPointer(const void *Ptr) { 376 ColorScope Color(*this, AddressColor); 377 OS << ' ' << Ptr; 378 } 379 380 void 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 407 void 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 424 void 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 438 void ASTDumper::dumpType(QualType T) { 439 OS << ' '; 440 dumpBareType(T); 441 } 442 443 void 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 461 void 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 471 void ASTDumper::dumpName(const NamedDecl *ND) { 472 if (ND->getDeclName()) { 473 ColorScope Color(*this, DeclNameColor); 474 OS << ' ' << ND->getNameAsString(); 475 } 476 } 477 478 bool ASTDumper::hasNodes(const DeclContext *DC) { 479 if (!DC) 480 return false; 481 482 return DC->decls_begin() != DC->decls_end(); 483 } 484 485 void 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 498 void 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 514 static Decl *getPreviousDeclImpl(...) { 515 return 0; 516 } 517 518 template<typename T> 519 static 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. 524 static 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 539 void 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 555 void 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 567 void 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 576 void 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 585 void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 586 dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 587 } 588 589 void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 590 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 591 dumpTemplateArgument(TAL[i]); 592 } 593 594 void 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 649 void 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 695 void ASTDumper::VisitLabelDecl(const LabelDecl *D) { 696 dumpName(D); 697 } 698 699 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 700 dumpName(D); 701 dumpType(D->getUnderlyingType()); 702 if (D->isModulePrivate()) 703 OS << " __module_private__"; 704 } 705 706 void 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 720 void ASTDumper::VisitRecordDecl(const RecordDecl *D) { 721 OS << ' ' << D->getKindName(); 722 dumpName(D); 723 if (D->isModulePrivate()) 724 OS << " __module_private__"; 725 } 726 727 void 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 736 void 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 748 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 749 dumpName(D); 750 dumpType(D->getType()); 751 752 StorageClass SC = D->getStorageClassAsWritten(); 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 825 void 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 850 void ASTDumper::VisitVarDecl(const VarDecl *D) { 851 dumpName(D); 852 dumpType(D->getType()); 853 StorageClass SC = D->getStorageClassAsWritten(); 854 if (SC != SC_None) 855 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 856 if (D->isThreadSpecified()) 857 OS << " __thread"; 858 if (D->isModulePrivate()) 859 OS << " __module_private__"; 860 if (D->isNRVOVariable()) 861 OS << " nrvo"; 862 if (D->hasInit()) { 863 lastChild(); 864 dumpStmt(D->getInit()); 865 } 866 } 867 868 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 869 lastChild(); 870 dumpStmt(D->getAsmString()); 871 } 872 873 void ASTDumper::VisitImportDecl(const ImportDecl *D) { 874 OS << ' ' << D->getImportedModule()->getFullModuleName(); 875 } 876 877 //===----------------------------------------------------------------------===// 878 // C++ Declarations 879 //===----------------------------------------------------------------------===// 880 881 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 882 dumpName(D); 883 if (D->isInline()) 884 OS << " inline"; 885 if (!D->isOriginalNamespace()) 886 dumpDeclRef(D->getOriginalNamespace(), "original"); 887 } 888 889 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 890 OS << ' '; 891 dumpBareDeclRef(D->getNominatedNamespace()); 892 } 893 894 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 895 dumpName(D); 896 dumpDeclRef(D->getAliasedNamespace()); 897 } 898 899 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 900 dumpName(D); 901 dumpType(D->getUnderlyingType()); 902 } 903 904 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 905 dumpName(D); 906 dumpTemplateParameters(D->getTemplateParameters()); 907 dumpDecl(D->getTemplatedDecl()); 908 } 909 910 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 911 VisitRecordDecl(D); 912 if (!D->isCompleteDefinition()) 913 return; 914 915 for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(), 916 E = D->bases_end(); 917 I != E; ++I) { 918 IndentScope Indent(*this); 919 if (I->isVirtual()) 920 OS << "virtual "; 921 dumpAccessSpecifier(I->getAccessSpecifier()); 922 dumpType(I->getType()); 923 if (I->isPackExpansion()) 924 OS << "..."; 925 } 926 } 927 928 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 929 dumpStmt(D->getAssertExpr()); 930 lastChild(); 931 dumpStmt(D->getMessage()); 932 } 933 934 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 935 dumpName(D); 936 dumpTemplateParameters(D->getTemplateParameters()); 937 dumpDecl(D->getTemplatedDecl()); 938 for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), 939 E = D->spec_end(); 940 I != E; ++I) { 941 FunctionTemplateDecl::spec_iterator Next = I; 942 ++Next; 943 if (Next == E) 944 lastChild(); 945 switch (I->getTemplateSpecializationKind()) { 946 case TSK_Undeclared: 947 case TSK_ImplicitInstantiation: 948 case TSK_ExplicitInstantiationDeclaration: 949 case TSK_ExplicitInstantiationDefinition: 950 if (D == D->getCanonicalDecl()) 951 dumpDecl(*I); 952 else 953 dumpDeclRef(*I); 954 break; 955 case TSK_ExplicitSpecialization: 956 dumpDeclRef(*I); 957 break; 958 } 959 } 960 } 961 962 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 963 dumpName(D); 964 dumpTemplateParameters(D->getTemplateParameters()); 965 966 ClassTemplateDecl::spec_iterator I = D->spec_begin(); 967 ClassTemplateDecl::spec_iterator E = D->spec_end(); 968 if (I == E) 969 lastChild(); 970 dumpDecl(D->getTemplatedDecl()); 971 for (; I != E; ++I) { 972 ClassTemplateDecl::spec_iterator Next = I; 973 ++Next; 974 if (Next == E) 975 lastChild(); 976 switch (I->getTemplateSpecializationKind()) { 977 case TSK_Undeclared: 978 case TSK_ImplicitInstantiation: 979 if (D == D->getCanonicalDecl()) 980 dumpDecl(*I); 981 else 982 dumpDeclRef(*I); 983 break; 984 case TSK_ExplicitSpecialization: 985 case TSK_ExplicitInstantiationDeclaration: 986 case TSK_ExplicitInstantiationDefinition: 987 dumpDeclRef(*I); 988 break; 989 } 990 } 991 } 992 993 void ASTDumper::VisitClassTemplateSpecializationDecl( 994 const ClassTemplateSpecializationDecl *D) { 995 VisitCXXRecordDecl(D); 996 dumpTemplateArgumentList(D->getTemplateArgs()); 997 } 998 999 void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1000 const ClassTemplatePartialSpecializationDecl *D) { 1001 VisitClassTemplateSpecializationDecl(D); 1002 dumpTemplateParameters(D->getTemplateParameters()); 1003 } 1004 1005 void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1006 const ClassScopeFunctionSpecializationDecl *D) { 1007 dumpDeclRef(D->getSpecialization()); 1008 if (D->hasExplicitTemplateArgs()) 1009 dumpTemplateArgumentListInfo(D->templateArgs()); 1010 } 1011 1012 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1013 if (D->wasDeclaredWithTypename()) 1014 OS << " typename"; 1015 else 1016 OS << " class"; 1017 if (D->isParameterPack()) 1018 OS << " ..."; 1019 dumpName(D); 1020 if (D->hasDefaultArgument()) 1021 dumpType(D->getDefaultArgument()); 1022 } 1023 1024 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1025 dumpType(D->getType()); 1026 if (D->isParameterPack()) 1027 OS << " ..."; 1028 dumpName(D); 1029 if (D->hasDefaultArgument()) 1030 dumpStmt(D->getDefaultArgument()); 1031 } 1032 1033 void ASTDumper::VisitTemplateTemplateParmDecl( 1034 const TemplateTemplateParmDecl *D) { 1035 if (D->isParameterPack()) 1036 OS << " ..."; 1037 dumpName(D); 1038 dumpTemplateParameters(D->getTemplateParameters()); 1039 if (D->hasDefaultArgument()) 1040 dumpTemplateArgumentLoc(D->getDefaultArgument()); 1041 } 1042 1043 void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1044 OS << ' '; 1045 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1046 OS << D->getNameAsString(); 1047 } 1048 1049 void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1050 const UnresolvedUsingTypenameDecl *D) { 1051 OS << ' '; 1052 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1053 OS << D->getNameAsString(); 1054 } 1055 1056 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1057 OS << ' '; 1058 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1059 OS << D->getNameAsString(); 1060 dumpType(D->getType()); 1061 } 1062 1063 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1064 OS << ' '; 1065 dumpBareDeclRef(D->getTargetDecl()); 1066 } 1067 1068 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1069 switch (D->getLanguage()) { 1070 case LinkageSpecDecl::lang_c: OS << " C"; break; 1071 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1072 } 1073 } 1074 1075 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1076 OS << ' '; 1077 dumpAccessSpecifier(D->getAccess()); 1078 } 1079 1080 void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1081 lastChild(); 1082 if (TypeSourceInfo *T = D->getFriendType()) 1083 dumpType(T->getType()); 1084 else 1085 dumpDecl(D->getFriendDecl()); 1086 } 1087 1088 //===----------------------------------------------------------------------===// 1089 // Obj-C Declarations 1090 //===----------------------------------------------------------------------===// 1091 1092 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1093 dumpName(D); 1094 dumpType(D->getType()); 1095 if (D->getSynthesize()) 1096 OS << " synthesize"; 1097 1098 switch (D->getAccessControl()) { 1099 case ObjCIvarDecl::None: 1100 OS << " none"; 1101 break; 1102 case ObjCIvarDecl::Private: 1103 OS << " private"; 1104 break; 1105 case ObjCIvarDecl::Protected: 1106 OS << " protected"; 1107 break; 1108 case ObjCIvarDecl::Public: 1109 OS << " public"; 1110 break; 1111 case ObjCIvarDecl::Package: 1112 OS << " package"; 1113 break; 1114 } 1115 } 1116 1117 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1118 if (D->isInstanceMethod()) 1119 OS << " -"; 1120 else 1121 OS << " +"; 1122 dumpName(D); 1123 dumpType(D->getResultType()); 1124 1125 bool OldMoreChildren = hasMoreChildren(); 1126 bool IsVariadic = D->isVariadic(); 1127 bool HasBody = D->hasBody(); 1128 1129 setMoreChildren(OldMoreChildren || IsVariadic || HasBody); 1130 if (D->isThisDeclarationADefinition()) { 1131 lastChild(); 1132 dumpDeclContext(D); 1133 } else { 1134 for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1135 E = D->param_end(); 1136 I != E; ++I) { 1137 if (I + 1 == E) 1138 lastChild(); 1139 dumpDecl(*I); 1140 } 1141 } 1142 1143 setMoreChildren(OldMoreChildren || HasBody); 1144 if (IsVariadic) { 1145 lastChild(); 1146 IndentScope Indent(*this); 1147 OS << "..."; 1148 } 1149 1150 setMoreChildren(OldMoreChildren); 1151 if (HasBody) { 1152 lastChild(); 1153 dumpStmt(D->getBody()); 1154 } 1155 } 1156 1157 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1158 dumpName(D); 1159 dumpDeclRef(D->getClassInterface()); 1160 if (D->protocol_begin() == D->protocol_end()) 1161 lastChild(); 1162 dumpDeclRef(D->getImplementation()); 1163 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1164 E = D->protocol_end(); 1165 I != E; ++I) { 1166 if (I + 1 == E) 1167 lastChild(); 1168 dumpDeclRef(*I); 1169 } 1170 } 1171 1172 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1173 dumpName(D); 1174 dumpDeclRef(D->getClassInterface()); 1175 lastChild(); 1176 dumpDeclRef(D->getCategoryDecl()); 1177 } 1178 1179 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1180 dumpName(D); 1181 for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), 1182 E = D->protocol_end(); 1183 I != E; ++I) { 1184 if (I + 1 == E) 1185 lastChild(); 1186 dumpDeclRef(*I); 1187 } 1188 } 1189 1190 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1191 dumpName(D); 1192 dumpDeclRef(D->getSuperClass(), "super"); 1193 if (D->protocol_begin() == D->protocol_end()) 1194 lastChild(); 1195 dumpDeclRef(D->getImplementation()); 1196 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 1197 E = D->protocol_end(); 1198 I != E; ++I) { 1199 if (I + 1 == E) 1200 lastChild(); 1201 dumpDeclRef(*I); 1202 } 1203 } 1204 1205 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1206 dumpName(D); 1207 dumpDeclRef(D->getSuperClass(), "super"); 1208 if (D->init_begin() == D->init_end()) 1209 lastChild(); 1210 dumpDeclRef(D->getClassInterface()); 1211 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1212 E = D->init_end(); 1213 I != E; ++I) { 1214 if (I + 1 == E) 1215 lastChild(); 1216 dumpCXXCtorInitializer(*I); 1217 } 1218 } 1219 1220 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1221 dumpName(D); 1222 lastChild(); 1223 dumpDeclRef(D->getClassInterface()); 1224 } 1225 1226 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1227 dumpName(D); 1228 dumpType(D->getType()); 1229 1230 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1231 OS << " required"; 1232 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1233 OS << " optional"; 1234 1235 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1236 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1237 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1238 OS << " readonly"; 1239 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1240 OS << " assign"; 1241 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1242 OS << " readwrite"; 1243 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1244 OS << " retain"; 1245 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1246 OS << " copy"; 1247 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1248 OS << " nonatomic"; 1249 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1250 OS << " atomic"; 1251 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1252 OS << " weak"; 1253 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1254 OS << " strong"; 1255 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1256 OS << " unsafe_unretained"; 1257 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { 1258 if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) 1259 lastChild(); 1260 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1261 } 1262 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { 1263 lastChild(); 1264 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1265 } 1266 } 1267 } 1268 1269 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1270 dumpName(D->getPropertyDecl()); 1271 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1272 OS << " synthesize"; 1273 else 1274 OS << " dynamic"; 1275 dumpDeclRef(D->getPropertyDecl()); 1276 lastChild(); 1277 dumpDeclRef(D->getPropertyIvarDecl()); 1278 } 1279 1280 void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1281 for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); 1282 I != E; ++I) 1283 dumpDecl(*I); 1284 1285 if (D->isVariadic()) { 1286 IndentScope Indent(*this); 1287 OS << "..."; 1288 } 1289 1290 if (D->capturesCXXThis()) { 1291 IndentScope Indent(*this); 1292 OS << "capture this"; 1293 } 1294 for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end(); 1295 I != E; ++I) { 1296 IndentScope Indent(*this); 1297 OS << "capture"; 1298 if (I->isByRef()) 1299 OS << " byref"; 1300 if (I->isNested()) 1301 OS << " nested"; 1302 if (I->getVariable()) { 1303 OS << ' '; 1304 dumpBareDeclRef(I->getVariable()); 1305 } 1306 if (I->hasCopyExpr()) 1307 dumpStmt(I->getCopyExpr()); 1308 } 1309 lastChild(); 1310 dumpStmt(D->getBody()); 1311 } 1312 1313 //===----------------------------------------------------------------------===// 1314 // Stmt dumping methods. 1315 //===----------------------------------------------------------------------===// 1316 1317 void ASTDumper::dumpStmt(const Stmt *S) { 1318 IndentScope Indent(*this); 1319 1320 if (!S) { 1321 ColorScope Color(*this, NullColor); 1322 OS << "<<<NULL>>>"; 1323 return; 1324 } 1325 1326 if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1327 VisitDeclStmt(DS); 1328 return; 1329 } 1330 1331 setMoreChildren(S->children()); 1332 ConstStmtVisitor<ASTDumper>::Visit(S); 1333 setMoreChildren(false); 1334 for (Stmt::const_child_range CI = S->children(); CI; ++CI) { 1335 Stmt::const_child_range Next = CI; 1336 ++Next; 1337 if (!Next) 1338 lastChild(); 1339 dumpStmt(*CI); 1340 } 1341 } 1342 1343 void ASTDumper::VisitStmt(const Stmt *Node) { 1344 { 1345 ColorScope Color(*this, StmtColor); 1346 OS << Node->getStmtClassName(); 1347 } 1348 dumpPointer(Node); 1349 dumpSourceRange(Node->getSourceRange()); 1350 } 1351 1352 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1353 VisitStmt(Node); 1354 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1355 E = Node->decl_end(); 1356 I != E; ++I) { 1357 if (I + 1 == E) 1358 lastChild(); 1359 dumpDecl(*I); 1360 } 1361 } 1362 1363 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1364 VisitStmt(Node); 1365 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1366 E = Node->getAttrs().end(); 1367 I != E; ++I) { 1368 if (I + 1 == E) 1369 lastChild(); 1370 dumpAttr(*I); 1371 } 1372 } 1373 1374 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1375 VisitStmt(Node); 1376 OS << " '" << Node->getName() << "'"; 1377 } 1378 1379 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1380 VisitStmt(Node); 1381 OS << " '" << Node->getLabel()->getName() << "'"; 1382 dumpPointer(Node->getLabel()); 1383 } 1384 1385 //===----------------------------------------------------------------------===// 1386 // Expr dumping methods. 1387 //===----------------------------------------------------------------------===// 1388 1389 void ASTDumper::VisitExpr(const Expr *Node) { 1390 VisitStmt(Node); 1391 dumpType(Node->getType()); 1392 1393 { 1394 ColorScope Color(*this, ValueKindColor); 1395 switch (Node->getValueKind()) { 1396 case VK_RValue: 1397 break; 1398 case VK_LValue: 1399 OS << " lvalue"; 1400 break; 1401 case VK_XValue: 1402 OS << " xvalue"; 1403 break; 1404 } 1405 } 1406 1407 { 1408 ColorScope Color(*this, ObjectKindColor); 1409 switch (Node->getObjectKind()) { 1410 case OK_Ordinary: 1411 break; 1412 case OK_BitField: 1413 OS << " bitfield"; 1414 break; 1415 case OK_ObjCProperty: 1416 OS << " objcproperty"; 1417 break; 1418 case OK_ObjCSubscript: 1419 OS << " objcsubscript"; 1420 break; 1421 case OK_VectorComponent: 1422 OS << " vectorcomponent"; 1423 break; 1424 } 1425 } 1426 } 1427 1428 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1429 if (Node->path_empty()) 1430 return; 1431 1432 OS << " ("; 1433 bool First = true; 1434 for (CastExpr::path_const_iterator I = Node->path_begin(), 1435 E = Node->path_end(); 1436 I != E; ++I) { 1437 const CXXBaseSpecifier *Base = *I; 1438 if (!First) 1439 OS << " -> "; 1440 1441 const CXXRecordDecl *RD = 1442 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1443 1444 if (Base->isVirtual()) 1445 OS << "virtual "; 1446 OS << RD->getName(); 1447 First = false; 1448 } 1449 1450 OS << ')'; 1451 } 1452 1453 void ASTDumper::VisitCastExpr(const CastExpr *Node) { 1454 VisitExpr(Node); 1455 OS << " <"; 1456 { 1457 ColorScope Color(*this, CastColor); 1458 OS << Node->getCastKindName(); 1459 } 1460 dumpBasePath(OS, Node); 1461 OS << ">"; 1462 } 1463 1464 void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1465 VisitExpr(Node); 1466 1467 OS << " "; 1468 dumpBareDeclRef(Node->getDecl()); 1469 if (Node->getDecl() != Node->getFoundDecl()) { 1470 OS << " ("; 1471 dumpBareDeclRef(Node->getFoundDecl()); 1472 OS << ")"; 1473 } 1474 } 1475 1476 void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1477 VisitExpr(Node); 1478 OS << " ("; 1479 if (!Node->requiresADL()) 1480 OS << "no "; 1481 OS << "ADL) = '" << Node->getName() << '\''; 1482 1483 UnresolvedLookupExpr::decls_iterator 1484 I = Node->decls_begin(), E = Node->decls_end(); 1485 if (I == E) 1486 OS << " empty"; 1487 for (; I != E; ++I) 1488 dumpPointer(*I); 1489 } 1490 1491 void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1492 VisitExpr(Node); 1493 1494 { 1495 ColorScope Color(*this, DeclKindNameColor); 1496 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1497 } 1498 OS << "='" << *Node->getDecl() << "'"; 1499 dumpPointer(Node->getDecl()); 1500 if (Node->isFreeIvar()) 1501 OS << " isFreeIvar"; 1502 } 1503 1504 void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1505 VisitExpr(Node); 1506 switch (Node->getIdentType()) { 1507 default: llvm_unreachable("unknown case"); 1508 case PredefinedExpr::Func: OS << " __func__"; break; 1509 case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 1510 case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break; 1511 case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 1512 } 1513 } 1514 1515 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1516 VisitExpr(Node); 1517 ColorScope Color(*this, ValueColor); 1518 OS << " " << Node->getValue(); 1519 } 1520 1521 void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1522 VisitExpr(Node); 1523 1524 bool isSigned = Node->getType()->isSignedIntegerType(); 1525 ColorScope Color(*this, ValueColor); 1526 OS << " " << Node->getValue().toString(10, isSigned); 1527 } 1528 1529 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1530 VisitExpr(Node); 1531 ColorScope Color(*this, ValueColor); 1532 OS << " " << Node->getValueAsApproximateDouble(); 1533 } 1534 1535 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1536 VisitExpr(Str); 1537 ColorScope Color(*this, ValueColor); 1538 OS << " "; 1539 Str->outputString(OS); 1540 } 1541 1542 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1543 VisitExpr(Node); 1544 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1545 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1546 } 1547 1548 void ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1549 const UnaryExprOrTypeTraitExpr *Node) { 1550 VisitExpr(Node); 1551 switch(Node->getKind()) { 1552 case UETT_SizeOf: 1553 OS << " sizeof"; 1554 break; 1555 case UETT_AlignOf: 1556 OS << " alignof"; 1557 break; 1558 case UETT_VecStep: 1559 OS << " vec_step"; 1560 break; 1561 } 1562 if (Node->isArgumentType()) 1563 dumpType(Node->getArgumentType()); 1564 } 1565 1566 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1567 VisitExpr(Node); 1568 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1569 dumpPointer(Node->getMemberDecl()); 1570 } 1571 1572 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1573 VisitExpr(Node); 1574 OS << " " << Node->getAccessor().getNameStart(); 1575 } 1576 1577 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1578 VisitExpr(Node); 1579 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1580 } 1581 1582 void ASTDumper::VisitCompoundAssignOperator( 1583 const CompoundAssignOperator *Node) { 1584 VisitExpr(Node); 1585 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1586 << "' ComputeLHSTy="; 1587 dumpBareType(Node->getComputationLHSType()); 1588 OS << " ComputeResultTy="; 1589 dumpBareType(Node->getComputationResultType()); 1590 } 1591 1592 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1593 VisitExpr(Node); 1594 dumpDecl(Node->getBlockDecl()); 1595 } 1596 1597 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1598 VisitExpr(Node); 1599 1600 if (Expr *Source = Node->getSourceExpr()) { 1601 lastChild(); 1602 dumpStmt(Source); 1603 } 1604 } 1605 1606 // GNU extensions. 1607 1608 void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1609 VisitExpr(Node); 1610 OS << " " << Node->getLabel()->getName(); 1611 dumpPointer(Node->getLabel()); 1612 } 1613 1614 //===----------------------------------------------------------------------===// 1615 // C++ Expressions 1616 //===----------------------------------------------------------------------===// 1617 1618 void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1619 VisitExpr(Node); 1620 OS << " " << Node->getCastName() 1621 << "<" << Node->getTypeAsWritten().getAsString() << ">" 1622 << " <" << Node->getCastKindName(); 1623 dumpBasePath(OS, Node); 1624 OS << ">"; 1625 } 1626 1627 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1628 VisitExpr(Node); 1629 OS << " " << (Node->getValue() ? "true" : "false"); 1630 } 1631 1632 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1633 VisitExpr(Node); 1634 OS << " this"; 1635 } 1636 1637 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1638 VisitExpr(Node); 1639 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1640 << " <" << Node->getCastKindName() << ">"; 1641 } 1642 1643 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1644 VisitExpr(Node); 1645 CXXConstructorDecl *Ctor = Node->getConstructor(); 1646 dumpType(Ctor->getType()); 1647 if (Node->isElidable()) 1648 OS << " elidable"; 1649 if (Node->requiresZeroInitialization()) 1650 OS << " zeroing"; 1651 } 1652 1653 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1654 VisitExpr(Node); 1655 OS << " "; 1656 dumpCXXTemporary(Node->getTemporary()); 1657 } 1658 1659 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1660 VisitExpr(Node); 1661 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1662 dumpDeclRef(Node->getObject(i), "cleanup"); 1663 } 1664 1665 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1666 OS << "(CXXTemporary"; 1667 dumpPointer(Temporary); 1668 OS << ")"; 1669 } 1670 1671 //===----------------------------------------------------------------------===// 1672 // Obj-C Expressions 1673 //===----------------------------------------------------------------------===// 1674 1675 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1676 VisitExpr(Node); 1677 OS << " selector=" << Node->getSelector().getAsString(); 1678 switch (Node->getReceiverKind()) { 1679 case ObjCMessageExpr::Instance: 1680 break; 1681 1682 case ObjCMessageExpr::Class: 1683 OS << " class="; 1684 dumpBareType(Node->getClassReceiver()); 1685 break; 1686 1687 case ObjCMessageExpr::SuperInstance: 1688 OS << " super (instance)"; 1689 break; 1690 1691 case ObjCMessageExpr::SuperClass: 1692 OS << " super (class)"; 1693 break; 1694 } 1695 } 1696 1697 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1698 VisitExpr(Node); 1699 OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString(); 1700 } 1701 1702 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1703 VisitStmt(Node); 1704 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1705 dumpDecl(CatchParam); 1706 else 1707 OS << " catch all"; 1708 } 1709 1710 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1711 VisitExpr(Node); 1712 dumpType(Node->getEncodedType()); 1713 } 1714 1715 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1716 VisitExpr(Node); 1717 1718 OS << " " << Node->getSelector().getAsString(); 1719 } 1720 1721 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1722 VisitExpr(Node); 1723 1724 OS << ' ' << *Node->getProtocol(); 1725 } 1726 1727 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1728 VisitExpr(Node); 1729 if (Node->isImplicitProperty()) { 1730 OS << " Kind=MethodRef Getter=\""; 1731 if (Node->getImplicitPropertyGetter()) 1732 OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 1733 else 1734 OS << "(null)"; 1735 1736 OS << "\" Setter=\""; 1737 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1738 OS << Setter->getSelector().getAsString(); 1739 else 1740 OS << "(null)"; 1741 OS << "\""; 1742 } else { 1743 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 1744 } 1745 1746 if (Node->isSuperReceiver()) 1747 OS << " super"; 1748 1749 OS << " Messaging="; 1750 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1751 OS << "Getter&Setter"; 1752 else if (Node->isMessagingGetter()) 1753 OS << "Getter"; 1754 else if (Node->isMessagingSetter()) 1755 OS << "Setter"; 1756 } 1757 1758 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 1759 VisitExpr(Node); 1760 if (Node->isArraySubscriptRefExpr()) 1761 OS << " Kind=ArraySubscript GetterForArray=\""; 1762 else 1763 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1764 if (Node->getAtIndexMethodDecl()) 1765 OS << Node->getAtIndexMethodDecl()->getSelector().getAsString(); 1766 else 1767 OS << "(null)"; 1768 1769 if (Node->isArraySubscriptRefExpr()) 1770 OS << "\" SetterForArray=\""; 1771 else 1772 OS << "\" SetterForDictionary=\""; 1773 if (Node->setAtIndexMethodDecl()) 1774 OS << Node->setAtIndexMethodDecl()->getSelector().getAsString(); 1775 else 1776 OS << "(null)"; 1777 } 1778 1779 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1780 VisitExpr(Node); 1781 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1782 } 1783 1784 //===----------------------------------------------------------------------===// 1785 // Comments 1786 //===----------------------------------------------------------------------===// 1787 1788 const char *ASTDumper::getCommandName(unsigned CommandID) { 1789 if (Traits) 1790 return Traits->getCommandInfo(CommandID)->Name; 1791 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 1792 if (Info) 1793 return Info->Name; 1794 return "<not a builtin command>"; 1795 } 1796 1797 void ASTDumper::dumpFullComment(const FullComment *C) { 1798 if (!C) 1799 return; 1800 1801 FC = C; 1802 dumpComment(C); 1803 FC = 0; 1804 } 1805 1806 void ASTDumper::dumpComment(const Comment *C) { 1807 IndentScope Indent(*this); 1808 1809 if (!C) { 1810 ColorScope Color(*this, NullColor); 1811 OS << "<<<NULL>>>"; 1812 return; 1813 } 1814 1815 { 1816 ColorScope Color(*this, CommentColor); 1817 OS << C->getCommentKindName(); 1818 } 1819 dumpPointer(C); 1820 dumpSourceRange(C->getSourceRange()); 1821 ConstCommentVisitor<ASTDumper>::visit(C); 1822 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 1823 I != E; ++I) { 1824 if (I + 1 == E) 1825 lastChild(); 1826 dumpComment(*I); 1827 } 1828 } 1829 1830 void ASTDumper::visitTextComment(const TextComment *C) { 1831 OS << " Text=\"" << C->getText() << "\""; 1832 } 1833 1834 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 1835 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 1836 switch (C->getRenderKind()) { 1837 case InlineCommandComment::RenderNormal: 1838 OS << " RenderNormal"; 1839 break; 1840 case InlineCommandComment::RenderBold: 1841 OS << " RenderBold"; 1842 break; 1843 case InlineCommandComment::RenderMonospaced: 1844 OS << " RenderMonospaced"; 1845 break; 1846 case InlineCommandComment::RenderEmphasized: 1847 OS << " RenderEmphasized"; 1848 break; 1849 } 1850 1851 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 1852 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 1853 } 1854 1855 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 1856 OS << " Name=\"" << C->getTagName() << "\""; 1857 if (C->getNumAttrs() != 0) { 1858 OS << " Attrs: "; 1859 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 1860 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 1861 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 1862 } 1863 } 1864 if (C->isSelfClosing()) 1865 OS << " SelfClosing"; 1866 } 1867 1868 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 1869 OS << " Name=\"" << C->getTagName() << "\""; 1870 } 1871 1872 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 1873 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 1874 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 1875 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 1876 } 1877 1878 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 1879 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 1880 1881 if (C->isDirectionExplicit()) 1882 OS << " explicitly"; 1883 else 1884 OS << " implicitly"; 1885 1886 if (C->hasParamName()) { 1887 if (C->isParamIndexValid()) 1888 OS << " Param=\"" << C->getParamName(FC) << "\""; 1889 else 1890 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 1891 } 1892 1893 if (C->isParamIndexValid()) 1894 OS << " ParamIndex=" << C->getParamIndex(); 1895 } 1896 1897 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 1898 if (C->hasParamName()) { 1899 if (C->isPositionValid()) 1900 OS << " Param=\"" << C->getParamName(FC) << "\""; 1901 else 1902 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 1903 } 1904 1905 if (C->isPositionValid()) { 1906 OS << " Position=<"; 1907 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 1908 OS << C->getIndex(i); 1909 if (i != e - 1) 1910 OS << ", "; 1911 } 1912 OS << ">"; 1913 } 1914 } 1915 1916 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 1917 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 1918 " CloseName=\"" << C->getCloseName() << "\""; 1919 } 1920 1921 void ASTDumper::visitVerbatimBlockLineComment( 1922 const VerbatimBlockLineComment *C) { 1923 OS << " Text=\"" << C->getText() << "\""; 1924 } 1925 1926 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 1927 OS << " Text=\"" << C->getText() << "\""; 1928 } 1929 1930 //===----------------------------------------------------------------------===// 1931 // Decl method implementations 1932 //===----------------------------------------------------------------------===// 1933 1934 void Decl::dump() const { 1935 dump(llvm::errs()); 1936 } 1937 1938 void Decl::dump(raw_ostream &OS) const { 1939 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 1940 &getASTContext().getSourceManager()); 1941 P.dumpDecl(this); 1942 } 1943 1944 void Decl::dumpColor() const { 1945 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 1946 &getASTContext().getSourceManager(), /*ShowColors*/true); 1947 P.dumpDecl(this); 1948 } 1949 //===----------------------------------------------------------------------===// 1950 // Stmt method implementations 1951 //===----------------------------------------------------------------------===// 1952 1953 void Stmt::dump(SourceManager &SM) const { 1954 dump(llvm::errs(), SM); 1955 } 1956 1957 void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 1958 ASTDumper P(OS, 0, &SM); 1959 P.dumpStmt(this); 1960 } 1961 1962 void Stmt::dump() const { 1963 ASTDumper P(llvm::errs(), 0, 0); 1964 P.dumpStmt(this); 1965 } 1966 1967 void Stmt::dumpColor() const { 1968 ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true); 1969 P.dumpStmt(this); 1970 } 1971 1972 //===----------------------------------------------------------------------===// 1973 // Comment method implementations 1974 //===----------------------------------------------------------------------===// 1975 1976 void Comment::dump() const { 1977 dump(llvm::errs(), 0, 0); 1978 } 1979 1980 void Comment::dump(const ASTContext &Context) const { 1981 dump(llvm::errs(), &Context.getCommentCommandTraits(), 1982 &Context.getSourceManager()); 1983 } 1984 1985 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 1986 const SourceManager *SM) const { 1987 const FullComment *FC = dyn_cast<FullComment>(this); 1988 ASTDumper D(OS, Traits, SM); 1989 D.dumpFullComment(FC); 1990 } 1991 1992 void Comment::dumpColor() const { 1993 const FullComment *FC = dyn_cast<FullComment>(this); 1994 ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true); 1995 D.dumpFullComment(FC); 1996 } 1997