1 //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the AST dump methods, which dump out the 11 // AST in a form that exposes type details and other fields. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Attr.h" 17 #include "clang/AST/CommentVisitor.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/DeclLookups.h" 20 #include "clang/AST/DeclObjC.h" 21 #include "clang/AST/DeclVisitor.h" 22 #include "clang/AST/StmtVisitor.h" 23 #include "clang/Basic/Module.h" 24 #include "clang/Basic/SourceManager.h" 25 #include "llvm/Support/raw_ostream.h" 26 using namespace clang; 27 using namespace clang::comments; 28 29 //===----------------------------------------------------------------------===// 30 // ASTDumper Visitor 31 //===----------------------------------------------------------------------===// 32 33 namespace { 34 // Colors used for various parts of the AST dump 35 // Do not use bold yellow for any text. It is hard to read on white screens. 36 37 struct TerminalColor { 38 raw_ostream::Colors Color; 39 bool Bold; 40 }; 41 42 // Red - CastColor 43 // Green - TypeColor 44 // Bold Green - DeclKindNameColor, UndeserializedColor 45 // Yellow - AddressColor, LocationColor 46 // Blue - CommentColor, NullColor, IndentColor 47 // Bold Blue - AttrColor 48 // Bold Magenta - StmtColor 49 // Cyan - ValueKindColor, ObjectKindColor 50 // Bold Cyan - ValueColor, DeclNameColor 51 52 // Decl kind names (VarDecl, FunctionDecl, etc) 53 static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true }; 54 // Attr names (CleanupAttr, GuardedByAttr, etc) 55 static const TerminalColor AttrColor = { raw_ostream::BLUE, true }; 56 // Statement names (DeclStmt, ImplicitCastExpr, etc) 57 static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true }; 58 // Comment names (FullComment, ParagraphComment, TextComment, etc) 59 static const TerminalColor CommentColor = { raw_ostream::BLUE, false }; 60 61 // Type names (int, float, etc, plus user defined types) 62 static const TerminalColor TypeColor = { raw_ostream::GREEN, false }; 63 64 // Pointer address 65 static const TerminalColor AddressColor = { raw_ostream::YELLOW, false }; 66 // Source locations 67 static const TerminalColor LocationColor = { raw_ostream::YELLOW, false }; 68 69 // lvalue/xvalue 70 static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false }; 71 // bitfield/objcproperty/objcsubscript/vectorcomponent 72 static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false }; 73 74 // Null statements 75 static const TerminalColor NullColor = { raw_ostream::BLUE, false }; 76 77 // Undeserialized entities 78 static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true }; 79 80 // CastKind from CastExpr's 81 static const TerminalColor CastColor = { raw_ostream::RED, false }; 82 83 // Value of the statement 84 static const TerminalColor ValueColor = { raw_ostream::CYAN, true }; 85 // Decl names 86 static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; 87 88 // Indents ( `, -. | ) 89 static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; 90 91 class ASTDumper 92 : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, 93 public ConstCommentVisitor<ASTDumper> { 94 raw_ostream &OS; 95 const CommandTraits *Traits; 96 const SourceManager *SM; 97 bool IsFirstLine; 98 99 // Indicates whether more child are expected at the current tree depth 100 enum IndentType { IT_Child, IT_LastChild }; 101 102 /// Indents[i] indicates if another child exists at level i. 103 /// Used by Indent() to print the tree structure. 104 llvm::SmallVector<IndentType, 32> Indents; 105 106 /// Indicates that more children will be needed at this indent level. 107 /// If true, prevents lastChild() from marking the node as the last child. 108 /// This is used when there are multiple collections of children to be 109 /// dumped as well as during conditional node dumping. 110 bool MoreChildren; 111 112 /// Keep track of the last location we print out so that we can 113 /// print out deltas from then on out. 114 const char *LastLocFilename; 115 unsigned LastLocLine; 116 117 /// The \c FullComment parent of the comment being dumped. 118 const FullComment *FC; 119 120 bool ShowColors; 121 122 class IndentScope { 123 ASTDumper &Dumper; 124 // Preserve the Dumper's MoreChildren value from the previous IndentScope 125 bool MoreChildren; 126 public: 127 IndentScope(ASTDumper &Dumper) : Dumper(Dumper) { 128 MoreChildren = Dumper.hasMoreChildren(); 129 Dumper.setMoreChildren(false); 130 Dumper.indent(); 131 } 132 ~IndentScope() { 133 Dumper.setMoreChildren(MoreChildren); 134 Dumper.unindent(); 135 } 136 }; 137 138 class ColorScope { 139 ASTDumper &Dumper; 140 public: 141 ColorScope(ASTDumper &Dumper, TerminalColor Color) 142 : Dumper(Dumper) { 143 if (Dumper.ShowColors) 144 Dumper.OS.changeColor(Color.Color, Color.Bold); 145 } 146 ~ColorScope() { 147 if (Dumper.ShowColors) 148 Dumper.OS.resetColor(); 149 } 150 }; 151 152 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 " " "`-" 352 void 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 381 void 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. 387 void 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. 394 bool ASTDumper::hasMoreChildren() { 395 return MoreChildren; 396 } 397 398 void ASTDumper::setMoreChildren(bool Value) { 399 MoreChildren = Value; 400 } 401 402 void ASTDumper::dumpPointer(const void *Ptr) { 403 ColorScope Color(*this, AddressColor); 404 OS << ' ' << Ptr; 405 } 406 407 void 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 434 void 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 451 void 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 465 void ASTDumper::dumpType(QualType T) { 466 OS << ' '; 467 dumpBareType(T); 468 } 469 470 void 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 486 void 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 496 void ASTDumper::dumpName(const NamedDecl *ND) { 497 if (ND->getDeclName()) { 498 ColorScope Color(*this, DeclNameColor); 499 OS << ' ' << ND->getNameAsString(); 500 } 501 } 502 503 bool 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 511 void 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 532 void 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 579 void ASTDumper::dumpAttr(const Attr *A) { 580 IndentScope Indent(*this); 581 { 582 ColorScope Color(*this, AttrColor); 583 584 switch (A->getKind()) { 585 #define ATTR(X) case attr::X: OS << #X; break; 586 #include "clang/Basic/AttrList.inc" 587 default: llvm_unreachable("unexpected attribute kind"); 588 } 589 OS << "Attr"; 590 } 591 dumpPointer(A); 592 dumpSourceRange(A->getRange()); 593 #include "clang/AST/AttrDump.inc" 594 if (A->isImplicit()) 595 OS << " Implicit"; 596 } 597 598 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 599 600 template<typename T> 601 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 602 const T *First = D->getFirstDecl(); 603 if (First != D) 604 OS << " first " << First; 605 } 606 607 template<typename T> 608 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 609 const T *Prev = D->getPreviousDecl(); 610 if (Prev) 611 OS << " prev " << Prev; 612 } 613 614 /// Dump the previous declaration in the redeclaration chain for a declaration, 615 /// if any. 616 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 617 switch (D->getKind()) { 618 #define DECL(DERIVED, BASE) \ 619 case Decl::DERIVED: \ 620 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 621 #define ABSTRACT_DECL(DECL) 622 #include "clang/AST/DeclNodes.inc" 623 } 624 llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 625 } 626 627 //===----------------------------------------------------------------------===// 628 // C++ Utilities 629 //===----------------------------------------------------------------------===// 630 631 void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { 632 switch (AS) { 633 case AS_none: 634 break; 635 case AS_public: 636 OS << "public"; 637 break; 638 case AS_protected: 639 OS << "protected"; 640 break; 641 case AS_private: 642 OS << "private"; 643 break; 644 } 645 } 646 647 void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { 648 IndentScope Indent(*this); 649 OS << "CXXCtorInitializer"; 650 if (Init->isAnyMemberInitializer()) { 651 OS << ' '; 652 dumpBareDeclRef(Init->getAnyMember()); 653 } else { 654 dumpType(QualType(Init->getBaseClass(), 0)); 655 } 656 dumpStmt(Init->getInit()); 657 } 658 659 void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { 660 if (!TPL) 661 return; 662 663 for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end(); 664 I != E; ++I) 665 dumpDecl(*I); 666 } 667 668 void ASTDumper::dumpTemplateArgumentListInfo( 669 const TemplateArgumentListInfo &TALI) { 670 for (unsigned i = 0, e = TALI.size(); i < e; ++i) { 671 if (i + 1 == e) 672 lastChild(); 673 dumpTemplateArgumentLoc(TALI[i]); 674 } 675 } 676 677 void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 678 dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 679 } 680 681 void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 682 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 683 dumpTemplateArgument(TAL[i]); 684 } 685 686 void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { 687 IndentScope Indent(*this); 688 OS << "TemplateArgument"; 689 if (R.isValid()) 690 dumpSourceRange(R); 691 692 switch (A.getKind()) { 693 case TemplateArgument::Null: 694 OS << " null"; 695 break; 696 case TemplateArgument::Type: 697 OS << " type"; 698 lastChild(); 699 dumpType(A.getAsType()); 700 break; 701 case TemplateArgument::Declaration: 702 OS << " decl"; 703 lastChild(); 704 dumpDeclRef(A.getAsDecl()); 705 break; 706 case TemplateArgument::NullPtr: 707 OS << " nullptr"; 708 break; 709 case TemplateArgument::Integral: 710 OS << " integral " << A.getAsIntegral(); 711 break; 712 case TemplateArgument::Template: 713 OS << " template "; 714 A.getAsTemplate().dump(OS); 715 break; 716 case TemplateArgument::TemplateExpansion: 717 OS << " template expansion"; 718 A.getAsTemplateOrTemplatePattern().dump(OS); 719 break; 720 case TemplateArgument::Expression: 721 OS << " expr"; 722 lastChild(); 723 dumpStmt(A.getAsExpr()); 724 break; 725 case TemplateArgument::Pack: 726 OS << " pack"; 727 for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); 728 I != E; ++I) { 729 if (I + 1 == E) 730 lastChild(); 731 dumpTemplateArgument(*I); 732 } 733 break; 734 } 735 } 736 737 //===----------------------------------------------------------------------===// 738 // Decl dumping methods. 739 //===----------------------------------------------------------------------===// 740 741 void ASTDumper::dumpDecl(const Decl *D) { 742 IndentScope Indent(*this); 743 744 if (!D) { 745 ColorScope Color(*this, NullColor); 746 OS << "<<<NULL>>>"; 747 return; 748 } 749 750 { 751 ColorScope Color(*this, DeclKindNameColor); 752 OS << D->getDeclKindName() << "Decl"; 753 } 754 dumpPointer(D); 755 if (D->getLexicalDeclContext() != D->getDeclContext()) 756 OS << " parent " << cast<Decl>(D->getDeclContext()); 757 dumpPreviousDecl(OS, D); 758 dumpSourceRange(D->getSourceRange()); 759 if (Module *M = D->getOwningModule()) 760 OS << " in " << M->getFullModuleName(); 761 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 762 if (ND->isHidden()) 763 OS << " hidden"; 764 765 bool HasAttrs = D->attr_begin() != D->attr_end(); 766 const FullComment *Comment = 767 D->getASTContext().getLocalCommentForDeclUncached(D); 768 // Decls within functions are visited by the body 769 bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && 770 hasNodes(dyn_cast<DeclContext>(D)); 771 772 setMoreChildren(HasAttrs || Comment || HasDeclContext); 773 ConstDeclVisitor<ASTDumper>::Visit(D); 774 775 setMoreChildren(Comment || HasDeclContext); 776 for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); 777 I != E; ++I) { 778 if (I + 1 == E) 779 lastChild(); 780 dumpAttr(*I); 781 } 782 783 setMoreChildren(HasDeclContext); 784 lastChild(); 785 dumpFullComment(Comment); 786 787 if (D->isInvalidDecl()) 788 OS << " invalid"; 789 790 setMoreChildren(false); 791 if (HasDeclContext) 792 dumpDeclContext(cast<DeclContext>(D)); 793 } 794 795 void ASTDumper::VisitLabelDecl(const LabelDecl *D) { 796 dumpName(D); 797 } 798 799 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 800 dumpName(D); 801 dumpType(D->getUnderlyingType()); 802 if (D->isModulePrivate()) 803 OS << " __module_private__"; 804 } 805 806 void ASTDumper::VisitEnumDecl(const EnumDecl *D) { 807 if (D->isScoped()) { 808 if (D->isScopedUsingClassTag()) 809 OS << " class"; 810 else 811 OS << " struct"; 812 } 813 dumpName(D); 814 if (D->isModulePrivate()) 815 OS << " __module_private__"; 816 if (D->isFixed()) 817 dumpType(D->getIntegerType()); 818 } 819 820 void ASTDumper::VisitRecordDecl(const RecordDecl *D) { 821 OS << ' ' << D->getKindName(); 822 dumpName(D); 823 if (D->isModulePrivate()) 824 OS << " __module_private__"; 825 if (D->isCompleteDefinition()) 826 OS << " definition"; 827 } 828 829 void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 830 dumpName(D); 831 dumpType(D->getType()); 832 if (const Expr *Init = D->getInitExpr()) { 833 lastChild(); 834 dumpStmt(Init); 835 } 836 } 837 838 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 839 dumpName(D); 840 dumpType(D->getType()); 841 for (IndirectFieldDecl::chain_iterator I = D->chain_begin(), 842 E = D->chain_end(); 843 I != E; ++I) { 844 if (I + 1 == E) 845 lastChild(); 846 dumpDeclRef(*I); 847 } 848 } 849 850 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 851 dumpName(D); 852 dumpType(D->getType()); 853 854 StorageClass SC = D->getStorageClass(); 855 if (SC != SC_None) 856 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 857 if (D->isInlineSpecified()) 858 OS << " inline"; 859 if (D->isVirtualAsWritten()) 860 OS << " virtual"; 861 if (D->isModulePrivate()) 862 OS << " __module_private__"; 863 864 if (D->isPure()) 865 OS << " pure"; 866 else if (D->isDeletedAsWritten()) 867 OS << " delete"; 868 869 if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { 870 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 871 switch (EPI.ExceptionSpecType) { 872 default: break; 873 case EST_Unevaluated: 874 OS << " noexcept-unevaluated " << EPI.ExceptionSpecDecl; 875 break; 876 case EST_Uninstantiated: 877 OS << " noexcept-uninstantiated " << EPI.ExceptionSpecTemplate; 878 break; 879 } 880 } 881 882 bool OldMoreChildren = hasMoreChildren(); 883 const FunctionTemplateSpecializationInfo *FTSI = 884 D->getTemplateSpecializationInfo(); 885 bool HasTemplateSpecialization = FTSI; 886 887 bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() != 888 D->getDeclsInPrototypeScope().end(); 889 890 bool HasFunctionDecls = D->param_begin() != D->param_end(); 891 892 const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D); 893 bool HasCtorInitializers = C && C->init_begin() != C->init_end(); 894 895 bool HasDeclarationBody = D->doesThisDeclarationHaveABody(); 896 897 setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls || 898 HasCtorInitializers || HasDeclarationBody); 899 if (HasTemplateSpecialization) { 900 lastChild(); 901 dumpTemplateArgumentList(*FTSI->TemplateArguments); 902 } 903 904 setMoreChildren(OldMoreChildren || HasFunctionDecls || 905 HasCtorInitializers || HasDeclarationBody); 906 for (ArrayRef<NamedDecl *>::iterator 907 I = D->getDeclsInPrototypeScope().begin(), 908 E = D->getDeclsInPrototypeScope().end(); I != E; ++I) { 909 if (I + 1 == E) 910 lastChild(); 911 dumpDecl(*I); 912 } 913 914 setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody); 915 for (FunctionDecl::param_const_iterator I = D->param_begin(), 916 E = D->param_end(); 917 I != E; ++I) { 918 if (I + 1 == E) 919 lastChild(); 920 dumpDecl(*I); 921 } 922 923 setMoreChildren(OldMoreChildren || HasDeclarationBody); 924 if (HasCtorInitializers) 925 for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 926 E = C->init_end(); 927 I != E; ++I) { 928 if (I + 1 == E) 929 lastChild(); 930 dumpCXXCtorInitializer(*I); 931 } 932 933 setMoreChildren(OldMoreChildren); 934 if (HasDeclarationBody) { 935 lastChild(); 936 dumpStmt(D->getBody()); 937 } 938 } 939 940 void ASTDumper::VisitFieldDecl(const FieldDecl *D) { 941 dumpName(D); 942 dumpType(D->getType()); 943 if (D->isMutable()) 944 OS << " mutable"; 945 if (D->isModulePrivate()) 946 OS << " __module_private__"; 947 948 bool OldMoreChildren = hasMoreChildren(); 949 bool IsBitField = D->isBitField(); 950 Expr *Init = D->getInClassInitializer(); 951 bool HasInit = Init; 952 953 setMoreChildren(OldMoreChildren || HasInit); 954 if (IsBitField) { 955 lastChild(); 956 dumpStmt(D->getBitWidth()); 957 } 958 setMoreChildren(OldMoreChildren); 959 if (HasInit) { 960 lastChild(); 961 dumpStmt(Init); 962 } 963 } 964 965 void ASTDumper::VisitVarDecl(const VarDecl *D) { 966 dumpName(D); 967 dumpType(D->getType()); 968 StorageClass SC = D->getStorageClass(); 969 if (SC != SC_None) 970 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 971 switch (D->getTLSKind()) { 972 case VarDecl::TLS_None: break; 973 case VarDecl::TLS_Static: OS << " tls"; break; 974 case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 975 } 976 if (D->isModulePrivate()) 977 OS << " __module_private__"; 978 if (D->isNRVOVariable()) 979 OS << " nrvo"; 980 if (D->hasInit()) { 981 lastChild(); 982 dumpStmt(D->getInit()); 983 } 984 } 985 986 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 987 lastChild(); 988 dumpStmt(D->getAsmString()); 989 } 990 991 void ASTDumper::VisitImportDecl(const ImportDecl *D) { 992 OS << ' ' << D->getImportedModule()->getFullModuleName(); 993 } 994 995 //===----------------------------------------------------------------------===// 996 // C++ Declarations 997 //===----------------------------------------------------------------------===// 998 999 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 1000 dumpName(D); 1001 if (D->isInline()) 1002 OS << " inline"; 1003 if (!D->isOriginalNamespace()) 1004 dumpDeclRef(D->getOriginalNamespace(), "original"); 1005 } 1006 1007 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1008 OS << ' '; 1009 dumpBareDeclRef(D->getNominatedNamespace()); 1010 } 1011 1012 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1013 dumpName(D); 1014 dumpDeclRef(D->getAliasedNamespace()); 1015 } 1016 1017 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1018 dumpName(D); 1019 dumpType(D->getUnderlyingType()); 1020 } 1021 1022 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 1023 dumpName(D); 1024 dumpTemplateParameters(D->getTemplateParameters()); 1025 dumpDecl(D->getTemplatedDecl()); 1026 } 1027 1028 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1029 VisitRecordDecl(D); 1030 if (!D->isCompleteDefinition()) 1031 return; 1032 1033 for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(), 1034 E = D->bases_end(); 1035 I != E; ++I) { 1036 IndentScope Indent(*this); 1037 if (I->isVirtual()) 1038 OS << "virtual "; 1039 dumpAccessSpecifier(I->getAccessSpecifier()); 1040 dumpType(I->getType()); 1041 if (I->isPackExpansion()) 1042 OS << "..."; 1043 } 1044 } 1045 1046 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 1047 dumpStmt(D->getAssertExpr()); 1048 lastChild(); 1049 dumpStmt(D->getMessage()); 1050 } 1051 1052 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1053 dumpName(D); 1054 dumpTemplateParameters(D->getTemplateParameters()); 1055 dumpDecl(D->getTemplatedDecl()); 1056 for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), 1057 E = D->spec_end(); 1058 I != E; ++I) { 1059 FunctionTemplateDecl::spec_iterator Next = I; 1060 ++Next; 1061 if (Next == E) 1062 lastChild(); 1063 switch (I->getTemplateSpecializationKind()) { 1064 case TSK_Undeclared: 1065 case TSK_ImplicitInstantiation: 1066 case TSK_ExplicitInstantiationDeclaration: 1067 case TSK_ExplicitInstantiationDefinition: 1068 if (D == D->getCanonicalDecl()) 1069 dumpDecl(*I); 1070 else 1071 dumpDeclRef(*I); 1072 break; 1073 case TSK_ExplicitSpecialization: 1074 dumpDeclRef(*I); 1075 break; 1076 } 1077 } 1078 } 1079 1080 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1081 dumpName(D); 1082 dumpTemplateParameters(D->getTemplateParameters()); 1083 1084 ClassTemplateDecl::spec_iterator I = D->spec_begin(); 1085 ClassTemplateDecl::spec_iterator E = D->spec_end(); 1086 if (I == E) 1087 lastChild(); 1088 dumpDecl(D->getTemplatedDecl()); 1089 for (; I != E; ++I) { 1090 ClassTemplateDecl::spec_iterator Next = I; 1091 ++Next; 1092 if (Next == E) 1093 lastChild(); 1094 switch (I->getTemplateSpecializationKind()) { 1095 case TSK_Undeclared: 1096 case TSK_ImplicitInstantiation: 1097 if (D == D->getCanonicalDecl()) 1098 dumpDecl(*I); 1099 else 1100 dumpDeclRef(*I); 1101 break; 1102 case TSK_ExplicitSpecialization: 1103 case TSK_ExplicitInstantiationDeclaration: 1104 case TSK_ExplicitInstantiationDefinition: 1105 dumpDeclRef(*I); 1106 break; 1107 } 1108 } 1109 } 1110 1111 void ASTDumper::VisitClassTemplateSpecializationDecl( 1112 const ClassTemplateSpecializationDecl *D) { 1113 VisitCXXRecordDecl(D); 1114 dumpTemplateArgumentList(D->getTemplateArgs()); 1115 } 1116 1117 void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1118 const ClassTemplatePartialSpecializationDecl *D) { 1119 VisitClassTemplateSpecializationDecl(D); 1120 dumpTemplateParameters(D->getTemplateParameters()); 1121 } 1122 1123 void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1124 const ClassScopeFunctionSpecializationDecl *D) { 1125 dumpDeclRef(D->getSpecialization()); 1126 if (D->hasExplicitTemplateArgs()) 1127 dumpTemplateArgumentListInfo(D->templateArgs()); 1128 } 1129 1130 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1131 dumpName(D); 1132 dumpTemplateParameters(D->getTemplateParameters()); 1133 1134 VarTemplateDecl::spec_iterator I = D->spec_begin(); 1135 VarTemplateDecl::spec_iterator E = D->spec_end(); 1136 if (I == E) 1137 lastChild(); 1138 dumpDecl(D->getTemplatedDecl()); 1139 for (; I != E; ++I) { 1140 VarTemplateDecl::spec_iterator Next = I; 1141 ++Next; 1142 if (Next == E) 1143 lastChild(); 1144 switch (I->getTemplateSpecializationKind()) { 1145 case TSK_Undeclared: 1146 case TSK_ImplicitInstantiation: 1147 if (D == D->getCanonicalDecl()) 1148 dumpDecl(*I); 1149 else 1150 dumpDeclRef(*I); 1151 break; 1152 case TSK_ExplicitSpecialization: 1153 case TSK_ExplicitInstantiationDeclaration: 1154 case TSK_ExplicitInstantiationDefinition: 1155 dumpDeclRef(*I); 1156 break; 1157 } 1158 } 1159 } 1160 1161 void ASTDumper::VisitVarTemplateSpecializationDecl( 1162 const VarTemplateSpecializationDecl *D) { 1163 dumpTemplateArgumentList(D->getTemplateArgs()); 1164 VisitVarDecl(D); 1165 } 1166 1167 void ASTDumper::VisitVarTemplatePartialSpecializationDecl( 1168 const VarTemplatePartialSpecializationDecl *D) { 1169 dumpTemplateParameters(D->getTemplateParameters()); 1170 VisitVarTemplateSpecializationDecl(D); 1171 } 1172 1173 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1174 if (D->wasDeclaredWithTypename()) 1175 OS << " typename"; 1176 else 1177 OS << " class"; 1178 if (D->isParameterPack()) 1179 OS << " ..."; 1180 dumpName(D); 1181 if (D->hasDefaultArgument()) 1182 dumpType(D->getDefaultArgument()); 1183 } 1184 1185 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1186 dumpType(D->getType()); 1187 if (D->isParameterPack()) 1188 OS << " ..."; 1189 dumpName(D); 1190 if (D->hasDefaultArgument()) 1191 dumpStmt(D->getDefaultArgument()); 1192 } 1193 1194 void ASTDumper::VisitTemplateTemplateParmDecl( 1195 const TemplateTemplateParmDecl *D) { 1196 if (D->isParameterPack()) 1197 OS << " ..."; 1198 dumpName(D); 1199 dumpTemplateParameters(D->getTemplateParameters()); 1200 if (D->hasDefaultArgument()) 1201 dumpTemplateArgumentLoc(D->getDefaultArgument()); 1202 } 1203 1204 void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1205 OS << ' '; 1206 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1207 OS << D->getNameAsString(); 1208 } 1209 1210 void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1211 const UnresolvedUsingTypenameDecl *D) { 1212 OS << ' '; 1213 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1214 OS << D->getNameAsString(); 1215 } 1216 1217 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1218 OS << ' '; 1219 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1220 OS << D->getNameAsString(); 1221 dumpType(D->getType()); 1222 } 1223 1224 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1225 OS << ' '; 1226 dumpBareDeclRef(D->getTargetDecl()); 1227 } 1228 1229 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1230 switch (D->getLanguage()) { 1231 case LinkageSpecDecl::lang_c: OS << " C"; break; 1232 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1233 } 1234 } 1235 1236 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1237 OS << ' '; 1238 dumpAccessSpecifier(D->getAccess()); 1239 } 1240 1241 void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1242 lastChild(); 1243 if (TypeSourceInfo *T = D->getFriendType()) 1244 dumpType(T->getType()); 1245 else 1246 dumpDecl(D->getFriendDecl()); 1247 } 1248 1249 //===----------------------------------------------------------------------===// 1250 // Obj-C Declarations 1251 //===----------------------------------------------------------------------===// 1252 1253 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1254 dumpName(D); 1255 dumpType(D->getType()); 1256 if (D->getSynthesize()) 1257 OS << " synthesize"; 1258 1259 switch (D->getAccessControl()) { 1260 case ObjCIvarDecl::None: 1261 OS << " none"; 1262 break; 1263 case ObjCIvarDecl::Private: 1264 OS << " private"; 1265 break; 1266 case ObjCIvarDecl::Protected: 1267 OS << " protected"; 1268 break; 1269 case ObjCIvarDecl::Public: 1270 OS << " public"; 1271 break; 1272 case ObjCIvarDecl::Package: 1273 OS << " package"; 1274 break; 1275 } 1276 } 1277 1278 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1279 if (D->isInstanceMethod()) 1280 OS << " -"; 1281 else 1282 OS << " +"; 1283 dumpName(D); 1284 dumpType(D->getReturnType()); 1285 1286 bool OldMoreChildren = hasMoreChildren(); 1287 bool IsVariadic = D->isVariadic(); 1288 bool HasBody = D->hasBody(); 1289 1290 setMoreChildren(OldMoreChildren || IsVariadic || HasBody); 1291 if (D->isThisDeclarationADefinition()) { 1292 lastChild(); 1293 dumpDeclContext(D); 1294 } else { 1295 for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1296 E = D->param_end(); 1297 I != E; ++I) { 1298 if (I + 1 == E) 1299 lastChild(); 1300 dumpDecl(*I); 1301 } 1302 } 1303 1304 setMoreChildren(OldMoreChildren || HasBody); 1305 if (IsVariadic) { 1306 lastChild(); 1307 IndentScope Indent(*this); 1308 OS << "..."; 1309 } 1310 1311 setMoreChildren(OldMoreChildren); 1312 if (HasBody) { 1313 lastChild(); 1314 dumpStmt(D->getBody()); 1315 } 1316 } 1317 1318 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1319 dumpName(D); 1320 dumpDeclRef(D->getClassInterface()); 1321 if (D->protocol_begin() == D->protocol_end()) 1322 lastChild(); 1323 dumpDeclRef(D->getImplementation()); 1324 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1325 E = D->protocol_end(); 1326 I != E; ++I) { 1327 if (I + 1 == E) 1328 lastChild(); 1329 dumpDeclRef(*I); 1330 } 1331 } 1332 1333 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1334 dumpName(D); 1335 dumpDeclRef(D->getClassInterface()); 1336 lastChild(); 1337 dumpDeclRef(D->getCategoryDecl()); 1338 } 1339 1340 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1341 dumpName(D); 1342 for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), 1343 E = D->protocol_end(); 1344 I != E; ++I) { 1345 if (I + 1 == E) 1346 lastChild(); 1347 dumpDeclRef(*I); 1348 } 1349 } 1350 1351 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1352 dumpName(D); 1353 dumpDeclRef(D->getSuperClass(), "super"); 1354 if (D->protocol_begin() == D->protocol_end()) 1355 lastChild(); 1356 dumpDeclRef(D->getImplementation()); 1357 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 1358 E = D->protocol_end(); 1359 I != E; ++I) { 1360 if (I + 1 == E) 1361 lastChild(); 1362 dumpDeclRef(*I); 1363 } 1364 } 1365 1366 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1367 dumpName(D); 1368 dumpDeclRef(D->getSuperClass(), "super"); 1369 if (D->init_begin() == D->init_end()) 1370 lastChild(); 1371 dumpDeclRef(D->getClassInterface()); 1372 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1373 E = D->init_end(); 1374 I != E; ++I) { 1375 if (I + 1 == E) 1376 lastChild(); 1377 dumpCXXCtorInitializer(*I); 1378 } 1379 } 1380 1381 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1382 dumpName(D); 1383 lastChild(); 1384 dumpDeclRef(D->getClassInterface()); 1385 } 1386 1387 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1388 dumpName(D); 1389 dumpType(D->getType()); 1390 1391 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1392 OS << " required"; 1393 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1394 OS << " optional"; 1395 1396 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1397 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1398 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1399 OS << " readonly"; 1400 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1401 OS << " assign"; 1402 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1403 OS << " readwrite"; 1404 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1405 OS << " retain"; 1406 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1407 OS << " copy"; 1408 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1409 OS << " nonatomic"; 1410 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1411 OS << " atomic"; 1412 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1413 OS << " weak"; 1414 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1415 OS << " strong"; 1416 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1417 OS << " unsafe_unretained"; 1418 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { 1419 if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) 1420 lastChild(); 1421 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1422 } 1423 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { 1424 lastChild(); 1425 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1426 } 1427 } 1428 } 1429 1430 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1431 dumpName(D->getPropertyDecl()); 1432 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1433 OS << " synthesize"; 1434 else 1435 OS << " dynamic"; 1436 dumpDeclRef(D->getPropertyDecl()); 1437 lastChild(); 1438 dumpDeclRef(D->getPropertyIvarDecl()); 1439 } 1440 1441 void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1442 for (auto I : D->params()) 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 1477 void 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 1503 void 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 1512 void 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 1523 void 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 1534 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1535 VisitStmt(Node); 1536 OS << " '" << Node->getName() << "'"; 1537 } 1538 1539 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1540 VisitStmt(Node); 1541 OS << " '" << Node->getLabel()->getName() << "'"; 1542 dumpPointer(Node->getLabel()); 1543 } 1544 1545 void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1546 VisitStmt(Node); 1547 dumpDecl(Node->getExceptionDecl()); 1548 } 1549 1550 //===----------------------------------------------------------------------===// 1551 // Expr dumping methods. 1552 //===----------------------------------------------------------------------===// 1553 1554 void 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 1593 static 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 1618 void 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 1629 void 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 1641 void 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 1656 void 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 1669 void 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 1681 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1682 VisitExpr(Node); 1683 ColorScope Color(*this, ValueColor); 1684 OS << " " << Node->getValue(); 1685 } 1686 1687 void 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 1695 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1696 VisitExpr(Node); 1697 ColorScope Color(*this, ValueColor); 1698 OS << " " << Node->getValueAsApproximateDouble(); 1699 } 1700 1701 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1702 VisitExpr(Str); 1703 ColorScope Color(*this, ValueColor); 1704 OS << " "; 1705 Str->outputString(OS); 1706 } 1707 1708 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1709 VisitExpr(Node); 1710 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1711 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1712 } 1713 1714 void 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 1732 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1733 VisitExpr(Node); 1734 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1735 dumpPointer(Node->getMemberDecl()); 1736 } 1737 1738 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1739 VisitExpr(Node); 1740 OS << " " << Node->getAccessor().getNameStart(); 1741 } 1742 1743 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1744 VisitExpr(Node); 1745 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1746 } 1747 1748 void 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 1758 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1759 VisitExpr(Node); 1760 dumpDecl(Node->getBlockDecl()); 1761 } 1762 1763 void 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 1774 void 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 1784 void 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 1793 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1794 VisitExpr(Node); 1795 OS << " " << (Node->getValue() ? "true" : "false"); 1796 } 1797 1798 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1799 VisitExpr(Node); 1800 OS << " this"; 1801 } 1802 1803 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1804 VisitExpr(Node); 1805 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1806 << " <" << Node->getCastKindName() << ">"; 1807 } 1808 1809 void 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 1819 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1820 VisitExpr(Node); 1821 OS << " "; 1822 dumpCXXTemporary(Node->getTemporary()); 1823 } 1824 1825 void 1826 ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { 1827 VisitExpr(Node); 1828 if (const ValueDecl *VD = Node->getExtendingDecl()) { 1829 OS << " extended by "; 1830 dumpBareDeclRef(VD); 1831 } 1832 } 1833 1834 void 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 1840 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1841 OS << "(CXXTemporary"; 1842 dumpPointer(Temporary); 1843 OS << ")"; 1844 } 1845 1846 //===----------------------------------------------------------------------===// 1847 // Obj-C Expressions 1848 //===----------------------------------------------------------------------===// 1849 1850 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1851 VisitExpr(Node); 1852 OS << " selector="; 1853 Node->getSelector().print(OS); 1854 switch (Node->getReceiverKind()) { 1855 case ObjCMessageExpr::Instance: 1856 break; 1857 1858 case ObjCMessageExpr::Class: 1859 OS << " class="; 1860 dumpBareType(Node->getClassReceiver()); 1861 break; 1862 1863 case ObjCMessageExpr::SuperInstance: 1864 OS << " super (instance)"; 1865 break; 1866 1867 case ObjCMessageExpr::SuperClass: 1868 OS << " super (class)"; 1869 break; 1870 } 1871 } 1872 1873 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1874 VisitExpr(Node); 1875 OS << " selector="; 1876 Node->getBoxingMethod()->getSelector().print(OS); 1877 } 1878 1879 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1880 VisitStmt(Node); 1881 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1882 dumpDecl(CatchParam); 1883 else 1884 OS << " catch all"; 1885 } 1886 1887 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1888 VisitExpr(Node); 1889 dumpType(Node->getEncodedType()); 1890 } 1891 1892 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1893 VisitExpr(Node); 1894 1895 OS << " "; 1896 Node->getSelector().print(OS); 1897 } 1898 1899 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1900 VisitExpr(Node); 1901 1902 OS << ' ' << *Node->getProtocol(); 1903 } 1904 1905 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1906 VisitExpr(Node); 1907 if (Node->isImplicitProperty()) { 1908 OS << " Kind=MethodRef Getter=\""; 1909 if (Node->getImplicitPropertyGetter()) 1910 Node->getImplicitPropertyGetter()->getSelector().print(OS); 1911 else 1912 OS << "(null)"; 1913 1914 OS << "\" Setter=\""; 1915 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1916 Setter->getSelector().print(OS); 1917 else 1918 OS << "(null)"; 1919 OS << "\""; 1920 } else { 1921 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 1922 } 1923 1924 if (Node->isSuperReceiver()) 1925 OS << " super"; 1926 1927 OS << " Messaging="; 1928 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1929 OS << "Getter&Setter"; 1930 else if (Node->isMessagingGetter()) 1931 OS << "Getter"; 1932 else if (Node->isMessagingSetter()) 1933 OS << "Setter"; 1934 } 1935 1936 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 1937 VisitExpr(Node); 1938 if (Node->isArraySubscriptRefExpr()) 1939 OS << " Kind=ArraySubscript GetterForArray=\""; 1940 else 1941 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1942 if (Node->getAtIndexMethodDecl()) 1943 Node->getAtIndexMethodDecl()->getSelector().print(OS); 1944 else 1945 OS << "(null)"; 1946 1947 if (Node->isArraySubscriptRefExpr()) 1948 OS << "\" SetterForArray=\""; 1949 else 1950 OS << "\" SetterForDictionary=\""; 1951 if (Node->setAtIndexMethodDecl()) 1952 Node->setAtIndexMethodDecl()->getSelector().print(OS); 1953 else 1954 OS << "(null)"; 1955 } 1956 1957 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1958 VisitExpr(Node); 1959 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1960 } 1961 1962 //===----------------------------------------------------------------------===// 1963 // Comments 1964 //===----------------------------------------------------------------------===// 1965 1966 const char *ASTDumper::getCommandName(unsigned CommandID) { 1967 if (Traits) 1968 return Traits->getCommandInfo(CommandID)->Name; 1969 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 1970 if (Info) 1971 return Info->Name; 1972 return "<not a builtin command>"; 1973 } 1974 1975 void ASTDumper::dumpFullComment(const FullComment *C) { 1976 if (!C) 1977 return; 1978 1979 FC = C; 1980 dumpComment(C); 1981 FC = 0; 1982 } 1983 1984 void ASTDumper::dumpComment(const Comment *C) { 1985 IndentScope Indent(*this); 1986 1987 if (!C) { 1988 ColorScope Color(*this, NullColor); 1989 OS << "<<<NULL>>>"; 1990 return; 1991 } 1992 1993 { 1994 ColorScope Color(*this, CommentColor); 1995 OS << C->getCommentKindName(); 1996 } 1997 dumpPointer(C); 1998 dumpSourceRange(C->getSourceRange()); 1999 ConstCommentVisitor<ASTDumper>::visit(C); 2000 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 2001 I != E; ++I) { 2002 if (I + 1 == E) 2003 lastChild(); 2004 dumpComment(*I); 2005 } 2006 } 2007 2008 void ASTDumper::visitTextComment(const TextComment *C) { 2009 OS << " Text=\"" << C->getText() << "\""; 2010 } 2011 2012 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 2013 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2014 switch (C->getRenderKind()) { 2015 case InlineCommandComment::RenderNormal: 2016 OS << " RenderNormal"; 2017 break; 2018 case InlineCommandComment::RenderBold: 2019 OS << " RenderBold"; 2020 break; 2021 case InlineCommandComment::RenderMonospaced: 2022 OS << " RenderMonospaced"; 2023 break; 2024 case InlineCommandComment::RenderEmphasized: 2025 OS << " RenderEmphasized"; 2026 break; 2027 } 2028 2029 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2030 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2031 } 2032 2033 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 2034 OS << " Name=\"" << C->getTagName() << "\""; 2035 if (C->getNumAttrs() != 0) { 2036 OS << " Attrs: "; 2037 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 2038 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 2039 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 2040 } 2041 } 2042 if (C->isSelfClosing()) 2043 OS << " SelfClosing"; 2044 } 2045 2046 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 2047 OS << " Name=\"" << C->getTagName() << "\""; 2048 } 2049 2050 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 2051 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2052 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2053 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2054 } 2055 2056 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 2057 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 2058 2059 if (C->isDirectionExplicit()) 2060 OS << " explicitly"; 2061 else 2062 OS << " implicitly"; 2063 2064 if (C->hasParamName()) { 2065 if (C->isParamIndexValid()) 2066 OS << " Param=\"" << C->getParamName(FC) << "\""; 2067 else 2068 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2069 } 2070 2071 if (C->isParamIndexValid()) 2072 OS << " ParamIndex=" << C->getParamIndex(); 2073 } 2074 2075 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 2076 if (C->hasParamName()) { 2077 if (C->isPositionValid()) 2078 OS << " Param=\"" << C->getParamName(FC) << "\""; 2079 else 2080 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2081 } 2082 2083 if (C->isPositionValid()) { 2084 OS << " Position=<"; 2085 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 2086 OS << C->getIndex(i); 2087 if (i != e - 1) 2088 OS << ", "; 2089 } 2090 OS << ">"; 2091 } 2092 } 2093 2094 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 2095 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 2096 " CloseName=\"" << C->getCloseName() << "\""; 2097 } 2098 2099 void ASTDumper::visitVerbatimBlockLineComment( 2100 const VerbatimBlockLineComment *C) { 2101 OS << " Text=\"" << C->getText() << "\""; 2102 } 2103 2104 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 2105 OS << " Text=\"" << C->getText() << "\""; 2106 } 2107 2108 //===----------------------------------------------------------------------===// 2109 // Decl method implementations 2110 //===----------------------------------------------------------------------===// 2111 2112 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } 2113 2114 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const { 2115 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 2116 &getASTContext().getSourceManager()); 2117 P.dumpDecl(this); 2118 } 2119 2120 LLVM_DUMP_METHOD void Decl::dumpColor() const { 2121 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 2122 &getASTContext().getSourceManager(), /*ShowColors*/true); 2123 P.dumpDecl(this); 2124 } 2125 2126 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { 2127 dumpLookups(llvm::errs()); 2128 } 2129 2130 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS) const { 2131 const DeclContext *DC = this; 2132 while (!DC->isTranslationUnit()) 2133 DC = DC->getParent(); 2134 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 2135 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); 2136 P.dumpLookups(this); 2137 } 2138 2139 //===----------------------------------------------------------------------===// 2140 // Stmt method implementations 2141 //===----------------------------------------------------------------------===// 2142 2143 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { 2144 dump(llvm::errs(), SM); 2145 } 2146 2147 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 2148 ASTDumper P(OS, 0, &SM); 2149 P.dumpStmt(this); 2150 } 2151 2152 LLVM_DUMP_METHOD void Stmt::dump() const { 2153 ASTDumper P(llvm::errs(), 0, 0); 2154 P.dumpStmt(this); 2155 } 2156 2157 LLVM_DUMP_METHOD void Stmt::dumpColor() const { 2158 ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true); 2159 P.dumpStmt(this); 2160 } 2161 2162 //===----------------------------------------------------------------------===// 2163 // Comment method implementations 2164 //===----------------------------------------------------------------------===// 2165 2166 LLVM_DUMP_METHOD void Comment::dump() const { dump(llvm::errs(), 0, 0); } 2167 2168 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { 2169 dump(llvm::errs(), &Context.getCommentCommandTraits(), 2170 &Context.getSourceManager()); 2171 } 2172 2173 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 2174 const SourceManager *SM) const { 2175 const FullComment *FC = dyn_cast<FullComment>(this); 2176 ASTDumper D(OS, Traits, SM); 2177 D.dumpFullComment(FC); 2178 } 2179 2180 LLVM_DUMP_METHOD void Comment::dumpColor() const { 2181 const FullComment *FC = dyn_cast<FullComment>(this); 2182 ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true); 2183 D.dumpFullComment(FC); 2184 } 2185