Core analysis engine template cleanup step 2:

merge ExplodedGraphImpl and ExplodedGraph.

llvm-svn: 78291
This commit is contained in:
Zhongxing Xu
2009-08-06 06:28:40 +00:00
parent f368fa6728
commit c90a0c2e81
9 changed files with 176 additions and 270 deletions

View File

@@ -358,15 +358,15 @@ public:
/// getEngine - Return the analysis engine used to analyze a given
/// function or method.
GRExprEngine& getEngine() { return Eng; }
GRExprEngine &getEngine() { return Eng; }
/// getGraph - Get the exploded graph created by the analysis engine
/// for the analyzed method or function.
ExplodedGraph<GRState>& getGraph();
ExplodedGraph &getGraph();
/// getStateManager - Return the state manager used by the analysis
/// engine.
GRStateManager& getStateManager();
GRStateManager &getStateManager();
virtual void GeneratePathDiagnostic(PathDiagnostic& PD,
BugReportEquivClass& R);
@@ -402,7 +402,7 @@ public:
GRBugReporter& getBugReporter() { return BR; }
ExplodedGraph<GRState>& getGraph() { return BR.getGraph(); }
ExplodedGraph &getGraph() { return BR.getGraph(); }
void addNotableSymbol(SymbolRef Sym) {
// FIXME: For now forward to GRBugReporter.

View File

@@ -48,7 +48,7 @@ class GREndPathNodebuilderImpl;
class ExplodedNode : public llvm::FoldingSetNode {
protected:
friend class ExplodedGraphImpl;
friend class ExplodedGraph;
friend class GRCoreEngineImpl;
friend class GRStmtNodeBuilderImpl;
friend class GRBranchNodeBuilderImpl;
@@ -192,17 +192,19 @@ public:
static void SetAuditor(Auditor* A);
};
// FIXME: Is this class necessary?
class InterExplodedGraphMap {
llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
friend class ExplodedGraph;
template <typename StateTy>
struct GRTrait {
static inline void Profile(llvm::FoldingSetNodeID& ID, const StateTy* St) {
St->Profile(ID);
}
public:
ExplodedNode* getMappedNode(const ExplodedNode* N) const;
InterExplodedGraphMap() {};
virtual ~InterExplodedGraphMap() {}
};
class InterExplodedGraphMapImpl;
class ExplodedGraphImpl {
class ExplodedGraph {
protected:
friend class GRCoreEngineImpl;
friend class GRStmtNodeBuilderImpl;
@@ -224,7 +226,10 @@ protected:
/// EndNodes - The nodes in the simulation graph which have been
/// specially marked as the endpoint of an abstract simulation path.
EndNodesTy EndNodes;
/// Nodes - The nodes in the graph.
llvm::FoldingSet<ExplodedNode> Nodes;
/// Allocator - BumpPtrAllocator to create nodes.
llvm::BumpPtrAllocator Allocator;
@@ -241,14 +246,18 @@ protected:
/// NumNodes - The number of nodes in the graph.
unsigned NumNodes;
/// getNodeImpl - Retrieve the node associated with a (Location,State)
/// pair, where 'State' is represented as an opaque void*. This method
/// is intended to be used only by GRCoreEngineImpl.
virtual ExplodedNode* getNodeImpl(const ProgramPoint& L,
const void* State,
bool* IsNew) = 0;
public:
/// getNode - Retrieve the node associated with a (Location,State) pair,
/// where the 'Location' is a ProgramPoint in the CFG. If no node for
/// this pair exists, it is created. IsNew is set to true if
/// the node was freshly created.
ExplodedNode* getNode(const ProgramPoint& L, const GRState *State,
bool* IsNew = 0);
virtual ExplodedGraphImpl* MakeEmptyGraph() const = 0;
ExplodedGraph* MakeEmptyGraph() const {
return new ExplodedGraph(cfg, CodeDecl, Ctx);
}
/// addRoot - Add an untyped node to the set of roots.
ExplodedNode* addRoot(ExplodedNode* V) {
@@ -261,20 +270,52 @@ protected:
EndNodes.push_back(V);
return V;
}
// ctor.
ExplodedGraphImpl(CFG& c, Decl& cd, ASTContext& ctx)
ExplodedGraph(CFG& c, Decl& cd, ASTContext& ctx)
: cfg(c), CodeDecl(cd), Ctx(ctx), NumNodes(0) {}
public:
virtual ~ExplodedGraphImpl() {}
virtual ~ExplodedGraph() {}
unsigned num_roots() const { return Roots.size(); }
unsigned num_eops() const { return EndNodes.size(); }
bool empty() const { return NumNodes == 0; }
unsigned size() const { return NumNodes; }
// Iterators.
typedef ExplodedNode NodeTy;
typedef llvm::FoldingSet<ExplodedNode> AllNodesTy;
typedef NodeTy** roots_iterator;
typedef NodeTy* const * const_roots_iterator;
typedef NodeTy** eop_iterator;
typedef NodeTy* const * const_eop_iterator;
typedef AllNodesTy::iterator node_iterator;
typedef AllNodesTy::const_iterator const_node_iterator;
node_iterator nodes_begin() { return Nodes.begin(); }
node_iterator nodes_end() { return Nodes.end(); }
const_node_iterator nodes_begin() const { return Nodes.begin(); }
const_node_iterator nodes_end() const { return Nodes.end(); }
roots_iterator roots_begin() { return Roots.begin(); }
roots_iterator roots_end() { return Roots.end(); }
const_roots_iterator roots_begin() const { return Roots.begin(); }
const_roots_iterator roots_end() const { return Roots.end(); }
eop_iterator eop_begin() { return EndNodes.begin(); }
eop_iterator eop_end() { return EndNodes.end(); }
const_eop_iterator eop_begin() const { return EndNodes.begin(); }
const_eop_iterator eop_end() const { return EndNodes.end(); }
llvm::BumpPtrAllocator& getAllocator() { return Allocator; }
CFG& getCFG() { return cfg; }
ASTContext& getContext() { return Ctx; }
@@ -288,176 +329,14 @@ public:
typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
ExplodedGraphImpl* Trim(const ExplodedNode* const * NBeg,
const ExplodedNode* const * NEnd,
InterExplodedGraphMapImpl *M,
llvm::DenseMap<const void*, const void*> *InverseMap) const;
};
class InterExplodedGraphMapImpl {
llvm::DenseMap<const ExplodedNode*, ExplodedNode*> M;
friend class ExplodedGraphImpl;
void add(const ExplodedNode* From, ExplodedNode* To);
protected:
ExplodedNode* getMappedImplNode(const ExplodedNode* N) const;
InterExplodedGraphMapImpl();
public:
virtual ~InterExplodedGraphMapImpl() {}
};
//===----------------------------------------------------------------------===//
// Type-specialized ExplodedGraph classes.
//===----------------------------------------------------------------------===//
class InterExplodedGraphMap : public InterExplodedGraphMapImpl {
public:
InterExplodedGraphMap() {};
~InterExplodedGraphMap() {};
ExplodedNode* getMappedNode(const ExplodedNode* N) const {
return static_cast<ExplodedNode*>(getMappedImplNode(N));
}
};
template <typename STATE>
class ExplodedGraph : public ExplodedGraphImpl {
public:
typedef STATE StateTy;
typedef ExplodedNode NodeTy;
typedef llvm::FoldingSet<NodeTy> AllNodesTy;
protected:
virtual ExplodedNode* getNodeImpl(const ProgramPoint& L,
const void* State,
bool* IsNew) {
return getNode(L, static_cast<const StateTy*>(State), IsNew);
}
/// Nodes - The nodes in the graph.
AllNodesTy Nodes;
protected:
virtual ExplodedGraphImpl* MakeEmptyGraph() const {
return new ExplodedGraph(cfg, CodeDecl, Ctx);
}
public:
ExplodedGraph(CFG& c, Decl& cd, ASTContext& ctx)
: ExplodedGraphImpl(c, cd, ctx) {}
/// getNode - Retrieve the node associated with a (Location,State) pair,
/// where the 'Location' is a ProgramPoint in the CFG. If no node for
/// this pair exists, it is created. IsNew is set to true if
/// the node was freshly created.
NodeTy* getNode(const ProgramPoint& L, const GRState* State,
bool* IsNew = NULL) {
// Profile 'State' to determine if we already have an existing node.
llvm::FoldingSetNodeID profile;
void* InsertPos = 0;
NodeTy::Profile(profile, L, State);
NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
if (!V) {
// Allocate a new node.
V = (NodeTy*) Allocator.Allocate<NodeTy>();
new (V) NodeTy(L, State);
// Insert the node into the node set and return it.
Nodes.InsertNode(V, InsertPos);
++NumNodes;
if (IsNew) *IsNew = true;
}
else
if (IsNew) *IsNew = false;
return V;
}
// Iterators.
typedef NodeTy** roots_iterator;
typedef const NodeTy** const_roots_iterator;
typedef NodeTy** eop_iterator;
typedef const NodeTy** const_eop_iterator;
typedef typename AllNodesTy::iterator node_iterator;
typedef typename AllNodesTy::const_iterator const_node_iterator;
node_iterator nodes_begin() {
return Nodes.begin();
}
node_iterator nodes_end() {
return Nodes.end();
}
const_node_iterator nodes_begin() const {
return Nodes.begin();
}
const_node_iterator nodes_end() const {
return Nodes.end();
}
roots_iterator roots_begin() {
return reinterpret_cast<roots_iterator>(Roots.begin());
}
roots_iterator roots_end() {
return reinterpret_cast<roots_iterator>(Roots.end());
}
const_roots_iterator roots_begin() const {
return const_cast<ExplodedGraph>(this)->roots_begin();
}
const_roots_iterator roots_end() const {
return const_cast<ExplodedGraph>(this)->roots_end();
}
eop_iterator eop_begin() {
return reinterpret_cast<eop_iterator>(EndNodes.begin());
}
eop_iterator eop_end() {
return reinterpret_cast<eop_iterator>(EndNodes.end());
}
const_eop_iterator eop_begin() const {
return const_cast<ExplodedGraph>(this)->eop_begin();
}
const_eop_iterator eop_end() const {
return const_cast<ExplodedGraph>(this)->eop_end();
}
std::pair<ExplodedGraph*, InterExplodedGraphMap*>
Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
llvm::DenseMap<const void*, const void*> *InverseMap = 0) const {
if (NBeg == NEnd)
return std::make_pair((ExplodedGraph*) 0,
(InterExplodedGraphMap*) 0);
assert (NBeg < NEnd);
const ExplodedNode* const* NBegImpl =
(const ExplodedNode* const*) NBeg;
const ExplodedNode* const* NEndImpl =
(const ExplodedNode* const*) NEnd;
llvm::OwningPtr<InterExplodedGraphMap> M(new InterExplodedGraphMap());
llvm::DenseMap<const void*, const void*> *InverseMap = 0) const;
ExplodedGraphImpl* G = ExplodedGraphImpl::Trim(NBegImpl, NEndImpl, M.get(),
InverseMap);
return std::make_pair(static_cast<ExplodedGraph*>(G), M.take());
}
ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg,
const ExplodedNode* const * NEnd,
InterExplodedGraphMap *M,
llvm::DenseMap<const void*, const void*> *InverseMap) const;
};
class ExplodedNodeSet {

View File

@@ -49,7 +49,7 @@ protected:
friend class GREndPathNodeBuilderImpl;
/// G - The simulation graph. Each node is a (location,state) pair.
llvm::OwningPtr<ExplodedGraphImpl> G;
llvm::OwningPtr<ExplodedGraph> G;
/// WList - A set of queued nodes that need to be processed by the
/// worklist algorithm. It is up to the implementation of WList to decide
@@ -61,14 +61,14 @@ protected:
/// number of times different CFGBlocks have been visited along a path.
GRBlockCounter::Factory BCounterFactory;
void GenerateNode(const ProgramPoint& Loc, const void* State,
void GenerateNode(const ProgramPoint& Loc, const GRState* State,
ExplodedNode* Pred);
/// getInitialState - Gets the void* representing the initial 'state'
/// of the analysis. This is simply a wrapper (implemented
/// in GRCoreEngine) that performs type erasure on the initial
/// state returned by the checker object.
virtual const void* getInitialState() = 0;
virtual const GRState* getInitialState() = 0;
void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
@@ -98,7 +98,7 @@ private:
GRCoreEngineImpl& operator=(const GRCoreEngineImpl&);
protected:
GRCoreEngineImpl(ExplodedGraphImpl* g, GRWorkList* wl)
GRCoreEngineImpl(ExplodedGraph* g, GRWorkList* wl)
: G(g), WList(wl), BCounterFactory(g->getAllocator()) {}
public:
@@ -142,16 +142,16 @@ public:
}
ExplodedNode*
generateNodeImpl(const ProgramPoint &PP, const void* State,
generateNodeImpl(const ProgramPoint &PP, const GRState* State,
ExplodedNode* Pred);
ExplodedNode*
generateNodeImpl(const Stmt* S, const void* State, ExplodedNode* Pred,
generateNodeImpl(const Stmt* S, const GRState* State, ExplodedNode* Pred,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
const void *tag = 0);
ExplodedNode*
generateNodeImpl(const Stmt* S, const void* State,
generateNodeImpl(const Stmt* S, const GRState* State,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
const void *tag = 0) {
ExplodedNode* N = getLastNode();
@@ -160,7 +160,7 @@ public:
}
ExplodedNode*
generateNodeImpl(const Stmt* S, const void* State, const void *tag = 0) {
generateNodeImpl(const Stmt* S, const GRState* State, const void *tag = 0) {
ExplodedNode* N = getLastNode();
assert (N && "Predecessor of new node is infeasible.");
return generateNodeImpl(S, State, N, ProgramPoint::PostStmtKind, tag);
@@ -325,10 +325,10 @@ public:
~GRBranchNodeBuilderImpl();
ExplodedNode* getPredecessor() const { return Pred; }
const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
const ExplodedGraph& getGraph() const { return *Eng.G; }
GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
ExplodedNode* generateNodeImpl(const void* State, bool branch);
ExplodedNode* generateNodeImpl(const GRState* State, bool branch);
CFGBlock* getTargetBlock(bool branch) const {
return branch ? DstT : DstF;
@@ -349,7 +349,7 @@ public:
template<typename STATE>
class GRBranchNodeBuilder {
typedef STATE StateTy;
typedef ExplodedGraph<StateTy> GraphTy;
typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
GRBranchNodeBuilderImpl& NB;
@@ -425,7 +425,7 @@ public:
Iterator begin() { return Iterator(DispatchBlock.succ_begin()); }
Iterator end() { return Iterator(DispatchBlock.succ_end()); }
ExplodedNode* generateNodeImpl(const Iterator& I, const void* State,
ExplodedNode* generateNodeImpl(const Iterator& I, const GRState* State,
bool isSink);
Expr* getTarget() const { return E; }
@@ -435,7 +435,7 @@ public:
template<typename STATE>
class GRIndirectGotoNodeBuilder {
typedef STATE StateTy;
typedef ExplodedGraph<StateTy> GraphTy;
typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
GRIndirectGotoNodeBuilderImpl& NB;
@@ -492,9 +492,9 @@ public:
Iterator end() { return Iterator(Src->succ_rend()); }
ExplodedNode* generateCaseStmtNodeImpl(const Iterator& I,
const void* State);
const GRState* State);
ExplodedNode* generateDefaultCaseNodeImpl(const void* State,
ExplodedNode* generateDefaultCaseNodeImpl(const GRState* State,
bool isSink);
Expr* getCondition() const { return Condition; }
@@ -504,7 +504,7 @@ public:
template<typename STATE>
class GRSwitchNodeBuilder {
typedef STATE StateTy;
typedef ExplodedGraph<StateTy> GraphTy;
typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
GRSwitchNodeBuilderImpl& NB;
@@ -554,7 +554,7 @@ public:
return getBlockCounter().getNumVisited(B.getBlockID());
}
ExplodedNode* generateNodeImpl(const void* State,
ExplodedNode* generateNodeImpl(const GRState* State,
const void *tag = 0,
ExplodedNode *P = 0);
@@ -604,13 +604,13 @@ public:
typedef SUBENGINE SubEngineTy;
typedef typename SubEngineTy::StateTy StateTy;
typedef typename StateTy::ManagerTy StateManagerTy;
typedef ExplodedGraph<StateTy> GraphTy;
typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
protected:
SubEngineTy& SubEngine;
virtual const void* getInitialState() {
virtual const GRState* getInitialState() {
return SubEngine.getInitialState();
}

View File

@@ -34,8 +34,8 @@ namespace clang {
class GRExprEngine {
public:
typedef GRState StateTy;
typedef ExplodedGraph<StateTy> GraphTy;
typedef GraphTy::NodeTy NodeTy;
typedef ExplodedGraph GraphTy;
typedef GraphTy::NodeTy NodeTy;
// Builders.
typedef GRStmtNodeBuilder<StateTy> StmtNodeBuilder;

View File

@@ -26,7 +26,7 @@ class BugReporter;
class ASTContext;
class GRExprEngine;
class PathDiagnosticClient;
template <typename T> class ExplodedGraph;
class ExplodedGraph;
class GRSimpleAPICheck : public GRAuditor<GRState> {

View File

@@ -349,17 +349,6 @@ public:
};
};
template<> struct GRTrait<GRState*> {
static inline void* toPtr(GRState* St) { return (void*) St; }
static inline GRState* toState(void* P) { return (GRState*) P; }
static inline void Profile(llvm::FoldingSetNodeID& profile, GRState* St) {
// At this point states have already been uniqued. Just
// add the pointer.
profile.AddPointer(St);
}
};
class GRStateSet {
typedef llvm::SmallPtrSet<const GRState*,5> ImplTy;
ImplTy Impl;
@@ -468,7 +457,7 @@ public:
const GRState *getInitialState();
ASTContext &getContext() { return ValueMgr.getContext(); }
const ASTContext &getContext() const { return ValueMgr.getContext(); }
const ASTContext &getContext() const { return ValueMgr.getContext(); }
const Decl &getCodeDecl() { return codedecl; }
GRTransferFuncs& getTransferFuncs() { return *TF; }

View File

@@ -1286,8 +1286,7 @@ BugReportEquivClass::~BugReportEquivClass() {
GRBugReporter::~GRBugReporter() { FlushReports(); }
BugReporterData::~BugReporterData() {}
ExplodedGraph<GRState>&
GRBugReporter::getGraph() { return Eng.getGraph(); }
ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
GRStateManager&
GRBugReporter::getStateManager() { return Eng.getStateManager(); }
@@ -1332,9 +1331,9 @@ void BugReporter::FlushReports() {
// PathDiagnostics generation.
//===----------------------------------------------------------------------===//
static std::pair<std::pair<ExplodedGraph<GRState>*, NodeBackMap*>,
static std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
std::pair<ExplodedNode*, unsigned> >
MakeReportGraph(const ExplodedGraph<GRState>* G,
MakeReportGraph(const ExplodedGraph* G,
const ExplodedNode** NStart,
const ExplodedNode** NEnd) {
@@ -1342,7 +1341,7 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
// error nodes to the root. In the new graph we should only have one
// error node unless there are two or more error nodes with the same minimum
// path length.
ExplodedGraph<GRState>* GTrim;
ExplodedGraph* GTrim;
InterExplodedGraphMap* NMap;
llvm::DenseMap<const void*, const void*> InverseMap;
@@ -1350,7 +1349,7 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
// Create owning pointers for GTrim and NMap just to ensure that they are
// released when this function exists.
llvm::OwningPtr<ExplodedGraph<GRState> > AutoReleaseGTrim(GTrim);
llvm::OwningPtr<ExplodedGraph> AutoReleaseGTrim(GTrim);
llvm::OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
// Find the (first) error node in the trimmed graph. We just need to consult
@@ -1358,7 +1357,7 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
// in the new graph.
std::queue<const ExplodedNode*> WS;
typedef llvm::DenseMap<const ExplodedNode*,unsigned> IndexMapTy;
typedef llvm::DenseMap<const ExplodedNode*, unsigned> IndexMapTy;
IndexMapTy IndexMap;
for (const ExplodedNode** I = NStart; I != NEnd; ++I)
@@ -1372,9 +1371,8 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
// Create a new (third!) graph with a single path. This is the graph
// that will be returned to the caller.
ExplodedGraph<GRState> *GNew =
new ExplodedGraph<GRState>(GTrim->getCFG(), GTrim->getCodeDecl(),
GTrim->getContext());
ExplodedGraph *GNew = new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(),
GTrim->getContext());
// Sometimes the trimmed graph can contain a cycle. Perform a reverse BFS
// to the root node, and then construct a new graph that contains only
@@ -1418,8 +1416,7 @@ MakeReportGraph(const ExplodedGraph<GRState>* G,
// Create the equivalent node in the new graph with the same state
// and location.
ExplodedNode* NewN =
GNew->getNode(N->getLocation(), N->getState());
ExplodedNode* NewN = GNew->getNode(N->getLocation(), N->getState());
// Store the mapping to the original node.
llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
@@ -1576,7 +1573,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
// Construct a new graph that contains only a single path from the error
// node to a root.
const std::pair<std::pair<ExplodedGraph<GRState>*, NodeBackMap*>,
const std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
std::pair<ExplodedNode*, unsigned> >&
GPair = MakeReportGraph(&getGraph(), &Nodes[0], &Nodes[0] + Nodes.size());
@@ -1588,7 +1585,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
assert(R && "No original report found for sliced graph.");
llvm::OwningPtr<ExplodedGraph<GRState> > ReportGraph(GPair.first.first);
llvm::OwningPtr<ExplodedGraph> ReportGraph(GPair.first.first);
llvm::OwningPtr<NodeBackMap> BackMap(GPair.first.second);
const ExplodedNode *N = GPair.second.first;

View File

@@ -127,13 +127,56 @@ ExplodedNode::NodeGroup::~NodeGroup() {
if (getKind() == SizeOther) delete &getVector(getPtr());
}
ExplodedGraphImpl*
ExplodedGraphImpl::Trim(const ExplodedNode* const* BeginSources,
const ExplodedNode* const* EndSources,
InterExplodedGraphMapImpl* M,
llvm::DenseMap<const void*, const void*> *InverseMap)
const {
ExplodedNode *ExplodedGraph::getNode(const ProgramPoint& L,
const GRState* State, bool* IsNew) {
// Profile 'State' to determine if we already have an existing node.
llvm::FoldingSetNodeID profile;
void* InsertPos = 0;
NodeTy::Profile(profile, L, State);
NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
if (!V) {
// Allocate a new node.
V = (NodeTy*) Allocator.Allocate<NodeTy>();
new (V) NodeTy(L, State);
// Insert the node into the node set and return it.
Nodes.InsertNode(V, InsertPos);
++NumNodes;
if (IsNew) *IsNew = true;
}
else
if (IsNew) *IsNew = false;
return V;
}
std::pair<ExplodedGraph*, InterExplodedGraphMap*>
ExplodedGraph::Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd,
llvm::DenseMap<const void*, const void*> *InverseMap) const {
if (NBeg == NEnd)
return std::make_pair((ExplodedGraph*) 0,
(InterExplodedGraphMap*) 0);
assert (NBeg < NEnd);
llvm::OwningPtr<InterExplodedGraphMap> M(new InterExplodedGraphMap());
ExplodedGraph* G = TrimInternal(NBeg, NEnd, M.get(), InverseMap);
return std::make_pair(static_cast<ExplodedGraph*>(G), M.take());
}
ExplodedGraph*
ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources,
const ExplodedNode* const* EndSources,
InterExplodedGraphMap* M,
llvm::DenseMap<const void*, const void*> *InverseMap) const {
typedef llvm::DenseSet<const ExplodedNode*> Pass1Ty;
Pass1Ty Pass1;
@@ -177,7 +220,7 @@ const {
return 0;
// Create an empty graph.
ExplodedGraphImpl* G = MakeEmptyGraph();
ExplodedGraph* G = MakeEmptyGraph();
// ===- Pass 2 (forward DFS to construct the new graph) -===
while (!WL2.empty()) {
@@ -190,7 +233,7 @@ const {
// Create the corresponding node in the new graph and record the mapping
// from the old node to the new node.
ExplodedNode* NewN = G->getNodeImpl(N->getLocation(), N->State, NULL);
ExplodedNode* NewN = G->getNode(N->getLocation(), N->State, NULL);
Pass2[N] = NewN;
// Also record the reverse mapping from the new node to the old node.
@@ -238,12 +281,10 @@ const {
}
ExplodedNode*
InterExplodedGraphMapImpl::getMappedImplNode(const ExplodedNode* N) const {
InterExplodedGraphMap::getMappedNode(const ExplodedNode* N) const {
llvm::DenseMap<const ExplodedNode*, ExplodedNode*>::iterator I =
M.find(N);
return I == M.end() ? 0 : I->second;
}
InterExplodedGraphMapImpl::InterExplodedGraphMapImpl() {}

View File

@@ -341,11 +341,11 @@ void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
/// GenerateNode - Utility method to generate nodes, hook up successors,
/// and add nodes to the worklist.
void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State,
ExplodedNode* Pred) {
void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc,
const GRState* State, ExplodedNode* Pred) {
bool IsNew;
ExplodedNode* Node = G->getNodeImpl(Loc, State, &IsNew);
ExplodedNode* Node = G->getNode(Loc, State, &IsNew);
if (Pred)
Node->addPredecessor(Pred); // Link 'Node' with its predecessor.
@@ -383,7 +383,7 @@ void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNode* N) {
}
bool IsNew;
ExplodedNode* Succ = Eng.G->getNodeImpl(Loc, N->State, &IsNew);
ExplodedNode* Succ = Eng.G->getNode(Loc, N->State, &IsNew);
Succ->addPredecessor(N);
if (IsNew)
@@ -426,7 +426,7 @@ static inline PostStmt GetPostLoc(const Stmt* S, ProgramPoint::Kind K,
}
ExplodedNode*
GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State,
GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const GRState* State,
ExplodedNode* Pred,
ProgramPoint::Kind K,
const void *tag) {
@@ -437,10 +437,10 @@ GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State,
ExplodedNode*
GRStmtNodeBuilderImpl::generateNodeImpl(const ProgramPoint &Loc,
const void* State,
const GRState* State,
ExplodedNode* Pred) {
bool IsNew;
ExplodedNode* N = Eng.G->getNodeImpl(Loc, State, &IsNew);
ExplodedNode* N = Eng.G->getNode(Loc, State, &IsNew);
N->addPredecessor(Pred);
Deferred.erase(Pred);
@@ -454,8 +454,8 @@ GRStmtNodeBuilderImpl::generateNodeImpl(const ProgramPoint &Loc,
return NULL;
}
ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
bool branch) {
ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const GRState* State,
bool branch) {
// If the branch has been marked infeasible we should not generate a node.
if (!isFeasible(branch))
@@ -464,7 +464,7 @@ ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
bool IsNew;
ExplodedNode* Succ =
Eng.G->getNodeImpl(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew);
Eng.G->getNode(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew);
Succ->addPredecessor(Pred);
@@ -492,12 +492,12 @@ GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() {
ExplodedNode*
GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
const void* St,
const GRState* St,
bool isSink) {
bool IsNew;
ExplodedNode* Succ =
Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()), St, &IsNew);
Eng.G->getNode(BlockEdge(Src, I.getBlock()), St, &IsNew);
Succ->addPredecessor(Pred);
@@ -517,11 +517,11 @@ GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
ExplodedNode*
GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
const void* St) {
const GRState* St) {
bool IsNew;
ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()),
ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock()),
St, &IsNew);
Succ->addPredecessor(Pred);
@@ -535,7 +535,7 @@ GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
ExplodedNode*
GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const GRState* St,
bool isSink) {
// Get the block for the default case.
@@ -544,7 +544,7 @@ GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
bool IsNew;
ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock),
St, &IsNew);
Succ->addPredecessor(Pred);
@@ -566,14 +566,14 @@ GREndPathNodeBuilderImpl::~GREndPathNodeBuilderImpl() {
}
ExplodedNode*
GREndPathNodeBuilderImpl::generateNodeImpl(const void* State,
GREndPathNodeBuilderImpl::generateNodeImpl(const GRState* State,
const void *tag,
ExplodedNode* P) {
HasGeneratedNode = true;
bool IsNew;
ExplodedNode* Node =
Eng.G->getNodeImpl(BlockEntrance(&B, tag), State, &IsNew);
Eng.G->getNode(BlockEntrance(&B, tag), State, &IsNew);
Node->addPredecessor(P ? P : Pred);