25 #include "llvm/ADT/DenseSet.h" 26 #include "llvm/ADT/FoldingSet.h" 27 #include "llvm/ADT/Optional.h" 28 #include "llvm/ADT/PointerUnion.h" 29 #include "llvm/ADT/SmallVector.h" 30 #include "llvm/Support/Casting.h" 34 using namespace clang;
52 return isa<DeclRefExpr>(Ex) ||
53 isa<MemberExpr>(Ex) ||
54 isa<ObjCIvarRefExpr>(Ex);
104 return !progPoint.
getTag();
117 if (state->store != pred_state->store || state->GDM != pred_state->GDM ||
162 pred->replaceSuccessor(succ);
163 succ->replacePredecessor(pred);
165 Nodes.RemoveNode(node);
167 node->~ExplodedNode();
183 if (shouldCollect(node))
185 ChangedNodes.clear();
203 using GroupStorage = llvm::PointerUnion<ExplodedNode *, ExplodedNodeVector *>;
208 V->Succs.addNode(
this, G);
211 void ExplodedNode::NodeGroup::replaceNode(
ExplodedNode *node) {
224 if (Storage.isNull()) {
249 unsigned ExplodedNode::NodeGroup::size()
const {
254 if (Storage.isNull())
261 ExplodedNode *
const *ExplodedNode::NodeGroup::begin()
const {
266 if (Storage.isNull())
270 return Storage.getAddrOfPtr1();
273 ExplodedNode *
const *ExplodedNode::NodeGroup::end()
const {
278 if (Storage.isNull())
282 return Storage.getAddrOfPtr1() + 1;
290 return pred_size() == 1 && succ_size() == 1 &&
291 getFirstPred()->getState()->getID() == getState()->getID() &&
292 getFirstPred()->succ_size() == 1;
300 llvm::FoldingSetNodeID profile;
301 void *InsertPos =
nullptr;
304 NodeTy*
V =
Nodes.FindNodeOrInsertPos(profile, InsertPos);
316 new (
V)
NodeTy(L, State, IsSink);
322 Nodes.InsertNode(V, InsertPos);
325 if (IsNew) *IsNew =
true;
328 if (IsNew) *IsNew =
false;
337 new (
V)
NodeTy(L, State, IsSink);
341 std::unique_ptr<ExplodedGraph>
353 Pass2Ty &Pass2 = ForwardMap ? *ForwardMap : Pass2Scratch;
358 for (
const auto Sink : Sinks)
363 while (!WL1.empty()) {
367 if (!Pass1.insert(N).second)
371 if (N->Preds.empty()) {
377 WL1.append(N->Preds.begin(), N->Preds.end());
388 while (!WL2.empty()) {
392 if (Pass2.find(N) != Pass2.end())
401 if (InverseMap) (*InverseMap)[NewN] = N;
404 if (N->Preds.empty())
414 Pass2Ty::iterator PI = Pass2.find(*I);
415 if (PI == Pass2.end())
427 Pass2Ty::iterator PI = Pass2.find(*I);
428 if (PI != Pass2.end()) {
429 const_cast<ExplodedNode *
>(PI->second)->addPredecessor(NewN, *G);
unsigned ReclaimCounter
Counter to determine when to reclaim nodes.
NodeVector FreeNodes
A list of nodes that can be reused.
unsigned NumNodes
NumNodes - The number of nodes in the graph.
Represents a point when we begin processing an inlined call.
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
Represents a program point just before an implicit call event.
const ProgramStateRef & getState() const
bool isConsumedExpr(Expr *E) const
NodeVector ChangedNodes
A list of recently allocated nodes that can potentially be recycled.
succ_iterator succ_begin()
Represents a program point after a store evaluation.
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy *> Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes...
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
unsigned succ_size() const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const LocationContext * getLocationContext() const
std::unique_ptr< ExplodedGraph > MakeEmptyGraph() const
unsigned pred_size() const
ExplodedNode * createUncachedNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false)
Create a node for a (Location, State) pair, but don't store it for deduplication later.
This represents one expression.
ExplodedNode *const * succ_iterator
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 ...
ParentMap & getParentMap() const
llvm::PointerUnion< ExplodedNode *, ExplodedNodeVector * > GroupStorage
unsigned ReclaimNodeInterval
Determines how often nodes are reclaimed.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
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.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
int64_t getID(ExplodedGraph *G) const
void push_back(const_reference Elt, BumpVectorContext &C)
Dataflow Directional Tag Classes.
BumpVectorContext & getNodeAllocator()
BumpVector< ExplodedNode * > ExplodedNodeVector
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called. ...
bool isTrivial() const
The node is trivial if it has only one successor, only one predecessor, it's predecessor has only one...
const ProgramPointTag * getTag() const
llvm::DenseMap< const ExplodedNode *, const ExplodedNode * > InterExplodedGraphMap
const LocationContext * getLocationContext() const
pred_iterator pred_begin()
llvm::BumpPtrAllocator & getAllocator()
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
ExplodedNode *const * pred_iterator
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.