26 #include "llvm/ADT/DenseSet.h" 27 #include "llvm/ADT/FoldingSet.h" 28 #include "llvm/ADT/Optional.h" 29 #include "llvm/ADT/PointerUnion.h" 30 #include "llvm/ADT/SmallVector.h" 31 #include "llvm/Support/Casting.h" 35 using namespace clang;
53 return isa<DeclRefExpr>(Ex) ||
54 isa<MemberExpr>(Ex) ||
55 isa<ObjCIvarRefExpr>(Ex);
58 bool ExplodedGraph::shouldCollect(
const ExplodedNode *node) {
105 return !progPoint.
getTag();
118 if (state->store != pred_state->store || state->GDM != pred_state->GDM ||
163 pred->replaceSuccessor(succ);
164 succ->replacePredecessor(pred);
166 Nodes.RemoveNode(node);
168 node->~ExplodedNode();
184 if (shouldCollect(node))
186 ChangedNodes.clear();
204 using GroupStorage = llvm::PointerUnion<ExplodedNode *, ExplodedNodeVector *>;
209 V->Succs.addNode(
this, G);
212 void ExplodedNode::NodeGroup::replaceNode(
ExplodedNode *node) {
225 if (Storage.isNull()) {
250 unsigned ExplodedNode::NodeGroup::size()
const {
255 if (Storage.isNull())
262 ExplodedNode *
const *ExplodedNode::NodeGroup::begin()
const {
267 if (Storage.isNull())
271 return Storage.getAddrOfPtr1();
274 ExplodedNode *
const *ExplodedNode::NodeGroup::end()
const {
279 if (Storage.isNull())
283 return Storage.getAddrOfPtr1() + 1;
291 return pred_size() == 1 && succ_size() == 1 &&
292 getFirstPred()->getState()->getID() == getState()->getID() &&
293 getFirstPred()->succ_size() == 1;
301 llvm::FoldingSetNodeID profile;
302 void *InsertPos =
nullptr;
305 NodeTy* V =
Nodes.FindNodeOrInsertPos(profile, InsertPos);
317 new (V)
NodeTy(L, State, IsSink);
323 Nodes.InsertNode(V, InsertPos);
326 if (IsNew) *IsNew =
true;
329 if (IsNew) *IsNew =
false;
338 new (V)
NodeTy(L, State, IsSink);
342 std::unique_ptr<ExplodedGraph>
354 Pass2Ty &Pass2 = ForwardMap ? *ForwardMap : Pass2Scratch;
359 for (
const auto Sink : Sinks)
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())
402 if (InverseMap) (*InverseMap)[NewN] = N;
405 if (N->Preds.empty())
415 Pass2Ty::iterator PI = Pass2.find(*I);
416 if (PI == Pass2.end())
428 Pass2Ty::iterator PI = Pass2.find(*I);
429 if (PI != Pass2.end()) {
430 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.