Skip to content

Commit ac886cb

Browse files
committed
Added initial graph visualization support for the GRConstants analysis.
llvm-svn: 46092
1 parent 873bbd5 commit ac886cb

File tree

1 file changed

+85
-11
lines changed

1 file changed

+85
-11
lines changed

clang/Analysis/GRConstants.cpp

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,30 @@
2828
#include "llvm/ADT/SmallVector.h"
2929
#include "llvm/Support/Compiler.h"
3030

31+
#ifndef NDEBUG
32+
#include "llvm/Support/GraphWriter.h"
33+
#include <sstream>
34+
#endif
35+
3136
using namespace clang;
3237
using llvm::APInt;
3338
using llvm::APFloat;
3439
using llvm::dyn_cast;
3540
using llvm::cast;
3641

3742
//===----------------------------------------------------------------------===//
38-
/// DSPtr - A variant smart pointer that wraps either a Decl* or a
43+
/// DSPtr - A variant smart pointer that wraps either a ValueDecl* or a
3944
/// Stmt*. Use cast<> or dyn_cast<> to get actual pointer type
4045
//===----------------------------------------------------------------------===//
4146
namespace {
4247
class VISIBILITY_HIDDEN DSPtr {
4348
uintptr_t Raw;
4449
public:
45-
enum VariantKind { IsDecl=0x1, IsBlkLvl=0x2, IsSubExp=0x3, Flags=0x3 };
50+
enum VariantKind { IsValueDecl=0x1, IsBlkLvl=0x2, IsSubExp=0x3, Flags=0x3 };
4651
inline void* getPtr() const { return reinterpret_cast<void*>(Raw & ~Flags); }
4752
inline VariantKind getKind() const { return (VariantKind) (Raw & Flags); }
4853

49-
DSPtr(Decl* D) : Raw(reinterpret_cast<uintptr_t>(D) | IsDecl) {}
54+
DSPtr(ValueDecl* D) : Raw(reinterpret_cast<uintptr_t>(D) | IsValueDecl) {}
5055
DSPtr(Stmt* S, bool isBlkLvl)
5156
: Raw(reinterpret_cast<uintptr_t>(S) | (isBlkLvl ? IsBlkLvl : IsSubExp)) {}
5257

@@ -64,14 +69,14 @@ class VISIBILITY_HIDDEN DSPtr {
6469

6570
// Machinery to get cast<> and dyn_cast<> working with DSPtr.
6671
namespace llvm {
67-
template<> inline bool isa<Decl,DSPtr>(const DSPtr& V) {
68-
return V.getKind() == DSPtr::IsDecl;
72+
template<> inline bool isa<ValueDecl,DSPtr>(const DSPtr& V) {
73+
return V.getKind() == DSPtr::IsValueDecl;
6974
}
7075
template<> inline bool isa<Stmt,DSPtr>(const DSPtr& V) {
71-
return ((unsigned) V.getKind()) > DSPtr::IsDecl;
76+
return ((unsigned) V.getKind()) > DSPtr::IsValueDecl;
7277
}
73-
template<> struct VISIBILITY_HIDDEN cast_retty_impl<Decl,DSPtr> {
74-
typedef const Decl* ret_type;
78+
template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,DSPtr> {
79+
typedef const ValueDecl* ret_type;
7580
};
7681
template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,DSPtr> {
7782
typedef const Stmt* ret_type;
@@ -147,7 +152,7 @@ class VISIBILITY_HIDDEN GRConstants : public CFGStmtVisitor<GRConstants> {
147152
typedef ExplodedNode<StateTy> NodeTy;
148153

149154
protected:
150-
// Liveness - live-variables information the Decl* and Expr* (block-level)
155+
// Liveness - live-variables information the ValueDecl* and Expr* (block-level)
151156
// in the CFG. Used to prune out dead state.
152157
LiveVariables* Liveness;
153158

@@ -192,7 +197,7 @@ class VISIBILITY_HIDDEN GRConstants : public CFGStmtVisitor<GRConstants> {
192197
StateTy RemoveGrandchildrenMappings(Stmt* S, StateTy M);
193198

194199
void AddBinding(Expr* E, ExprVariantTy V, bool isBlkLvl = false);
195-
void AddBinding(Decl* D, ExprVariantTy V);
200+
void AddBinding(ValueDecl* D, ExprVariantTy V);
196201

197202
ExprVariantTy GetBinding(Expr* E);
198203

@@ -236,7 +241,7 @@ void GRConstants::AddBinding(Expr* E, ExprVariantTy V, bool isBlkLvl) {
236241
CurrentState = StateMgr.Add(CurrentState, DSPtr(E,isBlkLvl), V.getVal());
237242
}
238243

239-
void GRConstants::AddBinding(Decl* D, ExprVariantTy V) {
244+
void GRConstants::AddBinding(ValueDecl* D, ExprVariantTy V) {
240245
if (V)
241246
CurrentState = StateMgr.Add(CurrentState, DSPtr(D), V.getVal());
242247
else
@@ -322,9 +327,78 @@ void GRConstants::VisitBinAssign(BinaryOperator* B) {
322327
// Driver.
323328
//===----------------------------------------------------------------------===//
324329

330+
#ifndef NDEBUG
331+
namespace llvm {
332+
template<>
333+
struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
334+
public DefaultDOTGraphTraits {
335+
336+
static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
337+
std::ostringstream Out;
338+
339+
Out << "Vertex: " << (void*) N << '\n';
340+
ProgramPoint Loc = N->getLocation();
341+
342+
switch (Loc.getKind()) {
343+
case ProgramPoint::BlockEntranceKind:
344+
Out << "Block Entrance: B"
345+
<< cast<BlockEntrance>(Loc).getBlock()->getBlockID();
346+
break;
347+
348+
case ProgramPoint::BlockExitKind:
349+
assert (false);
350+
break;
351+
352+
case ProgramPoint::PostStmtKind: {
353+
const PostStmt& L = cast<PostStmt>(Loc);
354+
Out << "Stmt: " << (void*) L.getStmt() << '\n';
355+
L.getStmt()->printPretty(Out);
356+
break;
357+
}
358+
359+
default: {
360+
const BlockEdge& E = cast<BlockEdge>(Loc);
361+
Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
362+
<< E.getDst()->getBlockID() << ')';
363+
}
364+
}
365+
366+
Out << "\n{";
367+
368+
GRConstants::StateTy M = N->getState();
369+
bool isFirst = true;
370+
371+
for (GRConstants::StateTy::iterator I=M.begin(), E=M.end(); I!=E; ++I) {
372+
if (!isFirst)
373+
Out << '\n';
374+
else
375+
isFirst = false;
376+
377+
if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey())) {
378+
Out << "Decl: " << (void*) V << ", " << V->getName();
379+
}
380+
else {
381+
Stmt* E = cast<Stmt>(I.getKey());
382+
Out << "Stmt: " << (void*) E;
383+
}
384+
385+
Out << " => " << I.getData();
386+
}
387+
388+
Out << " }";
389+
390+
return Out.str();
391+
}
392+
};
393+
} // end llvm namespace
394+
#endif
395+
325396
namespace clang {
326397
void RunGRConstants(CFG& cfg) {
327398
GREngine<GRConstants> Engine(cfg);
328399
Engine.ExecuteWorkList();
400+
#ifndef NDEBUG
401+
llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
402+
#endif
329403
}
330404
}

0 commit comments

Comments
 (0)