Moved logic for -dump-cfg and -view-cfg into AnalysisConsumer.

Renamed -dump-cfg to -cfg-dump, and -view-cfg to -cfg-view.  This naming better matches the same options for asts (e.g. -ast-dump).

llvm-svn: 53041
This commit is contained in:
Ted Kremenek 2008-07-02 18:23:21 +00:00
parent 6acc782dad
commit f992cfb4ab
5 changed files with 23 additions and 102 deletions

View File

@ -14,12 +14,10 @@
#include "ASTConsumers.h"
#include "HTMLDiagnostics.h"
#include "clang/AST/TranslationUnit.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/CFG.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/Timer.h"
#include "llvm/ADT/OwningPtr.h"
@ -518,92 +516,6 @@ namespace {
ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
//===----------------------------------------------------------------------===//
// CFGVisitor & VisitCFGs - Boilerplate interface and logic to visit
// the CFGs for all function definitions.
namespace {
class CFGVisitor : public ASTConsumer {
std::string FName;
public:
CFGVisitor(const std::string& fname) : FName(fname) {}
CFGVisitor() : FName("") {}
// CFG Visitor interface to be implemented by subclass.
virtual void VisitCFG(CFG& C, Decl& CD) = 0;
virtual bool printFuncDeclStart() { return true; }
virtual void HandleTopLevelDecl(Decl *D);
};
} // end anonymous namespace
void CFGVisitor::HandleTopLevelDecl(Decl *D) {
CFG *C = NULL;
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (!FD->getBody())
return;
if (FName.size() > 0 && FName != FD->getIdentifier()->getName())
return;
if (printFuncDeclStart()) {
DeclPrinter().PrintFunctionDeclStart(FD);
llvm::cerr << '\n';
}
C = CFG::buildCFG(FD->getBody());
}
else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
if (!MD->getBody())
return;
if (FName.size() > 0 && FName != MD->getSelector().getName())
return;
if (printFuncDeclStart()) {
DeclPrinter().PrintObjCMethodDecl(MD);
llvm::cerr << '\n';
}
C = CFG::buildCFG(MD->getBody());
}
if (C) {
VisitCFG(*C, *D);
delete C;
}
}
//===----------------------------------------------------------------------===//
// DumpCFGs - Dump CFGs to stderr or visualize with Graphviz
namespace {
class CFGDumper : public CFGVisitor {
const bool UseGraphviz;
public:
CFGDumper(bool use_graphviz, const std::string& fname)
: CFGVisitor(fname), UseGraphviz(use_graphviz) {}
virtual void VisitCFG(CFG& C, Decl&) {
if (UseGraphviz)
C.viewCFG();
else
C.dump();
}
};
} // end anonymous namespace
ASTConsumer *clang::CreateCFGDumper(bool ViewGraphs, const std::string& FName) {
return new CFGDumper(ViewGraphs, FName);
}
//===----------------------------------------------------------------------===//
// AST Serializer

View File

@ -36,8 +36,6 @@ ASTConsumer *CreateASTDumper();
ASTConsumer *CreateASTViewer();
ASTConsumer *CreateCFGDumper(bool ViewGraphs, const std::string& FName);
ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
const std::string& OutFile,
Diagnostic &Diags,

View File

@ -337,6 +337,16 @@ static void ActionLiveness(AnalysisManager& mgr) {
mgr.getLiveVariables()->dumpBlockLiveness(mgr.getSourceManager());
}
static void ActionCFGDump(AnalysisManager& mgr) {
mgr.DisplayFunction();
mgr.getCFG()->dump();
}
static void ActionCFGView(AnalysisManager& mgr) {
mgr.DisplayFunction();
mgr.getCFG()->viewCFG();
}
//===----------------------------------------------------------------------===//
// AnalysisConsumer creation.
//===----------------------------------------------------------------------===//
@ -376,6 +386,14 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
C->addCodeAction(&ActionSimpleChecks);
break;
case CFGDump:
C->addCodeAction(&ActionCFGDump);
break;
case CFGView:
C->addCodeAction(&ActionCFGView);
break;
default: break;
}

View File

@ -17,6 +17,8 @@
namespace clang {
enum Analyses {
CFGDump,
CFGView,
WarnDeadStores,
WarnUninitVals,
DisplayLiveVariables,

View File

@ -72,8 +72,6 @@ enum ProgActions {
ASTPrint, // Parse ASTs and print them.
ASTDump, // Parse ASTs and dump them.
ASTView, // Parse ASTs and view them in Graphviz.
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
TestSerialization, // Run experimental serialization code.
ParsePrintCallbacks, // Parse and print each callback.
ParseSyntaxOnly, // Parse and perform semantic analysis.
@ -108,10 +106,6 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
"Build ASTs and then debug dump them"),
clEnumValN(ASTView, "ast-view",
"Build ASTs and view them with GraphViz"),
clEnumValN(ParseCFGDump, "dump-cfg",
"Run parser, then build and print CFGs"),
clEnumValN(ParseCFGView, "view-cfg",
"Run parser, then build and view CFGs with Graphviz"),
clEnumValN(TestSerialization, "test-pickling",
"Run prototype serialization code"),
clEnumValN(EmitLLVM, "emit-llvm",
@ -168,6 +162,8 @@ AnalyzeAll("checker-opt-analyze-headers",
static llvm::cl::list<Analyses>
AnalysisList(llvm::cl::desc("Available Source Code Analyses:"),
llvm::cl::values(
clEnumValN(CFGDump, "cfg-dump", "Display Control-Flow Graphs"),
clEnumValN(CFGView, "cfg-view", "View Control-Flow Graphs using GraphViz"),
clEnumValN(DisplayLiveVariables, "dump-live-variables",
"Print results of live variable analysis"),
clEnumValN(WarnDeadStores, "warn-dead-stores",
@ -1189,12 +1185,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
case EmitHTML:
return CreateHTMLPrinter(OutputFile, Diag, PP, PPF);
case ParseCFGDump:
case ParseCFGView:
return CreateCFGDumper(ProgAction == ParseCFGView,
AnalyzeSpecificFunction);
case TestSerialization:
return CreateSerializationTest(Diag, FileMgr);