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