clang  10.0.0svn
ExplodedGraph.h
Go to the documentation of this file.
1 //===- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the template classes ExplodedNode and ExplodedGraph,
10 // which represent a path-sensitive, intra-procedural "exploded graph."
11 // See "Precise interprocedural dataflow analysis via graph reachability"
12 // by Reps, Horwitz, and Sagiv
13 // (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
14 // exploded graph.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
19 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
20 
24 #include "clang/Basic/LLVM.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/DenseMap.h"
30 #include "llvm/ADT/DepthFirstIterator.h"
31 #include "llvm/ADT/FoldingSet.h"
32 #include "llvm/ADT/GraphTraits.h"
33 #include "llvm/ADT/Optional.h"
34 #include "llvm/ADT/STLExtras.h"
35 #include "llvm/ADT/SetVector.h"
36 #include "llvm/Support/Allocator.h"
37 #include "llvm/Support/Compiler.h"
38 #include <cassert>
39 #include <cstdint>
40 #include <memory>
41 #include <utility>
42 #include <vector>
43 
44 namespace clang {
45 
46 class CFG;
47 class Decl;
48 class Expr;
49 class ParentMap;
50 class Stmt;
51 
52 namespace ento {
53 
54 class ExplodedGraph;
55 
56 //===----------------------------------------------------------------------===//
57 // ExplodedGraph "implementation" classes. These classes are not typed to
58 // contain a specific kind of state. Typed-specialized versions are defined
59 // on top of these classes.
60 //===----------------------------------------------------------------------===//
61 
62 // ExplodedNode is not constified all over the engine because we need to add
63 // successors to it at any time after creating it.
64 
65 class ExplodedNode : public llvm::FoldingSetNode {
66  friend class BranchNodeBuilder;
67  friend class CoreEngine;
69  friend class ExplodedGraph;
71  friend class NodeBuilder;
72  friend class SwitchNodeBuilder;
73 
74  /// Efficiently stores a list of ExplodedNodes, or an optional flag.
75  ///
76  /// NodeGroup provides opaque storage for a list of ExplodedNodes, optimizing
77  /// for the case when there is only one node in the group. This is a fairly
78  /// common case in an ExplodedGraph, where most nodes have only one
79  /// predecessor and many have only one successor. It can also be used to
80  /// store a flag rather than a node list, which ExplodedNode uses to mark
81  /// whether a node is a sink. If the flag is set, the group is implicitly
82  /// empty and no nodes may be added.
83  class NodeGroup {
84  // Conceptually a discriminated union. If the low bit is set, the node is
85  // a sink. If the low bit is not set, the pointer refers to the storage
86  // for the nodes in the group.
87  // This is not a PointerIntPair in order to keep the storage type opaque.
88  uintptr_t P;
89 
90  public:
91  NodeGroup(bool Flag = false) : P(Flag) {
92  assert(getFlag() == Flag);
93  }
94 
95  ExplodedNode * const *begin() const;
96 
97  ExplodedNode * const *end() const;
98 
99  unsigned size() const;
100 
101  bool empty() const { return P == 0 || getFlag() != 0; }
102 
103  /// Adds a node to the list.
104  ///
105  /// The group must not have been created with its flag set.
106  void addNode(ExplodedNode *N, ExplodedGraph &G);
107 
108  /// Replaces the single node in this group with a new node.
109  ///
110  /// Note that this should only be used when you know the group was not
111  /// created with its flag set, and that the group is empty or contains
112  /// only a single node.
113  void replaceNode(ExplodedNode *node);
114 
115  /// Returns whether this group was created with its flag set.
116  bool getFlag() const {
117  return (P & 1);
118  }
119  };
120 
121  /// Location - The program location (within a function body) associated
122  /// with this node.
123  const ProgramPoint Location;
124 
125  /// State - The state associated with this node.
127 
128  /// Preds - The predecessors of this node.
129  NodeGroup Preds;
130 
131  /// Succs - The successors of this node.
132  NodeGroup Succs;
133 
134 public:
136  bool IsSink)
137  : Location(loc), State(std::move(state)), Succs(IsSink) {
138  assert(isSink() == IsSink);
139  }
140 
141  /// getLocation - Returns the edge associated with the given node.
142  ProgramPoint getLocation() const { return Location; }
143 
145  return getLocation().getLocationContext();
146  }
147 
149  return getLocation().getStackFrame();
150  }
151 
152  const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
153 
154  CFG &getCFG() const { return *getLocationContext()->getCFG(); }
155 
156  const CFGBlock *getCFGBlock() const;
157 
158  const ParentMap &getParentMap() const {
159  return getLocationContext()->getParentMap();
160  }
161 
162  template <typename T>
163  T &getAnalysis() const {
164  return *getLocationContext()->getAnalysis<T>();
165  }
166 
167  const ProgramStateRef &getState() const { return State; }
168 
169  template <typename T>
170  Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
171  return Location.getAs<T>();
172  }
173 
174  /// Get the value of an arbitrary expression at this node.
175  SVal getSVal(const Stmt *S) const {
176  return getState()->getSVal(S, getLocationContext());
177  }
178 
179  static void Profile(llvm::FoldingSetNodeID &ID,
180  const ProgramPoint &Loc,
181  const ProgramStateRef &state,
182  bool IsSink) {
183  ID.Add(Loc);
184  ID.AddPointer(state.get());
185  ID.AddBoolean(IsSink);
186  }
187 
188  void Profile(llvm::FoldingSetNodeID& ID) const {
189  // We avoid copy constructors by not using accessors.
190  Profile(ID, Location, State, isSink());
191  }
192 
193  /// addPredeccessor - Adds a predecessor to the current node, and
194  /// in tandem add this node as a successor of the other node.
196 
197  unsigned succ_size() const { return Succs.size(); }
198  unsigned pred_size() const { return Preds.size(); }
199  bool succ_empty() const { return Succs.empty(); }
200  bool pred_empty() const { return Preds.empty(); }
201 
202  bool isSink() const { return Succs.getFlag(); }
203 
204  bool hasSinglePred() const {
205  return (pred_size() == 1);
206  }
207 
209  return pred_empty() ? nullptr : *(pred_begin());
210  }
211 
212  const ExplodedNode *getFirstPred() const {
213  return const_cast<ExplodedNode*>(this)->getFirstPred();
214  }
215 
217  return succ_empty() ? nullptr : *(succ_begin());
218  }
219 
220  const ExplodedNode *getFirstSucc() const {
221  return const_cast<ExplodedNode*>(this)->getFirstSucc();
222  }
223 
224  // Iterators over successor and predecessor vertices.
225  using succ_iterator = ExplodedNode * const *;
226  using succ_range = llvm::iterator_range<succ_iterator>;
227 
228  using const_succ_iterator = const ExplodedNode * const *;
229  using const_succ_range = llvm::iterator_range<const_succ_iterator>;
230 
231  using pred_iterator = ExplodedNode * const *;
232  using pred_range = llvm::iterator_range<pred_iterator>;
233 
234  using const_pred_iterator = const ExplodedNode * const *;
235  using const_pred_range = llvm::iterator_range<const_pred_iterator>;
236 
237  pred_iterator pred_begin() { return Preds.begin(); }
238  pred_iterator pred_end() { return Preds.end(); }
239  pred_range preds() { return {Preds.begin(), Preds.end()}; }
240 
242  return const_cast<ExplodedNode*>(this)->pred_begin();
243  }
245  return const_cast<ExplodedNode*>(this)->pred_end();
246  }
247  const_pred_range preds() const { return {Preds.begin(), Preds.end()}; }
248 
249  succ_iterator succ_begin() { return Succs.begin(); }
250  succ_iterator succ_end() { return Succs.end(); }
251  succ_range succs() { return {Succs.begin(), Succs.end()}; }
252 
254  return const_cast<ExplodedNode*>(this)->succ_begin();
255  }
257  return const_cast<ExplodedNode*>(this)->succ_end();
258  }
259  const_succ_range succs() const { return {Succs.begin(), Succs.end()}; }
260 
261  int64_t getID(ExplodedGraph *G) const;
262 
263  /// The node is trivial if it has only one successor, only one predecessor,
264  /// it's predecessor has only one successor,
265  /// and its program state is the same as the program state of the previous
266  /// node.
267  /// Trivial nodes may be skipped while printing exploded graph.
268  bool isTrivial() const;
269 
270  /// If the node's program point corresponds to a statement, retrieve that
271  /// statement. Useful for figuring out where to put a warning or a note.
272  /// If the statement belongs to a body-farmed definition,
273  /// retrieve the call site for that definition.
274  const Stmt *getStmtForDiagnostics() const;
275 
276  /// Find the next statement that was executed on this node's execution path.
277  /// Useful for explaining control flow that follows the current node.
278  /// If the statement belongs to a body-farmed definition, retrieve the
279  /// call site for that definition.
280  const Stmt *getNextStmtForDiagnostics() const;
281 
282  /// Find the statement that was executed immediately before this node.
283  /// Useful when the node corresponds to a CFG block entrance.
284  /// If the statement belongs to a body-farmed definition, retrieve the
285  /// call site for that definition.
286  const Stmt *getPreviousStmtForDiagnostics() const;
287 
288  /// Find the statement that was executed at or immediately before this node.
289  /// Useful when any nearby statement will do.
290  /// If the statement belongs to a body-farmed definition, retrieve the
291  /// call site for that definition.
293 
294 private:
295  void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); }
296  void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
297 };
298 
299 using InterExplodedGraphMap =
300  llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>;
301 
303 protected:
304  friend class CoreEngine;
305 
306  // Type definitions.
307  using NodeVector = std::vector<ExplodedNode *>;
308 
309  /// The roots of the simulation graph. Usually there will be only
310  /// one, but clients are free to establish multiple subgraphs within a single
311  /// SimulGraph. Moreover, these subgraphs can often merge when paths from
312  /// different roots reach the same state at the same program location.
314 
315  /// The nodes in the simulation graph which have been
316  /// specially marked as the endpoint of an abstract simulation path.
318 
319  /// Nodes - The nodes in the graph.
320  llvm::FoldingSet<ExplodedNode> Nodes;
321 
322  /// BVC - Allocator and context for allocating nodes and their predecessor
323  /// and successor groups.
325 
326  /// NumNodes - The number of nodes in the graph.
327  unsigned NumNodes = 0;
328 
329  /// A list of recently allocated nodes that can potentially be recycled.
331 
332  /// A list of nodes that can be reused.
334 
335  /// Determines how often nodes are reclaimed.
336  ///
337  /// If this is 0, nodes will never be reclaimed.
338  unsigned ReclaimNodeInterval = 0;
339 
340  /// Counter to determine when to reclaim nodes.
341  unsigned ReclaimCounter;
342 
343 public:
344  ExplodedGraph();
345  ~ExplodedGraph();
346 
347  /// Retrieve the node associated with a (Location,State) pair,
348  /// where the 'Location' is a ProgramPoint in the CFG. If no node for
349  /// this pair exists, it is created. IsNew is set to true if
350  /// the node was freshly created.
352  bool IsSink = false,
353  bool* IsNew = nullptr);
354 
355  /// Create a node for a (Location, State) pair,
356  /// but don't store it for deduplication later. This
357  /// is useful when copying an already completed
358  /// ExplodedGraph for further processing.
359  ExplodedNode *createUncachedNode(const ProgramPoint &L,
361  bool IsSink = false);
362 
363  std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const {
364  return std::make_unique<ExplodedGraph>();
365  }
366 
367  /// addRoot - Add an untyped node to the set of roots.
369  Roots.push_back(V);
370  return V;
371  }
372 
373  /// addEndOfPath - Add an untyped node to the set of EOP nodes.
375  EndNodes.push_back(V);
376  return V;
377  }
378 
379  unsigned num_roots() const { return Roots.size(); }
380  unsigned num_eops() const { return EndNodes.size(); }
381 
382  bool empty() const { return NumNodes == 0; }
383  unsigned size() const { return NumNodes; }
384 
385  void reserve(unsigned NodeCount) { Nodes.reserve(NodeCount); }
386 
387  // Iterators.
389  using AllNodesTy = llvm::FoldingSet<ExplodedNode>;
390  using roots_iterator = NodeVector::iterator;
391  using const_roots_iterator = NodeVector::const_iterator;
392  using eop_iterator = NodeVector::iterator;
393  using const_eop_iterator = NodeVector::const_iterator;
394  using node_iterator = AllNodesTy::iterator;
395  using const_node_iterator = AllNodesTy::const_iterator;
396 
397  node_iterator nodes_begin() { return Nodes.begin(); }
398 
399  node_iterator nodes_end() { return Nodes.end(); }
400 
401  const_node_iterator nodes_begin() const { return Nodes.begin(); }
402 
403  const_node_iterator nodes_end() const { return Nodes.end(); }
404 
405  roots_iterator roots_begin() { return Roots.begin(); }
406 
407  roots_iterator roots_end() { return Roots.end(); }
408 
409  const_roots_iterator roots_begin() const { return Roots.begin(); }
410 
411  const_roots_iterator roots_end() const { return Roots.end(); }
412 
413  eop_iterator eop_begin() { return EndNodes.begin(); }
414 
415  eop_iterator eop_end() { return EndNodes.end(); }
416 
417  const_eop_iterator eop_begin() const { return EndNodes.begin(); }
418 
419  const_eop_iterator eop_end() const { return EndNodes.end(); }
420 
421  llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
423 
424  using NodeMap = llvm::DenseMap<const ExplodedNode *, ExplodedNode *>;
425 
426  /// Creates a trimmed version of the graph that only contains paths leading
427  /// to the given nodes.
428  ///
429  /// \param Nodes The nodes which must appear in the final graph. Presumably
430  /// these are end-of-path nodes (i.e. they have no successors).
431  /// \param[out] ForwardMap A optional map from nodes in this graph to nodes in
432  /// the returned graph.
433  /// \param[out] InverseMap An optional map from nodes in the returned graph to
434  /// nodes in this graph.
435  /// \returns The trimmed graph
436  std::unique_ptr<ExplodedGraph>
437  trim(ArrayRef<const NodeTy *> Nodes,
438  InterExplodedGraphMap *ForwardMap = nullptr,
439  InterExplodedGraphMap *InverseMap = nullptr) const;
440 
441  /// Enable tracking of recently allocated nodes for potential reclamation
442  /// when calling reclaimRecentlyAllocatedNodes().
443  void enableNodeReclamation(unsigned Interval) {
444  ReclaimCounter = ReclaimNodeInterval = Interval;
445  }
446 
447  /// Reclaim "uninteresting" nodes created since the last time this method
448  /// was called.
449  void reclaimRecentlyAllocatedNodes();
450 
451  /// Returns true if nodes for the given expression kind are always
452  /// kept around.
453  static bool isInterestingLValueExpr(const Expr *Ex);
454 
455 private:
456  bool shouldCollect(const ExplodedNode *node);
457  void collectNode(ExplodedNode *node);
458 };
459 
462  ImplTy Impl;
463 
464 public:
466  assert(N && !static_cast<ExplodedNode*>(N)->isSink());
467  Impl.insert(N);
468  }
469 
470  ExplodedNodeSet() = default;
471 
472  void Add(ExplodedNode *N) {
473  if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
474  }
475 
476  using iterator = ImplTy::iterator;
477  using const_iterator = ImplTy::const_iterator;
478 
479  unsigned size() const { return Impl.size(); }
480  bool empty() const { return Impl.empty(); }
481  bool erase(ExplodedNode *N) { return Impl.remove(N); }
482 
483  void clear() { Impl.clear(); }
484 
485  void insert(const ExplodedNodeSet &S) {
486  assert(&S != this);
487  if (empty())
488  Impl = S.Impl;
489  else
490  Impl.insert(S.begin(), S.end());
491  }
492 
493  iterator begin() { return Impl.begin(); }
494  iterator end() { return Impl.end(); }
495 
496  const_iterator begin() const { return Impl.begin(); }
497  const_iterator end() const { return Impl.end(); }
498 };
499 
500 } // namespace ento
501 
502 } // namespace clang
503 
504 // GraphTraits
505 
506 namespace llvm {
507  template <> struct GraphTraits<clang::ento::ExplodedGraph *> {
511  using nodes_iterator = llvm::df_iterator<GraphTy>;
512 
513  static NodeRef getEntryNode(const GraphTy G) {
514  return *G->roots_begin();
515  }
516 
517  static bool predecessorOfTrivial(NodeRef N) {
518  return N->succ_size() == 1 && N->getFirstSucc()->isTrivial();
519  }
520 
522  if (predecessorOfTrivial(N))
523  return child_begin(*N->succ_begin());
524  return N->succ_begin();
525  }
526 
528  if (predecessorOfTrivial(N))
529  return child_end(N->getFirstSucc());
530  return N->succ_end();
531  }
532 
534  return df_begin(G);
535  }
536 
537  static nodes_iterator nodes_end(const GraphTy G) {
538  return df_end(G);
539  }
540  };
541 } // namespace llvm
542 
543 #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
const_iterator end() const
unsigned ReclaimCounter
Counter to determine when to reclaim nodes.
llvm::iterator_range< const_succ_iterator > const_succ_range
void Profile(llvm::FoldingSetNodeID &ID) const
const_roots_iterator roots_begin() const
const Stmt * getStmtForDiagnostics() const
If the node&#39;s program point corresponds to a statement, retrieve that statement.
const Stmt * getCurrentOrPreviousStmtForDiagnostics() const
Find the statement that was executed at or immediately before this node.
const ExplodedNode * getFirstPred() const
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
Definition: Dominators.h:30
Stmt - This represents one statement.
Definition: Stmt.h:66
NodeVector FreeNodes
A list of nodes that can be reused.
AllNodesTy::const_iterator const_node_iterator
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
const_eop_iterator eop_begin() const
StringRef P
const CFGBlock * getCFGBlock() const
const_succ_iterator succ_begin() const
const_pred_range preds() const
const_node_iterator nodes_end() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
static ChildIteratorType child_end(NodeRef N)
const ProgramStateRef & getState() const
llvm::BumpPtrAllocator & getAllocator()
Definition: BumpVector.h:55
const_pred_iterator pred_end() const
const_succ_iterator succ_end() const
const Decl & getCodeDecl() const
roots_iterator roots_begin()
NodeVector ChangedNodes
A list of recently allocated nodes that can potentially be recycled.
const_eop_iterator eop_end() const
LineState State
NodeVector EndNodes
The nodes in the simulation graph which have been specially marked as the endpoint of an abstract sim...
static nodes_iterator nodes_begin(const GraphTy G)
succ_iterator succ_begin()
Definition: Format.h:2327
NodeVector::const_iterator const_eop_iterator
std::vector< ExplodedNode * > NodeVector
NodeVector::iterator roots_iterator
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
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
const StackFrameContext * getStackFrame() const
Definition: ProgramPoint.h:183
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
unsigned succ_size() const
llvm::iterator_range< const_pred_iterator > const_pred_range
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const LocationContext * getLocationContext() const
std::unique_ptr< ExplodedGraph > MakeEmptyGraph() const
clang::ento::ExplodedNode::succ_iterator ChildIteratorType
const_roots_iterator roots_end() const
ExplodedNode * getFirstPred()
llvm::FoldingSet< ExplodedNode > AllNodesTy
unsigned pred_size() const
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon (for non-expression statements).
const ExplodedNode *const * const_succ_iterator
Represents a single basic block in a source-level CFG.
Definition: CFG.h:576
AllNodesTy::iterator node_iterator
This represents one expression.
Definition: Expr.h:108
pred_iterator pred_end()
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:1225
ExplodedNode * getFirstSucc()
const ParentMap & getParentMap() const
llvm::DenseMap< const ExplodedNode *, ExplodedNode * > NodeMap
#define V(N, I)
Definition: ASTContext.h:2913
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Definition: opencl-c-base.h:62
static nodes_iterator nodes_end(const GraphTy G)
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition: CoreEngine.h:236
ExplodedNode *const * succ_iterator
void Add(ExplodedNode *N)
unsigned num_roots() const
const_node_iterator nodes_begin() const
static ChildIteratorType child_begin(NodeRef N)
static void Profile(llvm::FoldingSetNodeID &ID, const ProgramPoint &Loc, const ProgramStateRef &state, bool IsSink)
static NodeRef getEntryNode(const GraphTy G)
node_iterator nodes_begin()
ImplTy::const_iterator const_iterator
BumpVectorContext BVC
BVC - Allocator and context for allocating nodes and their predecessor and successor groups...
roots_iterator roots_end()
llvm::FoldingSet< ExplodedNode > Nodes
Nodes - The nodes in the graph.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
const Stmt * getPreviousStmtForDiagnostics() const
Find the statement that was executed immediately before this node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:75
NodeVector::iterator eop_iterator
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
void insert(const ExplodedNodeSet &S)
int64_t getID(ExplodedGraph *G) const
CoreEngine - Implements the core logic of the graph-reachability analysis.
Definition: CoreEngine.h:55
NodeVector::const_iterator const_roots_iterator
Dataflow Directional Tag Classes.
BumpVectorContext & getNodeAllocator()
ExplodedNodeSet(ExplodedNode *N)
NodeVector Roots
The roots of the simulation graph.
const ExplodedNode * getFirstSucc() const
bool isTrivial() const
The node is trivial if it has only one successor, only one predecessor, it&#39;s predecessor has only one...
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
Definition: CoreEngine.h:430
ExplodedNode(const ProgramPoint &loc, ProgramStateRef state, bool IsSink)
const Decl * getDecl() const
void reserve(unsigned NodeCount)
llvm::iterator_range< pred_iterator > pred_range
llvm::DenseMap< const ExplodedNode *, const ExplodedNode * > InterExplodedGraphMap
succ_iterator succ_end()
static Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef ID)
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:179
friend class EndOfFunctionNodeBuilder
Definition: ExplodedGraph.h:68
const_succ_range succs() const
llvm::iterator_range< succ_iterator > succ_range
bool erase(ExplodedNode *N)
unsigned num_eops() const
const ParentMap & getParentMap() const
pred_iterator pred_begin()
llvm::BumpPtrAllocator & getAllocator()
ExplodedNode * addEndOfPath(ExplodedNode *V)
addEndOfPath - Add an untyped node to the set of EOP nodes.
const Stmt * getNextStmtForDiagnostics() const
Find the next statement that was executed on this node&#39;s execution path.
const StackFrameContext * getStackFrame() const
const ExplodedNode *const * const_pred_iterator
const_pred_iterator pred_begin() const
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:151
ExplodedNode *const * pred_iterator
ExplodedNode * addRoot(ExplodedNode *V)
addRoot - Add an untyped node to the set of roots.
const_iterator begin() const