CoreEngine.h revision f178ac8b68b29e44867777232ba8fee59edc4037
1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- C++ -*-//
2bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
3bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//                     The LLVM Compiler Infrastructure
4bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// This file is distributed under the University of Illinois Open Source
6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// License. See LICENSE.TXT for details.
7bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
8bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//===----------------------------------------------------------------------===//
9bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
10bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//  This file defines a generic engine for intraprocedural, path-sensitive,
11bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//  dataflow analysis via graph reachability.
12bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//===----------------------------------------------------------------------===//
140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#ifndef LLVM_CLANG_GR_COREENGINE
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#define LLVM_CLANG_GR_COREENGINE
170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "clang/AST/Expr.h"
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "llvm/ADT/OwningPtr.h"
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace clang {
260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace ento {
280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)//===----------------------------------------------------------------------===//
300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/// CoreEngine - Implements the core logic of the graph-reachability
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)///   analysis. It traverses the CFG and generates the ExplodedGraph.
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)///   Program "states" are treated as opaque void pointers.
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)///   The template class CoreEngine (which subclasses CoreEngine)
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)///   provides the matching component to the engine that knows the actual types
35bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch///   for states.  Note that this engine only dispatches to transfer functions
36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch///   at the statement and block-level.  The analyses themselves must implement
37bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch///   any transfer function logic and the sub-expression level (if any).
38bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass CoreEngine {
39bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class StmtNodeBuilder;
40bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class GenericNodeBuilderImpl;
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  friend class BranchNodeBuilder;
42bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class IndirectGotoNodeBuilder;
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  friend class SwitchNodeBuilder;
44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class EndOfFunctionNodeBuilder;
45bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class CallEnterNodeBuilder;
46bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  friend class CallExitNodeBuilder;
47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochpublic:
49bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            BlocksAborted;
51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochprivate:
52bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
53bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  SubEngine& SubEng;
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
55bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// G - The simulation graph.  Each node is a (location,state) pair.
56bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  llvm::OwningPtr<ExplodedGraph> G;
57bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
58bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// WList - A set of queued nodes that need to be processed by the
59bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  worklist algorithm.  It is up to the implementation of WList to decide
60bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  the order that nodes are processed.
61bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  WorkList* WList;
62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
63bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// BCounterFactory - A factory object for created BlockCounter objects.
64bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///   These are used to record for key nodes in the ExplodedGraph the
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///   number of times different CFGBlocks have been visited along a path.
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BlockCounter::Factory BCounterFactory;
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// The locations where we stopped doing work because we visited a location
69bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  too many times.
70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  BlocksAborted blocksAborted;
71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void generateNode(const ProgramPoint& Loc, const GRState* State,
73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                    ExplodedNode* Pred);
74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
77bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleBlockExit(const CFGBlock* B, ExplodedNode* Pred);
78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandlePostStmt(const CFGBlock* B, unsigned StmtIdx, ExplodedNode *Pred);
79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleBranch(const Stmt* Cond, const Stmt* Term, const CFGBlock* B,
81bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                    ExplodedNode* Pred);
82bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
83bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                       unsigned Index, ExplodedNode *Pred);
84bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleCallExit(const CallExit &L, ExplodedNode *Pred);
85bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
86bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochprivate:
87bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  CoreEngine(const CoreEngine&); // Do not implement.
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  CoreEngine& operator=(const CoreEngine&);
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
90bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochpublic:
91bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// Construct a CoreEngine object to analyze the provided CFG using
92bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  a DFS exploration of the exploded graph.
93bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  CoreEngine(SubEngine& subengine)
94bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    : SubEng(subengine), G(new ExplodedGraph()),
95bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      WList(WorkList::makeBFS()),
96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      BCounterFactory(G->getAllocator()) {}
97bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// Construct a CoreEngine object to analyze the provided CFG and to
99bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  use the provided worklist object to execute the worklist algorithm.
100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  The CoreEngine object assumes ownership of 'wlist'.
101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  CoreEngine(WorkList* wlist, SubEngine& subengine)
102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    : SubEng(subengine), G(new ExplodedGraph()), WList(wlist),
103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      BCounterFactory(G->getAllocator()) {}
104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ~CoreEngine() {
106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    delete WList;
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// getGraph - Returns the exploded graph.
110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ExplodedGraph& getGraph() { return *G.get(); }
111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ///  transfered to the caller.
114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ExplodedGraph* takeGraph() { return G.take(); }
115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ///  steps.  Returns true if there is still simulation state on the worklist.
118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                       const GRState *InitState);
120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
121bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       const GRState *InitState,
122bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       ExplodedNodeSet &Dst);
123bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
124bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Functions for external checking of whether we have unfinished work
125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool wasBlockAborted() const { return !blocksAborted.empty(); }
126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool hasWorkRemaining() const { return wasBlockAborted() || WList->hasWork(); }
127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  WorkList *getWorkList() const { return WList; }
129bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  BlocksAborted::const_iterator blocks_aborted_begin() const {
1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return blocksAborted.begin();
132bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BlocksAborted::const_iterator blocks_aborted_end() const {
134bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return blocksAborted.end();
135bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
136bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch};
137bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass StmtNodeBuilder {
139bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  CoreEngine& Eng;
140bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const CFGBlock& B;
141bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const unsigned Idx;
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExplodedNode* Pred;
143bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  GRStateManager& Mgr;
144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochpublic:
146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool PurgingDeadSymbols;
147bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool BuildSinks;
148bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool hasGeneratedNode;
149bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ProgramPoint::Kind PointKind;
150bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const void *Tag;
151bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
152bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const GRState* CleanedState;
153bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
154bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
155bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
156bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DeferredTy Deferred;
1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
158bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void GenerateAutoTransition(ExplodedNode* N);
1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
160bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochpublic:
161bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  StmtNodeBuilder(const CFGBlock* b, unsigned idx, ExplodedNode* N,
162bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                    CoreEngine* e, GRStateManager &mgr);
163bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
164bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ~StmtNodeBuilder();
165bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
166bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ExplodedNode* getPredecessor() const { return Pred; }
167bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // FIXME: This should not be exposed.
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  WorkList *getWorkList() { return Eng.WList; }
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  void SetCleanedState(const GRState* St) {
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    CleanedState = St;
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  unsigned getCurrentBlockCount() const {
1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return getBlockCounter().getNumVisited(
1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                            Pred->getLocationContext()->getCurrentStackFrame(),
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                           B.getBlockID());
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    hasGeneratedNode = true;
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return generateNodeInternal(PP, St, Pred);
1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode* generateNode(const Stmt *S, const GRState *St,
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                             ExplodedNode *Pred, ProgramPoint::Kind K,
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                             const void *tag = 0) {
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    hasGeneratedNode = true;
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (PurgingDeadSymbols)
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      K = ProgramPoint::PostPurgeDeadSymbolsKind;
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return generateNodeInternal(S, St, Pred, K, tag ? tag : Tag);
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode* generateNode(const Stmt *S, const GRState *St,
2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                             ExplodedNode *Pred, const void *tag = 0) {
2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return generateNode(S, St, Pred, PointKind, tag);
2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State,
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                             ExplodedNode* Pred) {
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    hasGeneratedNode = true;
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return generateNodeInternal(PP, State, Pred);
2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode*
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generateNodeInternal(const ProgramPoint &PP, const GRState* State,
2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                       ExplodedNode* Pred);
2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode*
2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred,
2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                   ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                   const void *tag = 0);
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  /// getStmt - Return the current block-level expression associated with
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ///  this builder.
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const Stmt* getStmt() const {
2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    CFGStmt CS = B[Idx].getAs<CFGStmt>();
2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (CS)
2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return CS.getStmt();
2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    else
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return 0;
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  /// getBlock - Return the CFGBlock associated with the block-level expression
2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ///  of this builder.
2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const CFGBlock* getBlock() const { return &B; }
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  unsigned getIndex() const { return Idx; }
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const GRState* GetState(ExplodedNode* Pred) const {
2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (Pred == getPredecessor())
2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return CleanedState;
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    else
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return Pred->getState();
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         ExplodedNode* Pred, const GRState* St) {
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return MakeNode(Dst, S, Pred, St, PointKind);
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,ExplodedNode* Pred,
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         const GRState* St, ProgramPoint::Kind K);
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, const Stmt* S,
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       ExplodedNode* Pred, const GRState* St) {
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool Tmp = BuildSinks;
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    BuildSinks = true;
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ExplodedNode* N = MakeNode(Dst, S, Pred, St);
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    BuildSinks = Tmp;
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return N;
2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
2590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BranchNodeBuilder {
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CoreEngine& Eng;
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const CFGBlock* Src;
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const CFGBlock* DstT;
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const CFGBlock* DstF;
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExplodedNode* Pred;
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
268bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DeferredTy Deferred;
269bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool GeneratedTrue;
2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool GeneratedFalse;
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool InFeasibleTrue;
2730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool InFeasibleFalse;
274bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)public:
2760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BranchNodeBuilder(const CFGBlock* src, const CFGBlock* dstT,
2770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                      const CFGBlock* dstF, ExplodedNode* pred, CoreEngine* e)
278bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    GeneratedTrue(false), GeneratedFalse(false),
2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
2810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ~BranchNodeBuilder();
2830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode* getPredecessor() const { return Pred; }
2850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const ExplodedGraph& getGraph() const { return *Eng.G; }
2870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
2890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode* generateNode(const GRState* State, bool branch);
2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const CFGBlock* getTargetBlock(bool branch) const {
2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return branch ? DstT : DstF;
2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
295bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
296bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void markInfeasible(bool branch) {
297bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    if (branch)
298bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      InFeasibleTrue = GeneratedTrue = true;
299bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    else
300bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      InFeasibleFalse = GeneratedFalse = true;
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
302bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
303bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  bool isFeasible(bool branch) {
304bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return branch ? !InFeasibleTrue : !InFeasibleFalse;
305bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
306bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
307bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const GRState* getState() const {
308bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return getPredecessor()->getState();
309bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
310bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch};
311bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
312bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass IndirectGotoNodeBuilder {
313bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  CoreEngine& Eng;
314bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const CFGBlock* Src;
3150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const CFGBlock& DispatchBlock;
316bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const Expr* E;
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ExplodedNode* Pred;
318bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
319bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochpublic:
320bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  IndirectGotoNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
321bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                    const Expr* e, const CFGBlock* dispatch, CoreEngine* eng)
322bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
323bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
324bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  class iterator {
325bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    CFGBlock::const_succ_iterator I;
326bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
327bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    friend class IndirectGotoNodeBuilder;
328bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    iterator(CFGBlock::const_succ_iterator i) : I(i) {}
3290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  public:
330bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
3310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    iterator& operator++() { ++I; return *this; }
332bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    bool operator!=(const iterator& X) const { return I != X.I; }
333bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
334bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    const LabelDecl *getLabel() const {
335bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      return llvm::cast<LabelStmt>((*I)->getLabel())->getDecl();
336bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    }
337bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
338bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    const CFGBlock *getBlock() const {
339bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      return *I;
340bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    }
341  };
342
343  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
344  iterator end() { return iterator(DispatchBlock.succ_end()); }
345
346  ExplodedNode* generateNode(const iterator& I, const GRState* State,
347                             bool isSink = false);
348
349  const Expr* getTarget() const { return E; }
350
351  const GRState* getState() const { return Pred->State; }
352};
353
354class SwitchNodeBuilder {
355  CoreEngine& Eng;
356  const CFGBlock* Src;
357  const Expr* Condition;
358  ExplodedNode* Pred;
359
360public:
361  SwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
362                      const Expr* condition, CoreEngine* eng)
363  : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
364
365  class iterator {
366    CFGBlock::const_succ_reverse_iterator I;
367
368    friend class SwitchNodeBuilder;
369    iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
370
371  public:
372    iterator& operator++() { ++I; return *this; }
373    bool operator!=(const iterator &X) const { return I != X.I; }
374    bool operator==(const iterator &X) const { return I == X.I; }
375
376    const CaseStmt* getCase() const {
377      return llvm::cast<CaseStmt>((*I)->getLabel());
378    }
379
380    const CFGBlock* getBlock() const {
381      return *I;
382    }
383  };
384
385  iterator begin() { return iterator(Src->succ_rbegin()+1); }
386  iterator end() { return iterator(Src->succ_rend()); }
387
388  const SwitchStmt *getSwitch() const {
389    return llvm::cast<SwitchStmt>(Src->getTerminator());
390  }
391
392  ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State);
393
394  ExplodedNode* generateDefaultCaseNode(const GRState* State,
395                                        bool isSink = false);
396
397  const Expr* getCondition() const { return Condition; }
398
399  const GRState* getState() const { return Pred->State; }
400};
401
402class GenericNodeBuilderImpl {
403protected:
404  CoreEngine &engine;
405  ExplodedNode *pred;
406  ProgramPoint pp;
407  llvm::SmallVector<ExplodedNode*, 2> sinksGenerated;
408
409  ExplodedNode *generateNodeImpl(const GRState *state, ExplodedNode *pred,
410                                 ProgramPoint programPoint, bool asSink);
411
412  GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p)
413    : engine(eng), pred(pr), pp(p), hasGeneratedNode(false) {}
414
415public:
416  bool hasGeneratedNode;
417
418  WorkList &getWorkList() { return *engine.WList; }
419
420  ExplodedNode* getPredecessor() const { return pred; }
421
422  BlockCounter getBlockCounter() const {
423    return engine.WList->getBlockCounter();
424  }
425
426  const llvm::SmallVectorImpl<ExplodedNode*> &sinks() const {
427    return sinksGenerated;
428  }
429};
430
431template <typename PP_T>
432class GenericNodeBuilder : public GenericNodeBuilderImpl {
433public:
434  GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP_T &p)
435    : GenericNodeBuilderImpl(eng, pr, p) {}
436
437  ExplodedNode *generateNode(const GRState *state, ExplodedNode *pred,
438                             const void *tag, bool asSink) {
439    return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag),
440                            asSink);
441  }
442
443  const PP_T &getProgramPoint() const { return cast<PP_T>(pp); }
444};
445
446class EndOfFunctionNodeBuilder {
447  CoreEngine &Eng;
448  const CFGBlock& B;
449  ExplodedNode* Pred;
450  void *Tag;
451
452public:
453  bool hasGeneratedNode;
454
455public:
456  EndOfFunctionNodeBuilder(const CFGBlock* b, ExplodedNode* N, CoreEngine* e,
457                           void *checkerTag = 0)
458    : Eng(*e), B(*b), Pred(N), Tag(checkerTag), hasGeneratedNode(false) {}
459
460  ~EndOfFunctionNodeBuilder();
461
462  EndOfFunctionNodeBuilder withCheckerTag(void *tag) {
463    return EndOfFunctionNodeBuilder(&B, Pred, &Eng, tag);
464  }
465
466  WorkList &getWorkList() { return *Eng.WList; }
467
468  ExplodedNode* getPredecessor() const { return Pred; }
469
470  BlockCounter getBlockCounter() const {
471    return Eng.WList->getBlockCounter();
472  }
473
474  unsigned getCurrentBlockCount() const {
475    return getBlockCounter().getNumVisited(
476                            Pred->getLocationContext()->getCurrentStackFrame(),
477                                           B.getBlockID());
478  }
479
480  ExplodedNode* generateNode(const GRState* State, ExplodedNode *P = 0,
481                             const void *tag = 0);
482
483  void GenerateCallExitNode(const GRState *state);
484
485  const CFGBlock* getBlock() const { return &B; }
486
487  const GRState* getState() const {
488    return getPredecessor()->getState();
489  }
490};
491
492class CallEnterNodeBuilder {
493  CoreEngine &Eng;
494
495  const ExplodedNode *Pred;
496
497  // The call site. For implicit automatic object dtor, this is the trigger
498  // statement.
499  const Stmt *CE;
500
501  // The context of the callee.
502  const StackFrameContext *CalleeCtx;
503
504  // The parent block of the CallExpr.
505  const CFGBlock *Block;
506
507  // The CFGBlock index of the CallExpr.
508  unsigned Index;
509
510public:
511  CallEnterNodeBuilder(CoreEngine &eng, const ExplodedNode *pred,
512                         const Stmt *s, const StackFrameContext *callee,
513                         const CFGBlock *blk, unsigned idx)
514    : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {}
515
516  const GRState *getState() const { return Pred->getState(); }
517
518  const LocationContext *getLocationContext() const {
519    return Pred->getLocationContext();
520  }
521
522  const Stmt *getCallExpr() const { return CE; }
523
524  const StackFrameContext *getCalleeContext() const { return CalleeCtx; }
525
526  const CFGBlock *getBlock() const { return Block; }
527
528  unsigned getIndex() const { return Index; }
529
530  void generateNode(const GRState *state);
531};
532
533class CallExitNodeBuilder {
534  CoreEngine &Eng;
535  const ExplodedNode *Pred;
536
537public:
538  CallExitNodeBuilder(CoreEngine &eng, const ExplodedNode *pred)
539    : Eng(eng), Pred(pred) {}
540
541  const ExplodedNode *getPredecessor() const { return Pred; }
542
543  const GRState *getState() const { return Pred->getState(); }
544
545  void generateNode(const GRState *state);
546};
547
548} // end GR namespace
549
550} // end clang namespace
551
552#endif
553