ExprEngine.h revision ca804539d908d3a0e8c72a0df5f1f571d29490bb
14b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=//
24b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
34b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
44b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
54b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
64b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
74b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
84b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
94b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
104b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//  This file defines a meta-engine for path-sensitive dataflow analysis that
114b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//  is built on CoreEngine, but provides the boilerplate to execute transfer
124b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//  functions and build the ExplodedGraph at the expression level.
134b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//
140853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_EXPRENGINE
17eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor#define LLVM_CLANG_GR_EXPRENGINE
1805a07605322dfef2b017781042043a261c5a89cdSebastian Redl
19914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
200a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
214ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
2231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
23eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h"
2487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
2528019772db70d4547be05a042eb950bc910f134fDouglas Gregor#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
260853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/Type.h"
27a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor#include "clang/AST/ExprObjC.h"
28cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include "clang/AST/ExprCXX.h"
29313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor#include "clang/AST/StmtObjC.h"
30385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor
31788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregornamespace clang {
320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
33f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass ObjCForCollectionStmt;
34f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
354db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregornamespace ento {
36cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
374db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregorclass AnalysisManager;
384db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor
394db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregorclass ExprEngine : public SubEngine {
404db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  AnalysisManager &AMgr;
410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  CoreEngine Engine;
43521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  /// G - the simulation graph.
45521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  ExplodedGraph& G;
46521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
47521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  /// Builder - The current StmtNodeBuilder which is used when building the
48521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  ///  nodes for a given statement.
49521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  StmtNodeBuilder* Builder;
50521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
51521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  /// StateMgr - Object that manages the data for all created states.
52521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar  GRStateManager StateMgr;
53521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar
540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  /// SymMgr - Object that manages the symbol information.
55f96b524306ccfa623235d375deee79637bd38f29Steve Naroff  SymbolManager& SymMgr;
5644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
573c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// svalBuilder - SValBuilder object that creates SVals from expressions.
580853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  SValBuilder &svalBuilder;
590853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
60788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  /// EntryNode - The immediate predecessor node.
61788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  ExplodedNode* EntryNode;
62788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
63bdbb004f38978da0c4a75af3294d1c7b5ff84af1Douglas Gregor  /// CleanedState - The state for EntryNode "cleaned" of all dead
64788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  ///  variables and symbols (as determined by a liveness analysis).
6528019772db70d4547be05a042eb950bc910f134fDouglas Gregor  const GRState* CleanedState;
66405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor
67405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  /// currentStmt - The current block-level statement.
680853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  const Stmt* currentStmt;
690853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
700853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  // Obj-C Class Identifiers.
710853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  IdentifierInfo* NSExceptionII;
724ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor
73914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  // Obj-C Selectors.
74914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  Selector* NSExceptionInstanceRaiseSelectors;
75914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  Selector RaiseSel;
76914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor
77914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  /// The BugReporter associated with this engine.  It is important that
78914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  ///  this object be placed at the very end of member variables so that its
79914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  ///  destructor is called before the rest of the ExprEngine is destroyed.
80914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  GRBugReporter BR;
81807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar
82807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar  llvm::OwningPtr<TransferFuncs> TF;
83807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar
84914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregorpublic:
857d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  ExprEngine(AnalysisManager &mgr, TransferFuncs *tf);
867d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor
877d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  ~ExprEngine();
887d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor
89c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar  void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
90abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor    Engine.ExecuteWorkList(L, Steps, 0);
91abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  }
92abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
93df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  /// Execute the work list with an initial state. Nodes that reaches the exit
94c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar  /// of the function are added into the Dst set, which represent the exit
95c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar  /// state of the function call.
96df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
97df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                       const GRState *InitState,
98df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                                       ExplodedNodeSet &Dst) {
99f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar    Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
100f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  }
101f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
102f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  /// getContext - Return the ASTContext associated with this analysis.
103f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  ASTContext& getContext() const { return AMgr.getASTContext(); }
104f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
105f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  virtual AnalysisManager &getAnalysisManager() { return AMgr; }
106f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
107f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  CheckerManager &getCheckerManager() const {
10868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar    return *AMgr.getCheckerManager();
10968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar  }
11068d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar
111f96b524306ccfa623235d375deee79637bd38f29Steve Naroff  SValBuilder &getSValBuilder() { return svalBuilder; }
112f96b524306ccfa623235d375deee79637bd38f29Steve Naroff
113f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  TransferFuncs& getTF() { return *TF; }
114a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
115a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  BugReporter& getBugReporter() { return BR; }
116405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor
117a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
1184cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
1194cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  // FIXME: Remove once TransferFuncs is no longer referenced.
1204cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  void setTransferFunction(TransferFuncs* tf);
1214cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
1224cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  /// ViewGraph - Visualize the ExplodedGraph created by executing the
1234cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  ///  simulation.
1244cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor  void ViewGraph(bool trim = false);
125313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
126313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
127313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
128bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  /// getInitialState - Return the initial state used for the root vertex
129788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  ///  in the ExplodedGraph.
130788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  const GRState* getInitialState(const LocationContext *InitLoc);
131788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
132788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  ExplodedGraph& getGraph() { return G; }
133788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  const ExplodedGraph& getGraph() const { return G; }
134788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
135788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  /// processCFGElement - Called by CoreEngine. Used to generate new successor
136788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  ///  nodes by processing the 'effects' of a CFG element.
137788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  void processCFGElement(const CFGElement E, StmtNodeBuilder& builder);
138bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
139bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder);
140bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
141bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &builder);
142bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
143bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder);
144bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
145bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
146bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                            StmtNodeBuilder &builder);
147175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  void ProcessBaseDtor(const CFGBaseDtor D, StmtNodeBuilder &builder);
148eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  void ProcessMemberDtor(const CFGMemberDtor D, StmtNodeBuilder &builder);
149eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  void ProcessTemporaryDtor(const CFGTemporaryDtor D,
150eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor                            StmtNodeBuilder &builder);
151eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor
152eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  /// Called by CoreEngine when processing the entrance of a CFGBlock.
153eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
154eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor                                GenericNodeBuilder<BlockEntrance> &nodeBuilder);
155eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor
156eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  /// ProcessBranch - Called by CoreEngine.  Used to generate successor
157eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  ///  nodes by processing the 'effects' of a branch condition.
158eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor  void processBranch(const Stmt* Condition, const Stmt* Term,
159175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor                     BranchNodeBuilder& builder);
160385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor
161175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
162175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  ///  nodes by processing the 'effects' of a computed goto jump.
163175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  void processIndirectGoto(IndirectGotoNodeBuilder& builder);
164175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
165175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
166f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  ///  nodes by processing the 'effects' of a switch statement.
167f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  void processSwitch(SwitchNodeBuilder& builder);
168f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor
169f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
170f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  ///  nodes when the control reaches the end of a function.
171f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  void processEndOfFunction(EndOfFunctionNodeBuilder& builder);
172175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
173175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  /// Generate the entry node of the callee.
174175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor  void processCallEnter(CallEnterNodeBuilder &builder);
175cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
176cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  /// Generate the first post callsite node.
177cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  void processCallExit(CallExitNodeBuilder &builder);
178cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
179cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  /// Called by CoreEngine when the analysis worklist has terminated.
180cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  void processEndWorklist(bool hasWorkRemaining);
181cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor
182cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  /// evalAssume - Callback function invoked by the ConstraintManager when
18328233428da1ebec20c893d6297ae3191318940ddDouglas Gregor  ///  making assumptions about state values.
18428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor  const GRState *processAssume(const GRState *state, SVal cond,bool assumption);
18528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor
18628233428da1ebec20c893d6297ae3191318940ddDouglas Gregor  /// wantsRegionChangeUpdate - Called by GRStateManager to determine if a
187c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  ///  region change should trigger a processRegionChanges update.
188671947b18dba342f9aba022ee992babef325a833Douglas Gregor  bool wantsRegionChangeUpdate(const GRState* state);
189671947b18dba342f9aba022ee992babef325a833Douglas Gregor
190671947b18dba342f9aba022ee992babef325a833Douglas Gregor  /// processRegionChanges - Called by GRStateManager whenever a change is made
191671947b18dba342f9aba022ee992babef325a833Douglas Gregor  ///  to the store. Used to update checkers that track region values.
192671947b18dba342f9aba022ee992babef325a833Douglas Gregor  const GRState *
193c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  processRegionChanges(const GRState *state,
194c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor                       const StoreManager::InvalidatedSymbols *invalidated,
195c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor                       const MemRegion * const *Begin,
196c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor                       const MemRegion * const *End);
197c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
198c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  virtual GRStateManager& getStateManager() { return StateMgr; }
199c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
200c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
201c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
202c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  ConstraintManager& getConstraintManager() {
203c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    return StateMgr.getConstraintManager();
204c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  }
205c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor
206c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  // FIXME: Remove when we migrate over to just using SValBuilder.
207c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor  BasicValueFactory& getBasicVals() {
208c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor    return StateMgr.getBasicVals();
209385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor  }
210cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor  const BasicValueFactory& getBasicVals() const {
211eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    return StateMgr.getBasicVals();
2123c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  }
213eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
2148538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  // FIXME: Remove when we migrate over to just using ValueManager.
215eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  SymbolManager& getSymbolManager() { return SymMgr; }
21687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  const SymbolManager& getSymbolManager() const { return SymMgr; }
21787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
21887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  // Functions for external checking of whether we have unfinished work
21987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
22087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
22187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
22287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
22387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  const CoreEngine &getCoreEngine() const { return Engine; }
22487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
22587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorpublic:
22687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
22787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                         ExplodedNode* Pred, const GRState* St,
22887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                         ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
22987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                         const ProgramPointTag *tag = 0);
23087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
23187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// Visit - Transfer function logic for all statements.  Dispatches to
23287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  ///  other functions that handle specific kinds of statements.
23387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
23487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
23587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// VisitArraySubscriptExpr - Transfer function for array accesses.
23687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr* Ex,
23787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                   ExplodedNode* Pred,
23887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                   ExplodedNodeSet& Dst);
23987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
24087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// VisitAsmStmt - Transfer function logic for inline asm.
24187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
24287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
24387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitAsmStmtHelperOutputs(const AsmStmt* A,
24487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                 AsmStmt::const_outputs_iterator I,
24587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                 AsmStmt::const_outputs_iterator E,
24687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                 ExplodedNode* Pred, ExplodedNodeSet& Dst);
24787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
24887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitAsmStmtHelperInputs(const AsmStmt* A,
2491827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor                                AsmStmt::const_inputs_iterator I,
25058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor                                AsmStmt::const_inputs_iterator E,
25158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor                                ExplodedNode* Pred, ExplodedNodeSet& Dst);
25258ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
2531827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor  /// VisitBlockExpr - Transfer function logic for BlockExprs.
2541827e10051638770ad9ccf3e285caf95f995afd1Douglas Gregor  void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
255f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor                      ExplodedNodeSet &Dst);
256f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
257f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  /// VisitBinaryOperator - Transfer function logic for binary operators.
258f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode* Pred,
259f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor                           ExplodedNodeSet& Dst);
260f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
261f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
262f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  /// VisitCall - Transfer function for function calls.
26387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitCallExpr(const CallExpr* CE, ExplodedNode* Pred,
26487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                     ExplodedNodeSet& Dst);
265f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
266f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  /// VisitCast - Transfer function logic for all casts (implicit and explicit).
267f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
268f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor                ExplodedNodeSet &Dst);
269f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
270f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
27187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL,
27287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                ExplodedNode* Pred, ExplodedNodeSet& Dst);
27387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
27487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
275f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  void VisitCommonDeclRefExpr(const Expr* DR, const NamedDecl *D,
276f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor                              ExplodedNode* Pred, ExplodedNodeSet& Dst);
277f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor
278f5586f6b311c98e1022a8fe0609053849b70d323Douglas Gregor  /// VisitDeclStmt - Transfer function logic for DeclStmts.
279727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor  void VisitDeclStmt(const DeclStmt* DS, ExplodedNode* Pred,
280727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor                     ExplodedNodeSet& Dst);
281727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor
282727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor  /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
283727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor  void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R,
284727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor                        ExplodedNode* Pred, ExplodedNodeSet& Dst);
285727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor
286727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor  void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
287727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor                         ExplodedNodeSet& Dst);
288727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor
289727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor  /// VisitLogicalExpr - Transfer function logic for '&&', '||'
290727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor  void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred,
291727d93ef49e18147149354fadd10e86b13bc4ab0Douglas Gregor                        ExplodedNodeSet& Dst);
292ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
293ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  /// VisitMemberExpr - Transfer function for member expressions.
294ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred,
295ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar                           ExplodedNodeSet& Dst);
296ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
297c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor  /// Transfer function logic for ObjCAtSynchronizedStmts.
298c4421e966d77a18f815284175b3fcbb46f36fa39Douglas Gregor  void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
29987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
30087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
30187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E,
30287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
30387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
30487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// Transfer function logic for computing the lvalue of an Objective-C ivar.
30587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred,
30687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor                                ExplodedNodeSet& Dst);
30787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
308385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor  /// VisitObjCForCollectionStmt - Transfer function logic for
309385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor  ///  ObjCForCollectionStmt.
310385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S,
311385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor                                  ExplodedNode* Pred, ExplodedNodeSet& Dst);
31231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar
31331b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar  void VisitObjCMessage(const ObjCMessage &msg, ExplodedNode *Pred,
314bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                        ExplodedNodeSet& Dst);
3153687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor
3168b96253907c47141af0b7b2a44a368748d006a87Douglas Gregor  /// VisitReturnStmt - Transfer function logic for return statements.
317abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred,
318754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor                       ExplodedNodeSet& Dst);
319175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
320f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor  /// VisitOffsetOfExpr - Transfer function for offsetof.
321df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred,
322df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                         ExplodedNodeSet& Dst);
323175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor
324df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
3252283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr* Ex,
326df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor                              ExplodedNode* Pred, ExplodedNodeSet& Dst);
327df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
328eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  /// VisitUnaryOperator - Transfer function logic for unary operators.
329eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred,
3300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                          ExplodedNodeSet& Dst);
331bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
332bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
333bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                        ExplodedNodeSet & Dst);
334bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
335bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr,
336bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
337bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor    VisitCXXConstructExpr(expr, 0, Pred, Dst);
338bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  }
339bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
340bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest,
341bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
342bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
343bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void VisitCXXDestructor(const CXXDestructorDecl *DD,
344bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                          const MemRegion *Dest, const Stmt *S,
345bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
346bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
347bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
348bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor                       ExplodedNodeSet &Dst);
3490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
3500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
351c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar                          ExplodedNodeSet &Dst);
352c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar
353ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  void VisitAggExpr(const Expr *E, const MemRegion *Dest, ExplodedNode *Pred,
354ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar                    ExplodedNodeSet &Dst);
355ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
3563687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  /// Create a C++ temporary object for an rvalue.
3573687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor  void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
3583687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor                                ExplodedNode *Pred,
359405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                                ExplodedNodeSet &Dst);
360405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor
3610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  /// Synthesize CXXThisRegion.
3620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  const CXXThisRegion *getCXXThisRegion(const CXXRecordDecl *RD,
3630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                        const StackFrameContext *SFC);
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3650853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis  const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *decl,
3660853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis                                        const StackFrameContext *frameCtx);
3670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis
368914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  /// Evaluate arguments with a work list algorithm.
369914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor  void evalArguments(ConstExprIterator AI, ConstExprIterator AE,
370914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor                     const FunctionProtoType *FnType,
371914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor                     ExplodedNode *Pred, ExplodedNodeSet &Dst,
372914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor                     bool FstArgAsLValue = false);
373914ed9d30e9abf829a62aa996b083b1e47c19ff6Douglas Gregor
374405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  /// Evaluate callee expression (for a function call).
375405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  void evalCallee(const CallExpr *callExpr, const ExplodedNodeSet &src,
376f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar                  ExplodedNodeSet &dest);
37777accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff
3783c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl  /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
379b85bca2676b433ae555db09de4dd2823ff13b856Zhongxing Xu  ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
380313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  ///  with those assumptions.
381313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  void evalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src,
382313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor                         const Expr *Ex);
383313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
384313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  SVal evalMinus(SVal X) {
385313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor    return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
386313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  }
3877d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor
388f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  SVal evalComplement(SVal X) {
389eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
390eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
391eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
392eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorpublic:
393f96b524306ccfa623235d375deee79637bd38f29Steve Naroff
394f96b524306ccfa623235d375deee79637bd38f29Steve Naroff  SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
395f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar                 NonLoc L, NonLoc R, QualType T) {
396eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    return svalBuilder.evalBinOpNN(state, op, L, R, T);
397eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
398eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
399f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
400eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor                 NonLoc L, SVal R, QualType T) {
401eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
402eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
403f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar
404eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
405eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor                 SVal LHS, SVal RHS, QualType T) {
406f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar    return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
407eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
408eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
409eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorprotected:
410eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  void evalObjCMessage(ExplodedNodeSet& Dst, const ObjCMessage &msg,
411eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor                       ExplodedNode* Pred, const GRState *state) {
412eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    assert (Builder && "StmtNodeBuilder must be defined.");
413eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor    getTF().evalObjCMessage(Dst, *this, *Builder, msg, Pred, state);
414eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  }
415eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
416eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  const GRState* MarkBranch(const GRState* St, const Stmt* Terminator,
417eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor                            bool branchTaken);
418eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
419eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  /// evalBind - Handle the semantics of binding a value to a specific location.
420eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  ///  This method is used by evalStore, VisitDeclStmt, and others.
421eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  void evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred,
422eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor                const GRState* St, SVal location, SVal Val,
423eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor                bool atDeclInit = false);
424eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
425eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorpublic:
426eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  // FIXME: 'tag' should be removed, and a LocationContext should be used
427eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  // instead.
428eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  // FIXME: Comment on the meaning of the arguments, when 'St' may not
4298538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  // be the same as Pred->state, and when 'location' may not be the
430eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor  // same as state->getLValue(Ex).
431f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  /// Simulate a read of the result of Ex.
432f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar  void evalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
433788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor                const GRState* St, SVal location, const ProgramPointTag *tag = 0,
434788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor                QualType LoadTy = QualType());
435788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
436788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  // FIXME: 'tag' should be removed, and a LocationContext should be used
437788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  // instead.
438788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  void evalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE,
439a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                 ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
440405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                 const ProgramPointTag *tag = 0);
441405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregorprivate:
442405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  void evalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
443405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                      const GRState* St, SVal location, const ProgramPointTag *tag,
444405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                      QualType LoadTy);
445405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor
446405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  // FIXME: 'tag' should be removed, and a LocationContext should be used
447405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  // instead.
448405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor  void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred,
449405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                    const GRState* St, SVal location,
450405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor                    const ProgramPointTag *tag, bool isLoad);
451a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
452a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
45387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
45487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
45587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregorpublic:
45687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// Returns true if calling the specific function or method would possibly
45787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  /// cause global variables to be invalidated.
45887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  bool doesInvalidateGlobals(const CallOrObjCMessage &callOrMessage) const;
45987c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
46087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor};
46187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
46287c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} // end ento namespace
46387c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
46487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor} // end clang namespace
46587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
46687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor#endif
46787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor