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
This commit is contained in:
Chris Lattner 2007-09-15 23:02:28 +00:00
Родитель 556beb71b8
Коммит 3d4997da95
3 изменённых файлов: 56 добавлений и 61 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "ASTStreamers.h" #include "ASTStreamers.h"
#include "clang/AST/AST.h" #include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/CFG.h" #include "clang/AST/CFG.h"
#include "clang/Analysis/LiveVariables.h" #include "clang/Analysis/LiveVariables.h"
#include "clang/Analysis/LocalCheckers.h" #include "clang/Analysis/LocalCheckers.h"
@ -80,68 +81,58 @@ static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) {
// FIXME: implement the rest... // FIXME: implement the rest...
} }
void clang::PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats) { namespace {
ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), class ASTPrinter : public ASTConsumer {
PP.getIdentifierTable()); virtual void HandleTopLevelDecl(Decl *D) {
ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID); if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
PrintFunctionDeclStart(FD);
while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->getBody()) {
PrintFunctionDeclStart(FD); fprintf(stderr, " ");
FD->getBody()->dumpPretty();
if (FD->getBody()) { fprintf(stderr, "\n");
fprintf(stderr, " "); }
FD->getBody()->dumpPretty(); } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
fprintf(stderr, "\n"); PrintTypeDefDecl(TD);
} else if (ObjcInterfaceDecl *OID = dyn_cast<ObjcInterfaceDecl>(D)) {
PrintObjcInterfaceDecl(OID);
} else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName());
} }
} else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
PrintTypeDefDecl(TD);
} else if (ObjcInterfaceDecl *OID = dyn_cast<ObjcInterfaceDecl>(D)) {
PrintObjcInterfaceDecl(OID);
} else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(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) { ASTConsumer *clang::CreateASTPrinter() { return new ASTPrinter(); }
ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(),
PP.getIdentifierTable()); namespace {
ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID); class ASTDumper : public ASTConsumer {
SourceManager *SM;
while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) { public:
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { void Initialize(ASTContext &Context, unsigned MainFileID) {
PrintFunctionDeclStart(FD); SM = &Context.SourceMgr;
if (FD->getBody()) {
fprintf(stderr, "\n");
FD->getBody()->dumpAll(PP.getSourceManager());
fprintf(stderr, "\n");
}
} else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
PrintTypeDefDecl(TD);
} else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
fprintf(stderr, "Read top-level variable decl: '%s'\n", SD->getName());
} }
}
virtual void HandleTopLevelDecl(Decl *D) {
if (Stats) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
fprintf(stderr, "\nSTATISTICS:\n"); PrintFunctionDeclStart(FD);
ASTStreamer_PrintStats(Streamer);
Context.PrintStats(); if (FD->getBody()) {
} fprintf(stderr, "\n");
FD->getBody()->dumpAll(*SM);
ASTStreamer_Terminate(Streamer); fprintf(stderr, "\n");
}
} else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
PrintTypeDefDecl(TD);
} else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(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 // CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit
// the CFGs for all function definitions. // the CFGs for all function definitions.

Просмотреть файл

@ -21,8 +21,8 @@ class FunctionDecl;
class TypedefDecl; class TypedefDecl;
class ASTConsumer; class ASTConsumer;
void PrintASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); ASTConsumer *CreateASTPrinter();
void DumpASTs(Preprocessor &PP, unsigned MainFileID, bool Stats); ASTConsumer *CreateASTDumper();
void DumpCFGs(Preprocessor &PP, unsigned MainFileID, void DumpCFGs(Preprocessor &PP, unsigned MainFileID,
bool Stats, bool use_graphviz = false); bool Stats, bool use_graphviz = false);

Просмотреть файл

@ -844,12 +844,16 @@ static void ProcessInputFile(Preprocessor &PP, unsigned MainFileID,
ParseAST(PP, MainFileID, NullConsumer, Stats); ParseAST(PP, MainFileID, NullConsumer, Stats);
break; break;
} }
case ParseASTPrint: case ParseASTPrint: {
PrintASTs(PP, MainFileID, Stats); std::auto_ptr<ASTConsumer> C(CreateASTPrinter());
ParseAST(PP, MainFileID, *C.get(), Stats);
break; break;
case ParseASTDump: }
DumpASTs(PP, MainFileID, Stats); case ParseASTDump: {
std::auto_ptr<ASTConsumer> C(CreateASTDumper());
ParseAST(PP, MainFileID, *C.get(), Stats);
break; break;
}
case ParseCFGDump: case ParseCFGDump:
DumpCFGs(PP, MainFileID, Stats); DumpCFGs(PP, MainFileID, Stats);
break; break;