/// 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);
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.
class ExplodedNode : public llvm::FoldingSetNode {
protected:
- friend class ExplodedGraphImpl;
+ friend class ExplodedGraph;
friend class GRCoreEngineImpl;
friend class GRStmtNodeBuilderImpl;
friend class GRBranchNodeBuilderImpl;
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;
/// 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;
/// 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) {
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; }
-
- llvm::BumpPtrAllocator& getAllocator() { return Allocator; }
- CFG& getCFG() { return cfg; }
- ASTContext& getContext() { return Ctx; }
-
- Decl& getCodeDecl() { return CodeDecl; }
- const Decl& getCodeDecl() const { return CodeDecl; }
-
- const FunctionDecl* getFunctionDecl() const {
- return llvm::dyn_cast<FunctionDecl>(&CodeDecl);
- }
-
- 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 ExplodedNode NodeTy;
+ typedef llvm::FoldingSet<ExplodedNode> AllNodesTy;
typedef NodeTy** roots_iterator;
- typedef const NodeTy** const_roots_iterator;
+ typedef NodeTy* const * 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;
+ 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_begin() { return Nodes.begin(); }
- node_iterator nodes_end() {
- return Nodes.end();
- }
+ node_iterator nodes_end() { return Nodes.end(); }
- const_node_iterator nodes_begin() const {
- return Nodes.begin();
- }
+ const_node_iterator nodes_begin() const { return Nodes.begin(); }
- const_node_iterator nodes_end() const {
- return Nodes.end();
- }
+ const_node_iterator nodes_end() const { return Nodes.end(); }
- roots_iterator roots_begin() {
- return reinterpret_cast<roots_iterator>(Roots.begin());
- }
+ roots_iterator roots_begin() { return Roots.begin(); }
- roots_iterator roots_end() {
- return reinterpret_cast<roots_iterator>(Roots.end());
- }
+ roots_iterator roots_end() { return Roots.end(); }
- const_roots_iterator roots_begin() const {
- return const_cast<ExplodedGraph>(this)->roots_begin();
- }
+ const_roots_iterator roots_begin() const { return Roots.begin(); }
- const_roots_iterator roots_end() const {
- return const_cast<ExplodedGraph>(this)->roots_end();
- }
+ const_roots_iterator roots_end() const { return Roots.end(); }
- eop_iterator eop_begin() {
- return reinterpret_cast<eop_iterator>(EndNodes.begin());
- }
+ eop_iterator eop_begin() { return EndNodes.begin(); }
- eop_iterator eop_end() {
- return reinterpret_cast<eop_iterator>(EndNodes.end());
- }
+ eop_iterator eop_end() { return EndNodes.end(); }
- const_eop_iterator eop_begin() const {
- return const_cast<ExplodedGraph>(this)->eop_begin();
- }
+ const_eop_iterator eop_begin() const { return EndNodes.begin(); }
- const_eop_iterator eop_end() const {
- return const_cast<ExplodedGraph>(this)->eop_end();
+ const_eop_iterator eop_end() const { return EndNodes.end(); }
+
+ llvm::BumpPtrAllocator& getAllocator() { return Allocator; }
+ CFG& getCFG() { return cfg; }
+ ASTContext& getContext() { return Ctx; }
+
+ Decl& getCodeDecl() { return CodeDecl; }
+ const Decl& getCodeDecl() const { return CodeDecl; }
+
+ const FunctionDecl* getFunctionDecl() const {
+ return llvm::dyn_cast<FunctionDecl>(&CodeDecl);
}
+ typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
+
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 {
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
/// 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);
GRCoreEngineImpl& operator=(const GRCoreEngineImpl&);
protected:
- GRCoreEngineImpl(ExplodedGraphImpl* g, GRWorkList* wl)
+ GRCoreEngineImpl(ExplodedGraph* g, GRWorkList* wl)
: G(g), WList(wl), BCounterFactory(g->getAllocator()) {}
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();
}
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);
~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;
template<typename STATE>
class GRBranchNodeBuilder {
typedef STATE StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
+ typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
GRBranchNodeBuilderImpl& NB;
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; }
template<typename STATE>
class GRIndirectGotoNodeBuilder {
typedef STATE StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
+ typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
GRIndirectGotoNodeBuilderImpl& NB;
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; }
template<typename STATE>
class GRSwitchNodeBuilder {
typedef STATE StateTy;
- typedef ExplodedGraph<StateTy> GraphTy;
+ typedef ExplodedGraph GraphTy;
typedef typename GraphTy::NodeTy NodeTy;
GRSwitchNodeBuilderImpl& NB;
return getBlockCounter().getNumVisited(B.getBlockID());
}
- ExplodedNode* generateNodeImpl(const void* State,
+ ExplodedNode* generateNodeImpl(const GRState* State,
const void *tag = 0,
ExplodedNode *P = 0);
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();
}
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;
class ASTContext;
class GRExprEngine;
class PathDiagnosticClient;
-template <typename T> class ExplodedGraph;
+class ExplodedGraph;
class GRSimpleAPICheck : public GRAuditor<GRState> {
};
};
-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;
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; }
GRBugReporter::~GRBugReporter() { FlushReports(); }
BugReporterData::~BugReporterData() {}
-ExplodedGraph<GRState>&
-GRBugReporter::getGraph() { return Eng.getGraph(); }
+ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
GRStateManager&
GRBugReporter::getStateManager() { return Eng.getStateManager(); }
// 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) {
// 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;
// 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
// 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)
// 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
// 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);
// 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());
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;
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;
return 0;
// Create an empty graph.
- ExplodedGraphImpl* G = MakeEmptyGraph();
+ ExplodedGraph* G = MakeEmptyGraph();
// ===- Pass 2 (forward DFS to construct the new graph) -===
while (!WL2.empty()) {
// 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.
}
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() {}
-
/// 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.
}
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)
}
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) {
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);
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))
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);
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);
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);
ExplodedNode*
-GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
+GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const GRState* St,
bool isSink) {
// Get the block for the default case.
bool IsNew;
- ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock),
+ ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock),
St, &IsNew);
Succ->addPredecessor(Pred);
}
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);