//===--- StmtDumper.cpp - Dumping implementation for Stmt ASTs ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Stmt::dump/Stmt::print methods, which dump out the
// AST in a form that exposes type details and other fields.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/StmtVisitor.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;

//===----------------------------------------------------------------------===//
// StmtDumper Visitor
//===----------------------------------------------------------------------===//

namespace  {
  class StmtDumper : public StmtVisitor<StmtDumper> {
    SourceManager *SM;
    raw_ostream &OS;
    unsigned IndentLevel;

    /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump
    /// the first few levels of an AST.  This keeps track of how many ast levels
    /// are left.
    unsigned MaxDepth;

    /// LastLocFilename/LastLocLine - Keep track of the last location we print
    /// out so that we can print out deltas from then on out.
    const char *LastLocFilename;
    unsigned LastLocLine;

  public:
    StmtDumper(SourceManager *sm, raw_ostream &os, unsigned maxDepth)
      : SM(sm), OS(os), IndentLevel(0-1), MaxDepth(maxDepth) {
      LastLocFilename = "";
      LastLocLine = ~0U;
    }

    void DumpSubTree(Stmt *S) {
      // Prune the recursion if not using dump all.
      if (MaxDepth == 0) return;

      ++IndentLevel;
      if (S) {
        if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
          VisitDeclStmt(DS);
        else {
          Visit(S);

          // Print out children.
          Stmt::child_range CI = S->children();
          if (CI) {
            while (CI) {
              OS << '\n';
              DumpSubTree(*CI++);
            }
          }
        }
        OS << ')';
      } else {
        Indent();
        OS << "<<<NULL>>>";
      }
      --IndentLevel;
    }

    void DumpDeclarator(Decl *D);

    void Indent() const {
      for (int i = 0, e = IndentLevel; i < e; ++i)
        OS << "  ";
    }

    void DumpType(QualType T) {
      SplitQualType T_split = T.split();
      OS << "'" << QualType::getAsString(T_split) << "'";

      if (!T.isNull()) {
        // If the type is sugared, also dump a (shallow) desugared type.
        SplitQualType D_split = T.getSplitDesugaredType();
        if (T_split != D_split)
          OS << ":'" << QualType::getAsString(D_split) << "'";
      }
    }
    void DumpDeclRef(Decl *node);
    void DumpStmt(const Stmt *Node) {
      Indent();
      OS << "(" << Node->getStmtClassName()
         << " " << (void*)Node;
      DumpSourceRange(Node);
    }
    void DumpValueKind(ExprValueKind K) {
      switch (K) {
      case VK_RValue: break;
      case VK_LValue: OS << " lvalue"; break;
      case VK_XValue: OS << " xvalue"; break;
      }
    }
    void DumpObjectKind(ExprObjectKind K) {
      switch (K) {
      case OK_Ordinary: break;
      case OK_BitField: OS << " bitfield"; break;
      case OK_ObjCProperty: OS << " objcproperty"; break;
      case OK_VectorComponent: OS << " vectorcomponent"; break;
      }
    }
    void DumpExpr(const Expr *Node) {
      DumpStmt(Node);
      OS << ' ';
      DumpType(Node->getType());
      DumpValueKind(Node->getValueKind());
      DumpObjectKind(Node->getObjectKind());
    }
    void DumpSourceRange(const Stmt *Node);
    void DumpLocation(SourceLocation Loc);

    // Stmts.
    void VisitStmt(Stmt *Node);
    void VisitDeclStmt(DeclStmt *Node);
    void VisitLabelStmt(LabelStmt *Node);
    void VisitGotoStmt(GotoStmt *Node);

    // Exprs
    void VisitExpr(Expr *Node);
    void VisitCastExpr(CastExpr *Node);
    void VisitDeclRefExpr(DeclRefExpr *Node);
    void VisitPredefinedExpr(PredefinedExpr *Node);
    void VisitCharacterLiteral(CharacterLiteral *Node);
    void VisitIntegerLiteral(IntegerLiteral *Node);
    void VisitFloatingLiteral(FloatingLiteral *Node);
    void VisitStringLiteral(StringLiteral *Str);
    void VisitUnaryOperator(UnaryOperator *Node);
    void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node);
    void VisitMemberExpr(MemberExpr *Node);
    void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
    void VisitBinaryOperator(BinaryOperator *Node);
    void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
    void VisitAddrLabelExpr(AddrLabelExpr *Node);
    void VisitBlockExpr(BlockExpr *Node);
    void VisitOpaqueValueExpr(OpaqueValueExpr *Node);

    // C++
    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
    void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
    void VisitCXXThisExpr(CXXThisExpr *Node);
    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
    void VisitCXXConstructExpr(CXXConstructExpr *Node);
    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node);
    void VisitExprWithCleanups(ExprWithCleanups *Node);
    void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node);
    void DumpCXXTemporary(CXXTemporary *Temporary);

    // ObjC
    void VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node);
    void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
    void VisitObjCMessageExpr(ObjCMessageExpr* Node);
    void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
    void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
    void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
    void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
  };
}

//===----------------------------------------------------------------------===//
//  Utilities
//===----------------------------------------------------------------------===//

void StmtDumper::DumpLocation(SourceLocation Loc) {
  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);

  // The general format we print out is filename:line:col, but we drop pieces
  // that haven't changed since the last loc printed.
  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);

  if (PLoc.isInvalid()) {
    OS << "<invalid sloc>";
    return;
  }

  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
    OS << PLoc.getFilename() << ':' << PLoc.getLine()
       << ':' << PLoc.getColumn();
    LastLocFilename = PLoc.getFilename();
    LastLocLine = PLoc.getLine();
  } else if (PLoc.getLine() != LastLocLine) {
    OS << "line" << ':' << PLoc.getLine()
       << ':' << PLoc.getColumn();
    LastLocLine = PLoc.getLine();
  } else {
    OS << "col" << ':' << PLoc.getColumn();
  }
}

void StmtDumper::DumpSourceRange(const Stmt *Node) {
  // Can't translate locations if a SourceManager isn't available.
  if (SM == 0) return;

  // TODO: If the parent expression is available, we can print a delta vs its
  // location.
  SourceRange R = Node->getSourceRange();

  OS << " <";
  DumpLocation(R.getBegin());
  if (R.getBegin() != R.getEnd()) {
    OS << ", ";
    DumpLocation(R.getEnd());
  }
  OS << ">";

  // <t2.c:123:421[blah], t2.c:412:321>

}


//===----------------------------------------------------------------------===//
//  Stmt printing methods.
//===----------------------------------------------------------------------===//

void StmtDumper::VisitStmt(Stmt *Node) {
  DumpStmt(Node);
}

void StmtDumper::DumpDeclarator(Decl *D) {
  // FIXME: Need to complete/beautify this... this code simply shows the
  // nodes are where they need to be.
  if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
    OS << "\"typedef " << localType->getUnderlyingType().getAsString()
       << ' ' << *localType << '"';
  } else if (TypeAliasDecl *localType = dyn_cast<TypeAliasDecl>(D)) {
    OS << "\"using " << *localType << " = "
       << localType->getUnderlyingType().getAsString() << '"';
  } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
    OS << "\"";
    // Emit storage class for vardecls.
    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
      if (V->getStorageClass() != SC_None)
        OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
           << " ";
    }

    std::string Name = VD->getNameAsString();
    VD->getType().getAsStringInternal(Name,
                          PrintingPolicy(VD->getASTContext().getLangOptions()));
    OS << Name;

    // If this is a vardecl with an initializer, emit it.
    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
      if (V->getInit()) {
        OS << " =\n";
        DumpSubTree(V->getInit());
      }
    }
    OS << '"';
  } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
    // print a free standing tag decl (e.g. "struct x;").
    const char *tagname;
    if (const IdentifierInfo *II = TD->getIdentifier())
      tagname = II->getNameStart();
    else
      tagname = "<anonymous>";
    OS << '"' << TD->getKindName() << ' ' << tagname << ";\"";
    // FIXME: print tag bodies.
  } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) {
    // print using-directive decl (e.g. "using namespace x;")
    const char *ns;
    if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier())
      ns = II->getNameStart();
    else
      ns = "<anonymous>";
    OS << '"' << UD->getDeclKindName() << ns << ";\"";
  } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
    // print using decl (e.g. "using std::string;")
    const char *tn = UD->isTypeName() ? "typename " : "";
    OS << '"' << UD->getDeclKindName() << tn;
    UD->getQualifier()->print(OS,
                        PrintingPolicy(UD->getASTContext().getLangOptions()));
    OS << ";\"";
  } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
    OS << "label " << LD->getNameAsString();
  } else if (StaticAssertDecl *SAD = dyn_cast<StaticAssertDecl>(D)) {
    OS << "\"static_assert(\n";
    DumpSubTree(SAD->getAssertExpr());
    OS << ",\n";
    DumpSubTree(SAD->getMessage());
    OS << ");\"";
  } else {
    llvm_unreachable("Unexpected decl");
  }
}

void StmtDumper::VisitDeclStmt(DeclStmt *Node) {
  DumpStmt(Node);
  OS << "\n";
  for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
       DI != DE; ++DI) {
    Decl* D = *DI;
    ++IndentLevel;
    Indent();
    OS << (void*) D << " ";
    DumpDeclarator(D);
    if (DI+1 != DE)
      OS << "\n";
    --IndentLevel;
  }
}

void StmtDumper::VisitLabelStmt(LabelStmt *Node) {
  DumpStmt(Node);
  OS << " '" << Node->getName() << "'";
}

void StmtDumper::VisitGotoStmt(GotoStmt *Node) {
  DumpStmt(Node);
  OS << " '" << Node->getLabel()->getName()
     << "':" << (void*)Node->getLabel();
}

//===----------------------------------------------------------------------===//
//  Expr printing methods.
//===----------------------------------------------------------------------===//

void StmtDumper::VisitExpr(Expr *Node) {
  DumpExpr(Node);
}

static void DumpBasePath(raw_ostream &OS, CastExpr *Node) {
  if (Node->path_empty())
    return;

  OS << " (";
  bool First = true;
  for (CastExpr::path_iterator
         I = Node->path_begin(), E = Node->path_end(); I != E; ++I) {
    const CXXBaseSpecifier *Base = *I;
    if (!First)
      OS << " -> ";
    
    const CXXRecordDecl *RD =
    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
    
    if (Base->isVirtual())
      OS << "virtual ";
    OS << RD->getName();
    First = false;
  }
    
  OS << ')';
}

void StmtDumper::VisitCastExpr(CastExpr *Node) {
  DumpExpr(Node);
  OS << " <" << Node->getCastKindName();
  DumpBasePath(OS, Node);
  OS << ">";
}

void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
  DumpExpr(Node);

  OS << " ";
  DumpDeclRef(Node->getDecl());
  if (Node->getDecl() != Node->getFoundDecl()) {
    OS << " (";
    DumpDeclRef(Node->getFoundDecl());
    OS << ")";
  }
}

void StmtDumper::DumpDeclRef(Decl *d) {
  OS << d->getDeclKindName() << ' ' << (void*) d;

  if (NamedDecl *nd = dyn_cast<NamedDecl>(d)) {
    OS << " '";
    nd->getDeclName().printName(OS);
    OS << "'";
  }

  if (ValueDecl *vd = dyn_cast<ValueDecl>(d)) {
    OS << ' '; DumpType(vd->getType());
  }
}

void StmtDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
  DumpExpr(Node);
  OS << " (";
  if (!Node->requiresADL()) OS << "no ";
  OS << "ADL) = '" << Node->getName() << '\'';

  UnresolvedLookupExpr::decls_iterator
    I = Node->decls_begin(), E = Node->decls_end();
  if (I == E) OS << " empty";
  for (; I != E; ++I)
    OS << " " << (void*) *I;
}

void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
  DumpExpr(Node);

  OS << " " << Node->getDecl()->getDeclKindName()
     << "Decl='" << *Node->getDecl()
     << "' " << (void*)Node->getDecl();
  if (Node->isFreeIvar())
    OS << " isFreeIvar";
}

void StmtDumper::VisitPredefinedExpr(PredefinedExpr *Node) {
  DumpExpr(Node);
  switch (Node->getIdentType()) {
  default: llvm_unreachable("unknown case");
  case PredefinedExpr::Func:           OS <<  " __func__"; break;
  case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
  case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
  }
}

void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) {
  DumpExpr(Node);
  OS << " " << Node->getValue();
}

void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) {
  DumpExpr(Node);

  bool isSigned = Node->getType()->isSignedIntegerType();
  OS << " " << Node->getValue().toString(10, isSigned);
}
void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) {
  DumpExpr(Node);
  OS << " " << Node->getValueAsApproximateDouble();
}

void StmtDumper::VisitStringLiteral(StringLiteral *Str) {
  DumpExpr(Str);
  // FIXME: this doesn't print wstrings right.
  OS << " ";
  switch (Str->getKind()) {
  case StringLiteral::Ascii: break; // No prefix
  case StringLiteral::Wide:  OS << 'L'; break;
  case StringLiteral::UTF8:  OS << "u8"; break;
  case StringLiteral::UTF16: OS << 'u'; break;
  case StringLiteral::UTF32: OS << 'U'; break;
  }
  OS << '"';
  OS.write_escaped(Str->getString());
  OS << '"';
}

void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) {
  DumpExpr(Node);
  OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
     << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}
void StmtDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
  DumpExpr(Node);
  switch(Node->getKind()) {
  case UETT_SizeOf:
    OS << " sizeof ";
    break;
  case UETT_AlignOf:
    OS << " __alignof ";
    break;
  case UETT_VecStep:
    OS << " vec_step ";
    break;
  }
  if (Node->isArgumentType())
    DumpType(Node->getArgumentType());
}

void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
  DumpExpr(Node);
  OS << " " << (Node->isArrow() ? "->" : ".")
     << *Node->getMemberDecl() << ' '
     << (void*)Node->getMemberDecl();
}
void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
  DumpExpr(Node);
  OS << " " << Node->getAccessor().getNameStart();
}
void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) {
  DumpExpr(Node);
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}
void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
  DumpExpr(Node);
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
     << "' ComputeLHSTy=";
  DumpType(Node->getComputationLHSType());
  OS << " ComputeResultTy=";
  DumpType(Node->getComputationResultType());
}

void StmtDumper::VisitBlockExpr(BlockExpr *Node) {
  DumpExpr(Node);

  IndentLevel++;
  BlockDecl *block = Node->getBlockDecl();
  if (block->capturesCXXThis()) {
    OS << '\n'; Indent(); OS << "(capture this)";
  }
  for (BlockDecl::capture_iterator
         i = block->capture_begin(), e = block->capture_end(); i != e; ++i) {
    OS << '\n';
    Indent();
    OS << "(capture ";
    if (i->isByRef()) OS << "byref ";
    if (i->isNested()) OS << "nested ";
    DumpDeclRef(i->getVariable());
    if (i->hasCopyExpr()) DumpSubTree(i->getCopyExpr());
    OS << ")";
  }
  IndentLevel--;

  DumpSubTree(block->getBody());
}

void StmtDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
  DumpExpr(Node);

  if (Expr *Source = Node->getSourceExpr()) {
    OS << '\n';
    DumpSubTree(Source);
  }
}

// GNU extensions.

void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
  DumpExpr(Node);
  OS << " " << Node->getLabel()->getName()
     << " " << (void*)Node->getLabel();
}

//===----------------------------------------------------------------------===//
// C++ Expressions
//===----------------------------------------------------------------------===//

void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
  DumpExpr(Node);
  OS << " " << Node->getCastName() 
     << "<" << Node->getTypeAsWritten().getAsString() << ">"
     << " <" << Node->getCastKindName();
  DumpBasePath(OS, Node);
  OS << ">";
}

void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
  DumpExpr(Node);
  OS << " " << (Node->getValue() ? "true" : "false");
}

void StmtDumper::VisitCXXThisExpr(CXXThisExpr *Node) {
  DumpExpr(Node);
  OS << " this";
}

void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
  DumpExpr(Node);
  OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
     << " <" << Node->getCastKindName() << ">";
}

void StmtDumper::VisitCXXConstructExpr(CXXConstructExpr *Node) {
  DumpExpr(Node);
  CXXConstructorDecl *Ctor = Node->getConstructor();
  DumpType(Ctor->getType());
  if (Node->isElidable())
    OS << " elidable";
  if (Node->requiresZeroInitialization())
    OS << " zeroing";
}

void StmtDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
  DumpExpr(Node);
  OS << " ";
  DumpCXXTemporary(Node->getTemporary());
}

void StmtDumper::VisitExprWithCleanups(ExprWithCleanups *Node) {
  DumpExpr(Node);
  ++IndentLevel;
  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) {
    OS << "\n";
    Indent();
    OS << "(cleanup ";
    DumpDeclRef(Node->getObject(i));
    OS << ")";
  }
  --IndentLevel;
}

void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) {
  OS << "(CXXTemporary " << (void *)Temporary << ")";
}

//===----------------------------------------------------------------------===//
// Obj-C Expressions
//===----------------------------------------------------------------------===//

void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
  DumpExpr(Node);
  OS << " selector=" << Node->getSelector().getAsString();
  switch (Node->getReceiverKind()) {
  case ObjCMessageExpr::Instance:
    break;

  case ObjCMessageExpr::Class:
    OS << " class=";
    DumpType(Node->getClassReceiver());
    break;

  case ObjCMessageExpr::SuperInstance:
    OS << " super (instance)";
    break;

  case ObjCMessageExpr::SuperClass:
    OS << " super (class)";
    break;
  }
}

void StmtDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) {
  DumpStmt(Node);
  if (VarDecl *CatchParam = Node->getCatchParamDecl()) {
    OS << " catch parm = ";
    DumpDeclarator(CatchParam);
  } else {
    OS << " catch all";
  }
}

void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
  DumpExpr(Node);
  OS << " ";
  DumpType(Node->getEncodedType());
}

void StmtDumper::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
  DumpExpr(Node);

  OS << " " << Node->getSelector().getAsString();
}

void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
  DumpExpr(Node);

  OS << ' ' <<* Node->getProtocol();
}

void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
  DumpExpr(Node);
  if (Node->isImplicitProperty()) {
    OS << " Kind=MethodRef Getter=\"";
    if (Node->getImplicitPropertyGetter())
      OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
    else
      OS << "(null)";

    OS << "\" Setter=\"";
    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
      OS << Setter->getSelector().getAsString();
    else
      OS << "(null)";
    OS << "\"";
  } else {
    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
  }

  if (Node->isSuperReceiver())
    OS << " super";
}

//===----------------------------------------------------------------------===//
// Stmt method implementations
//===----------------------------------------------------------------------===//

/// dump - This does a local dump of the specified AST fragment.  It dumps the
/// specified node and a few nodes underneath it, but not the whole subtree.
/// This is useful in a debugger.
void Stmt::dump(SourceManager &SM) const {
  dump(llvm::errs(), SM);
}

void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
  StmtDumper P(&SM, OS, 4);
  P.DumpSubTree(const_cast<Stmt*>(this));
  OS << "\n";
}

/// dump - This does a local dump of the specified AST fragment.  It dumps the
/// specified node and a few nodes underneath it, but not the whole subtree.
/// This is useful in a debugger.
void Stmt::dump() const {
  StmtDumper P(0, llvm::errs(), 4);
  P.DumpSubTree(const_cast<Stmt*>(this));
  llvm::errs() << "\n";
}

/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
void Stmt::dumpAll(SourceManager &SM) const {
  StmtDumper P(&SM, llvm::errs(), ~0U);
  P.DumpSubTree(const_cast<Stmt*>(this));
  llvm::errs() << "\n";
}

/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
void Stmt::dumpAll() const {
  StmtDumper P(0, llvm::errs(), ~0U);
  P.DumpSubTree(const_cast<Stmt*>(this));
  llvm::errs() << "\n";
}
