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