CoreEngine.h revision cca79db2ea94f71fb088f4b0f104cef8bedf8ff2
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- C++ -*-//
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//                     The LLVM Compiler Infrastructure
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// This file is distributed under the University of Illinois Open Source
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// License. See LICENSE.TXT for details.
7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang//
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===//
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//  This file defines a generic engine for intraprocedural, path-sensitive,
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//  dataflow analysis via graph reachability.
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===//
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef LLVM_CLANG_GR_COREENGINE
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define LLVM_CLANG_GR_COREENGINE
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "clang/AST/Expr.h"
19a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
20a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
21a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
22a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "llvm/ADT/OwningPtr.h"
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace clang {
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ProgramPointTag;
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace ento {
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass NodeBuilder;
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===//
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// CoreEngine - Implements the core logic of the graph-reachability
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///   analysis. It traverses the CFG and generates the ExplodedGraph.
35a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang///   Program "states" are treated as opaque void pointers.
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///   The template class CoreEngine (which subclasses CoreEngine)
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///   provides the matching component to the engine that knows the actual types
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///   for states.  Note that this engine only dispatches to transfer functions
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///   at the statement and block-level.  The analyses themselves must implement
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project///   any transfer function logic and the sub-expression level (if any).
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass CoreEngine {
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend struct NodeBuilderContext;
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class NodeBuilder;
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class CommonNodeBuilder;
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class GenericNodeBuilderImpl;
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class IndirectGotoNodeBuilder;
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class SwitchNodeBuilder;
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class EndOfFunctionNodeBuilder;
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class CallEnterNodeBuilder;
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class CallExitNodeBuilder;
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  friend class ExprEngine;
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
5577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            BlocksExhausted;
5677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            BlocksAborted;
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprivate:
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SubEngine& SubEng;
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// G - The simulation graph.  Each node is a (location,state) pair.
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  llvm::OwningPtr<ExplodedGraph> G;
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// WList - A set of queued nodes that need to be processed by the
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  worklist algorithm.  It is up to the implementation of WList to decide
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  the order that nodes are processed.
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  WorkList* WList;
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// BCounterFactory - A factory object for created BlockCounter objects.
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///   These are used to record for key nodes in the ExplodedGraph the
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///   number of times different CFGBlocks have been visited along a path.
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlockCounter::Factory BCounterFactory;
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// The locations where we stopped doing work because we visited a location
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  too many times.
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlocksExhausted blocksExhausted;
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
8177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /// The locations where we stopped because the engine aborted analysis,
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// usually because it could not reason about something.
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlocksAborted blocksAborted;
8477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void generateNode(const ProgramPoint &Loc,
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const ProgramState *State,
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ExplodedNode *Pred);
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred);
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred);
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred);
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ExplodedNode *Pred);
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       unsigned Index, ExplodedNode *Pred);
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void HandleCallExit(const CallExit &L, ExplodedNode *Pred);
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprivate:
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine(const CoreEngine&); // Do not implement.
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine& operator=(const CoreEngine&);
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Construct a CoreEngine object to analyze the provided CFG using
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  a DFS exploration of the exploded graph.
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine(SubEngine& subengine)
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : SubEng(subengine), G(new ExplodedGraph()),
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      WList(WorkList::makeBFS()),
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      BCounterFactory(G->getAllocator()) {}
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Construct a CoreEngine object to analyze the provided CFG and to
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  use the provided worklist object to execute the worklist algorithm.
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  The CoreEngine object assumes ownership of 'wlist'.
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine(WorkList* wlist, SubEngine& subengine)
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : SubEng(subengine), G(new ExplodedGraph()), WList(wlist),
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      BCounterFactory(G->getAllocator()) {}
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ~CoreEngine() {
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delete WList;
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// getGraph - Returns the exploded graph.
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedGraph& getGraph() { return *G.get(); }
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  transferred to the caller.
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedGraph* takeGraph() { return G.take(); }
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///  steps.  Returns true if there is still simulation state on the worklist.
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       const ProgramState *InitState);
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void ExecuteWorkListWithInitialState(const LocationContext *L,
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       unsigned Steps,
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       const ProgramState *InitState,
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       ExplodedNodeSet &Dst);
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // Functions for external checking of whether we have unfinished work
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool wasBlockAborted() const { return !blocksAborted.empty(); }
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool hasWorkRemaining() const { return wasBlocksExhausted() ||
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         WList->hasWork() ||
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         wasBlockAborted(); }
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Inform the CoreEngine that a basic block was aborted because
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// it could not be completely analyzed.
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    blocksAborted.push_back(std::make_pair(block, node));
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  WorkList *getWorkList() const { return WList; }
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlocksExhausted::const_iterator blocks_exhausted_begin() const {
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return blocksExhausted.begin();
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlocksExhausted::const_iterator blocks_exhausted_end() const {
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return blocksExhausted.end();
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlocksAborted::const_iterator blocks_aborted_begin() const {
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return blocksAborted.begin();
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlocksAborted::const_iterator blocks_aborted_end() const {
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return blocksAborted.end();
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Enqueue the results of the node builder onto the work list.
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void enqueue(ExplodedNodeSet &NB);
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectstruct NodeBuilderContext {
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine &Eng;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *Block;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *ContextPred;
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  NodeBuilderContext(CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : Eng(E), Block(B), ContextPred(N) { assert(B); assert(!N->isSink()); }
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Return the CFGBlock associated with this builder.
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *getBlock() const { return Block; }
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Returns the number of times the current basic block has been
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// visited on the exploded graph path.
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned getCurrentBlockCount() const {
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Eng.WList->getBlockCounter().getNumVisited(
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ContextPred->getLocationContext()->getCurrentStackFrame(),
18677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                    Block->getBlockID());
18777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
18877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
18977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner};
19077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
19177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner/// This is the simplest builder which generates nodes in the ExplodedGraph.
19277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass NodeBuilder {
19377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerprotected:
19477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const NodeBuilderContext &C;
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Specifies if the builder results have been finalized. For example, if it
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// is set to false, autotransitions are yet to be generated.
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool Finalized;
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool HasGeneratedNodes;
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief The frontier set - a set of nodes which need to be propagated after
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// the builder dies.
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNodeSet &Frontier;
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Checkes if the results are ready.
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  virtual bool checkResults() {
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (!Finalized)
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return false;
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return true;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool haveNoSinksInFrontier() {
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) {
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ((*I)->isSink())
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return false;
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return true;
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// Allow subclasses to finalize results before result_begin() is executed.
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  virtual void finalizeResults() {}
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNodeImpl(const ProgramPoint &PP,
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 const ProgramState *State,
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 ExplodedNode *Pred,
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 bool MarkAsSink = false);
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turnerpublic:
230c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner  NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              const NodeBuilderContext &Ctx, bool F = true)
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
233c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner  //  assert(DstSet.empty());
234c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner    Frontier.Add(SrcNode);
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
236295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
237295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
238295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner              const NodeBuilderContext &Ctx, bool F = true)
239295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
240a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    //assert(DstSet.empty());
241a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    //assert(!SrcSet.empty());
242a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    Frontier.insert(SrcSet);
243a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    assert(haveNoSinksInFrontier());
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  virtual ~NodeBuilder() {}
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Generates a node in the ExplodedGraph.
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ///
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// When a node is marked as sink, the exploration from the node is stopped -
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// the node becomes the last node on the path.
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNode(const ProgramPoint &PP,
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             const ProgramState *State,
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             ExplodedNode *Pred,
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             bool MarkAsSink = false) {
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return generateNodeImpl(PP, State, Pred, MarkAsSink);
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // TODO: will get removed.
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool hasGeneratedNodes() const {
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return HasGeneratedNodes;
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const ExplodedNodeSet &getResults() {
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    finalizeResults();
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(checkResults());
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Frontier;
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef ExplodedNodeSet::iterator iterator;
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /// \brief Iterators through the results frontier.
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  inline iterator begin() {
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    finalizeResults();
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    assert(checkResults());
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Frontier.begin();
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  inline iterator end() {
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    finalizeResults();
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return Frontier.end();
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const NodeBuilderContext &getContext() { return C; }
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void takeNodes(const ExplodedNodeSet &S) {
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I )
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Frontier.erase(*I);
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void takeNodes(ExplodedNode *N) {
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Frontier.erase(N);
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void addNodes(const ExplodedNodeSet &S) {
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Frontier.insert(S);
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void addNodes(ExplodedNode *N) {
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Frontier.Add(N);
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass CommonNodeBuilder {
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprotected:
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *Pred;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine &Eng;
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CommonNodeBuilder(CoreEngine* E, ExplodedNode *P) : Pred(P), Eng(*E) {}
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter(); }
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass PureStmtNodeBuilder: public NodeBuilder {
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  NodeBuilder *EnclosingBldr;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  PureStmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0)
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (EnclosingBldr)
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      EnclosingBldr->takeNodes(SrcNode);
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  PureStmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0)
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (EnclosingBldr)
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for (ExplodedNodeSet::iterator I = SrcSet.begin(),
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     E = SrcSet.end(); I != E; ++I )
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        EnclosingBldr->takeNodes(*I);
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  virtual ~PureStmtNodeBuilder();
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNode(const Stmt *S,
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             ExplodedNode *Pred,
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             const ProgramState *St,
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             bool MarkAsSink = false,
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             const ProgramPointTag *tag = 0,
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             bool Purging = false) {
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (Purging) {
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      assert(K == ProgramPoint::PostStmtKind);
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      K = ProgramPoint::PostPurgeDeadSymbolsKind;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  Pred->getLocationContext(), tag);
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return generateNodeImpl(L, St, Pred, MarkAsSink);
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNode(const ProgramPoint &PP,
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             ExplodedNode *Pred,
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             const ProgramState *State,
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             bool MarkAsSink = false) {
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return generateNodeImpl(PP, State, Pred, MarkAsSink);
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass BranchNodeBuilder: public NodeBuilder {
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *DstT;
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *DstF;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool InFeasibleTrue;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool InFeasibleFalse;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const NodeBuilderContext &C,
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const CFGBlock *dstT, const CFGBlock *dstF)
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const NodeBuilderContext &C,
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const CFGBlock *dstT, const CFGBlock *dstF)
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNode(const ProgramState *State, bool branch,
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             ExplodedNode *Pred);
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *getTargetBlock(bool branch) const {
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return branch ? DstT : DstF;
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  void markInfeasible(bool branch) {
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (branch)
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      InFeasibleTrue = true;
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      InFeasibleFalse = true;
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool isFeasible(bool branch) {
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return branch ? !InFeasibleTrue : !InFeasibleFalse;
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass IndirectGotoNodeBuilder {
40177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  CoreEngine& Eng;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *Src;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock &DispatchBlock;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const Expr *E;
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *Pred;
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src,
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const Expr *e, const CFGBlock *dispatch, CoreEngine* eng)
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  class iterator {
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFGBlock::const_succ_iterator I;
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    friend class IndirectGotoNodeBuilder;
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    iterator(CFGBlock::const_succ_iterator i) : I(i) {}
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  public:
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    iterator &operator++() { ++I; return *this; }
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool operator!=(const iterator &X) const { return I != X.I; }
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const LabelDecl *getLabel() const {
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return llvm::cast<LabelStmt>((*I)->getLabel())->getDecl();
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const CFGBlock *getBlock() const {
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return *I;
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
43077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
43177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  iterator end() { return iterator(DispatchBlock.succ_end()); }
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNode(const iterator &I,
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             const ProgramState *State,
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             bool isSink = false);
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const Expr *getTarget() const { return E; }
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const ProgramState *getState() const { return Pred->State; }
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass SwitchNodeBuilder {
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine& Eng;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *Src;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const Expr *Condition;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *Pred;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src,
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const Expr *condition, CoreEngine* eng)
45277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  class iterator {
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFGBlock::const_succ_reverse_iterator I;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    friend class SwitchNodeBuilder;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  public:
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    iterator &operator++() { ++I; return *this; }
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool operator!=(const iterator &X) const { return I != X.I; }
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bool operator==(const iterator &X) const { return I == X.I; }
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const CaseStmt *getCase() const {
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return llvm::cast<CaseStmt>((*I)->getLabel());
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const CFGBlock *getBlock() const {
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return *I;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  iterator begin() { return iterator(Src->succ_rbegin()+1); }
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  iterator end() { return iterator(Src->succ_rend()); }
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const SwitchStmt *getSwitch() const {
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return llvm::cast<SwitchStmt>(Src->getTerminator());
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateCaseStmtNode(const iterator &I,
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     const ProgramState *State);
48377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
48477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ExplodedNode *generateDefaultCaseNode(const ProgramState *State,
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        bool isSink = false);
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const Expr *getCondition() const { return Condition; }
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const ProgramState *getState() const { return Pred->State; }
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass GenericNodeBuilderImpl {
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprotected:
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CoreEngine &engine;
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *pred;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ProgramPoint pp;
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  SmallVector<ExplodedNode*, 2> sinksGenerated;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
49977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ExplodedNode *generateNodeImpl(const ProgramState *state,
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 ExplodedNode *pred,
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 ProgramPoint programPoint,
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 bool asSink);
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p)
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : engine(eng), pred(pr), pp(p), hasGeneratedNode(false) {}
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  bool hasGeneratedNode;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  WorkList &getWorkList() { return *engine.WList; }
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *getPredecessor() const { return pred; }
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  BlockCounter getBlockCounter() const {
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return engine.WList->getBlockCounter();
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const SmallVectorImpl<ExplodedNode*> &sinks() const {
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return sinksGenerated;
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projecttemplate <typename PP_T>
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass GenericNodeBuilder : public GenericNodeBuilderImpl {
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP_T &p)
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    : GenericNodeBuilderImpl(eng, pr, p) {}
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ExplodedNode *generateNode(const ProgramState *state, ExplodedNode *pred,
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             const ProgramPointTag *tag, bool asSink) {
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag),
532295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                            asSink);
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const PP_T &getProgramPoint() const { return cast<PP_T>(pp); }
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
53777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
53877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass EndOfFunctionNodeBuilder : public CommonNodeBuilder {
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock &B;
54077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ProgramPointTag *Tag;
54177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
54277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerpublic:
54377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  bool hasGeneratedNode;
54477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic:
546295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  EndOfFunctionNodeBuilder(const CFGBlock *b, ExplodedNode *N, CoreEngine* e,
547295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                           const ProgramPointTag *tag = 0)
548295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    : CommonNodeBuilder(e, N), B(*b), Tag(tag), hasGeneratedNode(false) {}
549295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
55077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ~EndOfFunctionNodeBuilder();
55177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
55277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  EndOfFunctionNodeBuilder withCheckerTag(const ProgramPointTag *tag) {
55377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    return EndOfFunctionNodeBuilder(&B, Pred, &Eng, tag);
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
55577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
55677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  WorkList &getWorkList() { return *Eng.WList; }
55777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
55877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ExplodedNode *getPredecessor() const { return Pred; }
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  unsigned getCurrentBlockCount() const {
56177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    return getBlockCounter().getNumVisited(
56277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                            Pred->getLocationContext()->getCurrentStackFrame(),
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           B.getBlockID());
56477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
56577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
56677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ExplodedNode *generateNode(const ProgramState *State,
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             ExplodedNode *P = 0,
56877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                             const ProgramPointTag *tag = 0);
56977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
57077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  void GenerateCallExitNode(const ProgramState *state);
57177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *getBlock() const { return &B; }
57377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
57477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ProgramState *getState() const {
57577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    return getPredecessor()->getState();
57677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project};
57877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
57977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass CallEnterNodeBuilder {
58077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  CoreEngine &Eng;
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
58277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ExplodedNode *Pred;
58377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
58477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  // The call site. For implicit automatic object dtor, this is the trigger
58577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  // statement.
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const Stmt *CE;
58777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
58877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  // The context of the callee.
58977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const StackFrameContext *CalleeCtx;
59077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  // The parent block of the CallExpr.
59277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const CFGBlock *Block;
59377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
59477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  // The CFGBlock index of the CallExpr.
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  unsigned Index;
59677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
59777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerpublic:
59877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  CallEnterNodeBuilder(CoreEngine &eng, const ExplodedNode *pred,
59977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                         const Stmt *s, const StackFrameContext *callee,
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const CFGBlock *blk, unsigned idx)
60177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {}
60277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
60377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ProgramState *getState() const { return Pred->getState(); }
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
60577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const LocationContext *getLocationContext() const {
60677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    return Pred->getLocationContext();
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
60877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
60977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const Stmt *getCallExpr() const { return CE; }
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
61177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const StackFrameContext *getCalleeContext() const { return CalleeCtx; }
61277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  const CFGBlock *getBlock() const { return Block; }
61477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
61577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  unsigned getIndex() const { return Index; }
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
61777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  void generateNode(const ProgramState *state);
61877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner};
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass CallExitNodeBuilder {
62177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  CoreEngine &Eng;
62277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ExplodedNode *Pred;
62377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
62477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerpublic:
62577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  CallExitNodeBuilder(CoreEngine &eng, const ExplodedNode *pred)
62677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    : Eng(eng), Pred(pred) {}
62777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
62877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ExplodedNode *getPredecessor() const { return Pred; }
62977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
63077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  const ProgramState *getState() const { return Pred->getState(); }
63177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
63277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  void generateNode(const ProgramState *state);
63377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner};
63477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
63577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner} // end GR namespace
63677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
63777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner} // end clang namespace
63877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
63977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
64077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner