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