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);
+}
+
+