StmtDumper.cpp revision dc355713be51fcb4ee52d9fd6b4548ceff47fadf
1//===--- StmtDumper.cpp - Dumping implementation for Stmt 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 Stmt::dump/Stmt::print methods, which dump out the 11// AST in a form that exposes type details and other fields. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/AST/StmtVisitor.h" 16#include "clang/AST/DeclObjC.h" 17#include "clang/AST/DeclCXX.h" 18#include "clang/AST/PrettyPrinter.h" 19#include "clang/Basic/SourceManager.h" 20#include "llvm/Support/raw_ostream.h" 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// StmtDumper Visitor 25//===----------------------------------------------------------------------===// 26 27namespace { 28 class StmtDumper : public StmtVisitor<StmtDumper> { 29 SourceManager *SM; 30 llvm::raw_ostream &OS; 31 unsigned IndentLevel; 32 33 /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump 34 /// the first few levels of an AST. This keeps track of how many ast levels 35 /// are left. 36 unsigned MaxDepth; 37 38 /// LastLocFilename/LastLocLine - Keep track of the last location we print 39 /// out so that we can print out deltas from then on out. 40 const char *LastLocFilename; 41 unsigned LastLocLine; 42 43 public: 44 StmtDumper(SourceManager *sm, llvm::raw_ostream &os, unsigned maxDepth) 45 : SM(sm), OS(os), IndentLevel(0-1), MaxDepth(maxDepth) { 46 LastLocFilename = ""; 47 LastLocLine = ~0U; 48 } 49 50 void DumpSubTree(Stmt *S) { 51 // Prune the recursion if not using dump all. 52 if (MaxDepth == 0) return; 53 54 ++IndentLevel; 55 if (S) { 56 if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) 57 VisitDeclStmt(DS); 58 else { 59 Visit(S); 60 61 // Print out children. 62 Stmt::child_range CI = S->children(); 63 if (CI) { 64 while (CI) { 65 OS << '\n'; 66 DumpSubTree(*CI++); 67 } 68 } 69 } 70 OS << ')'; 71 } else { 72 Indent(); 73 OS << "<<<NULL>>>"; 74 } 75 --IndentLevel; 76 } 77 78 void DumpDeclarator(Decl *D); 79 80 void Indent() const { 81 for (int i = 0, e = IndentLevel; i < e; ++i) 82 OS << " "; 83 } 84 85 void DumpType(QualType T) { 86 SplitQualType T_split = T.split(); 87 OS << "'" << QualType::getAsString(T_split) << "'"; 88 89 if (!T.isNull()) { 90 // If the type is sugared, also dump a (shallow) desugared type. 91 SplitQualType D_split = T.getSplitDesugaredType(); 92 if (T_split != D_split) 93 OS << ":'" << QualType::getAsString(D_split) << "'"; 94 } 95 } 96 void DumpDeclRef(Decl *node); 97 void DumpStmt(const Stmt *Node) { 98 Indent(); 99 OS << "(" << Node->getStmtClassName() 100 << " " << (void*)Node; 101 DumpSourceRange(Node); 102 } 103 void DumpValueKind(ExprValueKind K) { 104 switch (K) { 105 case VK_RValue: break; 106 case VK_LValue: OS << " lvalue"; break; 107 case VK_XValue: OS << " xvalue"; break; 108 } 109 } 110 void DumpObjectKind(ExprObjectKind K) { 111 switch (K) { 112 case OK_Ordinary: break; 113 case OK_BitField: OS << " bitfield"; break; 114 case OK_ObjCProperty: OS << " objcproperty"; break; 115 case OK_VectorComponent: OS << " vectorcomponent"; break; 116 } 117 } 118 void DumpExpr(const Expr *Node) { 119 DumpStmt(Node); 120 OS << ' '; 121 DumpType(Node->getType()); 122 DumpValueKind(Node->getValueKind()); 123 DumpObjectKind(Node->getObjectKind()); 124 } 125 void DumpSourceRange(const Stmt *Node); 126 void DumpLocation(SourceLocation Loc); 127 128 // Stmts. 129 void VisitStmt(Stmt *Node); 130 void VisitDeclStmt(DeclStmt *Node); 131 void VisitLabelStmt(LabelStmt *Node); 132 void VisitGotoStmt(GotoStmt *Node); 133 134 // Exprs 135 void VisitExpr(Expr *Node); 136 void VisitCastExpr(CastExpr *Node); 137 void VisitDeclRefExpr(DeclRefExpr *Node); 138 void VisitPredefinedExpr(PredefinedExpr *Node); 139 void VisitCharacterLiteral(CharacterLiteral *Node); 140 void VisitIntegerLiteral(IntegerLiteral *Node); 141 void VisitFloatingLiteral(FloatingLiteral *Node); 142 void VisitStringLiteral(StringLiteral *Str); 143 void VisitUnaryOperator(UnaryOperator *Node); 144 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node); 145 void VisitMemberExpr(MemberExpr *Node); 146 void VisitExtVectorElementExpr(ExtVectorElementExpr *Node); 147 void VisitBinaryOperator(BinaryOperator *Node); 148 void VisitCompoundAssignOperator(CompoundAssignOperator *Node); 149 void VisitAddrLabelExpr(AddrLabelExpr *Node); 150 void VisitBlockExpr(BlockExpr *Node); 151 152 // C++ 153 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 154 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node); 155 void VisitCXXThisExpr(CXXThisExpr *Node); 156 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node); 157 void VisitCXXConstructExpr(CXXConstructExpr *Node); 158 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node); 159 void VisitExprWithCleanups(ExprWithCleanups *Node); 160 void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node); 161 void DumpCXXTemporary(CXXTemporary *Temporary); 162 163 // ObjC 164 void VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node); 165 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node); 166 void VisitObjCMessageExpr(ObjCMessageExpr* Node); 167 void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); 168 void VisitObjCProtocolExpr(ObjCProtocolExpr *Node); 169 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node); 170 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); 171 }; 172} 173 174//===----------------------------------------------------------------------===// 175// Utilities 176//===----------------------------------------------------------------------===// 177 178void StmtDumper::DumpLocation(SourceLocation Loc) { 179 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 180 181 // The general format we print out is filename:line:col, but we drop pieces 182 // that haven't changed since the last loc printed. 183 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 184 185 if (PLoc.isInvalid()) { 186 OS << "<invalid sloc>"; 187 return; 188 } 189 190 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 191 OS << PLoc.getFilename() << ':' << PLoc.getLine() 192 << ':' << PLoc.getColumn(); 193 LastLocFilename = PLoc.getFilename(); 194 LastLocLine = PLoc.getLine(); 195 } else if (PLoc.getLine() != LastLocLine) { 196 OS << "line" << ':' << PLoc.getLine() 197 << ':' << PLoc.getColumn(); 198 LastLocLine = PLoc.getLine(); 199 } else { 200 OS << "col" << ':' << PLoc.getColumn(); 201 } 202} 203 204void StmtDumper::DumpSourceRange(const Stmt *Node) { 205 // Can't translate locations if a SourceManager isn't available. 206 if (SM == 0) return; 207 208 // TODO: If the parent expression is available, we can print a delta vs its 209 // location. 210 SourceRange R = Node->getSourceRange(); 211 212 OS << " <"; 213 DumpLocation(R.getBegin()); 214 if (R.getBegin() != R.getEnd()) { 215 OS << ", "; 216 DumpLocation(R.getEnd()); 217 } 218 OS << ">"; 219 220 // <t2.c:123:421[blah], t2.c:412:321> 221 222} 223 224 225//===----------------------------------------------------------------------===// 226// Stmt printing methods. 227//===----------------------------------------------------------------------===// 228 229void StmtDumper::VisitStmt(Stmt *Node) { 230 DumpStmt(Node); 231} 232 233void StmtDumper::DumpDeclarator(Decl *D) { 234 // FIXME: Need to complete/beautify this... this code simply shows the 235 // nodes are where they need to be. 236 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) { 237 OS << "\"typedef " << localType->getUnderlyingType().getAsString() 238 << ' ' << localType << '"'; 239 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 240 OS << "\""; 241 // Emit storage class for vardecls. 242 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 243 if (V->getStorageClass() != SC_None) 244 OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass()) 245 << " "; 246 } 247 248 std::string Name = VD->getNameAsString(); 249 VD->getType().getAsStringInternal(Name, 250 PrintingPolicy(VD->getASTContext().getLangOptions())); 251 OS << Name; 252 253 // If this is a vardecl with an initializer, emit it. 254 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 255 if (V->getInit()) { 256 OS << " =\n"; 257 DumpSubTree(V->getInit()); 258 } 259 } 260 OS << '"'; 261 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 262 // print a free standing tag decl (e.g. "struct x;"). 263 const char *tagname; 264 if (const IdentifierInfo *II = TD->getIdentifier()) 265 tagname = II->getNameStart(); 266 else 267 tagname = "<anonymous>"; 268 OS << '"' << TD->getKindName() << ' ' << tagname << ";\""; 269 // FIXME: print tag bodies. 270 } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) { 271 // print using-directive decl (e.g. "using namespace x;") 272 const char *ns; 273 if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier()) 274 ns = II->getNameStart(); 275 else 276 ns = "<anonymous>"; 277 OS << '"' << UD->getDeclKindName() << ns << ";\""; 278 } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) { 279 // print using decl (e.g. "using std::string;") 280 const char *tn = UD->isTypeName() ? "typename " : ""; 281 OS << '"' << UD->getDeclKindName() << tn; 282 UD->getQualifier()->print(OS, 283 PrintingPolicy(UD->getASTContext().getLangOptions())); 284 OS << ";\""; 285 } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) { 286 OS << "label " << LD->getNameAsString(); 287 } else { 288 assert(0 && "Unexpected decl"); 289 } 290} 291 292void StmtDumper::VisitDeclStmt(DeclStmt *Node) { 293 DumpStmt(Node); 294 OS << "\n"; 295 for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end(); 296 DI != DE; ++DI) { 297 Decl* D = *DI; 298 ++IndentLevel; 299 Indent(); 300 OS << (void*) D << " "; 301 DumpDeclarator(D); 302 if (DI+1 != DE) 303 OS << "\n"; 304 --IndentLevel; 305 } 306} 307 308void StmtDumper::VisitLabelStmt(LabelStmt *Node) { 309 DumpStmt(Node); 310 OS << " '" << Node->getName() << "'"; 311} 312 313void StmtDumper::VisitGotoStmt(GotoStmt *Node) { 314 DumpStmt(Node); 315 OS << " '" << Node->getLabel()->getName() 316 << "':" << (void*)Node->getLabel(); 317} 318 319//===----------------------------------------------------------------------===// 320// Expr printing methods. 321//===----------------------------------------------------------------------===// 322 323void StmtDumper::VisitExpr(Expr *Node) { 324 DumpExpr(Node); 325} 326 327static void DumpBasePath(llvm::raw_ostream &OS, CastExpr *Node) { 328 if (Node->path_empty()) 329 return; 330 331 OS << " ("; 332 bool First = true; 333 for (CastExpr::path_iterator 334 I = Node->path_begin(), E = Node->path_end(); I != E; ++I) { 335 const CXXBaseSpecifier *Base = *I; 336 if (!First) 337 OS << " -> "; 338 339 const CXXRecordDecl *RD = 340 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 341 342 if (Base->isVirtual()) 343 OS << "virtual "; 344 OS << RD->getName(); 345 First = false; 346 } 347 348 OS << ')'; 349} 350 351void StmtDumper::VisitCastExpr(CastExpr *Node) { 352 DumpExpr(Node); 353 OS << " <" << Node->getCastKindName(); 354 DumpBasePath(OS, Node); 355 OS << ">"; 356} 357 358void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { 359 DumpExpr(Node); 360 361 OS << " "; 362 DumpDeclRef(Node->getDecl()); 363} 364 365void StmtDumper::DumpDeclRef(Decl *d) { 366 OS << d->getDeclKindName() << ' ' << (void*) d; 367 368 if (NamedDecl *nd = dyn_cast<NamedDecl>(d)) { 369 OS << " '"; 370 nd->getDeclName().printName(OS); 371 OS << "'"; 372 } 373 374 if (ValueDecl *vd = dyn_cast<ValueDecl>(d)) { 375 OS << ' '; DumpType(vd->getType()); 376 } 377} 378 379void StmtDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 380 DumpExpr(Node); 381 OS << " ("; 382 if (!Node->requiresADL()) OS << "no "; 383 OS << "ADL) = '" << Node->getName() << '\''; 384 385 UnresolvedLookupExpr::decls_iterator 386 I = Node->decls_begin(), E = Node->decls_end(); 387 if (I == E) OS << " empty"; 388 for (; I != E; ++I) 389 OS << " " << (void*) *I; 390} 391 392void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 393 DumpExpr(Node); 394 395 OS << " " << Node->getDecl()->getDeclKindName() 396 << "Decl='" << Node->getDecl() 397 << "' " << (void*)Node->getDecl(); 398 if (Node->isFreeIvar()) 399 OS << " isFreeIvar"; 400} 401 402void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) { 403 DumpExpr(Node); 404 switch (Node->getIdentType()) { 405 default: assert(0 && "unknown case"); 406 case PredefinedExpr::Func: OS << " __func__"; break; 407 case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 408 case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 409 } 410} 411 412void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) { 413 DumpExpr(Node); 414 OS << Node->getValue(); 415} 416 417void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) { 418 DumpExpr(Node); 419 420 bool isSigned = Node->getType()->isSignedIntegerType(); 421 OS << " " << Node->getValue().toString(10, isSigned); 422} 423void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) { 424 DumpExpr(Node); 425 OS << " " << Node->getValueAsApproximateDouble(); 426} 427 428void StmtDumper::VisitStringLiteral(StringLiteral *Str) { 429 DumpExpr(Str); 430 // FIXME: this doesn't print wstrings right. 431 OS << " "; 432 if (Str->isWide()) 433 OS << "L"; 434 OS << '"'; 435 OS.write_escaped(Str->getString()); 436 OS << '"'; 437} 438 439void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) { 440 DumpExpr(Node); 441 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 442 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 443} 444void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 445 DumpExpr(Node); 446 OS << " " << (Node->isSizeOf() ? "sizeof" : "alignof") << " "; 447 if (Node->isArgumentType()) 448 DumpType(Node->getArgumentType()); 449} 450 451void StmtDumper::VisitMemberExpr(MemberExpr *Node) { 452 DumpExpr(Node); 453 OS << " " << (Node->isArrow() ? "->" : ".") 454 << Node->getMemberDecl() << ' ' 455 << (void*)Node->getMemberDecl(); 456} 457void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 458 DumpExpr(Node); 459 OS << " " << Node->getAccessor().getNameStart(); 460} 461void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) { 462 DumpExpr(Node); 463 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 464} 465void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 466 DumpExpr(Node); 467 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 468 << "' ComputeLHSTy="; 469 DumpType(Node->getComputationLHSType()); 470 OS << " ComputeResultTy="; 471 DumpType(Node->getComputationResultType()); 472} 473 474void StmtDumper::VisitBlockExpr(BlockExpr *Node) { 475 DumpExpr(Node); 476 477 IndentLevel++; 478 BlockDecl *block = Node->getBlockDecl(); 479 if (block->capturesCXXThis()) { 480 OS << '\n'; Indent(); OS << "(capture this)"; 481 } 482 for (BlockDecl::capture_iterator 483 i = block->capture_begin(), e = block->capture_end(); i != e; ++i) { 484 OS << '\n'; 485 Indent(); 486 OS << "(capture "; 487 if (i->isByRef()) OS << "byref "; 488 if (i->isNested()) OS << "nested "; 489 DumpDeclRef(i->getVariable()); 490 if (i->hasCopyExpr()) DumpSubTree(i->getCopyExpr()); 491 OS << ")"; 492 } 493 IndentLevel--; 494 495 DumpSubTree(block->getBody()); 496} 497 498// GNU extensions. 499 500void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) { 501 DumpExpr(Node); 502 OS << " " << Node->getLabel()->getName() 503 << " " << (void*)Node->getLabel(); 504} 505 506//===----------------------------------------------------------------------===// 507// C++ Expressions 508//===----------------------------------------------------------------------===// 509 510void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 511 DumpExpr(Node); 512 OS << " " << Node->getCastName() 513 << "<" << Node->getTypeAsWritten().getAsString() << ">" 514 << " <" << Node->getCastKindName(); 515 DumpBasePath(OS, Node); 516 OS << ">"; 517} 518 519void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 520 DumpExpr(Node); 521 OS << " " << (Node->getValue() ? "true" : "false"); 522} 523 524void StmtDumper::VisitCXXThisExpr(CXXThisExpr *Node) { 525 DumpExpr(Node); 526 OS << " this"; 527} 528 529void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 530 DumpExpr(Node); 531 OS << " functional cast to " << Node->getTypeAsWritten().getAsString(); 532} 533 534void StmtDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) { 535 DumpExpr(Node); 536 CXXConstructorDecl *Ctor = Node->getConstructor(); 537 DumpType(Ctor->getType()); 538 if (Node->isElidable()) 539 OS << " elidable"; 540 if (Node->requiresZeroInitialization()) 541 OS << " zeroing"; 542} 543 544void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 545 DumpExpr(Node); 546 OS << " "; 547 DumpCXXTemporary(Node->getTemporary()); 548} 549 550void StmtDumper::VisitExprWithCleanups(ExprWithCleanups *Node) { 551 DumpExpr(Node); 552 ++IndentLevel; 553 for (unsigned i = 0, e = Node->getNumTemporaries(); i != e; ++i) { 554 OS << "\n"; 555 Indent(); 556 DumpCXXTemporary(Node->getTemporary(i)); 557 } 558 --IndentLevel; 559} 560 561void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) { 562 OS << "(CXXTemporary " << (void *)Temporary << ")"; 563} 564 565//===----------------------------------------------------------------------===// 566// Obj-C Expressions 567//===----------------------------------------------------------------------===// 568 569void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) { 570 DumpExpr(Node); 571 OS << " selector=" << Node->getSelector().getAsString(); 572 switch (Node->getReceiverKind()) { 573 case ObjCMessageExpr::Instance: 574 break; 575 576 case ObjCMessageExpr::Class: 577 OS << " class="; 578 DumpType(Node->getClassReceiver()); 579 break; 580 581 case ObjCMessageExpr::SuperInstance: 582 OS << " super (instance)"; 583 break; 584 585 case ObjCMessageExpr::SuperClass: 586 OS << " super (class)"; 587 break; 588 } 589} 590 591void StmtDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) { 592 DumpStmt(Node); 593 if (VarDecl *CatchParam = Node->getCatchParamDecl()) { 594 OS << " catch parm = "; 595 DumpDeclarator(CatchParam); 596 } else { 597 OS << " catch all"; 598 } 599} 600 601void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 602 DumpExpr(Node); 603 OS << " "; 604 DumpType(Node->getEncodedType()); 605} 606 607void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 608 DumpExpr(Node); 609 610 OS << " " << Node->getSelector().getAsString(); 611} 612 613void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 614 DumpExpr(Node); 615 616 OS << ' ' << Node->getProtocol(); 617} 618 619void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 620 DumpExpr(Node); 621 if (Node->isImplicitProperty()) { 622 OS << " Kind=MethodRef Getter=\""; 623 if (Node->getImplicitPropertyGetter()) 624 OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 625 else 626 OS << "(null)"; 627 628 OS << "\" Setter=\""; 629 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 630 OS << Setter->getSelector().getAsString(); 631 else 632 OS << "(null)"; 633 OS << "\""; 634 } else { 635 OS << " Kind=PropertyRef Property=\"" << Node->getExplicitProperty() << '"'; 636 } 637 638 if (Node->isSuperReceiver()) 639 OS << " super"; 640} 641 642//===----------------------------------------------------------------------===// 643// Stmt method implementations 644//===----------------------------------------------------------------------===// 645 646/// dump - This does a local dump of the specified AST fragment. It dumps the 647/// specified node and a few nodes underneath it, but not the whole subtree. 648/// This is useful in a debugger. 649void Stmt::dump(SourceManager &SM) const { 650 dump(llvm::errs(), SM); 651} 652 653void Stmt::dump(llvm::raw_ostream &OS, SourceManager &SM) const { 654 StmtDumper P(&SM, OS, 4); 655 P.DumpSubTree(const_cast<Stmt*>(this)); 656 OS << "\n"; 657} 658 659/// dump - This does a local dump of the specified AST fragment. It dumps the 660/// specified node and a few nodes underneath it, but not the whole subtree. 661/// This is useful in a debugger. 662void Stmt::dump() const { 663 StmtDumper P(0, llvm::errs(), 4); 664 P.DumpSubTree(const_cast<Stmt*>(this)); 665 llvm::errs() << "\n"; 666} 667 668/// dumpAll - This does a dump of the specified AST fragment and all subtrees. 669void Stmt::dumpAll(SourceManager &SM) const { 670 StmtDumper P(&SM, llvm::errs(), ~0U); 671 P.DumpSubTree(const_cast<Stmt*>(this)); 672 llvm::errs() << "\n"; 673} 674 675/// dumpAll - This does a dump of the specified AST fragment and all subtrees. 676void Stmt::dumpAll() const { 677 StmtDumper P(0, llvm::errs(), ~0U); 678 P.DumpSubTree(const_cast<Stmt*>(this)); 679 llvm::errs() << "\n"; 680} 681