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