20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/DenseSet.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/Statistic.h"
26 using namespace clang;
51 : NumNodes(0), ReclaimNodeInterval(0) {}
62 return isa<DeclRefExpr>(Ex) ||
63 isa<MemberExpr>(Ex) ||
64 isa<ObjCIvarRefExpr>(Ex);
67 bool ExplodedGraph::shouldCollect(
const ExplodedNode *node) {
114 return !progPoint.
getTag();
127 if (state->store != pred_state->store || state->GDM != pred_state->GDM ||
172 pred->replaceSuccessor(succ);
173 succ->replacePredecessor(pred);
175 Nodes.RemoveNode(node);
177 node->~ExplodedNode();
195 if (shouldCollect(node))
216 typedef llvm::PointerUnion<ExplodedNode *, ExplodedNodeVector *>
GroupStorage;
221 V->Succs.addNode(
this, G);
227 void ExplodedNode::NodeGroup::replaceNode(
ExplodedNode *node) {
240 if (Storage.isNull()) {
265 unsigned ExplodedNode::NodeGroup::size()
const {
270 if (Storage.isNull())
277 ExplodedNode *
const *ExplodedNode::NodeGroup::begin()
const {
282 if (Storage.isNull())
286 return Storage.getAddrOfPtr1();
289 ExplodedNode *
const *ExplodedNode::NodeGroup::end()
const {
294 if (Storage.isNull())
298 return Storage.getAddrOfPtr1() + 1;
306 llvm::FoldingSetNodeID profile;
307 void *InsertPos =
nullptr;
310 NodeTy* V =
Nodes.FindNodeOrInsertPos(profile, InsertPos);
322 new (V)
NodeTy(L, State, IsSink);
328 Nodes.InsertNode(V, InsertPos);
331 if (IsNew) *IsNew =
true;
334 if (IsNew) *IsNew =
false;
339 std::unique_ptr<ExplodedGraph>
352 Pass2Ty &Pass2 = ForwardMap ? *ForwardMap : Pass2Scratch;
364 while (!WL1.empty()) {
368 if (!Pass1.insert(N).second)
372 if (N->Preds.empty()) {
378 WL1.append(N->Preds.begin(), N->Preds.end());
389 while (!WL2.empty()) {
393 if (Pass2.find(N) != Pass2.end())
403 if (InverseMap) (*InverseMap)[NewN] = N;
406 if (N->Preds.empty())
416 Pass2Ty::iterator PI = Pass2.find(*I);
417 if (PI == Pass2.end())
429 Pass2Ty::iterator PI = Pass2.find(*I);
430 if (PI != Pass2.end()) {
431 const_cast<ExplodedNode *
>(PI->second)->addPredecessor(NewN, *G);
unsigned ReclaimCounter
Counter to determine when to reclaim nodes.
ExplodedNode *const * succ_iterator
NodeVector FreeNodes
A list of nodes that can be reused.
unsigned NumNodes
NumNodes - The number of nodes in the graph.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
unsigned pred_size() const
unsigned succ_size() const
NodeVector ChangedNodes
A list of recently allocated nodes that can potentially be recycled.
BumpVector< ExplodedNode * > ExplodedNodeVector
succ_iterator succ_begin()
Represents a program point after a store evaluation.
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
const LocationContext * getLocationContext() const
llvm::DenseMap< const ExplodedNode *, const ExplodedNode * > InterExplodedGraphMap
const ProgramStateRef & getState() const
ParentMap & getParentMap() const
std::unique_ptr< ExplodedGraph > MakeEmptyGraph() const
static ExplodedNode::Auditor * NodeAuditor
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramPoint &Loc, const ProgramStateRef &state, bool IsSink)
ExplodedNode * getNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false, bool *IsNew=nullptr)
Retrieve the node associated with a (Location,State) pair, where the 'Location' is a ProgramPoint in ...
ExplodedNode *const * pred_iterator
bool isConsumedExpr(Expr *E) const
unsigned ReclaimNodeInterval
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
llvm::FoldingSet< ExplodedNode > Nodes
Nodes - The nodes in the graph.
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy * > Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
void push_back(const_reference Elt, BumpVectorContext &C)
BumpVectorContext & getNodeAllocator()
const LocationContext * getLocationContext() const
virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst)=0
void reclaimRecentlyAllocatedNodes()
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
static void SetAuditor(Auditor *A)
const ProgramPointTag * getTag() const
pred_iterator pred_begin()
llvm::BumpPtrAllocator & getAllocator()
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.
llvm::PointerUnion< ExplodedNode *, ExplodedNodeVector * > GroupStorage