add a new AST dumper interface (E->dump()).  This dumps out
the AST in a structural, non-pretty, form useful for understanding
the AST.  It isn't quite done yet, but is already somewhat useful.

For this example:

int test(short X, long long Y) {
  return X < ((100));
}

we get (with -parse-ast-dump):

int test(short X, long long Y)
(CompoundStmt 0x2905ce0
  (ReturnStmt 0x2905cd0
    (BinaryOperator 0x2905cb0 '<'
      (ImplicitCastExpr 0x2905ca0
        (DeclRefExpr 0x2905c20 Decl='X' 0x2905bb0))
      (ParenExpr 0x2905c80
        (ParenExpr 0x2905c60
          (IntegerLiteral 0x2905c40 100))))))




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40954 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/ASTStreamers.cpp b/Driver/ASTStreamers.cpp
index 19e12bd..7f67cd4 100644
--- a/Driver/ASTStreamers.cpp
+++ b/Driver/ASTStreamers.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/AST.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/ASTStreamer.h"
+using namespace clang;
 
 void clang::BuildASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
   // collect global stats on Decls/Stmts (until we have a module streamer)
@@ -40,7 +41,9 @@
   ASTStreamer_Terminate(Streamer);
 }
 
-void clang::PrintFunctionDecl(FunctionDecl *FD) {
+
+
+static void PrintFunctionDeclStart(FunctionDecl *FD) {
   bool HasBody = FD->getBody();
   
   std::string Proto = FD->getName();
@@ -70,16 +73,12 @@
   AFT->getResultType().getAsStringInternal(Proto);
   fprintf(stderr, "\n%s", Proto.c_str());
   
-  if (FD->getBody()) {
-    fprintf(stderr, " ");
-    FD->getBody()->dump();
-    fprintf(stderr, "\n");
-  } else {
+  if (!FD->getBody())
     fprintf(stderr, ";\n");
-  }
+  // Doesn't print the body.
 }
 
-void clang::PrintTypeDefDecl(TypedefDecl *TD) {
+static void PrintTypeDefDecl(TypedefDecl *TD) {
   std::string S = TD->getName();
   TD->getUnderlyingType().getAsStringInternal(S);
   fprintf(stderr, "typedef %s;\n", S.c_str());
@@ -91,7 +90,13 @@
   
   while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      PrintFunctionDecl(FD);
+      PrintFunctionDeclStart(FD);
+
+      if (FD->getBody()) {
+        fprintf(stderr, " ");
+        FD->getBody()->dumpPretty();
+        fprintf(stderr, "\n");
+      }
     } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
       PrintTypeDefDecl(TD);
     } else {
@@ -107,3 +112,34 @@
   
   ASTStreamer_Terminate(Streamer);
 }
+
+void clang::DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) {
+  ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
+  ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
+  
+  while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      PrintFunctionDeclStart(FD);
+      
+      if (FD->getBody()) {
+        fprintf(stderr, "\n");
+        FD->getBody()->dumpAll();
+        fprintf(stderr, "\n");
+      }
+    } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+      PrintTypeDefDecl(TD);
+    } else {
+      fprintf(stderr, "Read top-level variable decl: '%s'\n", D->getName());
+    }
+  }
+  
+  if (Stats) {
+    fprintf(stderr, "\nSTATISTICS:\n");
+    ASTStreamer_PrintStats(Streamer);
+    Context.PrintStats();
+  }
+  
+  ASTStreamer_Terminate(Streamer);
+}
+
+