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