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