CoreEngine.h revision e36de1fe51c39d9161915dd3dbef880954af6476
1d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- C++ -*-//
21eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump//
3f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//                     The LLVM Compiler Infrastructure
4f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//
5f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek// This file is distributed under the University of Illinois Open Source
6f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek// License. See LICENSE.TXT for details.
7f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//
8f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//===----------------------------------------------------------------------===//
9f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//
10f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//  This file defines a generic engine for intraprocedural, path-sensitive,
118e49dd6e7e73b275a74338a5127a524f0765303cTed Kremenek//  dataflow analysis via graph reachability.
12f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//
13f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek//===----------------------------------------------------------------------===//
14f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
15d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_COREENGINE
16d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#define LLVM_CLANG_GR_COREENGINE
17f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
1899c6ad3f22b865d0f4cce52bc36904403c9ed4c4Ted Kremenek#include "clang/AST/Expr.h"
1921142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h"
2021142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/PathSensitive/WorkList.h"
2121142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/PathSensitive/BlockCounter.h"
2221142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/PathSensitive/SubEngine.h"
23f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek#include "llvm/ADT/OwningPtr.h"
24f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
25f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremeneknamespace clang {
260111f575b968e423dccae439e501225b8314b257Zhongxing Xu
279ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento {
285a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
2924f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek//===----------------------------------------------------------------------===//
30d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// CoreEngine - Implements the core logic of the graph-reachability
31922059dec59c7bed235da01aff75ae522a369811Ted Kremenek///   analysis. It traverses the CFG and generates the ExplodedGraph.
32922059dec59c7bed235da01aff75ae522a369811Ted Kremenek///   Program "states" are treated as opaque void pointers.
33d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis///   The template class CoreEngine (which subclasses CoreEngine)
34922059dec59c7bed235da01aff75ae522a369811Ted Kremenek///   provides the matching component to the engine that knows the actual types
35922059dec59c7bed235da01aff75ae522a369811Ted Kremenek///   for states.  Note that this engine only dispatches to transfer functions
36922059dec59c7bed235da01aff75ae522a369811Ted Kremenek///   at the statement and block-level.  The analyses themselves must implement
37922059dec59c7bed235da01aff75ae522a369811Ted Kremenek///   any transfer function logic and the sub-expression level (if any).
38d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass CoreEngine {
39d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class StmtNodeBuilder;
40d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class BranchNodeBuilder;
41d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class IndirectGotoNodeBuilder;
42d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class SwitchNodeBuilder;
43e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  friend class EndOfFunctionNodeBuilder;
44d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class CallEnterNodeBuilder;
45d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  friend class CallExitNodeBuilder;
460111f575b968e423dccae439e501225b8314b257Zhongxing Xu
47a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Carepublic:
48a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Care  typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
49a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Care            BlocksAborted;
50a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Careprivate:
51a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Care
52d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  SubEngine& SubEng;
530111f575b968e423dccae439e501225b8314b257Zhongxing Xu
54f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  /// G - The simulation graph.  Each node is a (location,state) pair.
5538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  llvm::OwningPtr<ExplodedGraph> G;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  /// WList - A set of queued nodes that need to be processed by the
58f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  ///  worklist algorithm.  It is up to the implementation of WList to decide
59f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  ///  the order that nodes are processed.
60d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  WorkList* WList;
611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// BCounterFactory - A factory object for created BlockCounter objects.
638e49dd6e7e73b275a74338a5127a524f0765303cTed Kremenek  ///   These are used to record for key nodes in the ExplodedGraph the
648e49dd6e7e73b275a74338a5127a524f0765303cTed Kremenek  ///   number of times different CFGBlocks have been visited along a path.
65d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  BlockCounter::Factory BCounterFactory;
66f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek
67f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  /// The locations where we stopped doing work because we visited a location
68f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  ///  too many times.
69f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  BlocksAborted blocksAborted;
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  void generateNode(const ProgramPoint& Loc, const GRState* State,
72c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                    ExplodedNode* Pred);
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
75c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
7603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void HandleBlockExit(const CFGBlock* B, ExplodedNode* Pred);
779dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  void HandlePostStmt(const CFGBlock* B, unsigned StmtIdx, ExplodedNode *Pred);
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void HandleBranch(const Stmt* Cond, const Stmt* Term, const CFGBlock* B,
801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    ExplodedNode* Pred);
81102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  void HandleCallEnter(const CallEnter &L, const CFGBlock *Block,
82102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor                       unsigned Index, ExplodedNode *Pred);
83102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  void HandleCallExit(const CallExit &L, ExplodedNode *Pred);
840111f575b968e423dccae439e501225b8314b257Zhongxing Xu
850111f575b968e423dccae439e501225b8314b257Zhongxing Xu  /// Get the initial state from the subengine.
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const GRState* getInitialState(const LocationContext *InitLoc) {
87d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    return SubEng.getInitialState(InitLoc);
880111f575b968e423dccae439e501225b8314b257Zhongxing Xu  }
890111f575b968e423dccae439e501225b8314b257Zhongxing Xu
90e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processEndOfFunction(EndOfFunctionNodeBuilder& Builder) {
91e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processEndOfFunction(Builder);
92e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processCFGElement(const CFGElement E, StmtNodeBuilder& Builder) {
95e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processCFGElement(E, Builder);
96e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  bool processCFGBlockEntrance(const CFGBlock* Blk, const ExplodedNode *Pred,
99d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                            BlockCounter BC) {
100e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    return SubEng.processCFGBlockEntrance(Blk, Pred, BC);
101e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
1020111f575b968e423dccae439e501225b8314b257Zhongxing Xu
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processBranch(const Stmt* Condition, const Stmt* Terminator,
105d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                     BranchNodeBuilder& Builder) {
106e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processBranch(Condition, Terminator, Builder);
107e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
108f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
1097d7fe6d539b3bdb1701835223cca306c325614a7Ted Kremenek
110e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processIndirectGoto(IndirectGotoNodeBuilder& Builder) {
111e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processIndirectGoto(Builder);
112e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
113f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
115e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processSwitch(SwitchNodeBuilder& Builder) {
116e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processSwitch(Builder);
117e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
118e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu
119e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processCallEnter(CallEnterNodeBuilder &Builder) {
120e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processCallEnter(Builder);
121e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
122f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
123e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processCallExit(CallExitNodeBuilder &Builder) {
124e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    SubEng.processCallExit(Builder);
125e492340cc90eb92fc40e9e99645f19ed64640333Zhongxing Xu  }
126102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
127f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenekprivate:
128d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine(const CoreEngine&); // Do not implement.
129d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine& operator=(const CoreEngine&);
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
131f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenekpublic:
132d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// Construct a CoreEngine object to analyze the provided CFG using
1330111f575b968e423dccae439e501225b8314b257Zhongxing Xu  ///  a DFS exploration of the exploded graph.
134d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine(SubEngine& subengine)
135d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    : SubEng(subengine), G(new ExplodedGraph()),
136d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis      WList(WorkList::MakeBFS()),
137f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek      BCounterFactory(G->getAllocator()) {}
1380111f575b968e423dccae439e501225b8314b257Zhongxing Xu
139d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// Construct a CoreEngine object to analyze the provided CFG and to
1400111f575b968e423dccae439e501225b8314b257Zhongxing Xu  ///  use the provided worklist object to execute the worklist algorithm.
141d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ///  The CoreEngine object assumes ownership of 'wlist'.
142d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine(WorkList* wlist, SubEngine& subengine)
143d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    : SubEng(subengine), G(new ExplodedGraph()), WList(wlist),
144f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek      BCounterFactory(G->getAllocator()) {}
1450111f575b968e423dccae439e501225b8314b257Zhongxing Xu
146d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ~CoreEngine() {
1470111f575b968e423dccae439e501225b8314b257Zhongxing Xu    delete WList;
1480111f575b968e423dccae439e501225b8314b257Zhongxing Xu  }
1490111f575b968e423dccae439e501225b8314b257Zhongxing Xu
1500111f575b968e423dccae439e501225b8314b257Zhongxing Xu  /// getGraph - Returns the exploded graph.
151031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedGraph& getGraph() { return *G.get(); }
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1530111f575b968e423dccae439e501225b8314b257Zhongxing Xu  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
1540111f575b968e423dccae439e501225b8314b257Zhongxing Xu  ///  transfered to the caller.
155031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedGraph* takeGraph() { return G.take(); }
1560111f575b968e423dccae439e501225b8314b257Zhongxing Xu
157f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
158f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  ///  steps.  Returns true if there is still simulation state on the worklist.
1592ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
1602ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu                       const GRState *InitState);
1612ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
1622ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu                                       const GRState *InitState,
1632ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu                                       ExplodedNodeSet &Dst);
164bc42c533e7d3d946704a49e242939dd232f33072Tom Care
165bc42c533e7d3d946704a49e242939dd232f33072Tom Care  // Functions for external checking of whether we have unfinished work
166f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  bool wasBlockAborted() const { return !blocksAborted.empty(); }
167f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  bool hasWorkRemaining() const { return wasBlockAborted() || WList->hasWork(); }
168bc42c533e7d3d946704a49e242939dd232f33072Tom Care
169d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  WorkList *getWorkList() const { return WList; }
170f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek
171f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  BlocksAborted::const_iterator blocks_aborted_begin() const {
172f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek    return blocksAborted.begin();
173f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  }
174f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  BlocksAborted::const_iterator blocks_aborted_end() const {
175f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek    return blocksAborted.end();
176f598087b4adfea164acdd5b53ea2951bde740a2dTed Kremenek  }
177f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek};
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
179d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass StmtNodeBuilder {
180d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine& Eng;
18103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock& B;
182f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  const unsigned Idx;
183c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode* Pred;
184031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  GRStateManager& Mgr;
185031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
186031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xupublic:
187031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  bool PurgingDeadSymbols;
188031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  bool BuildSinks;
189031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  bool HasGeneratedNode;
190031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ProgramPoint::Kind PointKind;
191031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const void *Tag;
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const GRState* CleanedState;
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
195031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
196c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
197f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  DeferredTy Deferred;
1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
199c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  void GenerateAutoTransition(ExplodedNode* N);
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
201f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenekpublic:
202d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  StmtNodeBuilder(const CFGBlock* b, unsigned idx, ExplodedNode* N,
203d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                    CoreEngine* e, GRStateManager &mgr);
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
205d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ~StmtNodeBuilder();
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
207c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode* getBasePredecessor() const { return Pred; }
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
209798d2ca60d1cd6de70d28a5ce60337a2b03a663fZhongxing Xu  // FIXME: This should not be exposed.
210d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  WorkList *getWorkList() { return Eng.WList; }
211798d2ca60d1cd6de70d28a5ce60337a2b03a663fZhongxing Xu
212031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  void SetCleanedState(const GRState* St) {
213031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    CleanedState = St;
214031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  }
215031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
216d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21800a3a5f024ac54088ab887712b292171188064f0Ted Kremenek  unsigned getCurrentBlockCount() const {
219d9e0c0fc47d5881a609ec34372d554e3652db66cZhongxing Xu    return getBlockCounter().getNumVisited(
220d9e0c0fc47d5881a609ec34372d554e3652db66cZhongxing Xu                            Pred->getLocationContext()->getCurrentStackFrame(),
221d9e0c0fc47d5881a609ec34372d554e3652db66cZhongxing Xu                                           B.getBlockID());
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
223031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
224031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
225031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    HasGeneratedNode = true;
226031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    return generateNodeInternal(PP, St, Pred);
227031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  }
2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
229e1ccccff777f6bad6b25e9c6a762f98fd8003181Ted Kremenek  ExplodedNode* generateNode(const Stmt *S, const GRState *St,
230e1ccccff777f6bad6b25e9c6a762f98fd8003181Ted Kremenek                             ExplodedNode *Pred, ProgramPoint::Kind K) {
231031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    HasGeneratedNode = true;
232031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (PurgingDeadSymbols)
2341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      K = ProgramPoint::PostPurgeDeadSymbolsKind;
235031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
236031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    return generateNodeInternal(S, St, Pred, K, Tag);
237031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  }
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
239e1ccccff777f6bad6b25e9c6a762f98fd8003181Ted Kremenek  ExplodedNode* generateNode(const Stmt *S, const GRState *St,
240e1ccccff777f6bad6b25e9c6a762f98fd8003181Ted Kremenek                             ExplodedNode *Pred) {
241031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    return generateNode(S, St, Pred, PointKind);
242031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  }
243031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
244102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  ExplodedNode *generateNode(const ProgramPoint &PP, const GRState* State,
245102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor                             ExplodedNode* Pred) {
246102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    HasGeneratedNode = true;
247102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return generateNodeInternal(PP, State, Pred);
248102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
249102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
250c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode*
251031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  generateNodeInternal(const ProgramPoint &PP, const GRState* State,
252031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                       ExplodedNode* Pred);
2531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
254c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode*
255031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  generateNodeInternal(const Stmt* S, const GRState* State, ExplodedNode* Pred,
2561670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek                   ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
2571670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek                   const void *tag = 0);
2581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
259331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  /// getStmt - Return the current block-level expression associated with
260331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  ///  this builder.
261b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu  const Stmt* getStmt() const {
262b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    CFGStmt CS = B[Idx].getAs<CFGStmt>();
263b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    if (CS)
264b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu      return CS.getStmt();
265b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    else
266b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu      return 0;
267b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu  }
2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
269331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  /// getBlock - Return the CFGBlock associated with the block-level expression
270331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek  ///  of this builder.
27103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* getBlock() const { return &B; }
272bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek
273598278bee8e5797bc73d24d6ac8a1d6ff6413caeZhongxing Xu  unsigned getIndex() const { return Idx; }
274598278bee8e5797bc73d24d6ac8a1d6ff6413caeZhongxing Xu
275031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const GRState* GetState(ExplodedNode* Pred) const {
27621433a5fece2bb9a2c1792c18edd13b8d77e0bbdZhongxing Xu    if (Pred == getBasePredecessor())
2773bbad550be7edc628be31b51d2a51b6d7d46eafbTed Kremenek      return CleanedState;
2783bbad550be7edc628be31b51d2a51b6d7d46eafbTed Kremenek    else
2793bbad550be7edc628be31b51d2a51b6d7d46eafbTed Kremenek      return Pred->getState();
2803bbad550be7edc628be31b51d2a51b6d7d46eafbTed Kremenek  }
281031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
2823992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
2833992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu                         ExplodedNode* Pred, const GRState* St) {
284bf4e419d996bf42e4933cada610d973a0fcc40ebTed Kremenek    return MakeNode(Dst, S, Pred, St, PointKind);
285bf4e419d996bf42e4933cada610d973a0fcc40ebTed Kremenek  }
2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2873992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,ExplodedNode* Pred,
288868e78d59d2dfaf9cda511925e5a58f3a712db96Zhongxing Xu                         const GRState* St, ProgramPoint::Kind K);
2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2903992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu  ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, const Stmt* S,
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       ExplodedNode* Pred, const GRState* St) {
29270a733e64e2379a654631a14fa29e46761d5f80dTed Kremenek    bool Tmp = BuildSinks;
29370a733e64e2379a654631a14fa29e46761d5f80dTed Kremenek    BuildSinks = true;
294031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    ExplodedNode* N = MakeNode(Dst, S, Pred, St);
29570a733e64e2379a654631a14fa29e46761d5f80dTed Kremenek    BuildSinks = Tmp;
29670a733e64e2379a654631a14fa29e46761d5f80dTed Kremenek    return N;
29770a733e64e2379a654631a14fa29e46761d5f80dTed Kremenek  }
298f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek};
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
300d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass BranchNodeBuilder {
301d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine& Eng;
30203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* Src;
30303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* DstT;
30403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* DstF;
305c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode* Pred;
30652a16499df87730c0252b431abdf2b2e32d756a6Ted Kremenek
307c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  typedef llvm::SmallVector<ExplodedNode*,3> DeferredTy;
3083b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek  DeferredTy Deferred;
3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31071c29bdc931bc49644c581ec7d698f0dbf01a0aaTed Kremenek  bool GeneratedTrue;
31171c29bdc931bc49644c581ec7d698f0dbf01a0aaTed Kremenek  bool GeneratedFalse;
312520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek  bool InFeasibleTrue;
313520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek  bool InFeasibleFalse;
3141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3157d7fe6d539b3bdb1701835223cca306c325614a7Ted Kremenekpublic:
316d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  BranchNodeBuilder(const CFGBlock* src, const CFGBlock* dstT,
317d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                      const CFGBlock* dstF, ExplodedNode* pred, CoreEngine* e)
31871c29bdc931bc49644c581ec7d698f0dbf01a0aaTed Kremenek  : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
319520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek    GeneratedTrue(false), GeneratedFalse(false),
320520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
322d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ~BranchNodeBuilder();
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
324c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode* getPredecessor() const { return Pred; }
325031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
32638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const ExplodedGraph& getGraph() const { return *Eng.G; }
327031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
328d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
330031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* generateNode(const GRState* State, bool branch);
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* getTargetBlock(bool branch) const {
3338e49dd6e7e73b275a74338a5127a524f0765303cTed Kremenek    return branch ? DstT : DstF;
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33652a16499df87730c0252b431abdf2b2e32d756a6Ted Kremenek  void markInfeasible(bool branch) {
337520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek    if (branch)
338520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek      InFeasibleTrue = GeneratedTrue = true;
339520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek    else
340520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek      InFeasibleFalse = GeneratedFalse = true;
341520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek  }
3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
343520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek  bool isFeasible(bool branch) {
344520035439d7133064325c4df6378c5a8f2f05539Ted Kremenek    return branch ? !InFeasibleTrue : !InFeasibleFalse;
34552a16499df87730c0252b431abdf2b2e32d756a6Ted Kremenek  }
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
347031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const GRState* getState() const {
348b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek    return getPredecessor()->getState();
349b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek  }
3507d7fe6d539b3bdb1701835223cca306c325614a7Ted Kremenek};
351031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
352d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass IndirectGotoNodeBuilder {
353d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine& Eng;
35403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* Src;
35503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock& DispatchBlock;
35603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const Expr* E;
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNode* Pred;
358031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
359754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenekpublic:
360d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  IndirectGotoNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
361d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                    const Expr* e, const CFGBlock* dispatch, CoreEngine* eng)
36203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
363754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
364031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  class iterator {
36503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    CFGBlock::const_succ_iterator I;
3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
367d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    friend class IndirectGotoNodeBuilder;
36803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    iterator(CFGBlock::const_succ_iterator i) : I(i) {}
369754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  public:
3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
371031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    iterator& operator++() { ++I; return *this; }
372031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    bool operator!=(const iterator& X) const { return I != X.I; }
3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    const LabelStmt* getLabel() const {
37524f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek      return llvm::cast<LabelStmt>((*I)->getLabel());
37624f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek    }
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
37803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    const CFGBlock*  getBlock() const {
37924f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek      return *I;
38024f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek    }
381754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek  };
3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
383031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
384031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  iterator end() { return iterator(DispatchBlock.succ_end()); }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
386031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* generateNode(const iterator& I, const GRState* State,
387031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                             bool isSink = false);
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
38903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const Expr* getTarget() const { return E; }
390754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
391031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const GRState* getState() const { return Pred->State; }
392754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek};
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
394d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass SwitchNodeBuilder {
395d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine& Eng;
39603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* Src;
39703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const Expr* Condition;
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNode* Pred;
399031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
400daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenekpublic:
401d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  SwitchNodeBuilder(ExplodedNode* pred, const CFGBlock* src,
402d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                      const Expr* condition, CoreEngine* eng)
403daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
405031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  class iterator {
40603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    CFGBlock::const_succ_reverse_iterator I;
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
408d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    friend class SwitchNodeBuilder;
40903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
410031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu
411daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  public:
412031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    iterator& operator++() { ++I; return *this; }
41334feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek    bool operator!=(const iterator &X) const { return I != X.I; }
41434feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek    bool operator==(const iterator &X) const { return I == X.I; }
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    const CaseStmt* getCase() const {
417daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      return llvm::cast<CaseStmt>((*I)->getLabel());
418daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    }
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu    const CFGBlock* getBlock() const {
421daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek      return *I;
422daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek    }
423daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek  };
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
425031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  iterator begin() { return iterator(Src->succ_rbegin()+1); }
426031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  iterator end() { return iterator(Src->succ_rend()); }
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4284d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  const SwitchStmt *getSwitch() const {
4294d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    return llvm::cast<SwitchStmt>(Src->getTerminator());
4304d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek  }
4314d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek
432031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* generateCaseStmtNode(const iterator& I, const GRState* State);
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
434031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* generateDefaultCaseNode(const GRState* State,
435031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                                        bool isSink = false);
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const Expr* getCondition() const { return Condition; }
438daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek
439031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const GRState* getState() const { return Pred->State; }
440daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek};
44111062b118476368fa5b294954713e5df97d8599fTed Kremenek
442e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekclass EndOfFunctionNodeBuilder {
443d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine &Eng;
44403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock& B;
4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNode* Pred;
446f605aae3227ffa3a5dae8eb34fdd79ba0a0d19d1Zhongxing Xu
447f605aae3227ffa3a5dae8eb34fdd79ba0a0d19d1Zhongxing Xupublic:
44811062b118476368fa5b294954713e5df97d8599fTed Kremenek  bool HasGeneratedNode;
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45011062b118476368fa5b294954713e5df97d8599fTed Kremenekpublic:
451e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  EndOfFunctionNodeBuilder(const CFGBlock* b, ExplodedNode* N, CoreEngine* e)
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}
4531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
454e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  ~EndOfFunctionNodeBuilder();
4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
456d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  WorkList &getWorkList() { return *Eng.WList; }
457598278bee8e5797bc73d24d6ac8a1d6ff6413caeZhongxing Xu
458c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  ExplodedNode* getPredecessor() const { return Pred; }
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
460d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  BlockCounter getBlockCounter() const {
461031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu    return Eng.WList->getBlockCounter();
462031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  }
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46411062b118476368fa5b294954713e5df97d8599fTed Kremenek  unsigned getCurrentBlockCount() const {
465d9e0c0fc47d5881a609ec34372d554e3652db66cZhongxing Xu    return getBlockCounter().getNumVisited(
466d9e0c0fc47d5881a609ec34372d554e3652db66cZhongxing Xu                            Pred->getLocationContext()->getCurrentStackFrame(),
467d9e0c0fc47d5881a609ec34372d554e3652db66cZhongxing Xu                                           B.getBlockID());
4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
470031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* generateNode(const GRState* State, const void *tag = 0,
471031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                             ExplodedNode *P = 0);
4721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
473102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  void GenerateCallExitNode(const GRState *state);
474102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
47503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const CFGBlock* getBlock() const { return &B; }
47611062b118476368fa5b294954713e5df97d8599fTed Kremenek
477031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const GRState* getState() const {
47811062b118476368fa5b294954713e5df97d8599fTed Kremenek    return getPredecessor()->getState();
47911062b118476368fa5b294954713e5df97d8599fTed Kremenek  }
48011062b118476368fa5b294954713e5df97d8599fTed Kremenek};
481754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek
482d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass CallEnterNodeBuilder {
483d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine &Eng;
484102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
485102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const ExplodedNode *Pred;
486102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
48719b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  // The call site. For implicit automatic object dtor, this is the trigger
48819b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  // statement.
489102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const Stmt *CE;
490102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
49119b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  // The context of the callee.
49219b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  const StackFrameContext *CalleeCtx;
493102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
494102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  // The parent block of the CallExpr.
495102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const CFGBlock *Block;
496102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
497102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  // The CFGBlock index of the CallExpr.
498102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  unsigned Index;
499102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
500102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic:
501d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CallEnterNodeBuilder(CoreEngine &eng, const ExplodedNode *pred,
50219b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu                         const Stmt *s, const StackFrameContext *callee,
503102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor                         const CFGBlock *blk, unsigned idx)
504c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu    : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {}
505102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
506102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const GRState *getState() const { return Pred->getState(); }
507102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
508102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const LocationContext *getLocationContext() const {
509102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    return Pred->getLocationContext();
510102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  }
511102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
512102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const Stmt *getCallExpr() const { return CE; }
513102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
51419b78d9e3dbbc27bbcbdd8c3017a00fe88849ecdZhongxing Xu  const StackFrameContext *getCalleeContext() const { return CalleeCtx; }
515102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
516102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const CFGBlock *getBlock() const { return Block; }
517102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
518102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  unsigned getIndex() const { return Index; }
519102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
520d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  void generateNode(const GRState *state);
521102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor};
522102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
523d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass CallExitNodeBuilder {
524d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine &Eng;
525102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const ExplodedNode *Pred;
526102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
527102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregorpublic:
528d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CallExitNodeBuilder(CoreEngine &eng, const ExplodedNode *pred)
529102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor    : Eng(eng), Pred(pred) {}
530102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
531102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const ExplodedNode *getPredecessor() const { return Pred; }
532102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
533102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor  const GRState *getState() const { return Pred->getState(); }
534102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
535d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek  void generateNode(const GRState *state);
536102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor};
5375a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
5385a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis} // end GR namespace
5395a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
540f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek} // end clang namespace
541f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek
542f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek#endif
543