Hi alexfh,

This patch changes clang -ast-dump so that it dumps Decls in the same format 
that it already uses for Stmts.

This is an early version of the patch. I would like feedback about whether the 
general approach is okay.

There's two main changes in the patch. Later versions of the patch will split 
these into separate patches. The first change is to move parts of StmtDumper 
that aren't specific to Stmts into the new ASTDumper class. The second change 
is to create the new DeclDumper class, and change Decl::dump and StmtDumper to 
use it.

The main work still to do is to fill out DeclDumper to handle more types of 
Decl, adding tests in the process.

http://llvm-reviews.chandlerc.com/D52

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTDumper.h
  lib/AST/CMakeLists.txt
  lib/AST/DeclDumper.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/StmtDumper.cpp
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -360,17 +360,12 @@
   static void EnableStatistics();
   static void PrintStats();
 
-  /// 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.
+  /// dump - This does a dump of the specified AST fragment and all subtrees.
   /// This is useful in a debugger.
   LLVM_ATTRIBUTE_USED void dump() const;
   LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
   void dump(raw_ostream &OS, SourceManager &SM) const;
 
-  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
-  void dumpAll() const;
-  void dumpAll(SourceManager &SM) const;
-
   /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
   /// back to its original source language syntax.
   void dumpPretty(ASTContext &Context) const;
Index: lib/AST/ASTDumper.cpp
===================================================================
--- /dev/null
+++ lib/AST/ASTDumper.cpp
@@ -0,0 +1,96 @@
+//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTDumper class, which dumps out the
+// AST in a form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ASTDumper.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+void ASTDumper::flush() {
+  if (NeedNewLine)
+    OS << "\n";
+  NeedNewLine = false;
+}
+
+void ASTDumper::indent() {
+  if (NeedNewLine)
+    OS << "\n";
+
+  NeedNewLine = true;
+  for (int i = 0, e = IndentLevel; i < e; ++i)
+    OS << "  ";
+  OS << "(";
+  IndentLevel++;
+}
+
+void ASTDumper::unindent() {
+  OS << ")";
+  IndentLevel--;
+}
+
+void ASTDumper::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 ASTDumper::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 ASTDumper::dumpSourceRange(SourceRange R) {
+  // 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.
+
+  OS << " <";
+  dumpLocation(R.getBegin());
+  if (R.getBegin() != R.getEnd()) {
+    OS << ", ";
+    dumpLocation(R.getEnd());
+  }
+  OS << ">";
+}
Index: lib/AST/ASTDumper.h
===================================================================
--- /dev/null
+++ lib/AST/ASTDumper.h
@@ -0,0 +1,62 @@
+//===--- ASTDumper.h - Dumping implementation for ASTS ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTDumper class, which dumps out the
+// AST in a form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTDUMPER_H
+#define LLVM_CLANG_AST_ASTDUMPER_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+
+class SourceManager;
+class SourceRange;
+class SourceLocation;
+class QualType;
+class Decl;
+class Stmt;
+
+class ASTDumper {
+public:
+  ASTDumper(SourceManager *SM, raw_ostream &OS)
+    : SM(SM), OS(OS), IndentLevel(0), LastLocFilename(""), LastLocLine(~0U),
+    NeedNewLine(false) {
+  }
+
+  void flush();
+  void indent();
+  void unindent();
+
+  void dumpDecl(Decl *D);
+  void dumpStmt(Stmt *S);
+  void dumpType(QualType T);
+  void dumpSourceRange(SourceRange R);
+
+private:
+  void dumpLocation(SourceLocation Loc);
+
+  SourceManager *SM;
+  raw_ostream &OS;
+  unsigned IndentLevel;
+
+  /// 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;
+
+  bool NeedNewLine;
+};
+
+}
+
+#endif
Index: lib/AST/CMakeLists.txt
===================================================================
--- lib/AST/CMakeLists.txt
+++ lib/AST/CMakeLists.txt
@@ -5,6 +5,7 @@
   ASTConsumer.cpp
   ASTContext.cpp
   ASTDiagnostic.cpp
+  ASTDumper.cpp
   ASTImporter.cpp
   AttrImpl.cpp
   CXXInheritance.cpp
@@ -19,6 +20,7 @@
   DeclarationName.cpp
   DeclBase.cpp
   DeclCXX.cpp
+  DeclDumper.cpp
   DeclFriend.cpp
   DeclGroup.cpp
   DeclObjC.cpp
Index: lib/AST/DeclDumper.cpp
===================================================================
--- /dev/null
+++ lib/AST/DeclDumper.cpp
@@ -0,0 +1,110 @@
+//===--- DeclDumper.cpp - Dumping implementation for Decl 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 Decl::dump method, which dumps out the
+// AST in a form that exposes type details and other fields.
+//
+//===----------------------------------------------------------------------===//
+#include "ASTDumper.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  class DeclDumper : public DeclVisitor<DeclDumper> {
+    ASTDumper &Dumper;
+    raw_ostream &OS;
+
+  public:
+    DeclDumper(ASTDumper &Dumper, raw_ostream &OS)
+      : Dumper(Dumper), OS(OS) {
+    }
+
+    void dumpDecl(Decl *D);
+    void dumpDeclContext(DeclContext *DC);
+
+    void VisitEnumConstantDecl(EnumConstantDecl *D);
+    void VisitFunctionDecl(FunctionDecl *D);
+    void VisitFieldDecl(FieldDecl *D);
+    void VisitVarDecl(VarDecl *D);
+  };
+}
+
+void DeclDumper::dumpDecl(Decl *D) {
+  Dumper.indent();
+  if (D) {
+    OS << D->getDeclKindName() << "Decl"
+       << " " << (const void*)D;
+    if (isa<NamedDecl>(D))
+      OS << " " << cast<NamedDecl>(D)->getNameAsString();
+    Dumper.dumpSourceRange(D->getSourceRange());
+    Visit(D);
+    dumpDeclContext(dyn_cast<DeclContext>(D));
+  } else {
+    OS << "<<<NULL>>>";
+  }
+  Dumper.unindent();
+}
+
+void DeclDumper::dumpDeclContext(DeclContext *DC) {
+  // Decls within functions are visited by the body
+  if (!DC || isa<FunctionDecl>(*DC))
+    return;
+
+  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
+       D != DEnd; ++D)
+    dumpDecl(*D);
+}
+
+//----------------------------------------------------------------------------
+// Common C declarations
+//----------------------------------------------------------------------------
+
+void DeclDumper::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  if (Expr *Init = D->getInitExpr())
+    Dumper.dumpStmt(Init);
+}
+
+void DeclDumper::VisitFunctionDecl(FunctionDecl *D) {
+  if (D->doesThisDeclarationHaveABody())
+    Dumper.dumpStmt(D->getBody());
+}
+
+void DeclDumper::VisitFieldDecl(FieldDecl *D) {
+  if (Expr *Init = D->getInClassInitializer())
+    Dumper.dumpStmt(Init);
+}
+
+void DeclDumper::VisitVarDecl(VarDecl *D) {
+  if (Expr *Init = D->getInit())
+    Dumper.dumpStmt(Init);
+}
+
+//===----------------------------------------------------------------------===//
+// Decl method implementations
+//===----------------------------------------------------------------------===//
+
+void ASTDumper::dumpDecl(Decl *D) {
+  DeclDumper Dumper(*this, OS);
+  Dumper.dumpDecl(D);
+}
+
+void Decl::dump(raw_ostream &OS) const {
+  ASTDumper Dumper(&getASTContext().getSourceManager(), OS);
+  Dumper.dumpDecl(const_cast<Decl*>(this));
+  Dumper.flush();
+}
+
+void Decl::dump() const {
+  dump(llvm::errs());
+}
Index: lib/AST/DeclPrinter.cpp
===================================================================
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the Decl::dump method, which pretty print the
+// This file implements the Decl::print method, which pretty prints the
 // AST back out to C/Objective-C/C++/Objective-C++ code.
 //
 //===----------------------------------------------------------------------===//
@@ -172,16 +172,6 @@
   Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
 }
 
-void Decl::dump() const {
-  dump(llvm::errs());
-}
-
-void Decl::dump(raw_ostream &Out) const {
-  PrintingPolicy Policy = getASTContext().getPrintingPolicy();
-  Policy.DumpSourceManager = &getASTContext().getSourceManager();
-  print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ true);
-}
-
 raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
   for (unsigned i = 0; i != Indentation; ++i)
     Out << "  ";
Index: lib/AST/StmtDumper.cpp
===================================================================
--- lib/AST/StmtDumper.cpp
+++ lib/AST/StmtDumper.cpp
@@ -7,17 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the Stmt::dump/Stmt::print methods, which dump out the
+// This file implements the Stmt::dump method, which dumps out the
 // AST in a form that exposes type details and other fields.
 //
 //===----------------------------------------------------------------------===//
 
+#include "ASTDumper.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/AST/ASTContext.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;
 
@@ -27,32 +25,16 @@
 
 namespace  {
   class StmtDumper : public StmtVisitor<StmtDumper> {
-    SourceManager *SM;
+    ASTDumper &Dumper;
     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;
+    StmtDumper(ASTDumper &Dumper, raw_ostream &OS)
+      : Dumper(Dumper), OS(OS) {
     }
 
     void DumpSubTree(Stmt *S) {
-      // Prune the recursion if not using dump all.
-      if (MaxDepth == 0) return;
-
-      ++IndentLevel;
+      Dumper.indent();
       if (S) {
         if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
           VisitDeclStmt(DS);
@@ -61,45 +43,23 @@
 
           // Print out children.
           Stmt::child_range CI = S->children();
-          if (CI) {
-            while (CI) {
-              OS << '\n';
-              DumpSubTree(*CI++);
-            }
-          }
+          while (CI)
+            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 << "  ";
+      Dumper.unindent();
     }
 
     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) << "'";
-      }
+      Dumper.dumpType(T);
     }
     void DumpDeclRef(Decl *node);
     void DumpStmt(const Stmt *Node) {
-      Indent();
-      OS << "(" << Node->getStmtClassName()
+      OS << Node->getStmtClassName()
          << " " << (const void*)Node;
-      DumpSourceRange(Node);
+      Dumper.dumpSourceRange(Node->getSourceRange());
     }
     void DumpValueKind(ExprValueKind K) {
       switch (K) {
@@ -124,8 +84,6 @@
       DumpValueKind(Node->getValueKind());
       DumpObjectKind(Node->getObjectKind());
     }
-    void DumpSourceRange(const Stmt *Node);
-    void DumpLocation(SourceLocation Loc);
 
     // Stmts.
     void VisitStmt(Stmt *Node);
@@ -178,57 +136,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-//  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.
 //===----------------------------------------------------------------------===//
 
@@ -236,88 +143,11 @@
   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().getLangOpts()));
-    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().getLangOpts()));
-    OS << ";\"";
-  } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
-    OS << "label " << *LD;
-  } 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;
-  }
+       DI != DE; ++DI)
+    Dumper.dumpDecl(*DI);
 }
 
 void StmtDumper::VisitLabelStmt(LabelStmt *Node) {
@@ -503,35 +333,31 @@
   BlockDecl *block = Node->getBlockDecl();
   OS << " decl=" << block;
 
-  IndentLevel++;
   if (block->capturesCXXThis()) {
-    OS << '\n'; Indent(); OS << "(capture this)";
+    Dumper.indent();
+    OS << "capture this";
+    Dumper.unindent();
   }
   for (BlockDecl::capture_iterator
          i = block->capture_begin(), e = block->capture_end(); i != e; ++i) {
-    OS << '\n';
-    Indent();
-    OS << "(capture ";
+    Dumper.indent();
+    OS << "capture ";
     if (i->isByRef()) OS << "byref ";
     if (i->isNested()) OS << "nested ";
     if (i->getVariable())
       DumpDeclRef(i->getVariable());
     if (i->hasCopyExpr()) DumpSubTree(i->getCopyExpr());
-    OS << ")";
+    Dumper.unindent();
   }
-  IndentLevel--;
 
-  OS << '\n';
   DumpSubTree(block->getBody());
 }
 
 void StmtDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
   DumpExpr(Node);
 
-  if (Expr *Source = Node->getSourceExpr()) {
-    OS << '\n';
+  if (Expr *Source = Node->getSourceExpr())
     DumpSubTree(Source);
-  }
 }
 
 // GNU extensions.
@@ -589,15 +415,12 @@
 
 void StmtDumper::VisitExprWithCleanups(ExprWithCleanups *Node) {
   DumpExpr(Node);
-  ++IndentLevel;
   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) {
-    OS << "\n";
-    Indent();
-    OS << "(cleanup ";
+    Dumper.indent();
+    OS << "cleanup ";
     DumpDeclRef(Node->getObject(i));
-    OS << ")";
+    Dumper.unindent();
   }
-  --IndentLevel;
 }
 
 void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) {
@@ -638,8 +461,7 @@
 void StmtDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) {
   DumpStmt(Node);
   if (VarDecl *CatchParam = Node->getCatchParamDecl()) {
-    OS << " catch parm = ";
-    DumpDeclarator(CatchParam);
+    Dumper.dumpDecl(CatchParam);
   } else {
     OS << " catch all";
   }
@@ -724,38 +546,26 @@
 // 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 ASTDumper::dumpStmt(Stmt *S) {
+  StmtDumper P(*this, OS);
+  P.DumpSubTree(S);
+}
+
+/// \brief This does a dump of the specified AST fragment and all subtrees.
 void Stmt::dump(SourceManager &SM) const {
   dump(llvm::errs(), SM);
 }
 
+/// \brief This does a dump of the specified AST fragment and all subtrees.
 void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
-  StmtDumper P(&SM, OS, 4);
-  P.DumpSubTree(const_cast<Stmt*>(this));
-  OS << "\n";
+  ASTDumper Dumper(&SM, OS);
+  Dumper.dumpStmt(const_cast<Stmt*>(this));
+  Dumper.flush();
 }
 
-/// 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.
+/// \brief This does a dump of the specified AST fragment and all subtrees.
 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";
+  ASTDumper Dumper(0, llvm::errs());
+  Dumper.dumpStmt(const_cast<Stmt*>(this));
+  Dumper.flush();
 }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to