1226586Sdim//== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
2226586Sdim//
3226586Sdim//                     The LLVM Compiler Infrastructure
4226586Sdim//
5226586Sdim// This file is distributed under the University of Illinois Open Source
6226586Sdim// License. See LICENSE.TXT for details.
7226586Sdim//
8226586Sdim//===----------------------------------------------------------------------===//
9226586Sdim//
10243830Sdim// This file defines the state of the program along the analysisa path.
11226586Sdim//
12226586Sdim//===----------------------------------------------------------------------===//
13226586Sdim
14226586Sdim#ifndef LLVM_CLANG_GR_VALUESTATE_H
15226586Sdim#define LLVM_CLANG_GR_VALUESTATE_H
16226586Sdim
17226586Sdim#include "clang/Basic/LLVM.h"
18226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
19243830Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
20226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
21249423Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
22249423Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
23226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
24234353Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
25226586Sdim#include "llvm/ADT/FoldingSet.h"
26226586Sdim#include "llvm/ADT/ImmutableMap.h"
27249423Sdim#include "llvm/ADT/PointerIntPair.h"
28226586Sdim
29226586Sdimnamespace llvm {
30226586Sdimclass APSInt;
31226586Sdimclass BumpPtrAllocator;
32226586Sdim}
33226586Sdim
34226586Sdimnamespace clang {
35226586Sdimclass ASTContext;
36226586Sdim
37226586Sdimnamespace ento {
38226586Sdim
39239462Sdimclass CallEvent;
40239462Sdimclass CallEventManager;
41226586Sdim
42226586Sdimtypedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
43243830Sdim                                                       SubEngine*);
44226586Sdimtypedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
45226586Sdim
46226586Sdim//===----------------------------------------------------------------------===//
47226586Sdim// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
48226586Sdim//===----------------------------------------------------------------------===//
49226586Sdim
50226586Sdimtemplate <typename T> struct ProgramStatePartialTrait;
51226586Sdim
52226586Sdimtemplate <typename T> struct ProgramStateTrait {
53226586Sdim  typedef typename T::data_type data_type;
54226586Sdim  static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
55226586Sdim  static inline data_type MakeData(void *const* P) {
56226586Sdim    return P ? (data_type) *P : (data_type) 0;
57226586Sdim  }
58226586Sdim};
59226586Sdim
60226586Sdim/// \class ProgramState
61226586Sdim/// ProgramState - This class encapsulates:
62226586Sdim///
63226586Sdim///    1. A mapping from expressions to values (Environment)
64226586Sdim///    2. A mapping from locations to values (Store)
65226586Sdim///    3. Constraints on symbolic values (GenericDataMap)
66226586Sdim///
67226586Sdim///  Together these represent the "abstract state" of a program.
68226586Sdim///
69226586Sdim///  ProgramState is intended to be used as a functional object; that is,
70226586Sdim///  once it is created and made "persistent" in a FoldingSet, its
71226586Sdim///  values will never change.
72226586Sdimclass ProgramState : public llvm::FoldingSetNode {
73226586Sdimpublic:
74226586Sdim  typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
75226586Sdim  typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;
76226586Sdim
77226586Sdimprivate:
78243830Sdim  void operator=(const ProgramState& R) LLVM_DELETED_FUNCTION;
79226586Sdim
80226586Sdim  friend class ProgramStateManager;
81226586Sdim  friend class ExplodedGraph;
82226586Sdim  friend class ExplodedNode;
83226586Sdim
84226586Sdim  ProgramStateManager *stateMgr;
85226586Sdim  Environment Env;           // Maps a Stmt to its current SVal.
86226586Sdim  Store store;               // Maps a location to its current value.
87226586Sdim  GenericDataMap   GDM;      // Custom data stored by a client of this class.
88226586Sdim  unsigned refCount;
89226586Sdim
90226586Sdim  /// makeWithStore - Return a ProgramState with the same values as the current
91226586Sdim  ///  state with the exception of using the specified Store.
92234353Sdim  ProgramStateRef makeWithStore(const StoreRef &store) const;
93226586Sdim
94226586Sdim  void setStore(const StoreRef &storeRef);
95226586Sdim
96226586Sdimpublic:
97226586Sdim  /// This ctor is used when creating the first ProgramState object.
98226586Sdim  ProgramState(ProgramStateManager *mgr, const Environment& env,
99226586Sdim          StoreRef st, GenericDataMap gdm);
100226586Sdim
101226586Sdim  /// Copy ctor - We must explicitly define this or else the "Next" ptr
102226586Sdim  ///  in FoldingSetNode will also get copied.
103226586Sdim  ProgramState(const ProgramState &RHS);
104226586Sdim
105226586Sdim  ~ProgramState();
106226586Sdim
107226586Sdim  /// Return the ProgramStateManager associated with this state.
108243830Sdim  ProgramStateManager &getStateManager() const {
109243830Sdim    return *stateMgr;
110243830Sdim  }
111243830Sdim
112243830Sdim  /// Return the ConstraintManager.
113243830Sdim  ConstraintManager &getConstraintManager() const;
114226586Sdim
115226586Sdim  /// getEnvironment - Return the environment associated with this state.
116226586Sdim  ///  The environment is the mapping from expressions to values.
117226586Sdim  const Environment& getEnvironment() const { return Env; }
118226586Sdim
119226586Sdim  /// Return the store associated with this state.  The store
120226586Sdim  ///  is a mapping from locations to values.
121226586Sdim  Store getStore() const { return store; }
122226586Sdim
123226586Sdim
124226586Sdim  /// getGDM - Return the generic data map associated with this state.
125226586Sdim  GenericDataMap getGDM() const { return GDM; }
126226586Sdim
127226586Sdim  void setGDM(GenericDataMap gdm) { GDM = gdm; }
128226586Sdim
129226586Sdim  /// Profile - Profile the contents of a ProgramState object for use in a
130226586Sdim  ///  FoldingSet.  Two ProgramState objects are considered equal if they
131226586Sdim  ///  have the same Environment, Store, and GenericDataMap.
132226586Sdim  static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
133226586Sdim    V->Env.Profile(ID);
134226586Sdim    ID.AddPointer(V->store);
135226586Sdim    V->GDM.Profile(ID);
136226586Sdim  }
137226586Sdim
138226586Sdim  /// Profile - Used to profile the contents of this object for inclusion
139226586Sdim  ///  in a FoldingSet.
140226586Sdim  void Profile(llvm::FoldingSetNodeID& ID) const {
141226586Sdim    Profile(ID, this);
142226586Sdim  }
143226586Sdim
144226586Sdim  BasicValueFactory &getBasicVals() const;
145226586Sdim  SymbolManager &getSymbolManager() const;
146226586Sdim
147226586Sdim  //==---------------------------------------------------------------------==//
148226586Sdim  // Constraints on values.
149226586Sdim  //==---------------------------------------------------------------------==//
150226586Sdim  //
151226586Sdim  // Each ProgramState records constraints on symbolic values.  These constraints
152226586Sdim  // are managed using the ConstraintManager associated with a ProgramStateManager.
153226586Sdim  // As constraints gradually accrue on symbolic values, added constraints
154226586Sdim  // may conflict and indicate that a state is infeasible (as no real values
155226586Sdim  // could satisfy all the constraints).  This is the principal mechanism
156226586Sdim  // for modeling path-sensitivity in ExprEngine/ProgramState.
157226586Sdim  //
158226586Sdim  // Various "assume" methods form the interface for adding constraints to
159226586Sdim  // symbolic values.  A call to 'assume' indicates an assumption being placed
160226586Sdim  // on one or symbolic values.  'assume' methods take the following inputs:
161226586Sdim  //
162226586Sdim  //  (1) A ProgramState object representing the current state.
163226586Sdim  //
164226586Sdim  //  (2) The assumed constraint (which is specific to a given "assume" method).
165226586Sdim  //
166226586Sdim  //  (3) A binary value "Assumption" that indicates whether the constraint is
167226586Sdim  //      assumed to be true or false.
168226586Sdim  //
169226586Sdim  // The output of "assume*" is a new ProgramState object with the added constraints.
170226586Sdim  // If no new state is feasible, NULL is returned.
171226586Sdim  //
172226586Sdim
173249423Sdim  /// Assumes that the value of \p cond is zero (if \p assumption is "false")
174249423Sdim  /// or non-zero (if \p assumption is "true").
175249423Sdim  ///
176249423Sdim  /// This returns a new state with the added constraint on \p cond.
177249423Sdim  /// If no new state is feasible, NULL is returned.
178234353Sdim  ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
179226586Sdim
180249423Sdim  /// Assumes both "true" and "false" for \p cond, and returns both
181249423Sdim  /// corresponding states (respectively).
182249423Sdim  ///
183249423Sdim  /// This is more efficient than calling assume() twice. Note that one (but not
184249423Sdim  /// both) of the returned states may be NULL.
185249423Sdim  std::pair<ProgramStateRef, ProgramStateRef>
186226586Sdim  assume(DefinedOrUnknownSVal cond) const;
187226586Sdim
188234353Sdim  ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
189226586Sdim                               DefinedOrUnknownSVal upperBound,
190234353Sdim                               bool assumption,
191234353Sdim                               QualType IndexType = QualType()) const;
192249423Sdim
193249423Sdim  /// \brief Check if the given SVal is constrained to zero or is a zero
194249423Sdim  ///        constant.
195249423Sdim  ConditionTruthVal isNull(SVal V) const;
196249423Sdim
197226586Sdim  /// Utility method for getting regions.
198226586Sdim  const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
199226586Sdim
200226586Sdim  //==---------------------------------------------------------------------==//
201226586Sdim  // Binding and retrieving values to/from the environment and symbolic store.
202226586Sdim  //==---------------------------------------------------------------------==//
203226586Sdim
204226586Sdim  /// Create a new state by binding the value 'V' to the statement 'S' in the
205226586Sdim  /// state's environment.
206234353Sdim  ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
207234353Sdim                               SVal V, bool Invalidate = true) const;
208226586Sdim
209243830Sdim  ProgramStateRef bindLoc(Loc location,
210243830Sdim                          SVal V,
211243830Sdim                          bool notifyChanges = true) const;
212226586Sdim
213234353Sdim  ProgramStateRef bindLoc(SVal location, SVal V) const;
214226586Sdim
215234353Sdim  ProgramStateRef bindDefault(SVal loc, SVal V) const;
216226586Sdim
217243830Sdim  ProgramStateRef killBinding(Loc LV) const;
218226586Sdim
219249423Sdim  /// \brief Returns the state with bindings for the given regions
220249423Sdim  ///  cleared from the store.
221249423Sdim  ///
222249423Sdim  /// Optionally invalidates global regions as well.
223249423Sdim  ///
224249423Sdim  /// \param Regions the set of regions to be invalidated.
225249423Sdim  /// \param E the expression that caused the invalidation.
226249423Sdim  /// \param BlockCount The number of times the current basic block has been
227249423Sdim  //         visited.
228249423Sdim  /// \param CausesPointerEscape the flag is set to true when
229249423Sdim  ///        the invalidation entails escape of a symbol (representing a
230249423Sdim  ///        pointer). For example, due to it being passed as an argument in a
231249423Sdim  ///        call.
232249423Sdim  /// \param IS the set of invalidated symbols.
233249423Sdim  /// \param Call if non-null, the invalidated regions represent parameters to
234249423Sdim  ///        the call and should be considered directly invalidated.
235249423Sdim  /// \param ConstRegions the set of regions whose contents are accessible,
236249423Sdim  ///        even though the regions themselves should not be invalidated.
237249423Sdim  ProgramStateRef
238249423Sdim  invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
239249423Sdim                    unsigned BlockCount, const LocationContext *LCtx,
240249423Sdim                    bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
241249423Sdim                    const CallEvent *Call = 0,
242249423Sdim                    ArrayRef<const MemRegion *> ConstRegions =
243249423Sdim                      ArrayRef<const MemRegion *>()) const;
244226586Sdim
245249423Sdim  ProgramStateRef
246249423Sdim  invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
247249423Sdim                    unsigned BlockCount, const LocationContext *LCtx,
248249423Sdim                    bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
249249423Sdim                    const CallEvent *Call = 0,
250249423Sdim                    ArrayRef<SVal> ConstRegions = ArrayRef<SVal>()) const;
251249423Sdim
252226586Sdim  /// enterStackFrame - Returns the state for entry to the given stack frame,
253226586Sdim  ///  preserving the current state.
254239462Sdim  ProgramStateRef enterStackFrame(const CallEvent &Call,
255239462Sdim                                  const StackFrameContext *CalleeCtx) const;
256226586Sdim
257226586Sdim  /// Get the lvalue for a variable reference.
258226586Sdim  Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
259226586Sdim
260226586Sdim  Loc getLValue(const CompoundLiteralExpr *literal,
261226586Sdim                const LocationContext *LC) const;
262226586Sdim
263226586Sdim  /// Get the lvalue for an ivar reference.
264226586Sdim  SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
265226586Sdim
266226586Sdim  /// Get the lvalue for a field reference.
267226586Sdim  SVal getLValue(const FieldDecl *decl, SVal Base) const;
268226586Sdim
269239462Sdim  /// Get the lvalue for an indirect field reference.
270239462Sdim  SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const;
271239462Sdim
272226586Sdim  /// Get the lvalue for an array index.
273226586Sdim  SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
274226586Sdim
275226586Sdim  /// Returns the SVal bound to the statement 'S' in the state's environment.
276243830Sdim  SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
277226586Sdim
278234353Sdim  SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
279226586Sdim
280234353Sdim  /// \brief Return the value bound to the specified location.
281234353Sdim  /// Returns UnknownVal() if none found.
282226586Sdim  SVal getSVal(Loc LV, QualType T = QualType()) const;
283226586Sdim
284226586Sdim  /// Returns the "raw" SVal bound to LV before any value simplfication.
285226586Sdim  SVal getRawSVal(Loc LV, QualType T= QualType()) const;
286226586Sdim
287234353Sdim  /// \brief Return the value bound to the specified location.
288234353Sdim  /// Returns UnknownVal() if none found.
289226586Sdim  SVal getSVal(const MemRegion* R) const;
290226586Sdim
291226586Sdim  SVal getSValAsScalarOrLoc(const MemRegion *R) const;
292226586Sdim
293226586Sdim  /// \brief Visits the symbols reachable from the given SVal using the provided
294226586Sdim  /// SymbolVisitor.
295226586Sdim  ///
296226586Sdim  /// This is a convenience API. Consider using ScanReachableSymbols class
297226586Sdim  /// directly when making multiple scans on the same state with the same
298226586Sdim  /// visitor to avoid repeated initialization cost.
299226586Sdim  /// \sa ScanReachableSymbols
300226586Sdim  bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
301226586Sdim
302226586Sdim  /// \brief Visits the symbols reachable from the SVals in the given range
303226586Sdim  /// using the provided SymbolVisitor.
304226586Sdim  bool scanReachableSymbols(const SVal *I, const SVal *E,
305226586Sdim                            SymbolVisitor &visitor) const;
306226586Sdim
307226586Sdim  /// \brief Visits the symbols reachable from the regions in the given
308226586Sdim  /// MemRegions range using the provided SymbolVisitor.
309226586Sdim  bool scanReachableSymbols(const MemRegion * const *I,
310226586Sdim                            const MemRegion * const *E,
311226586Sdim                            SymbolVisitor &visitor) const;
312226586Sdim
313226586Sdim  template <typename CB> CB scanReachableSymbols(SVal val) const;
314226586Sdim  template <typename CB> CB scanReachableSymbols(const SVal *beg,
315226586Sdim                                                 const SVal *end) const;
316226586Sdim
317226586Sdim  template <typename CB> CB
318226586Sdim  scanReachableSymbols(const MemRegion * const *beg,
319226586Sdim                       const MemRegion * const *end) const;
320226586Sdim
321234353Sdim  /// Create a new state in which the statement is marked as tainted.
322234353Sdim  ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
323234353Sdim                               TaintTagType Kind = TaintTagGeneric) const;
324234353Sdim
325234353Sdim  /// Create a new state in which the symbol is marked as tainted.
326234353Sdim  ProgramStateRef addTaint(SymbolRef S,
327234353Sdim                               TaintTagType Kind = TaintTagGeneric) const;
328234353Sdim
329234353Sdim  /// Create a new state in which the region symbol is marked as tainted.
330234353Sdim  ProgramStateRef addTaint(const MemRegion *R,
331234353Sdim                               TaintTagType Kind = TaintTagGeneric) const;
332234353Sdim
333234353Sdim  /// Check if the statement is tainted in the current state.
334234353Sdim  bool isTainted(const Stmt *S, const LocationContext *LCtx,
335234353Sdim                 TaintTagType Kind = TaintTagGeneric) const;
336234353Sdim  bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
337234353Sdim  bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
338234353Sdim  bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
339234353Sdim
340239462Sdim  /// \brief Get dynamic type information for a region.
341239462Sdim  DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const;
342239462Sdim
343239462Sdim  /// \brief Set dynamic type information of the region; return the new state.
344239462Sdim  ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg,
345239462Sdim                                     DynamicTypeInfo NewTy) const;
346239462Sdim
347239462Sdim  /// \brief Set dynamic type information of the region; return the new state.
348239462Sdim  ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg,
349239462Sdim                                     QualType NewTy,
350239462Sdim                                     bool CanBeSubClassed = true) const {
351239462Sdim    return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed));
352239462Sdim  }
353239462Sdim
354226586Sdim  //==---------------------------------------------------------------------==//
355226586Sdim  // Accessing the Generic Data Map (GDM).
356226586Sdim  //==---------------------------------------------------------------------==//
357226586Sdim
358226586Sdim  void *const* FindGDM(void *K) const;
359226586Sdim
360226586Sdim  template<typename T>
361234353Sdim  ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
362226586Sdim
363226586Sdim  template <typename T>
364226586Sdim  typename ProgramStateTrait<T>::data_type
365226586Sdim  get() const {
366226586Sdim    return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
367226586Sdim  }
368226586Sdim
369226586Sdim  template<typename T>
370226586Sdim  typename ProgramStateTrait<T>::lookup_type
371226586Sdim  get(typename ProgramStateTrait<T>::key_type key) const {
372226586Sdim    void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
373226586Sdim    return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
374226586Sdim  }
375226586Sdim
376226586Sdim  template <typename T>
377226586Sdim  typename ProgramStateTrait<T>::context_type get_context() const;
378226586Sdim
379226586Sdim
380226586Sdim  template<typename T>
381234353Sdim  ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const;
382226586Sdim
383226586Sdim  template<typename T>
384234353Sdim  ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K,
385226586Sdim                        typename ProgramStateTrait<T>::context_type C) const;
386226586Sdim  template <typename T>
387234353Sdim  ProgramStateRef remove() const;
388226586Sdim
389226586Sdim  template<typename T>
390234353Sdim  ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const;
391226586Sdim
392226586Sdim  template<typename T>
393234353Sdim  ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
394226586Sdim                     typename ProgramStateTrait<T>::value_type E) const;
395226586Sdim
396226586Sdim  template<typename T>
397234353Sdim  ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
398226586Sdim                     typename ProgramStateTrait<T>::value_type E,
399226586Sdim                     typename ProgramStateTrait<T>::context_type C) const;
400226586Sdim
401226586Sdim  template<typename T>
402226586Sdim  bool contains(typename ProgramStateTrait<T>::key_type key) const {
403226586Sdim    void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
404226586Sdim    return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
405226586Sdim  }
406226586Sdim
407226586Sdim  // Pretty-printing.
408234353Sdim  void print(raw_ostream &Out, const char *nl = "\n",
409226586Sdim             const char *sep = "") const;
410234353Sdim  void printDOT(raw_ostream &Out) const;
411234353Sdim  void printTaint(raw_ostream &Out, const char *nl = "\n",
412234353Sdim                  const char *sep = "") const;
413226586Sdim
414234353Sdim  void dump() const;
415234353Sdim  void dumpTaint() const;
416226586Sdim
417226586Sdimprivate:
418234353Sdim  friend void ProgramStateRetain(const ProgramState *state);
419234353Sdim  friend void ProgramStateRelease(const ProgramState *state);
420249423Sdim
421249423Sdim  /// \sa invalidateValues()
422249423Sdim  /// \sa invalidateRegions()
423249423Sdim  ProgramStateRef
424249423Sdim  invalidateRegionsImpl(ArrayRef<SVal> Values,
425226586Sdim                        const Expr *E, unsigned BlockCount,
426234353Sdim                        const LocationContext *LCtx,
427249423Sdim                        bool ResultsInSymbolEscape,
428249423Sdim                        InvalidatedSymbols &IS,
429249423Sdim                        const CallEvent *Call,
430249423Sdim                        ArrayRef<SVal> ConstValues) const;
431226586Sdim};
432226586Sdim
433226586Sdim//===----------------------------------------------------------------------===//
434226586Sdim// ProgramStateManager - Factory object for ProgramStates.
435226586Sdim//===----------------------------------------------------------------------===//
436226586Sdim
437226586Sdimclass ProgramStateManager {
438226586Sdim  friend class ProgramState;
439234353Sdim  friend void ProgramStateRelease(const ProgramState *state);
440226586Sdimprivate:
441226586Sdim  /// Eng - The SubEngine that owns this state manager.
442226586Sdim  SubEngine *Eng; /* Can be null. */
443226586Sdim
444226586Sdim  EnvironmentManager                   EnvMgr;
445234353Sdim  OwningPtr<StoreManager>              StoreMgr;
446234353Sdim  OwningPtr<ConstraintManager>         ConstraintMgr;
447226586Sdim
448226586Sdim  ProgramState::GenericDataMap::Factory     GDMFactory;
449226586Sdim
450226586Sdim  typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
451226586Sdim  GDMContextsTy GDMContexts;
452226586Sdim
453226586Sdim  /// StateSet - FoldingSet containing all the states created for analyzing
454226586Sdim  ///  a particular function.  This is used to unique states.
455226586Sdim  llvm::FoldingSet<ProgramState> StateSet;
456226586Sdim
457226586Sdim  /// Object that manages the data for all created SVals.
458234353Sdim  OwningPtr<SValBuilder> svalBuilder;
459226586Sdim
460239462Sdim  /// Manages memory for created CallEvents.
461239462Sdim  OwningPtr<CallEventManager> CallEventMgr;
462239462Sdim
463226586Sdim  /// A BumpPtrAllocator to allocate states.
464226586Sdim  llvm::BumpPtrAllocator &Alloc;
465226586Sdim
466226586Sdim  /// A vector of ProgramStates that we can reuse.
467226586Sdim  std::vector<ProgramState *> freeStates;
468226586Sdim
469226586Sdimpublic:
470226586Sdim  ProgramStateManager(ASTContext &Ctx,
471226586Sdim                 StoreManagerCreator CreateStoreManager,
472226586Sdim                 ConstraintManagerCreator CreateConstraintManager,
473226586Sdim                 llvm::BumpPtrAllocator& alloc,
474243830Sdim                 SubEngine *subeng);
475226586Sdim
476226586Sdim  ~ProgramStateManager();
477226586Sdim
478234353Sdim  ProgramStateRef getInitialState(const LocationContext *InitLoc);
479226586Sdim
480226586Sdim  ASTContext &getContext() { return svalBuilder->getContext(); }
481226586Sdim  const ASTContext &getContext() const { return svalBuilder->getContext(); }
482226586Sdim
483226586Sdim  BasicValueFactory &getBasicVals() {
484226586Sdim    return svalBuilder->getBasicValueFactory();
485226586Sdim  }
486226586Sdim
487226586Sdim  SValBuilder &getSValBuilder() {
488226586Sdim    return *svalBuilder;
489226586Sdim  }
490226586Sdim
491226586Sdim  SymbolManager &getSymbolManager() {
492226586Sdim    return svalBuilder->getSymbolManager();
493226586Sdim  }
494226586Sdim  const SymbolManager &getSymbolManager() const {
495226586Sdim    return svalBuilder->getSymbolManager();
496226586Sdim  }
497226586Sdim
498226586Sdim  llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
499226586Sdim
500226586Sdim  MemRegionManager& getRegionManager() {
501226586Sdim    return svalBuilder->getRegionManager();
502226586Sdim  }
503226586Sdim  const MemRegionManager& getRegionManager() const {
504226586Sdim    return svalBuilder->getRegionManager();
505226586Sdim  }
506226586Sdim
507239462Sdim  CallEventManager &getCallEventManager() { return *CallEventMgr; }
508239462Sdim
509226586Sdim  StoreManager& getStoreManager() { return *StoreMgr; }
510226586Sdim  ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
511226586Sdim  SubEngine* getOwningEngine() { return Eng; }
512226586Sdim
513234353Sdim  ProgramStateRef removeDeadBindings(ProgramStateRef St,
514226586Sdim                                    const StackFrameContext *LCtx,
515226586Sdim                                    SymbolReaper& SymReaper);
516226586Sdim
517226586Sdimpublic:
518226586Sdim
519226586Sdim  SVal ArrayToPointer(Loc Array) {
520226586Sdim    return StoreMgr->ArrayToPointer(Array);
521226586Sdim  }
522226586Sdim
523226586Sdim  // Methods that manipulate the GDM.
524234353Sdim  ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
525234353Sdim  ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
526226586Sdim
527226586Sdim  // Methods that query & manipulate the Store.
528226586Sdim
529234353Sdim  void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
530226586Sdim    StoreMgr->iterBindings(state->getStore(), F);
531226586Sdim  }
532226586Sdim
533234353Sdim  ProgramStateRef getPersistentState(ProgramState &Impl);
534234353Sdim  ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
535234353Sdim                                           ProgramStateRef GDMState);
536226586Sdim
537234353Sdim  bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
538226586Sdim    return S1->Env == S2->Env;
539226586Sdim  }
540226586Sdim
541234353Sdim  bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
542226586Sdim    return S1->store == S2->store;
543226586Sdim  }
544226586Sdim
545226586Sdim  //==---------------------------------------------------------------------==//
546226586Sdim  // Generic Data Map methods.
547226586Sdim  //==---------------------------------------------------------------------==//
548226586Sdim  //
549226586Sdim  // ProgramStateManager and ProgramState support a "generic data map" that allows
550226586Sdim  // different clients of ProgramState objects to embed arbitrary data within a
551226586Sdim  // ProgramState object.  The generic data map is essentially an immutable map
552226586Sdim  // from a "tag" (that acts as the "key" for a client) and opaque values.
553226586Sdim  // Tags/keys and values are simply void* values.  The typical way that clients
554226586Sdim  // generate unique tags are by taking the address of a static variable.
555226586Sdim  // Clients are responsible for ensuring that data values referred to by a
556226586Sdim  // the data pointer are immutable (and thus are essentially purely functional
557226586Sdim  // data).
558226586Sdim  //
559226586Sdim  // The templated methods below use the ProgramStateTrait<T> class
560226586Sdim  // to resolve keys into the GDM and to return data values to clients.
561226586Sdim  //
562226586Sdim
563226586Sdim  // Trait based GDM dispatch.
564226586Sdim  template <typename T>
565234353Sdim  ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
566226586Sdim    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
567226586Sdim                  ProgramStateTrait<T>::MakeVoidPtr(D));
568226586Sdim  }
569226586Sdim
570226586Sdim  template<typename T>
571234353Sdim  ProgramStateRef set(ProgramStateRef st,
572226586Sdim                     typename ProgramStateTrait<T>::key_type K,
573226586Sdim                     typename ProgramStateTrait<T>::value_type V,
574226586Sdim                     typename ProgramStateTrait<T>::context_type C) {
575226586Sdim
576226586Sdim    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
577226586Sdim     ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
578226586Sdim  }
579226586Sdim
580226586Sdim  template <typename T>
581234353Sdim  ProgramStateRef add(ProgramStateRef st,
582226586Sdim                     typename ProgramStateTrait<T>::key_type K,
583226586Sdim                     typename ProgramStateTrait<T>::context_type C) {
584226586Sdim    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
585226586Sdim        ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
586226586Sdim  }
587226586Sdim
588226586Sdim  template <typename T>
589234353Sdim  ProgramStateRef remove(ProgramStateRef st,
590226586Sdim                        typename ProgramStateTrait<T>::key_type K,
591226586Sdim                        typename ProgramStateTrait<T>::context_type C) {
592226586Sdim
593226586Sdim    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
594226586Sdim     ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
595226586Sdim  }
596226586Sdim
597226586Sdim  template <typename T>
598234353Sdim  ProgramStateRef remove(ProgramStateRef st) {
599226586Sdim    return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
600226586Sdim  }
601226586Sdim
602226586Sdim  void *FindGDMContext(void *index,
603226586Sdim                       void *(*CreateContext)(llvm::BumpPtrAllocator&),
604226586Sdim                       void  (*DeleteContext)(void*));
605226586Sdim
606226586Sdim  template <typename T>
607226586Sdim  typename ProgramStateTrait<T>::context_type get_context() {
608226586Sdim    void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
609226586Sdim                             ProgramStateTrait<T>::CreateContext,
610226586Sdim                             ProgramStateTrait<T>::DeleteContext);
611226586Sdim
612226586Sdim    return ProgramStateTrait<T>::MakeContext(p);
613226586Sdim  }
614226586Sdim
615234353Sdim  void EndPath(ProgramStateRef St) {
616226586Sdim    ConstraintMgr->EndPath(St);
617226586Sdim  }
618226586Sdim};
619226586Sdim
620226586Sdim
621226586Sdim//===----------------------------------------------------------------------===//
622226586Sdim// Out-of-line method definitions for ProgramState.
623226586Sdim//===----------------------------------------------------------------------===//
624226586Sdim
625243830Sdiminline ConstraintManager &ProgramState::getConstraintManager() const {
626243830Sdim  return stateMgr->getConstraintManager();
627243830Sdim}
628243830Sdim
629226586Sdiminline const VarRegion* ProgramState::getRegion(const VarDecl *D,
630234353Sdim                                                const LocationContext *LC) const
631234353Sdim{
632226586Sdim  return getStateManager().getRegionManager().getVarRegion(D, LC);
633226586Sdim}
634226586Sdim
635234353Sdiminline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
636226586Sdim                                      bool Assumption) const {
637226586Sdim  if (Cond.isUnknown())
638226586Sdim    return this;
639249423Sdim
640249423Sdim  return getStateManager().ConstraintMgr
641249423Sdim      ->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
642226586Sdim}
643226586Sdim
644234353Sdiminline std::pair<ProgramStateRef , ProgramStateRef >
645226586SdimProgramState::assume(DefinedOrUnknownSVal Cond) const {
646226586Sdim  if (Cond.isUnknown())
647226586Sdim    return std::make_pair(this, this);
648249423Sdim
649249423Sdim  return getStateManager().ConstraintMgr
650249423Sdim      ->assumeDual(this, Cond.castAs<DefinedSVal>());
651226586Sdim}
652226586Sdim
653234353Sdiminline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
654249423Sdim  if (Optional<Loc> L = LV.getAs<Loc>())
655249423Sdim    return bindLoc(*L, V);
656249423Sdim  return this;
657226586Sdim}
658226586Sdim
659226586Sdiminline Loc ProgramState::getLValue(const VarDecl *VD,
660226586Sdim                               const LocationContext *LC) const {
661226586Sdim  return getStateManager().StoreMgr->getLValueVar(VD, LC);
662226586Sdim}
663226586Sdim
664226586Sdiminline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
665226586Sdim                               const LocationContext *LC) const {
666226586Sdim  return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
667226586Sdim}
668226586Sdim
669226586Sdiminline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
670226586Sdim  return getStateManager().StoreMgr->getLValueIvar(D, Base);
671226586Sdim}
672226586Sdim
673226586Sdiminline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
674226586Sdim  return getStateManager().StoreMgr->getLValueField(D, Base);
675226586Sdim}
676226586Sdim
677239462Sdiminline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
678239462Sdim                                    SVal Base) const {
679239462Sdim  StoreManager &SM = *getStateManager().StoreMgr;
680239462Sdim  for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
681239462Sdim                                         E = D->chain_end();
682239462Sdim       I != E; ++I) {
683239462Sdim    Base = SM.getLValueField(cast<FieldDecl>(*I), Base);
684239462Sdim  }
685239462Sdim
686239462Sdim  return Base;
687239462Sdim}
688239462Sdim
689226586Sdiminline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
690249423Sdim  if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
691226586Sdim    return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
692226586Sdim  return UnknownVal();
693226586Sdim}
694226586Sdim
695243830Sdiminline SVal ProgramState::getSVal(const Stmt *Ex,
696243830Sdim                                  const LocationContext *LCtx) const{
697234353Sdim  return Env.getSVal(EnvironmentEntry(Ex, LCtx),
698243830Sdim                     *getStateManager().svalBuilder);
699226586Sdim}
700226586Sdim
701234353Sdiminline SVal
702234353SdimProgramState::getSValAsScalarOrLoc(const Stmt *S,
703234353Sdim                                   const LocationContext *LCtx) const {
704226586Sdim  if (const Expr *Ex = dyn_cast<Expr>(S)) {
705226586Sdim    QualType T = Ex->getType();
706251662Sdim    if (Ex->isGLValue() || Loc::isLocType(T) ||
707251662Sdim        T->isIntegralOrEnumerationType())
708234353Sdim      return getSVal(S, LCtx);
709226586Sdim  }
710226586Sdim
711226586Sdim  return UnknownVal();
712226586Sdim}
713226586Sdim
714226586Sdiminline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
715234353Sdim  return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
716226586Sdim}
717226586Sdim
718226586Sdiminline SVal ProgramState::getSVal(const MemRegion* R) const {
719234353Sdim  return getStateManager().StoreMgr->getBinding(getStore(),
720234353Sdim                                                loc::MemRegionVal(R));
721226586Sdim}
722226586Sdim
723226586Sdiminline BasicValueFactory &ProgramState::getBasicVals() const {
724226586Sdim  return getStateManager().getBasicVals();
725226586Sdim}
726226586Sdim
727226586Sdiminline SymbolManager &ProgramState::getSymbolManager() const {
728226586Sdim  return getStateManager().getSymbolManager();
729226586Sdim}
730226586Sdim
731226586Sdimtemplate<typename T>
732234353SdimProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
733226586Sdim  return getStateManager().add<T>(this, K, get_context<T>());
734226586Sdim}
735226586Sdim
736226586Sdimtemplate <typename T>
737226586Sdimtypename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
738226586Sdim  return getStateManager().get_context<T>();
739226586Sdim}
740226586Sdim
741226586Sdimtemplate<typename T>
742234353SdimProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
743226586Sdim  return getStateManager().remove<T>(this, K, get_context<T>());
744226586Sdim}
745226586Sdim
746226586Sdimtemplate<typename T>
747234353SdimProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
748226586Sdim                               typename ProgramStateTrait<T>::context_type C) const {
749226586Sdim  return getStateManager().remove<T>(this, K, C);
750226586Sdim}
751226586Sdim
752226586Sdimtemplate <typename T>
753234353SdimProgramStateRef ProgramState::remove() const {
754226586Sdim  return getStateManager().remove<T>(this);
755226586Sdim}
756226586Sdim
757226586Sdimtemplate<typename T>
758234353SdimProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
759226586Sdim  return getStateManager().set<T>(this, D);
760226586Sdim}
761226586Sdim
762226586Sdimtemplate<typename T>
763234353SdimProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
764226586Sdim                            typename ProgramStateTrait<T>::value_type E) const {
765226586Sdim  return getStateManager().set<T>(this, K, E, get_context<T>());
766226586Sdim}
767226586Sdim
768226586Sdimtemplate<typename T>
769234353SdimProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
770226586Sdim                            typename ProgramStateTrait<T>::value_type E,
771226586Sdim                            typename ProgramStateTrait<T>::context_type C) const {
772226586Sdim  return getStateManager().set<T>(this, K, E, C);
773226586Sdim}
774226586Sdim
775226586Sdimtemplate <typename CB>
776226586SdimCB ProgramState::scanReachableSymbols(SVal val) const {
777226586Sdim  CB cb(this);
778226586Sdim  scanReachableSymbols(val, cb);
779226586Sdim  return cb;
780226586Sdim}
781226586Sdim
782226586Sdimtemplate <typename CB>
783226586SdimCB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
784226586Sdim  CB cb(this);
785226586Sdim  scanReachableSymbols(beg, end, cb);
786226586Sdim  return cb;
787226586Sdim}
788226586Sdim
789226586Sdimtemplate <typename CB>
790226586SdimCB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
791226586Sdim                                 const MemRegion * const *end) const {
792226586Sdim  CB cb(this);
793226586Sdim  scanReachableSymbols(beg, end, cb);
794226586Sdim  return cb;
795226586Sdim}
796226586Sdim
797226586Sdim/// \class ScanReachableSymbols
798226586Sdim/// A Utility class that allows to visit the reachable symbols using a custom
799226586Sdim/// SymbolVisitor.
800239462Sdimclass ScanReachableSymbols {
801226586Sdim  typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
802226586Sdim
803226586Sdim  VisitedItems visited;
804234353Sdim  ProgramStateRef state;
805226586Sdim  SymbolVisitor &visitor;
806226586Sdimpublic:
807226586Sdim
808234353Sdim  ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
809226586Sdim    : state(st), visitor(v) {}
810226586Sdim
811226586Sdim  bool scan(nonloc::CompoundVal val);
812226586Sdim  bool scan(SVal val);
813226586Sdim  bool scan(const MemRegion *R);
814226586Sdim  bool scan(const SymExpr *sym);
815226586Sdim};
816226586Sdim
817243830Sdim} // end ento namespace
818226586Sdim
819226586Sdim} // end clang namespace
820226586Sdim
821226586Sdim#endif
822