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