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