StmtDumper.cpp revision 900fc6388e803868a34b9483510c345e9b49d7eb
135718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala//===--- StmtDumper.cpp - Dumping implementation for Stmt ASTs ------------===// 235718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// 335718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// The LLVM Compiler Infrastructure 435718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// 535718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// This file is distributed under the University of Illinois Open Source 635718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// License. See LICENSE.TXT for details. 735718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// 835718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala//===----------------------------------------------------------------------===// 935718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// 1035718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// This file implements the Stmt::dump/Stmt::print methods, which dump out the 1135718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// AST in a form that exposes type details and other fields. 1235718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala// 1335718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala//===----------------------------------------------------------------------===// 1435718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala 1535718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala#include "clang/AST/StmtVisitor.h" 1635718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala#include "clang/AST/DeclObjC.h" 17b3757d3167eb4c57b02d83cb9cf9cfcf112c2a53Eino-Ville Talvala#include "clang/AST/DeclCXX.h" 18b3757d3167eb4c57b02d83cb9cf9cfcf112c2a53Eino-Ville Talvala#include "clang/AST/PrettyPrinter.h" 1935718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala#include "clang/Basic/SourceManager.h" 2035718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala#include "llvm/Support/raw_ostream.h" 2135718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvalausing namespace clang; 2235718d338d69d499a007e0cfdb1216952878c5a4Eino-Ville Talvala 23b3757d3167eb4c57b02d83cb9cf9cfcf112c2a53Eino-Ville Talvala//===----------------------------------------------------------------------===// 24b3757d3167eb4c57b02d83cb9cf9cfcf112c2a53Eino-Ville Talvala// StmtDumper Visitor 25b3757d3167eb4c57b02d83cb9cf9cfcf112c2a53Eino-Ville Talvala//===----------------------------------------------------------------------===// 26708e6bc6526990f447326d13702e79d5630303b8Eino-Ville Talvala 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_iterator CI = S->child_begin(), CE = S->child_end(); 63 if (CI != CE) { 64 while (CI != CE) { 65 OS << '\n'; 66 DumpSubTree(*CI++); 67 } 68 } 69 OS << ')'; 70 } 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 OS << "'" << T.getAsString() << "'"; 87 88 if (!T.isNull()) { 89 // If the type is sugared, also dump a (shallow) desugared type. 90 QualType Simplified = T.getDesugaredType(); 91 if (Simplified != T) 92 OS << ":'" << Simplified.getAsString() << "'"; 93 } 94 } 95 void DumpStmt(const Stmt *Node) { 96 Indent(); 97 OS << "(" << Node->getStmtClassName() 98 << " " << (void*)Node; 99 DumpSourceRange(Node); 100 } 101 void DumpExpr(const Expr *Node) { 102 DumpStmt(Node); 103 OS << ' '; 104 DumpType(Node->getType()); 105 } 106 void DumpSourceRange(const Stmt *Node); 107 void DumpLocation(SourceLocation Loc); 108 109 // Stmts. 110 void VisitStmt(Stmt *Node); 111 void VisitDeclStmt(DeclStmt *Node); 112 void VisitLabelStmt(LabelStmt *Node); 113 void VisitGotoStmt(GotoStmt *Node); 114 115 // Exprs 116 void VisitExpr(Expr *Node); 117 void VisitCastExpr(CastExpr *Node); 118 void VisitImplicitCastExpr(ImplicitCastExpr *Node); 119 void VisitDeclRefExpr(DeclRefExpr *Node); 120 void VisitPredefinedExpr(PredefinedExpr *Node); 121 void VisitCharacterLiteral(CharacterLiteral *Node); 122 void VisitIntegerLiteral(IntegerLiteral *Node); 123 void VisitFloatingLiteral(FloatingLiteral *Node); 124 void VisitStringLiteral(StringLiteral *Str); 125 void VisitUnaryOperator(UnaryOperator *Node); 126 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node); 127 void VisitMemberExpr(MemberExpr *Node); 128 void VisitExtVectorElementExpr(ExtVectorElementExpr *Node); 129 void VisitBinaryOperator(BinaryOperator *Node); 130 void VisitCompoundAssignOperator(CompoundAssignOperator *Node); 131 void VisitAddrLabelExpr(AddrLabelExpr *Node); 132 void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node); 133 134 // C++ 135 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 136 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node); 137 void VisitCXXThisExpr(CXXThisExpr *Node); 138 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node); 139 void VisitCXXConstructExpr(CXXConstructExpr *Node); 140 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node); 141 void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node); 142 void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node); 143 void DumpCXXTemporary(CXXTemporary *Temporary); 144 145 // ObjC 146 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node); 147 void VisitObjCMessageExpr(ObjCMessageExpr* Node); 148 void VisitObjCSelectorExpr(ObjCSelectorExpr *Node); 149 void VisitObjCProtocolExpr(ObjCProtocolExpr *Node); 150 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node); 151 void VisitObjCImplicitSetterGetterRefExpr( 152 ObjCImplicitSetterGetterRefExpr *Node); 153 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); 154 void VisitObjCSuperExpr(ObjCSuperExpr *Node); 155 }; 156} 157 158//===----------------------------------------------------------------------===// 159// Utilities 160//===----------------------------------------------------------------------===// 161 162void StmtDumper::DumpLocation(SourceLocation Loc) { 163 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 164 165 if (SpellingLoc.isInvalid()) { 166 OS << "<invalid sloc>"; 167 return; 168 } 169 170 // The general format we print out is filename:line:col, but we drop pieces 171 // that haven't changed since the last loc printed. 172 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 173 174 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 175 OS << PLoc.getFilename() << ':' << PLoc.getLine() 176 << ':' << PLoc.getColumn(); 177 LastLocFilename = PLoc.getFilename(); 178 LastLocLine = PLoc.getLine(); 179 } else if (PLoc.getLine() != LastLocLine) { 180 OS << "line" << ':' << PLoc.getLine() 181 << ':' << PLoc.getColumn(); 182 LastLocLine = PLoc.getLine(); 183 } else { 184 OS << "col" << ':' << PLoc.getColumn(); 185 } 186} 187 188void StmtDumper::DumpSourceRange(const Stmt *Node) { 189 // Can't translate locations if a SourceManager isn't available. 190 if (SM == 0) return; 191 192 // TODO: If the parent expression is available, we can print a delta vs its 193 // location. 194 SourceRange R = Node->getSourceRange(); 195 196 OS << " <"; 197 DumpLocation(R.getBegin()); 198 if (R.getBegin() != R.getEnd()) { 199 OS << ", "; 200 DumpLocation(R.getEnd()); 201 } 202 OS << ">"; 203 204 // <t2.c:123:421[blah], t2.c:412:321> 205 206} 207 208 209//===----------------------------------------------------------------------===// 210// Stmt printing methods. 211//===----------------------------------------------------------------------===// 212 213void StmtDumper::VisitStmt(Stmt *Node) { 214 DumpStmt(Node); 215} 216 217void StmtDumper::DumpDeclarator(Decl *D) { 218 // FIXME: Need to complete/beautify this... this code simply shows the 219 // nodes are where they need to be. 220 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) { 221 OS << "\"typedef " << localType->getUnderlyingType().getAsString() 222 << ' ' << localType << '"'; 223 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 224 OS << "\""; 225 // Emit storage class for vardecls. 226 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 227 if (V->getStorageClass() != VarDecl::None) 228 OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass()) 229 << " "; 230 } 231 232 std::string Name = VD->getNameAsString(); 233 VD->getType().getAsStringInternal(Name, 234 PrintingPolicy(VD->getASTContext().getLangOptions())); 235 OS << Name; 236 237 // If this is a vardecl with an initializer, emit it. 238 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 239 if (V->getInit()) { 240 OS << " =\n"; 241 DumpSubTree(V->getInit()); 242 } 243 } 244 OS << '"'; 245 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 246 // print a free standing tag decl (e.g. "struct x;"). 247 const char *tagname; 248 if (const IdentifierInfo *II = TD->getIdentifier()) 249 tagname = II->getNameStart(); 250 else 251 tagname = "<anonymous>"; 252 OS << '"' << TD->getKindName() << ' ' << tagname << ";\""; 253 // FIXME: print tag bodies. 254 } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) { 255 // print using-directive decl (e.g. "using namespace x;") 256 const char *ns; 257 if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier()) 258 ns = II->getNameStart(); 259 else 260 ns = "<anonymous>"; 261 OS << '"' << UD->getDeclKindName() << ns << ";\""; 262 } else { 263 assert(0 && "Unexpected decl"); 264 } 265} 266 267void StmtDumper::VisitDeclStmt(DeclStmt *Node) { 268 DumpStmt(Node); 269 OS << "\n"; 270 for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end(); 271 DI != DE; ++DI) { 272 Decl* D = *DI; 273 ++IndentLevel; 274 Indent(); 275 OS << (void*) D << " "; 276 DumpDeclarator(D); 277 if (DI+1 != DE) 278 OS << "\n"; 279 --IndentLevel; 280 } 281} 282 283void StmtDumper::VisitLabelStmt(LabelStmt *Node) { 284 DumpStmt(Node); 285 OS << " '" << Node->getName() << "'"; 286} 287 288void StmtDumper::VisitGotoStmt(GotoStmt *Node) { 289 DumpStmt(Node); 290 OS << " '" << Node->getLabel()->getName() 291 << "':" << (void*)Node->getLabel(); 292} 293 294//===----------------------------------------------------------------------===// 295// Expr printing methods. 296//===----------------------------------------------------------------------===// 297 298void StmtDumper::VisitExpr(Expr *Node) { 299 DumpExpr(Node); 300} 301 302void StmtDumper::VisitCastExpr(CastExpr *Node) { 303 DumpExpr(Node); 304 OS << " <" << Node->getCastKindName() << ">"; 305} 306 307void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 308 VisitCastExpr(Node); 309 if (Node->isLvalueCast()) 310 OS << " lvalue"; 311} 312 313void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { 314 DumpExpr(Node); 315 316 OS << " "; 317 switch (Node->getDecl()->getKind()) { 318 default: OS << "Decl"; break; 319 case Decl::Function: OS << "FunctionDecl"; break; 320 case Decl::Var: OS << "Var"; break; 321 case Decl::ParmVar: OS << "ParmVar"; break; 322 case Decl::EnumConstant: OS << "EnumConstant"; break; 323 case Decl::Typedef: OS << "Typedef"; break; 324 case Decl::Record: OS << "Record"; break; 325 case Decl::Enum: OS << "Enum"; break; 326 case Decl::CXXRecord: OS << "CXXRecord"; break; 327 case Decl::ObjCInterface: OS << "ObjCInterface"; break; 328 case Decl::ObjCClass: OS << "ObjCClass"; break; 329 } 330 331 OS << "='" << Node->getDecl() << "' " << (void*)Node->getDecl(); 332} 333 334void StmtDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 335 DumpExpr(Node); 336 OS << " ("; 337 if (!Node->requiresADL()) OS << "no "; 338 OS << "ADL) = '" << Node->getName() << '\''; 339 340 UnresolvedLookupExpr::decls_iterator 341 I = Node->decls_begin(), E = Node->decls_end(); 342 if (I == E) OS << " empty"; 343 for (; I != E; ++I) 344 OS << " " << (void*) *I; 345} 346 347void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 348 DumpExpr(Node); 349 350 OS << " " << Node->getDecl()->getDeclKindName() 351 << "Decl='" << Node->getDecl() 352 << "' " << (void*)Node->getDecl(); 353 if (Node->isFreeIvar()) 354 OS << " isFreeIvar"; 355} 356 357void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) { 358 DumpExpr(Node); 359 switch (Node->getIdentType()) { 360 default: assert(0 && "unknown case"); 361 case PredefinedExpr::Func: OS << " __func__"; break; 362 case PredefinedExpr::Function: OS << " __FUNCTION__"; break; 363 case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break; 364 } 365} 366 367void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) { 368 DumpExpr(Node); 369 OS << Node->getValue(); 370} 371 372void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) { 373 DumpExpr(Node); 374 375 bool isSigned = Node->getType()->isSignedIntegerType(); 376 OS << " " << Node->getValue().toString(10, isSigned); 377} 378void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) { 379 DumpExpr(Node); 380 OS << " " << Node->getValueAsApproximateDouble(); 381} 382 383void StmtDumper::VisitStringLiteral(StringLiteral *Str) { 384 DumpExpr(Str); 385 // FIXME: this doesn't print wstrings right. 386 OS << " "; 387 if (Str->isWide()) 388 OS << "L"; 389 OS << '"'; 390 OS.write_escaped(llvm::StringRef(Str->getStrData(), 391 Str->getByteLength())); 392 OS << '"'; 393} 394 395void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) { 396 DumpExpr(Node); 397 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 398 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 399} 400void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 401 DumpExpr(Node); 402 OS << " " << (Node->isSizeOf() ? "sizeof" : "alignof") << " "; 403 if (Node->isArgumentType()) 404 DumpType(Node->getArgumentType()); 405} 406 407void StmtDumper::VisitMemberExpr(MemberExpr *Node) { 408 DumpExpr(Node); 409 OS << " " << (Node->isArrow() ? "->" : ".") 410 << Node->getMemberDecl() << ' ' 411 << (void*)Node->getMemberDecl(); 412} 413void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 414 DumpExpr(Node); 415 OS << " " << Node->getAccessor().getNameStart(); 416} 417void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) { 418 DumpExpr(Node); 419 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 420} 421void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 422 DumpExpr(Node); 423 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 424 << "' ComputeLHSTy="; 425 DumpType(Node->getComputationLHSType()); 426 OS << " ComputeResultTy="; 427 DumpType(Node->getComputationResultType()); 428} 429 430// GNU extensions. 431 432void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) { 433 DumpExpr(Node); 434 OS << " " << Node->getLabel()->getName() 435 << " " << (void*)Node->getLabel(); 436} 437 438void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 439 DumpExpr(Node); 440 OS << " "; 441 DumpType(Node->getArgType1()); 442 OS << " "; 443 DumpType(Node->getArgType2()); 444} 445 446//===----------------------------------------------------------------------===// 447// C++ Expressions 448//===----------------------------------------------------------------------===// 449 450void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 451 DumpExpr(Node); 452 OS << " " << Node->getCastName() 453 << "<" << Node->getTypeAsWritten().getAsString() << ">" 454 << " <" << Node->getCastKindName() << ">"; 455} 456 457void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 458 DumpExpr(Node); 459 OS << " " << (Node->getValue() ? "true" : "false"); 460} 461 462void StmtDumper::VisitCXXThisExpr(CXXThisExpr *Node) { 463 DumpExpr(Node); 464 OS << " this"; 465} 466 467void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 468 DumpExpr(Node); 469 OS << " functional cast to " << Node->getTypeAsWritten().getAsString(); 470} 471 472void StmtDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) { 473 DumpExpr(Node); 474 CXXConstructorDecl *Ctor = Node->getConstructor(); 475 DumpType(Ctor->getType()); 476 if (Node->isElidable()) 477 OS << " elidable"; 478} 479 480void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 481 DumpExpr(Node); 482 OS << " "; 483 DumpCXXTemporary(Node->getTemporary()); 484} 485 486void StmtDumper::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *Node) { 487 DumpExpr(Node); 488 ++IndentLevel; 489 for (unsigned i = 0, e = Node->getNumTemporaries(); i != e; ++i) { 490 OS << "\n"; 491 Indent(); 492 DumpCXXTemporary(Node->getTemporary(i)); 493 } 494 --IndentLevel; 495} 496 497void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) { 498 OS << "(CXXTemporary " << (void *)Temporary << ")"; 499} 500 501//===----------------------------------------------------------------------===// 502// Obj-C Expressions 503//===----------------------------------------------------------------------===// 504 505void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) { 506 DumpExpr(Node); 507 OS << " selector=" << Node->getSelector().getAsString(); 508 if (IdentifierInfo *clsName = Node->getClassName()) 509 OS << " class=" << clsName->getNameStart(); 510} 511 512void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 513 DumpExpr(Node); 514 OS << " "; 515 DumpType(Node->getEncodedType()); 516} 517 518void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 519 DumpExpr(Node); 520 521 OS << " " << Node->getSelector().getAsString(); 522} 523 524void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 525 DumpExpr(Node); 526 527 OS << ' ' << Node->getProtocol(); 528} 529 530void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 531 DumpExpr(Node); 532 533 OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"'; 534} 535 536void StmtDumper::VisitObjCImplicitSetterGetterRefExpr( 537 ObjCImplicitSetterGetterRefExpr *Node) { 538 DumpExpr(Node); 539 540 ObjCMethodDecl *Getter = Node->getGetterMethod(); 541 ObjCMethodDecl *Setter = Node->getSetterMethod(); 542 OS << " Kind=MethodRef Getter=\"" 543 << Getter->getSelector().getAsString() 544 << "\" Setter=\""; 545 if (Setter) 546 OS << Setter->getSelector().getAsString(); 547 else 548 OS << "(null)"; 549 OS << "\""; 550} 551 552void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) { 553 DumpExpr(Node); 554 OS << " super"; 555} 556 557//===----------------------------------------------------------------------===// 558// Stmt method implementations 559//===----------------------------------------------------------------------===// 560 561/// dump - This does a local dump of the specified AST fragment. It dumps the 562/// specified node and a few nodes underneath it, but not the whole subtree. 563/// This is useful in a debugger. 564void Stmt::dump(SourceManager &SM) const { 565 StmtDumper P(&SM, llvm::errs(), 4); 566 P.DumpSubTree(const_cast<Stmt*>(this)); 567 llvm::errs() << "\n"; 568} 569 570/// dump - This does a local dump of the specified AST fragment. It dumps the 571/// specified node and a few nodes underneath it, but not the whole subtree. 572/// This is useful in a debugger. 573void Stmt::dump() const { 574 StmtDumper P(0, llvm::errs(), 4); 575 P.DumpSubTree(const_cast<Stmt*>(this)); 576 llvm::errs() << "\n"; 577} 578 579/// dumpAll - This does a dump of the specified AST fragment and all subtrees. 580void Stmt::dumpAll(SourceManager &SM) const { 581 StmtDumper P(&SM, llvm::errs(), ~0U); 582 P.DumpSubTree(const_cast<Stmt*>(this)); 583 llvm::errs() << "\n"; 584} 585 586/// dumpAll - This does a dump of the specified AST fragment and all subtrees. 587void Stmt::dumpAll() const { 588 StmtDumper P(0, llvm::errs(), ~0U); 589 P.DumpSubTree(const_cast<Stmt*>(this)); 590 llvm::errs() << "\n"; 591} 592