[cfe-commits] r55442 - in /cfe/trunk: Driver/AnalysisConsumer.cpp Driver/AnalysisConsumer.h Driver/clang.cpp utils/ubiviz
Ted Kremenek
kremenek at apple.com
Wed Aug 27 15:31:43 PDT 2008
Author: kremenek
Date: Wed Aug 27 17:31:43 2008
New Revision: 55442
URL: http://llvm.org/viewvc/llvm-project?rev=55442&view=rev
Log:
Added Ubigraph visualization for the static analyzer (this is pretty alpha quality).
Added:
cfe/trunk/utils/ubiviz (with props)
Modified:
cfe/trunk/Driver/AnalysisConsumer.cpp
cfe/trunk/Driver/AnalysisConsumer.h
cfe/trunk/Driver/clang.cpp
Modified: cfe/trunk/Driver/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/AnalysisConsumer.cpp?rev=55442&r1=55441&r2=55442&view=diff
==============================================================================
--- cfe/trunk/Driver/AnalysisConsumer.cpp (original)
+++ cfe/trunk/Driver/AnalysisConsumer.cpp Wed Aug 27 17:31:43 2008
@@ -31,11 +31,13 @@
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "llvm/Support/Streams.h"
-
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
#include <vector>
using namespace clang;
+static ExplodedNodeImpl::Auditor* CreateUbiViz();
//===----------------------------------------------------------------------===//
// Basic type definitions.
@@ -59,7 +61,8 @@
Actions ObjCImplementationActions;
public:
- const bool Visualize;
+ const bool VisGraphviz;
+ const bool VisUbigraph;
const bool TrimGraph;
const LangOptions& LOpts;
Diagnostic &Diags;
@@ -76,8 +79,9 @@
const LangOptions& lopts,
const std::string& fname,
const std::string& htmldir,
- bool visualize, bool trim, bool analyzeAll)
- : Visualize(visualize), TrimGraph(trim), LOpts(lopts), Diags(diags),
+ bool visgraphviz, bool visubi, bool trim, bool analyzeAll)
+ : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim),
+ LOpts(lopts), Diags(diags),
Ctx(0), PP(pp), PPF(ppf),
HTMLDir(htmldir),
FName(fname),
@@ -168,8 +172,16 @@
return liveness.get();
}
+ bool shouldVisualizeGraphviz() const {
+ return C.VisGraphviz;
+ }
+
+ bool shouldVisualizeUbigraph() const {
+ return C.VisUbigraph;
+ }
+
bool shouldVisualize() const {
- return C.Visualize;
+ return C.VisGraphviz || C.VisUbigraph;
}
bool shouldTrimGraph() const {
@@ -319,15 +331,26 @@
Eng.RegisterInternalChecks();
RegisterAppleChecks(Eng);
}
+
+ // Set the graph auditor.
+ llvm::OwningPtr<ExplodedNodeImpl::Auditor> Auditor;
+ if (mgr.shouldVisualizeUbigraph()) {
+ Auditor.reset(CreateUbiViz());
+ ExplodedNodeImpl::SetAuditor(Auditor.get());
+ }
// Execute the worklist algorithm.
Eng.ExecuteWorkList();
+ // Release the auditor (if any) so that it doesn't monitor the graph
+ // created BugReporter.
+ ExplodedNodeImpl::SetAuditor(0);
+
// Display warnings.
Eng.EmitWarnings(mgr);
// Visualize the exploded graph.
- if (mgr.shouldVisualize())
+ if (mgr.shouldVisualizeGraphviz())
Eng.ViewGraph(mgr.shouldTrimGraph());
}
@@ -418,12 +441,13 @@
const LangOptions& lopts,
const std::string& fname,
const std::string& htmldir,
- bool visualize, bool trim,
+ bool VisGraphviz, bool VisUbi,
+ bool trim,
bool analyzeAll) {
llvm::OwningPtr<AnalysisConsumer>
C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir,
- visualize, trim, analyzeAll));
+ VisGraphviz, VisUbi, trim, analyzeAll));
for ( ; Beg != End ; ++Beg)
switch (*Beg) {
@@ -438,3 +462,75 @@
return C.take();
}
+//===----------------------------------------------------------------------===//
+// Ubigraph Visualization. FIXME: Move to separate file.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class UbigraphViz : public ExplodedNodeImpl::Auditor {
+ llvm::OwningPtr<llvm::raw_ostream> Out;
+ unsigned Cntr;
+
+ typedef llvm::DenseMap<void*,unsigned> VMap;
+ VMap M;
+
+public:
+ UbigraphViz(llvm::raw_ostream* out) : Out(out), Cntr(0) {}
+ virtual void AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst);
+};
+
+} // end anonymous namespace
+
+static ExplodedNodeImpl::Auditor* CreateUbiViz() {
+ std::string ErrMsg;
+
+ llvm::sys::Path Filename = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
+ if (!ErrMsg.empty())
+ return 0;
+
+ Filename.appendComponent("llvm_ubi");
+ Filename.makeUnique(true,&ErrMsg);
+
+ if (!ErrMsg.empty())
+ return 0;
+
+ llvm::cerr << "Writing '" << Filename << "'.\n";
+
+ llvm::OwningPtr<llvm::raw_fd_ostream> Stream;
+ std::string filename = Filename.toString();
+ Stream.reset(new llvm::raw_fd_ostream(filename.c_str(), ErrMsg));
+
+ if (!ErrMsg.empty())
+ return 0;
+
+ return new UbigraphViz(Stream.take());
+}
+
+void UbigraphViz::AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst) {
+ // Lookup the Src. If it is a new node, it's a root.
+ VMap::iterator SrcI= M.find(Src);
+ unsigned SrcID;
+
+ if (SrcI == M.end()) {
+ M[Src] = SrcID = Cntr++;
+ *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
+ }
+ else
+ SrcID = SrcI->second;
+
+ // Lookup the Dst.
+ VMap::iterator DstI= M.find(Dst);
+ unsigned DstID;
+
+ if (DstI == M.end()) {
+ M[Dst] = DstID = Cntr++;
+ *Out << "('vertex', " << DstID << ")\n";
+ }
+ else
+ DstID = DstI->second;
+
+ // Add the edge.
+ *Out << "('edge', " << SrcID << ", " << DstID << ")\n";
+}
+
Modified: cfe/trunk/Driver/AnalysisConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/AnalysisConsumer.h?rev=55442&r1=55441&r2=55442&view=diff
==============================================================================
--- cfe/trunk/Driver/AnalysisConsumer.h (original)
+++ cfe/trunk/Driver/AnalysisConsumer.h Wed Aug 27 17:31:43 2008
@@ -28,8 +28,10 @@
const LangOptions& lopts,
const std::string& fname,
const std::string& htmldir,
- bool visualize, bool trim,
- bool analyzeAll);
+ bool VisualizeGraphViz,
+ bool VisualizeUbi,
+ bool VizTrimGraph,
+ bool AnalyzeAll);
} // end clang namespace
#endif
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=55442&r1=55441&r2=55442&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Wed Aug 27 17:31:43 2008
@@ -159,11 +159,15 @@
//===----------------------------------------------------------------------===//
static llvm::cl::opt<bool>
-VisualizeEG("visualize-egraph",
- llvm::cl::desc("Display static analysis Exploded Graph"));
+VisualizeEGDot("analyzer-viz-egraph-graphviz",
+ llvm::cl::desc("Display exploded graph using GraphViz"));
static llvm::cl::opt<bool>
-AnalyzeAll("checker-opt-analyze-headers",
+VisualizeEGUbi("analyzer-viz-egraph-ubigraph",
+ llvm::cl::desc("Display exploded graph using Ubigraph"));
+
+static llvm::cl::opt<bool>
+AnalyzeAll("analyzer-opt-analyze-headers",
llvm::cl::desc("Force the static analyzer to analyze "
"functions defined in header files"));
@@ -964,8 +968,8 @@
&AnalysisList[0]+AnalysisList.size(),
Diag, PP, PPF, LangOpts,
AnalyzeSpecificFunction,
- OutputFile, VisualizeEG, TrimGraph,
- AnalyzeAll);
+ OutputFile, VisualizeEGDot, VisualizeEGUbi,
+ TrimGraph, AnalyzeAll);
}
}
Added: cfe/trunk/utils/ubiviz
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/ubiviz?rev=55442&view=auto
==============================================================================
--- cfe/trunk/utils/ubiviz (added)
+++ cfe/trunk/utils/ubiviz Wed Aug 27 17:31:43 2008
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This script reads visualization data emitted by the static analyzer for
+# display in Ubigraph.
+#
+##===----------------------------------------------------------------------===##
+
+import xmlrpclib
+import sys
+
+def Error(message):
+ print >> sys.stderr, 'ubiviz: ' + message
+ sys.exit(1)
+
+def StreamData(filename):
+ file = open(filename)
+ for ln in file:
+ yield eval(ln)
+ file.close()
+
+def Display(G, data):
+ action = data[0]
+ if action == 'vertex':
+ vertex = data[1]
+ G.new_vertex_w_id(vertex)
+ for attribute in data[2:]:
+ G.set_vertex_attribute(vertex, attribute[0], attribute[1])
+ elif action == 'edge':
+ src = data[1]
+ dst = data[2]
+ edge = G.new_edge(src,dst)
+ for attribute in data[3:]:
+ G.set_edge_attribute(edge, attribute[0], attribute[1])
+
+def main(args):
+ if len(args) == 0:
+ Error('no input files')
+
+ server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
+ G = server.ubigraph
+
+ for arg in args:
+ G.clear()
+ for x in StreamData(arg):
+ Display(G,x)
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
+
+
\ No newline at end of file
Propchange: cfe/trunk/utils/ubiviz
------------------------------------------------------------------------------
svn:executable = *
More information about the cfe-commits
mailing list