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