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 if (Module *M = D->getOwningModule()) 796 OS << " in " << M->getFullModuleName(); 797 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 798 if (ND->isHidden()) 799 OS << " hidden"; 800 801 bool HasAttrs = D->hasAttrs(); 802 const FullComment *Comment = 803 D->getASTContext().getLocalCommentForDeclUncached(D); 804 // Decls within functions are visited by the body 805 bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && 806 hasNodes(dyn_cast<DeclContext>(D)); 807 808 setMoreChildren(HasAttrs || Comment || HasDeclContext); 809 ConstDeclVisitor<ASTDumper>::Visit(D); 810 811 setMoreChildren(Comment || HasDeclContext); 812 for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); 813 I != E; ++I) { 814 if (I + 1 == E) 815 lastChild(); 816 dumpAttr(*I); 817 } 818 819 setMoreChildren(HasDeclContext); 820 lastChild(); 821 dumpFullComment(Comment); 822 823 if (D->isInvalidDecl()) 824 OS << " invalid"; 825 826 setMoreChildren(false); 827 if (HasDeclContext) 828 dumpDeclContext(cast<DeclContext>(D)); 829 } 830 831 void ASTDumper::VisitLabelDecl(const LabelDecl *D) { 832 dumpName(D); 833 } 834 835 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 836 dumpName(D); 837 dumpType(D->getUnderlyingType()); 838 if (D->isModulePrivate()) 839 OS << " __module_private__"; 840 } 841 842 void ASTDumper::VisitEnumDecl(const EnumDecl *D) { 843 if (D->isScoped()) { 844 if (D->isScopedUsingClassTag()) 845 OS << " class"; 846 else 847 OS << " struct"; 848 } 849 dumpName(D); 850 if (D->isModulePrivate()) 851 OS << " __module_private__"; 852 if (D->isFixed()) 853 dumpType(D->getIntegerType()); 854 } 855 856 void ASTDumper::VisitRecordDecl(const RecordDecl *D) { 857 OS << ' ' << D->getKindName(); 858 dumpName(D); 859 if (D->isModulePrivate()) 860 OS << " __module_private__"; 861 if (D->isCompleteDefinition()) 862 OS << " definition"; 863 } 864 865 void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 866 dumpName(D); 867 dumpType(D->getType()); 868 if (const Expr *Init = D->getInitExpr()) { 869 lastChild(); 870 dumpStmt(Init); 871 } 872 } 873 874 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 875 dumpName(D); 876 dumpType(D->getType()); 877 878 ChildDumper Children(*this); 879 for (auto *Child : D->chain()) 880 Children.dumpRef(Child); 881 } 882 883 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 884 dumpName(D); 885 dumpType(D->getType()); 886 887 StorageClass SC = D->getStorageClass(); 888 if (SC != SC_None) 889 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 890 if (D->isInlineSpecified()) 891 OS << " inline"; 892 if (D->isVirtualAsWritten()) 893 OS << " virtual"; 894 if (D->isModulePrivate()) 895 OS << " __module_private__"; 896 897 if (D->isPure()) 898 OS << " pure"; 899 else if (D->isDeletedAsWritten()) 900 OS << " delete"; 901 902 if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { 903 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 904 switch (EPI.ExceptionSpecType) { 905 default: break; 906 case EST_Unevaluated: 907 OS << " noexcept-unevaluated " << EPI.ExceptionSpecDecl; 908 break; 909 case EST_Uninstantiated: 910 OS << " noexcept-uninstantiated " << EPI.ExceptionSpecTemplate; 911 break; 912 } 913 } 914 915 bool OldMoreChildren = hasMoreChildren(); 916 const FunctionTemplateSpecializationInfo *FTSI = 917 D->getTemplateSpecializationInfo(); 918 bool HasTemplateSpecialization = FTSI; 919 920 bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() != 921 D->getDeclsInPrototypeScope().end(); 922 923 bool HasFunctionDecls = D->param_begin() != D->param_end(); 924 925 const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D); 926 bool HasCtorInitializers = C && C->init_begin() != C->init_end(); 927 928 bool HasDeclarationBody = D->doesThisDeclarationHaveABody(); 929 930 setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls || 931 HasCtorInitializers || HasDeclarationBody); 932 if (HasTemplateSpecialization) { 933 lastChild(); 934 dumpTemplateArgumentList(*FTSI->TemplateArguments); 935 } 936 937 setMoreChildren(OldMoreChildren || HasFunctionDecls || 938 HasCtorInitializers || HasDeclarationBody); 939 for (ArrayRef<NamedDecl *>::iterator 940 I = D->getDeclsInPrototypeScope().begin(), 941 E = D->getDeclsInPrototypeScope().end(); I != E; ++I) { 942 if (I + 1 == E) 943 lastChild(); 944 dumpDecl(*I); 945 } 946 947 setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody); 948 for (FunctionDecl::param_const_iterator I = D->param_begin(), 949 E = D->param_end(); 950 I != E; ++I) { 951 if (I + 1 == E) 952 lastChild(); 953 dumpDecl(*I); 954 } 955 956 setMoreChildren(OldMoreChildren || HasDeclarationBody); 957 if (HasCtorInitializers) 958 for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 959 E = C->init_end(); 960 I != E; ++I) { 961 if (I + 1 == E) 962 lastChild(); 963 dumpCXXCtorInitializer(*I); 964 } 965 966 setMoreChildren(OldMoreChildren); 967 if (HasDeclarationBody) { 968 lastChild(); 969 dumpStmt(D->getBody()); 970 } 971 } 972 973 void ASTDumper::VisitFieldDecl(const FieldDecl *D) { 974 dumpName(D); 975 dumpType(D->getType()); 976 if (D->isMutable()) 977 OS << " mutable"; 978 if (D->isModulePrivate()) 979 OS << " __module_private__"; 980 981 bool OldMoreChildren = hasMoreChildren(); 982 bool IsBitField = D->isBitField(); 983 Expr *Init = D->getInClassInitializer(); 984 bool HasInit = Init; 985 986 setMoreChildren(OldMoreChildren || HasInit); 987 if (IsBitField) { 988 lastChild(); 989 dumpStmt(D->getBitWidth()); 990 } 991 setMoreChildren(OldMoreChildren); 992 if (HasInit) { 993 lastChild(); 994 dumpStmt(Init); 995 } 996 } 997 998 void ASTDumper::VisitVarDecl(const VarDecl *D) { 999 dumpName(D); 1000 dumpType(D->getType()); 1001 StorageClass SC = D->getStorageClass(); 1002 if (SC != SC_None) 1003 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1004 switch (D->getTLSKind()) { 1005 case VarDecl::TLS_None: break; 1006 case VarDecl::TLS_Static: OS << " tls"; break; 1007 case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 1008 } 1009 if (D->isModulePrivate()) 1010 OS << " __module_private__"; 1011 if (D->isNRVOVariable()) 1012 OS << " nrvo"; 1013 if (D->hasInit()) { 1014 lastChild(); 1015 dumpStmt(D->getInit()); 1016 } 1017 } 1018 1019 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 1020 lastChild(); 1021 dumpStmt(D->getAsmString()); 1022 } 1023 1024 void ASTDumper::VisitImportDecl(const ImportDecl *D) { 1025 OS << ' ' << D->getImportedModule()->getFullModuleName(); 1026 } 1027 1028 //===----------------------------------------------------------------------===// 1029 // C++ Declarations 1030 //===----------------------------------------------------------------------===// 1031 1032 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 1033 dumpName(D); 1034 if (D->isInline()) 1035 OS << " inline"; 1036 if (!D->isOriginalNamespace()) 1037 dumpDeclRef(D->getOriginalNamespace(), "original"); 1038 } 1039 1040 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1041 OS << ' '; 1042 dumpBareDeclRef(D->getNominatedNamespace()); 1043 } 1044 1045 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1046 dumpName(D); 1047 dumpDeclRef(D->getAliasedNamespace()); 1048 } 1049 1050 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1051 dumpName(D); 1052 dumpType(D->getUnderlyingType()); 1053 } 1054 1055 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 1056 dumpName(D); 1057 dumpTemplateParameters(D->getTemplateParameters()); 1058 dumpDecl(D->getTemplatedDecl()); 1059 } 1060 1061 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1062 VisitRecordDecl(D); 1063 if (!D->isCompleteDefinition()) 1064 return; 1065 1066 for (const auto &I : D->bases()) { 1067 IndentScope Indent(*this); 1068 if (I.isVirtual()) 1069 OS << "virtual "; 1070 dumpAccessSpecifier(I.getAccessSpecifier()); 1071 dumpType(I.getType()); 1072 if (I.isPackExpansion()) 1073 OS << "..."; 1074 } 1075 } 1076 1077 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 1078 dumpStmt(D->getAssertExpr()); 1079 lastChild(); 1080 dumpStmt(D->getMessage()); 1081 } 1082 1083 template<typename SpecializationDecl> 1084 void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children, 1085 const SpecializationDecl *D, 1086 bool DumpExplicitInst, 1087 bool DumpRefOnly) { 1088 bool DumpedAny = false; 1089 for (auto *RedeclWithBadType : D->redecls()) { 1090 // FIXME: The redecls() range sometimes has elements of a less-specific 1091 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives 1092 // us TagDecls, and should give CXXRecordDecls). 1093 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); 1094 if (!Redecl) { 1095 // Found the injected-class-name for a class template. This will be dumped 1096 // as part of its surrounding class so we don't need to dump it here. 1097 assert(isa<CXXRecordDecl>(RedeclWithBadType) && 1098 "expected an injected-class-name"); 1099 continue; 1100 } 1101 1102 switch (Redecl->getTemplateSpecializationKind()) { 1103 case TSK_ExplicitInstantiationDeclaration: 1104 case TSK_ExplicitInstantiationDefinition: 1105 if (!DumpExplicitInst) 1106 break; 1107 // Fall through. 1108 case TSK_Undeclared: 1109 case TSK_ImplicitInstantiation: 1110 Children.dump(Redecl, DumpRefOnly); 1111 DumpedAny = true; 1112 break; 1113 case TSK_ExplicitSpecialization: 1114 break; 1115 } 1116 } 1117 1118 // Ensure we dump at least one decl for each specialization. 1119 if (!DumpedAny) 1120 Children.dumpRef(D); 1121 } 1122 1123 template<typename TemplateDecl> 1124 void ASTDumper::VisitTemplateDecl(const TemplateDecl *D, 1125 bool DumpExplicitInst) { 1126 dumpName(D); 1127 dumpTemplateParameters(D->getTemplateParameters()); 1128 1129 ChildDumper Children(*this); 1130 Children.dump(D->getTemplatedDecl()); 1131 1132 for (auto *Child : D->specializations()) 1133 VisitTemplateDeclSpecialization(Children, Child, DumpExplicitInst, 1134 !D->isCanonicalDecl()); 1135 } 1136 1137 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1138 // FIXME: We don't add a declaration of a function template specialization 1139 // to its context when it's explicitly instantiated, so dump explicit 1140 // instantiations when we dump the template itself. 1141 VisitTemplateDecl(D, true); 1142 } 1143 1144 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1145 VisitTemplateDecl(D, false); 1146 } 1147 1148 void ASTDumper::VisitClassTemplateSpecializationDecl( 1149 const ClassTemplateSpecializationDecl *D) { 1150 VisitCXXRecordDecl(D); 1151 dumpTemplateArgumentList(D->getTemplateArgs()); 1152 } 1153 1154 void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1155 const ClassTemplatePartialSpecializationDecl *D) { 1156 VisitClassTemplateSpecializationDecl(D); 1157 dumpTemplateParameters(D->getTemplateParameters()); 1158 } 1159 1160 void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1161 const ClassScopeFunctionSpecializationDecl *D) { 1162 dumpDeclRef(D->getSpecialization()); 1163 if (D->hasExplicitTemplateArgs()) 1164 dumpTemplateArgumentListInfo(D->templateArgs()); 1165 } 1166 1167 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1168 VisitTemplateDecl(D, false); 1169 } 1170 1171 void ASTDumper::VisitVarTemplateSpecializationDecl( 1172 const VarTemplateSpecializationDecl *D) { 1173 dumpTemplateArgumentList(D->getTemplateArgs()); 1174 VisitVarDecl(D); 1175 } 1176 1177 void ASTDumper::VisitVarTemplatePartialSpecializationDecl( 1178 const VarTemplatePartialSpecializationDecl *D) { 1179 dumpTemplateParameters(D->getTemplateParameters()); 1180 VisitVarTemplateSpecializationDecl(D); 1181 } 1182 1183 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1184 if (D->wasDeclaredWithTypename()) 1185 OS << " typename"; 1186 else 1187 OS << " class"; 1188 if (D->isParameterPack()) 1189 OS << " ..."; 1190 dumpName(D); 1191 if (D->hasDefaultArgument()) { 1192 lastChild(); 1193 dumpTemplateArgument(D->getDefaultArgument()); 1194 } 1195 } 1196 1197 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1198 dumpType(D->getType()); 1199 if (D->isParameterPack()) 1200 OS << " ..."; 1201 dumpName(D); 1202 if (D->hasDefaultArgument()) { 1203 lastChild(); 1204 dumpTemplateArgument(D->getDefaultArgument()); 1205 } 1206 } 1207 1208 void ASTDumper::VisitTemplateTemplateParmDecl( 1209 const TemplateTemplateParmDecl *D) { 1210 if (D->isParameterPack()) 1211 OS << " ..."; 1212 dumpName(D); 1213 dumpTemplateParameters(D->getTemplateParameters()); 1214 if (D->hasDefaultArgument()) { 1215 lastChild(); 1216 dumpTemplateArgumentLoc(D->getDefaultArgument()); 1217 } 1218 } 1219 1220 void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1221 OS << ' '; 1222 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1223 OS << D->getNameAsString(); 1224 } 1225 1226 void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1227 const UnresolvedUsingTypenameDecl *D) { 1228 OS << ' '; 1229 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1230 OS << D->getNameAsString(); 1231 } 1232 1233 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1234 OS << ' '; 1235 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1236 OS << D->getNameAsString(); 1237 dumpType(D->getType()); 1238 } 1239 1240 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1241 OS << ' '; 1242 dumpBareDeclRef(D->getTargetDecl()); 1243 } 1244 1245 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1246 switch (D->getLanguage()) { 1247 case LinkageSpecDecl::lang_c: OS << " C"; break; 1248 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1249 } 1250 } 1251 1252 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1253 OS << ' '; 1254 dumpAccessSpecifier(D->getAccess()); 1255 } 1256 1257 void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1258 lastChild(); 1259 if (TypeSourceInfo *T = D->getFriendType()) 1260 dumpType(T->getType()); 1261 else 1262 dumpDecl(D->getFriendDecl()); 1263 } 1264 1265 //===----------------------------------------------------------------------===// 1266 // Obj-C Declarations 1267 //===----------------------------------------------------------------------===// 1268 1269 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1270 dumpName(D); 1271 dumpType(D->getType()); 1272 if (D->getSynthesize()) 1273 OS << " synthesize"; 1274 1275 switch (D->getAccessControl()) { 1276 case ObjCIvarDecl::None: 1277 OS << " none"; 1278 break; 1279 case ObjCIvarDecl::Private: 1280 OS << " private"; 1281 break; 1282 case ObjCIvarDecl::Protected: 1283 OS << " protected"; 1284 break; 1285 case ObjCIvarDecl::Public: 1286 OS << " public"; 1287 break; 1288 case ObjCIvarDecl::Package: 1289 OS << " package"; 1290 break; 1291 } 1292 } 1293 1294 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1295 if (D->isInstanceMethod()) 1296 OS << " -"; 1297 else 1298 OS << " +"; 1299 dumpName(D); 1300 dumpType(D->getReturnType()); 1301 1302 bool OldMoreChildren = hasMoreChildren(); 1303 bool IsVariadic = D->isVariadic(); 1304 bool HasBody = D->hasBody(); 1305 1306 setMoreChildren(OldMoreChildren || IsVariadic || HasBody); 1307 if (D->isThisDeclarationADefinition()) { 1308 lastChild(); 1309 dumpDeclContext(D); 1310 } else { 1311 for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1312 E = D->param_end(); 1313 I != E; ++I) { 1314 if (I + 1 == E) 1315 lastChild(); 1316 dumpDecl(*I); 1317 } 1318 } 1319 1320 setMoreChildren(OldMoreChildren || HasBody); 1321 if (IsVariadic) { 1322 lastChild(); 1323 IndentScope Indent(*this); 1324 OS << "..."; 1325 } 1326 1327 setMoreChildren(OldMoreChildren); 1328 if (HasBody) { 1329 lastChild(); 1330 dumpStmt(D->getBody()); 1331 } 1332 } 1333 1334 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1335 dumpName(D); 1336 dumpDeclRef(D->getClassInterface()); 1337 if (D->protocol_begin() == D->protocol_end()) 1338 lastChild(); 1339 dumpDeclRef(D->getImplementation()); 1340 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1341 E = D->protocol_end(); 1342 I != E; ++I) { 1343 if (I + 1 == E) 1344 lastChild(); 1345 dumpDeclRef(*I); 1346 } 1347 } 1348 1349 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1350 dumpName(D); 1351 dumpDeclRef(D->getClassInterface()); 1352 lastChild(); 1353 dumpDeclRef(D->getCategoryDecl()); 1354 } 1355 1356 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1357 dumpName(D); 1358 1359 ChildDumper Children(*this); 1360 for (auto *Child : D->protocols()) 1361 Children.dumpRef(Child); 1362 } 1363 1364 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1365 dumpName(D); 1366 dumpDeclRef(D->getSuperClass(), "super"); 1367 1368 ChildDumper Children(*this); 1369 Children.dumpRef(D->getImplementation()); 1370 for (auto *Child : D->protocols()) 1371 Children.dumpRef(Child); 1372 } 1373 1374 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1375 dumpName(D); 1376 dumpDeclRef(D->getSuperClass(), "super"); 1377 if (D->init_begin() == D->init_end()) 1378 lastChild(); 1379 dumpDeclRef(D->getClassInterface()); 1380 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1381 E = D->init_end(); 1382 I != E; ++I) { 1383 if (I + 1 == E) 1384 lastChild(); 1385 dumpCXXCtorInitializer(*I); 1386 } 1387 } 1388 1389 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1390 dumpName(D); 1391 lastChild(); 1392 dumpDeclRef(D->getClassInterface()); 1393 } 1394 1395 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1396 dumpName(D); 1397 dumpType(D->getType()); 1398 1399 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1400 OS << " required"; 1401 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1402 OS << " optional"; 1403 1404 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1405 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1406 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1407 OS << " readonly"; 1408 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1409 OS << " assign"; 1410 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1411 OS << " readwrite"; 1412 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1413 OS << " retain"; 1414 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1415 OS << " copy"; 1416 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1417 OS << " nonatomic"; 1418 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1419 OS << " atomic"; 1420 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1421 OS << " weak"; 1422 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1423 OS << " strong"; 1424 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1425 OS << " unsafe_unretained"; 1426 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { 1427 if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) 1428 lastChild(); 1429 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1430 } 1431 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { 1432 lastChild(); 1433 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1434 } 1435 } 1436 } 1437 1438 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1439 dumpName(D->getPropertyDecl()); 1440 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1441 OS << " synthesize"; 1442 else 1443 OS << " dynamic"; 1444 dumpDeclRef(D->getPropertyDecl()); 1445 lastChild(); 1446 dumpDeclRef(D->getPropertyIvarDecl()); 1447 } 1448 1449 void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1450 for (auto I : D->params()) 1451 dumpDecl(I); 1452 1453 if (D->isVariadic()) { 1454 IndentScope Indent(*this); 1455 OS << "..."; 1456 } 1457 1458 if (D->capturesCXXThis()) { 1459 IndentScope Indent(*this); 1460 OS << "capture this"; 1461 } 1462 for (const auto &I : D->captures()) { 1463 IndentScope Indent(*this); 1464 OS << "capture"; 1465 if (I.isByRef()) 1466 OS << " byref"; 1467 if (I.isNested()) 1468 OS << " nested"; 1469 if (I.getVariable()) { 1470 OS << ' '; 1471 dumpBareDeclRef(I.getVariable()); 1472 } 1473 if (I.hasCopyExpr()) 1474 dumpStmt(I.getCopyExpr()); 1475 } 1476 lastChild(); 1477 dumpStmt(D->getBody()); 1478 } 1479 1480 //===----------------------------------------------------------------------===// 1481 // Stmt dumping methods. 1482 //===----------------------------------------------------------------------===// 1483 1484 void ASTDumper::dumpStmt(const Stmt *S) { 1485 IndentScope Indent(*this); 1486 1487 if (!S) { 1488 ColorScope Color(*this, NullColor); 1489 OS << "<<<NULL>>>"; 1490 return; 1491 } 1492 1493 if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1494 VisitDeclStmt(DS); 1495 return; 1496 } 1497 1498 setMoreChildren(!S->children().empty()); 1499 ConstStmtVisitor<ASTDumper>::Visit(S); 1500 setMoreChildren(false); 1501 for (Stmt::const_child_range CI = S->children(); CI; ++CI) { 1502 Stmt::const_child_range Next = CI; 1503 ++Next; 1504 if (!Next) 1505 lastChild(); 1506 dumpStmt(*CI); 1507 } 1508 } 1509 1510 void ASTDumper::VisitStmt(const Stmt *Node) { 1511 { 1512 ColorScope Color(*this, StmtColor); 1513 OS << Node->getStmtClassName(); 1514 } 1515 dumpPointer(Node); 1516 dumpSourceRange(Node->getSourceRange()); 1517 } 1518 1519 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1520 VisitStmt(Node); 1521 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1522 E = Node->decl_end(); 1523 I != E; ++I) { 1524 if (I + 1 == E) 1525 lastChild(); 1526 dumpDecl(*I); 1527 } 1528 } 1529 1530 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1531 VisitStmt(Node); 1532 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1533 E = Node->getAttrs().end(); 1534 I != E; ++I) { 1535 if (I + 1 == E) 1536 lastChild(); 1537 dumpAttr(*I); 1538 } 1539 } 1540 1541 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1542 VisitStmt(Node); 1543 OS << " '" << Node->getName() << "'"; 1544 } 1545 1546 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1547 VisitStmt(Node); 1548 OS << " '" << Node->getLabel()->getName() << "'"; 1549 dumpPointer(Node->getLabel()); 1550 } 1551 1552 void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1553 VisitStmt(Node); 1554 dumpDecl(Node->getExceptionDecl()); 1555 } 1556 1557 //===----------------------------------------------------------------------===// 1558 // Expr dumping methods. 1559 //===----------------------------------------------------------------------===// 1560 1561 void ASTDumper::VisitExpr(const Expr *Node) { 1562 VisitStmt(Node); 1563 dumpType(Node->getType()); 1564 1565 { 1566 ColorScope Color(*this, ValueKindColor); 1567 switch (Node->getValueKind()) { 1568 case VK_RValue: 1569 break; 1570 case VK_LValue: 1571 OS << " lvalue"; 1572 break; 1573 case VK_XValue: 1574 OS << " xvalue"; 1575 break; 1576 } 1577 } 1578 1579 { 1580 ColorScope Color(*this, ObjectKindColor); 1581 switch (Node->getObjectKind()) { 1582 case OK_Ordinary: 1583 break; 1584 case OK_BitField: 1585 OS << " bitfield"; 1586 break; 1587 case OK_ObjCProperty: 1588 OS << " objcproperty"; 1589 break; 1590 case OK_ObjCSubscript: 1591 OS << " objcsubscript"; 1592 break; 1593 case OK_VectorComponent: 1594 OS << " vectorcomponent"; 1595 break; 1596 } 1597 } 1598 } 1599 1600 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1601 if (Node->path_empty()) 1602 return; 1603 1604 OS << " ("; 1605 bool First = true; 1606 for (CastExpr::path_const_iterator I = Node->path_begin(), 1607 E = Node->path_end(); 1608 I != E; ++I) { 1609 const CXXBaseSpecifier *Base = *I; 1610 if (!First) 1611 OS << " -> "; 1612 1613 const CXXRecordDecl *RD = 1614 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1615 1616 if (Base->isVirtual()) 1617 OS << "virtual "; 1618 OS << RD->getName(); 1619 First = false; 1620 } 1621 1622 OS << ')'; 1623 } 1624 1625 void ASTDumper::VisitCastExpr(const CastExpr *Node) { 1626 VisitExpr(Node); 1627 OS << " <"; 1628 { 1629 ColorScope Color(*this, CastColor); 1630 OS << Node->getCastKindName(); 1631 } 1632 dumpBasePath(OS, Node); 1633 OS << ">"; 1634 } 1635 1636 void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1637 VisitExpr(Node); 1638 1639 OS << " "; 1640 dumpBareDeclRef(Node->getDecl()); 1641 if (Node->getDecl() != Node->getFoundDecl()) { 1642 OS << " ("; 1643 dumpBareDeclRef(Node->getFoundDecl()); 1644 OS << ")"; 1645 } 1646 } 1647 1648 void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1649 VisitExpr(Node); 1650 OS << " ("; 1651 if (!Node->requiresADL()) 1652 OS << "no "; 1653 OS << "ADL) = '" << Node->getName() << '\''; 1654 1655 UnresolvedLookupExpr::decls_iterator 1656 I = Node->decls_begin(), E = Node->decls_end(); 1657 if (I == E) 1658 OS << " empty"; 1659 for (; I != E; ++I) 1660 dumpPointer(*I); 1661 } 1662 1663 void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1664 VisitExpr(Node); 1665 1666 { 1667 ColorScope Color(*this, DeclKindNameColor); 1668 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1669 } 1670 OS << "='" << *Node->getDecl() << "'"; 1671 dumpPointer(Node->getDecl()); 1672 if (Node->isFreeIvar()) 1673 OS << " isFreeIvar"; 1674 } 1675 1676 void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1677 VisitExpr(Node); 1678 switch (Node->getIdentType()) { 1679 default: llvm_unreachable("unknown case"); 1680 case PredefinedExpr::Func: OS << " __func__"; break; 1681 case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 1682 case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break; 1683 case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break; 1684 case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 1685 } 1686 } 1687 1688 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1689 VisitExpr(Node); 1690 ColorScope Color(*this, ValueColor); 1691 OS << " " << Node->getValue(); 1692 } 1693 1694 void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1695 VisitExpr(Node); 1696 1697 bool isSigned = Node->getType()->isSignedIntegerType(); 1698 ColorScope Color(*this, ValueColor); 1699 OS << " " << Node->getValue().toString(10, isSigned); 1700 } 1701 1702 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1703 VisitExpr(Node); 1704 ColorScope Color(*this, ValueColor); 1705 OS << " " << Node->getValueAsApproximateDouble(); 1706 } 1707 1708 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1709 VisitExpr(Str); 1710 ColorScope Color(*this, ValueColor); 1711 OS << " "; 1712 Str->outputString(OS); 1713 } 1714 1715 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1716 VisitExpr(Node); 1717 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1718 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1719 } 1720 1721 void ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1722 const UnaryExprOrTypeTraitExpr *Node) { 1723 VisitExpr(Node); 1724 switch(Node->getKind()) { 1725 case UETT_SizeOf: 1726 OS << " sizeof"; 1727 break; 1728 case UETT_AlignOf: 1729 OS << " alignof"; 1730 break; 1731 case UETT_VecStep: 1732 OS << " vec_step"; 1733 break; 1734 } 1735 if (Node->isArgumentType()) 1736 dumpType(Node->getArgumentType()); 1737 } 1738 1739 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1740 VisitExpr(Node); 1741 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1742 dumpPointer(Node->getMemberDecl()); 1743 } 1744 1745 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1746 VisitExpr(Node); 1747 OS << " " << Node->getAccessor().getNameStart(); 1748 } 1749 1750 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1751 VisitExpr(Node); 1752 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1753 } 1754 1755 void ASTDumper::VisitCompoundAssignOperator( 1756 const CompoundAssignOperator *Node) { 1757 VisitExpr(Node); 1758 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1759 << "' ComputeLHSTy="; 1760 dumpBareType(Node->getComputationLHSType()); 1761 OS << " ComputeResultTy="; 1762 dumpBareType(Node->getComputationResultType()); 1763 } 1764 1765 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1766 VisitExpr(Node); 1767 dumpDecl(Node->getBlockDecl()); 1768 } 1769 1770 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1771 VisitExpr(Node); 1772 1773 if (Expr *Source = Node->getSourceExpr()) { 1774 lastChild(); 1775 dumpStmt(Source); 1776 } 1777 } 1778 1779 // GNU extensions. 1780 1781 void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1782 VisitExpr(Node); 1783 OS << " " << Node->getLabel()->getName(); 1784 dumpPointer(Node->getLabel()); 1785 } 1786 1787 //===----------------------------------------------------------------------===// 1788 // C++ Expressions 1789 //===----------------------------------------------------------------------===// 1790 1791 void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1792 VisitExpr(Node); 1793 OS << " " << Node->getCastName() 1794 << "<" << Node->getTypeAsWritten().getAsString() << ">" 1795 << " <" << Node->getCastKindName(); 1796 dumpBasePath(OS, Node); 1797 OS << ">"; 1798 } 1799 1800 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1801 VisitExpr(Node); 1802 OS << " " << (Node->getValue() ? "true" : "false"); 1803 } 1804 1805 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1806 VisitExpr(Node); 1807 OS << " this"; 1808 } 1809 1810 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1811 VisitExpr(Node); 1812 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1813 << " <" << Node->getCastKindName() << ">"; 1814 } 1815 1816 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1817 VisitExpr(Node); 1818 CXXConstructorDecl *Ctor = Node->getConstructor(); 1819 dumpType(Ctor->getType()); 1820 if (Node->isElidable()) 1821 OS << " elidable"; 1822 if (Node->requiresZeroInitialization()) 1823 OS << " zeroing"; 1824 } 1825 1826 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1827 VisitExpr(Node); 1828 OS << " "; 1829 dumpCXXTemporary(Node->getTemporary()); 1830 } 1831 1832 void 1833 ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { 1834 VisitExpr(Node); 1835 if (const ValueDecl *VD = Node->getExtendingDecl()) { 1836 OS << " extended by "; 1837 dumpBareDeclRef(VD); 1838 } 1839 } 1840 1841 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1842 VisitExpr(Node); 1843 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1844 dumpDeclRef(Node->getObject(i), "cleanup"); 1845 } 1846 1847 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1848 OS << "(CXXTemporary"; 1849 dumpPointer(Temporary); 1850 OS << ")"; 1851 } 1852 1853 //===----------------------------------------------------------------------===// 1854 // Obj-C Expressions 1855 //===----------------------------------------------------------------------===// 1856 1857 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1858 VisitExpr(Node); 1859 OS << " selector="; 1860 Node->getSelector().print(OS); 1861 switch (Node->getReceiverKind()) { 1862 case ObjCMessageExpr::Instance: 1863 break; 1864 1865 case ObjCMessageExpr::Class: 1866 OS << " class="; 1867 dumpBareType(Node->getClassReceiver()); 1868 break; 1869 1870 case ObjCMessageExpr::SuperInstance: 1871 OS << " super (instance)"; 1872 break; 1873 1874 case ObjCMessageExpr::SuperClass: 1875 OS << " super (class)"; 1876 break; 1877 } 1878 } 1879 1880 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1881 VisitExpr(Node); 1882 OS << " selector="; 1883 Node->getBoxingMethod()->getSelector().print(OS); 1884 } 1885 1886 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1887 VisitStmt(Node); 1888 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1889 dumpDecl(CatchParam); 1890 else 1891 OS << " catch all"; 1892 } 1893 1894 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1895 VisitExpr(Node); 1896 dumpType(Node->getEncodedType()); 1897 } 1898 1899 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1900 VisitExpr(Node); 1901 1902 OS << " "; 1903 Node->getSelector().print(OS); 1904 } 1905 1906 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1907 VisitExpr(Node); 1908 1909 OS << ' ' << *Node->getProtocol(); 1910 } 1911 1912 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1913 VisitExpr(Node); 1914 if (Node->isImplicitProperty()) { 1915 OS << " Kind=MethodRef Getter=\""; 1916 if (Node->getImplicitPropertyGetter()) 1917 Node->getImplicitPropertyGetter()->getSelector().print(OS); 1918 else 1919 OS << "(null)"; 1920 1921 OS << "\" Setter=\""; 1922 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1923 Setter->getSelector().print(OS); 1924 else 1925 OS << "(null)"; 1926 OS << "\""; 1927 } else { 1928 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 1929 } 1930 1931 if (Node->isSuperReceiver()) 1932 OS << " super"; 1933 1934 OS << " Messaging="; 1935 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1936 OS << "Getter&Setter"; 1937 else if (Node->isMessagingGetter()) 1938 OS << "Getter"; 1939 else if (Node->isMessagingSetter()) 1940 OS << "Setter"; 1941 } 1942 1943 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 1944 VisitExpr(Node); 1945 if (Node->isArraySubscriptRefExpr()) 1946 OS << " Kind=ArraySubscript GetterForArray=\""; 1947 else 1948 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1949 if (Node->getAtIndexMethodDecl()) 1950 Node->getAtIndexMethodDecl()->getSelector().print(OS); 1951 else 1952 OS << "(null)"; 1953 1954 if (Node->isArraySubscriptRefExpr()) 1955 OS << "\" SetterForArray=\""; 1956 else 1957 OS << "\" SetterForDictionary=\""; 1958 if (Node->setAtIndexMethodDecl()) 1959 Node->setAtIndexMethodDecl()->getSelector().print(OS); 1960 else 1961 OS << "(null)"; 1962 } 1963 1964 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1965 VisitExpr(Node); 1966 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1967 } 1968 1969 //===----------------------------------------------------------------------===// 1970 // Comments 1971 //===----------------------------------------------------------------------===// 1972 1973 const char *ASTDumper::getCommandName(unsigned CommandID) { 1974 if (Traits) 1975 return Traits->getCommandInfo(CommandID)->Name; 1976 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 1977 if (Info) 1978 return Info->Name; 1979 return "<not a builtin command>"; 1980 } 1981 1982 void ASTDumper::dumpFullComment(const FullComment *C) { 1983 if (!C) 1984 return; 1985 1986 FC = C; 1987 dumpComment(C); 1988 FC = 0; 1989 } 1990 1991 void ASTDumper::dumpComment(const Comment *C) { 1992 IndentScope Indent(*this); 1993 1994 if (!C) { 1995 ColorScope Color(*this, NullColor); 1996 OS << "<<<NULL>>>"; 1997 return; 1998 } 1999 2000 { 2001 ColorScope Color(*this, CommentColor); 2002 OS << C->getCommentKindName(); 2003 } 2004 dumpPointer(C); 2005 dumpSourceRange(C->getSourceRange()); 2006 ConstCommentVisitor<ASTDumper>::visit(C); 2007 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 2008 I != E; ++I) { 2009 if (I + 1 == E) 2010 lastChild(); 2011 dumpComment(*I); 2012 } 2013 } 2014 2015 void ASTDumper::visitTextComment(const TextComment *C) { 2016 OS << " Text=\"" << C->getText() << "\""; 2017 } 2018 2019 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 2020 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2021 switch (C->getRenderKind()) { 2022 case InlineCommandComment::RenderNormal: 2023 OS << " RenderNormal"; 2024 break; 2025 case InlineCommandComment::RenderBold: 2026 OS << " RenderBold"; 2027 break; 2028 case InlineCommandComment::RenderMonospaced: 2029 OS << " RenderMonospaced"; 2030 break; 2031 case InlineCommandComment::RenderEmphasized: 2032 OS << " RenderEmphasized"; 2033 break; 2034 } 2035 2036 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2037 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2038 } 2039 2040 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 2041 OS << " Name=\"" << C->getTagName() << "\""; 2042 if (C->getNumAttrs() != 0) { 2043 OS << " Attrs: "; 2044 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 2045 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 2046 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 2047 } 2048 } 2049 if (C->isSelfClosing()) 2050 OS << " SelfClosing"; 2051 } 2052 2053 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 2054 OS << " Name=\"" << C->getTagName() << "\""; 2055 } 2056 2057 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 2058 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2059 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2060 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2061 } 2062 2063 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 2064 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 2065 2066 if (C->isDirectionExplicit()) 2067 OS << " explicitly"; 2068 else 2069 OS << " implicitly"; 2070 2071 if (C->hasParamName()) { 2072 if (C->isParamIndexValid()) 2073 OS << " Param=\"" << C->getParamName(FC) << "\""; 2074 else 2075 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2076 } 2077 2078 if (C->isParamIndexValid() && !C->isVarArgParam()) 2079 OS << " ParamIndex=" << C->getParamIndex(); 2080 } 2081 2082 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 2083 if (C->hasParamName()) { 2084 if (C->isPositionValid()) 2085 OS << " Param=\"" << C->getParamName(FC) << "\""; 2086 else 2087 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2088 } 2089 2090 if (C->isPositionValid()) { 2091 OS << " Position=<"; 2092 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 2093 OS << C->getIndex(i); 2094 if (i != e - 1) 2095 OS << ", "; 2096 } 2097 OS << ">"; 2098 } 2099 } 2100 2101 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 2102 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 2103 " CloseName=\"" << C->getCloseName() << "\""; 2104 } 2105 2106 void ASTDumper::visitVerbatimBlockLineComment( 2107 const VerbatimBlockLineComment *C) { 2108 OS << " Text=\"" << C->getText() << "\""; 2109 } 2110 2111 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 2112 OS << " Text=\"" << C->getText() << "\""; 2113 } 2114 2115 //===----------------------------------------------------------------------===// 2116 // Decl method implementations 2117 //===----------------------------------------------------------------------===// 2118 2119 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } 2120 2121 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const { 2122 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 2123 &getASTContext().getSourceManager()); 2124 P.dumpDecl(this); 2125 } 2126 2127 LLVM_DUMP_METHOD void Decl::dumpColor() const { 2128 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 2129 &getASTContext().getSourceManager(), /*ShowColors*/true); 2130 P.dumpDecl(this); 2131 } 2132 2133 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { 2134 dumpLookups(llvm::errs()); 2135 } 2136 2137 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS) const { 2138 const DeclContext *DC = this; 2139 while (!DC->isTranslationUnit()) 2140 DC = DC->getParent(); 2141 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 2142 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); 2143 P.dumpLookups(this); 2144 } 2145 2146 //===----------------------------------------------------------------------===// 2147 // Stmt method implementations 2148 //===----------------------------------------------------------------------===// 2149 2150 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { 2151 dump(llvm::errs(), SM); 2152 } 2153 2154 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 2155 ASTDumper P(OS, 0, &SM); 2156 P.dumpStmt(this); 2157 } 2158 2159 LLVM_DUMP_METHOD void Stmt::dump() const { 2160 ASTDumper P(llvm::errs(), 0, 0); 2161 P.dumpStmt(this); 2162 } 2163 2164 LLVM_DUMP_METHOD void Stmt::dumpColor() const { 2165 ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true); 2166 P.dumpStmt(this); 2167 } 2168 2169 //===----------------------------------------------------------------------===// 2170 // Comment method implementations 2171 //===----------------------------------------------------------------------===// 2172 2173 LLVM_DUMP_METHOD void Comment::dump() const { dump(llvm::errs(), 0, 0); } 2174 2175 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { 2176 dump(llvm::errs(), &Context.getCommentCommandTraits(), 2177 &Context.getSourceManager()); 2178 } 2179 2180 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 2181 const SourceManager *SM) const { 2182 const FullComment *FC = dyn_cast<FullComment>(this); 2183 ASTDumper D(OS, Traits, SM); 2184 D.dumpFullComment(FC); 2185 } 2186 2187 LLVM_DUMP_METHOD void Comment::dumpColor() const { 2188 const FullComment *FC = dyn_cast<FullComment>(this); 2189 ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true); 2190 D.dumpFullComment(FC); 2191 } 2192