From 09c39db0c42de4fb79dd5a64221fe0fb65fc16b4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 15 Sep 2007 23:02:28 +0000 Subject: [PATCH] convert ast printer and dumper ocver to ASTConsumer interface, genericizing them and eliminating boilerplate code. llvm-svn: 41992 --- clang/Driver/ASTStreamers.cpp | 101 ++++++++++++++++------------------ clang/Driver/ASTStreamers.h | 4 +- clang/Driver/clang.cpp | 12 ++-- 3 files changed, 56 insertions(+), 61 deletions(-) diff --git a/clang/Driver/ASTStreamers.cpp b/clang/Driver/ASTStreamers.cpp index b3517dfaef39..72524f16bc76 100644 --- a/clang/Driver/ASTStreamers.cpp +++ b/clang/Driver/ASTStreamers.cpp @@ -13,6 +13,7 @@ #include "ASTStreamers.h" #include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" #include "clang/AST/CFG.h" #include "clang/Analysis/LiveVariables.h" #include "clang/Analysis/LocalCheckers.h" @@ -80,68 +81,58 @@ static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) { // FIXME: implement the rest... } -void clang::PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) { - ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), - PP.getIdentifierTable()); - ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID); - - while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) { - if (FunctionDecl *FD = dyn_cast(D)) { - PrintFunctionDeclStart(FD); - - if (FD->getBody()) { - fprintf(stderr, " "); - FD->getBody()->dumpPretty(); - fprintf(stderr, "\n"); +namespace { + class ASTPrinter : public ASTConsumer { + virtual void HandleTopLevelDecl(Decl *D) { + if (FunctionDecl *FD = dyn_cast(D)) { + PrintFunctionDeclStart(FD); + + if (FD->getBody()) { + fprintf(stderr, " "); + FD->getBody()->dumpPretty(); + fprintf(stderr, "\n"); + } + } else if (TypedefDecl *TD = dyn_cast(D)) { + PrintTypeDefDecl(TD); + } else if (ObjcInterfaceDecl *OID = dyn_cast(D)) { + PrintObjcInterfaceDecl(OID); + } else if (ScopedDecl *SD = dyn_cast(D)) { + fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName()); } - } else if (TypedefDecl *TD = dyn_cast(D)) { - PrintTypeDefDecl(TD); - } else if (ObjcInterfaceDecl *OID = dyn_cast(D)) { - PrintObjcInterfaceDecl(OID); - } else if (ScopedDecl *SD = dyn_cast(D)) { - fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName()); } - } - - if (Stats) { - fprintf(stderr, "\nSTATISTICS:\n"); - ASTStreamer_PrintStats(Streamer); - Context.PrintStats(); - } - - ASTStreamer_Terminate(Streamer); + }; } -void clang::DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) { - ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), - PP.getIdentifierTable()); - ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID); - - while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) { - if (FunctionDecl *FD = dyn_cast(D)) { - PrintFunctionDeclStart(FD); - - if (FD->getBody()) { - fprintf(stderr, "\n"); - FD->getBody()->dumpAll(PP.getSourceManager()); - fprintf(stderr, "\n"); - } - } else if (TypedefDecl *TD = dyn_cast(D)) { - PrintTypeDefDecl(TD); - } else if (ScopedDecl *SD = dyn_cast(D)) { - fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName()); +ASTConsumer *clang::CreateASTPrinter() { return new ASTPrinter(); } + +namespace { + class ASTDumper : public ASTConsumer { + SourceManager *SM; + public: + void Initialize(ASTContext &Context, unsigned MainFileID) { + SM = &Context.SourceMgr; } - } - - if (Stats) { - fprintf(stderr, "\nSTATISTICS:\n"); - ASTStreamer_PrintStats(Streamer); - Context.PrintStats(); - } - - ASTStreamer_Terminate(Streamer); + + virtual void HandleTopLevelDecl(Decl *D) { + if (FunctionDecl *FD = dyn_cast(D)) { + PrintFunctionDeclStart(FD); + + if (FD->getBody()) { + fprintf(stderr, "\n"); + FD->getBody()->dumpAll(*SM); + fprintf(stderr, "\n"); + } + } else if (TypedefDecl *TD = dyn_cast(D)) { + PrintTypeDefDecl(TD); + } else if (ScopedDecl *SD = dyn_cast(D)) { + fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName()); + } + } + }; } +ASTConsumer *clang::CreateASTDumper() { return new ASTDumper(); } + //===----------------------------------------------------------------------===// // CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit // the CFGs for all function definitions. diff --git a/clang/Driver/ASTStreamers.h b/clang/Driver/ASTStreamers.h index e21c1c9aa001..09f1423e6591 100644 --- a/clang/Driver/ASTStreamers.h +++ b/clang/Driver/ASTStreamers.h @@ -21,8 +21,8 @@ class FunctionDecl; class TypedefDecl; class ASTConsumer; -void PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); -void DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); +ASTConsumer *CreateASTPrinter(); +ASTConsumer *CreateASTDumper(); void DumpCFGs(Preprocessor &PP, unsigned MainFileID, bool Stats, bool use_graphviz = false); diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index d6f4da8a8748..7c25a0a9b08f 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -844,12 +844,16 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID, ParseAST(PP, MainFileID, NullConsumer, Stats); break; } - case ParseASTPrint: - PrintASTs(PP, MainFileID, Stats); + case ParseASTPrint: { + std::auto_ptr C(CreateASTPrinter()); + ParseAST(PP, MainFileID, *C.get(), Stats); break; - case ParseASTDump: - DumpASTs(PP, MainFileID, Stats); + } + case ParseASTDump: { + std::auto_ptr C(CreateASTDumper()); + ParseAST(PP, MainFileID, *C.get(), Stats); break; + } case ParseCFGDump: DumpCFGs(PP, MainFileID, Stats); break;