From 3d4997da95b169f0ac32cf83af3368778c429898 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41992 91177308-0d34-0410-b5e6-96231b3b80d8 --- Driver/ASTStreamers.cpp | 101 ++++++++++++++++++---------------------- Driver/ASTStreamers.h | 4 +- Driver/clang.cpp | 12 +++-- 3 files changed, 56 insertions(+), 61 deletions(-) diff --git a/Driver/ASTStreamers.cpp b/Driver/ASTStreamers.cpp index b3517dfaef..72524f16bc 100644 --- a/Driver/ASTStreamers.cpp +++ b/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/Driver/ASTStreamers.h b/Driver/ASTStreamers.h index e21c1c9aa0..09f1423e65 100644 --- a/Driver/ASTStreamers.h +++ b/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/Driver/clang.cpp b/Driver/clang.cpp index d6f4da8a87..7c25a0a9b0 100644 --- a/Driver/clang.cpp +++ b/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;