ExprEngine.h revision 740d490593e0de8732a697c9f77b90ddd463863b
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=//
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// License. See LICENSE.TXT for details.
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===//
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//  This file defines a meta-engine for path-sensitive dataflow analysis that
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//  is built on CoreEngine, but provides the boilerplate to execute transfer
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//  functions and build the ExplodedGraph at the expression level.
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===----------------------------------------------------------------------===//
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#ifndef LLVM_CLANG_GR_EXPRENGINE
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define LLVM_CLANG_GR_EXPRENGINE
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/AST/Expr.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/AST/Type.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace clang {
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class AnalysisDeclContextManager;
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class CXXCatchStmt;
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CXXConstructExpr;
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class CXXDeleteExpr;
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class CXXNewExpr;
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class CXXTemporaryObjectExpr;
36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass CXXThisExpr;
37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass MaterializeTemporaryExpr;
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass ObjCAtSynchronizedStmt;
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass ObjCForCollectionStmt;
40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace ento {
42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass AnalysisManager;
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass CallEvent;
45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass ObjCMessage;
46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ExprEngine : public SubEngine {
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AnalysisManager &AMgr;
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  AnalysisDeclContextManager &AnalysisDeclContexts;
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CoreEngine Engine;
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// G - the simulation graph.
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ExplodedGraph& G;
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  /// StateMgr - Object that manages the data for all created states.
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ProgramStateManager StateMgr;
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  /// SymMgr - Object that manages the symbol information.
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SymbolManager& SymMgr;
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  /// svalBuilder - SValBuilder object that creates SVals from expressions.
64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  SValBuilder &svalBuilder;
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  /// EntryNode - The immediate predecessor node.
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ExplodedNode *EntryNode;
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// CleanedState - The state for EntryNode "cleaned" of all dead
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ///  variables and symbols (as determined by a liveness analysis).
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProgramStateRef CleanedState;
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// currentStmt - The current block-level statement.
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const Stmt *currentStmt;
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  unsigned int currentStmtIdx;
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const NodeBuilderContext *currentBuilderContext;
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// Obj-C Class Identifiers.
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  IdentifierInfo* NSExceptionII;
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// Obj-C Selectors.
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Selector* NSExceptionInstanceRaiseSelectors;
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Selector RaiseSel;
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// Whether or not GC is enabled in this analysis.
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool ObjCGCEnabled;
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// The BugReporter associated with this engine.  It is important that
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ///  this object be placed at the very end of member variables so that its
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ///  destructor is called before the rest of the ExprEngine is destroyed.
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GRBugReporter BR;
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochpublic:
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExprEngine(AnalysisManager &mgr, bool gcEnabled,
95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch             SetOfConstDecls *VisitedCallees,
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)             FunctionSummariesTy *FS);
97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ~ExprEngine();
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Returns true if there is still simulation state on the worklist.
101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return Engine.ExecuteWorkList(L, Steps, 0);
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  /// Execute the work list with an initial state. Nodes that reaches the exit
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// of the function are added into the Dst set, which represent the exit
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// state of the function call. Returns true if there is still simulation
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// state on the worklist.
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                       ProgramStateRef InitState,
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                       ExplodedNodeSet &Dst) {
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// getContext - Return the ASTContext associated with this analysis.
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASTContext &getContext() const { return AMgr.getASTContext(); }
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual AnalysisManager &getAnalysisManager() { return AMgr; }
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CheckerManager &getCheckerManager() const {
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return *AMgr.getCheckerManager();
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SValBuilder &getSValBuilder() { return svalBuilder; }
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BugReporter& getBugReporter() { return BR; }
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const NodeBuilderContext &getBuilderContext() {
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    assert(currentBuilderContext);
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return *currentBuilderContext;
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool isObjCGCEnabled() { return ObjCGCEnabled; }
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const Stmt *getStmt() const;
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void GenerateAutoTransition(ExplodedNode *N);
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void enqueueEndOfPath(ExplodedNodeSet &S);
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void GenerateCallExitNode(ExplodedNode *N);
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// ViewGraph - Visualize the ExplodedGraph created by executing the
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  simulation.
143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ViewGraph(bool trim = false);
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// getInitialState - Return the initial state used for the root vertex
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  in the ExplodedGraph.
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ProgramStateRef getInitialState(const LocationContext *InitLoc);
150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ExplodedGraph& getGraph() { return G; }
152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const ExplodedGraph& getGraph() const { return G; }
153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// \brief Run the analyzer's garbage collection - remove dead symbols and
155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// bindings.
156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///
157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// \param Node - The predecessor node, from which the processing should
158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// start.
159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// \param Out - The returned set of output nodes.
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// \param ReferenceStmt - Run garbage collection using the symbols,
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// which are live before the given statement.
162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// \param LC - The location context of the ReferenceStmt.
163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// \param DiagnosticStmt - the statement used to associate the diagnostic
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// message, if any warnings should occur while removing the dead (leaks
165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// are usually reported here).
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// \param K - In some cases it is possible to use PreStmt kind. (Do
167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// not use it unless you know what you are doing.)
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            const Stmt *ReferenceStmt, const LocationContext *LC,
170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            const Stmt *DiagnosticStmt,
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// processCFGElement - Called by CoreEngine. Used to generate new successor
174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  nodes by processing the 'effects' of a CFG element.
175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void processCFGElement(const CFGElement E, ExplodedNode *Pred,
176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                         unsigned StmtIdx, NodeBuilderContext *Ctx);
177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               ExplodedNode *Pred, ExplodedNodeSet &Dst);
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ProcessBaseDtor(const CFGBaseDtor D,
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                       ExplodedNode *Pred, ExplodedNodeSet &Dst);
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ProcessMemberDtor(const CFGMemberDtor D,
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void ProcessTemporaryDtor(const CFGTemporaryDtor D,
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                            ExplodedNode *Pred, ExplodedNodeSet &Dst);
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Called by CoreEngine when processing the entrance of a CFGBlock.
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void processCFGBlockEntrance(const BlockEdge &L,
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                       NodeBuilderWithSinks &nodeBuilder);
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// ProcessBranch - Called by CoreEngine.  Used to generate successor
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  nodes by processing the 'effects' of a branch condition.
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void processBranch(const Stmt *Condition, const Stmt *Term,
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     NodeBuilderContext& BuilderCtx,
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     ExplodedNode *Pred,
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     ExplodedNodeSet &Dst,
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     const CFGBlock *DstT,
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     const CFGBlock *DstF);
205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  nodes by processing the 'effects' of a computed goto jump.
208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void processIndirectGoto(IndirectGotoNodeBuilder& builder);
209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  nodes by processing the 'effects' of a switch statement.
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void processSwitch(SwitchNodeBuilder& builder);
213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  nodes when the control reaches the end of a function.
216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void processEndOfFunction(NodeBuilderContext& BC);
217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Generate the entry node of the callee.
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void processCallEnter(CallEnter CE, ExplodedNode *Pred);
220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Generate the sequence of nodes that simulate the call exit and the post
222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// visit for CallExpr.
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void processCallExit(ExplodedNode *Pred);
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// Called by CoreEngine when the analysis worklist has terminated.
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void processEndWorklist(bool hasWorkRemaining);
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// evalAssume - Callback function invoked by the ConstraintManager when
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///  making assumptions about state values.
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption);
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///  region change should trigger a processRegionChanges update.
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool wantsRegionChangeUpdate(ProgramStateRef state);
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// processRegionChanges - Called by ProgramStateManager whenever a change is made
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///  to the store. Used to update checkers that track region values.
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ProgramStateRef
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  processRegionChanges(ProgramStateRef state,
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const StoreManager::InvalidatedSymbols *invalidated,
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       ArrayRef<const MemRegion *> ExplicitRegions,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       ArrayRef<const MemRegion *> Regions,
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const CallEvent *Call);
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// printState - Called by ProgramStateManager to print checker-specific data.
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void printState(raw_ostream &Out, ProgramStateRef State,
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  const char *NL, const char *Sep);
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ProgramStateManager& getStateManager() { return StateMgr; }
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConstraintManager& getConstraintManager() {
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return StateMgr.getConstraintManager();
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // FIXME: Remove when we migrate over to just using SValBuilder.
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BasicValueFactory& getBasicVals() {
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return StateMgr.getBasicVals();
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const BasicValueFactory& getBasicVals() const {
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return StateMgr.getBasicVals();
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // FIXME: Remove when we migrate over to just using ValueManager.
266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SymbolManager& getSymbolManager() { return SymMgr; }
267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const SymbolManager& getSymbolManager() const { return SymMgr; }
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Functions for external checking of whether we have unfinished work
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const CoreEngine &getCoreEngine() const { return Engine; }
275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)public:
277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Visit - Transfer function logic for all statements.  Dispatches to
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  other functions that handle specific kinds of statements.
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitArraySubscriptExpr - Transfer function for array accesses.
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex,
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                   ExplodedNode *Pred,
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                   ExplodedNodeSet &Dst);
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitAsmStmt - Transfer function logic for inline asm.
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst);
288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                      ExplodedNodeSet &Dst);
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitBlockExpr - Transfer function logic for BlockExprs.
294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                      ExplodedNodeSet &Dst);
296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitBinaryOperator - Transfer function logic for binary operators.
298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred,
299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                           ExplodedNodeSet &Dst);
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitCall - Transfer function for function calls.
303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     ExplodedNodeSet &Dst);
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitCast - Transfer function logic for all casts (implicit and explicit).
307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                ExplodedNodeSet &Dst);
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                              ExplodedNode *Pred, ExplodedNodeSet &Dst);
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// VisitDeclStmt - Transfer function logic for DeclStmts.
319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     ExplodedNodeSet &Dst);
321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R,
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        ExplodedNode *Pred, ExplodedNodeSet &Dst);
325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                         ExplodedNodeSet &Dst);
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// VisitLogicalExpr - Transfer function logic for '&&', '||'
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        ExplodedNodeSet &Dst);
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// VisitMemberExpr - Transfer function for member expressions.
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           ExplodedNodeSet &Dst);
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// Transfer function logic for ObjCAtSynchronizedStmts.
338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// Transfer function logic for computing the lvalue of an Objective-C ivar.
342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                ExplodedNodeSet &Dst);
344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// VisitObjCForCollectionStmt - Transfer function logic for
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ///  ObjCForCollectionStmt.
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  ExplodedNode *Pred, ExplodedNodeSet &Dst);
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitObjCMessage(const ObjCMessage &msg, ExplodedNode *Pred,
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        ExplodedNodeSet &Dst);
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// VisitReturnStmt - Transfer function logic for return statements.
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred,
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       ExplodedNodeSet &Dst);
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// VisitOffsetOfExpr - Transfer function for offsetof.
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         ExplodedNodeSet &Dst);
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              ExplodedNode *Pred, ExplodedNodeSet &Dst);
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// VisitUnaryOperator - Transfer function logic for unary operators.
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred,
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                          ExplodedNodeSet &Dst);
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// Handle ++ and -- (both pre- and post-increment).
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitIncrementDecrementOperator(const UnaryOperator* U,
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       ExplodedNode *Pred,
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       ExplodedNodeSet &Dst);
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         ExplodedNodeSet &Dst);
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        ExplodedNodeSet & Dst);
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr,
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest,
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void VisitCXXDestructor(const CXXDestructorDecl *DD,
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                          const MemRegion *Dest, const Stmt *S,
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                       ExplodedNodeSet &Dst);
392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          ExplodedNodeSet &Dst);
395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// Create a C++ temporary object for an rvalue.
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                ExplodedNode *Pred,
399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                ExplodedNodeSet &Dst);
400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ///  with those assumptions.
404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                         const Expr *Ex);
406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::pair<const ProgramPointTag *, const ProgramPointTag*>
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    getEagerlyAssumeTags();
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SVal evalMinus(SVal X) {
411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SVal evalComplement(SVal X) {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)public:
419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                 NonLoc L, NonLoc R, QualType T) {
422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return svalBuilder.evalBinOpNN(state, op, L, R, T);
423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 NonLoc L, SVal R, QualType T) {
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 SVal LHS, SVal RHS, QualType T) {
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochprotected:
436558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMessage &msg,
437558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                       ExplodedNode *Pred, ProgramStateRef state,
438558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                       bool GenSink);
439558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ProgramStateRef MarkBranch(ProgramStateRef state,
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                 const Stmt *Terminator,
442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                 const LocationContext *LCtx,
443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                 bool branchTaken);
444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  /// evalBind - Handle the semantics of binding a value to a specific location.
446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ///  This method is used by evalStore, VisitDeclStmt, and others.
447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                SVal location, SVal Val, bool atDeclInit = false);
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)public:
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // FIXME: 'tag' should be removed, and a LocationContext should be used
452  // instead.
453  // FIXME: Comment on the meaning of the arguments, when 'St' may not
454  // be the same as Pred->state, and when 'location' may not be the
455  // same as state->getLValue(Ex).
456  /// Simulate a read of the result of Ex.
457  void evalLoad(ExplodedNodeSet &Dst,
458                const Expr *NodeEx,  /* Eventually will be a CFGStmt */
459                const Expr *BoundExpr,
460                ExplodedNode *Pred,
461                ProgramStateRef St,
462                SVal location,
463                const ProgramPointTag *tag = 0,
464                QualType LoadTy = QualType());
465
466  // FIXME: 'tag' should be removed, and a LocationContext should be used
467  // instead.
468  void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
469                 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
470                 const ProgramPointTag *tag = 0);
471private:
472  void evalLoadCommon(ExplodedNodeSet &Dst,
473                      const Expr *NodeEx,  /* Eventually will be a CFGStmt */
474                      const Expr *BoundEx,
475                      ExplodedNode *Pred,
476                      ProgramStateRef St,
477                      SVal location,
478                      const ProgramPointTag *tag,
479                      QualType LoadTy);
480
481  // FIXME: 'tag' should be removed, and a LocationContext should be used
482  // instead.
483  void evalLocation(ExplodedNodeSet &Dst,
484                    const Stmt *NodeEx, /* This will eventually be a CFGStmt */
485                    const Stmt *BoundEx,
486                    ExplodedNode *Pred,
487                    ProgramStateRef St, SVal location,
488                    const ProgramPointTag *tag, bool isLoad);
489
490  bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred);
491  bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
492
493  bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
494};
495
496/// Traits for storing the call processing policy inside GDM.
497/// The GDM stores the corresponding CallExpr pointer.
498struct ReplayWithoutInlining{};
499template <>
500struct ProgramStateTrait<ReplayWithoutInlining> :
501  public ProgramStatePartialTrait<void*> {
502  static void *GDMIndex() { static int index = 0; return &index; }
503};
504
505} // end ento namespace
506
507} // end clang namespace
508
509#endif
510