#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"
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
ASTConsumer *CreateASTViewer();
-ASTConsumer *CreateCFGDumper(bool ViewGraphs, const std::string& FName);
-
ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
const std::string& OutFile,
Diagnostic &Diags,
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.
//===----------------------------------------------------------------------===//
C->addCodeAction(&ActionSimpleChecks);
break;
+ case CFGDump:
+ C->addCodeAction(&ActionCFGDump);
+ break;
+
+ case CFGView:
+ C->addCodeAction(&ActionCFGView);
+ break;
+
default: break;
}
namespace clang {
enum Analyses {
+ CFGDump,
+ CFGView,
WarnDeadStores,
WarnUninitVals,
DisplayLiveVariables,
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.
"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",
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",
case EmitHTML:
return CreateHTMLPrinter(OutputFile, Diag, PP, PPF);
-
- case ParseCFGDump:
- case ParseCFGView:
- return CreateCFGDumper(ProgAction == ParseCFGView,
- AnalyzeSpecificFunction);
-
+
case TestSerialization:
return CreateSerializationTest(Diag, FileMgr);