ProgramState.h revision 5eca482fe895ea57bc82410222e6426c09e63284
1ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
2ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
3ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//                     The LLVM Compiler Infrastructure
4ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
5ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// This file is distributed under the University of Illinois Open Source
6ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// License. See LICENSE.TXT for details.
7ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
8ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
9ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
10ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//  This file defines SymbolRef, ExprBindKey, and ProgramState*.
11ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//
12ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
13ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
14ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#ifndef LLVM_CLANG_GR_VALUESTATE_H
15ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#define LLVM_CLANG_GR_VALUESTATE_H
16ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
17ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "clang/Basic/LLVM.h"
18ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
19ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
20ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
21ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
22ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
23ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "llvm/ADT/PointerIntPair.h"
24ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "llvm/ADT/FoldingSet.h"
25ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#include "llvm/ADT/ImmutableMap.h"
26ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
27ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace llvm {
28ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass APSInt;
29ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass BumpPtrAllocator;
30ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
31ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
32ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace clang {
33ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass ASTContext;
34ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
35ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremeneknamespace ento {
36ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
37eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaksclass CallOrObjCMessage;
38ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass ProgramStateManager;
39ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektypedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
40ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                                       SubEngine&);
41ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektypedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
42ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
43ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
44ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
45ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
46ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
47ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename T> struct ProgramStatePartialTrait;
48ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
49ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename T> struct ProgramStateTrait {
50ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typedef typename T::data_type data_type;
51ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  static inline void *GDMIndex() { return &T::TagInt; }
52ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
53ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  static inline data_type MakeData(void *const* P) {
54ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return P ? (data_type) *P : (data_type) 0;
55ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
56ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek};
57ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
58ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass ProgramStateManager;
59ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
605f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks/// \class ProgramState
61ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek/// ProgramState - This class encapsulates:
62ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///
63ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///    1. A mapping from expressions to values (Environment)
64ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///    2. A mapping from locations to values (Store)
65ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///    3. Constraints on symbolic values (GenericDataMap)
66ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///
67ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///  Together these represent the "abstract state" of a program.
68ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///
69ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///  ProgramState is intended to be used as a functional object; that is,
70ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///  once it is created and made "persistent" in a FoldingSet, its
71ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek///  values will never change.
72ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass ProgramState : public llvm::FoldingSetNode {
73ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekpublic:
74ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
75ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;
76ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
77ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekprivate:
78ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void operator=(const ProgramState& R) const; // Do not implement.
79ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
80ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  friend class ProgramStateManager;
81ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  friend class ExplodedGraph;
82ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  friend class ExplodedNode;
83ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
84ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramStateManager *stateMgr;
85ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  Environment Env;           // Maps a Stmt to its current SVal.
86ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  Store store;               // Maps a location to its current value.
87ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  GenericDataMap   GDM;      // Custom data stored by a client of this class.
88ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  unsigned refCount;
89ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
90ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// makeWithStore - Return a ProgramState with the same values as the current
91ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  state with the exception of using the specified Store.
92ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *makeWithStore(const StoreRef &store) const;
93ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
94ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void setStore(const StoreRef &storeRef);
95ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
96ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekpublic:
97ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
98ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// This ctor is used when creating the first ProgramState object.
99ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramState(ProgramStateManager *mgr, const Environment& env,
100ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek          StoreRef st, GenericDataMap gdm);
101ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
102ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Copy ctor - We must explicitly define this or else the "Next" ptr
103ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  in FoldingSetNode will also get copied.
104ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramState(const ProgramState &RHS);
105ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
106ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ~ProgramState();
107ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
108ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Return the ProgramStateManager associated with this state.
109ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramStateManager &getStateManager() const { return *stateMgr; }
110ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
111ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Return true if this state is referenced by a persistent ExplodedNode.
112ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool referencedByExplodedNode() const { return refCount > 0; }
113ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
114ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// getEnvironment - Return the environment associated with this state.
115ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  The environment is the mapping from expressions to values.
116ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const Environment& getEnvironment() const { return Env; }
117ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
118ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Return the store associated with this state.  The store
119ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  is a mapping from locations to values.
120ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  Store getStore() const { return store; }
121ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
122ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
123ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// getGDM - Return the generic data map associated with this state.
124ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  GenericDataMap getGDM() const { return GDM; }
125ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
126ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void setGDM(GenericDataMap gdm) { GDM = gdm; }
127ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
128ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Profile - Profile the contents of a ProgramState object for use in a
129ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  FoldingSet.  Two ProgramState objects are considered equal if they
130ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  have the same Environment, Store, and GenericDataMap.
131ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
132ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    V->Env.Profile(ID);
133ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    ID.AddPointer(V->store);
134ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    V->GDM.Profile(ID);
135ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
136ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
137ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Profile - Used to profile the contents of this object for inclusion
138ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  in a FoldingSet.
139ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void Profile(llvm::FoldingSetNodeID& ID) const {
140ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    Profile(ID, this);
141ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
142ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
143ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  BasicValueFactory &getBasicVals() const;
144ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SymbolManager &getSymbolManager() const;
145ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
146ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
147ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Constraints on values.
148ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
149ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
150ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Each ProgramState records constraints on symbolic values.  These constraints
151ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // are managed using the ConstraintManager associated with a ProgramStateManager.
152ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // As constraints gradually accrue on symbolic values, added constraints
153ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // may conflict and indicate that a state is infeasible (as no real values
154ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // could satisfy all the constraints).  This is the principal mechanism
155ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // for modeling path-sensitivity in ExprEngine/ProgramState.
156ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
157ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Various "assume" methods form the interface for adding constraints to
158ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // symbolic values.  A call to 'assume' indicates an assumption being placed
159ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // on one or symbolic values.  'assume' methods take the following inputs:
160ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
161ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //  (1) A ProgramState object representing the current state.
162ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
163ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //  (2) The assumed constraint (which is specific to a given "assume" method).
164ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
165ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //  (3) A binary value "Assumption" that indicates whether the constraint is
166ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //      assumed to be true or false.
167ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
168ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // The output of "assume*" is a new ProgramState object with the added constraints.
169ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // If no new state is feasible, NULL is returned.
170ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
171ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
172ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *assume(DefinedOrUnknownSVal cond, bool assumption) const;
173ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
174ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// This method assumes both "true" and "false" for 'cond', and
175ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  returns both corresponding states.  It's shorthand for doing
176ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  'assume' twice.
177ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  std::pair<const ProgramState*, const ProgramState*>
178ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  assume(DefinedOrUnknownSVal cond) const;
179ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
180ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *assumeInBound(DefinedOrUnknownSVal idx,
181ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                               DefinedOrUnknownSVal upperBound,
182ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                               bool assumption) const;
183ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
1845f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// Utility method for getting regions.
185ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
186ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
187ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
188ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Binding and retrieving values to/from the environment and symbolic store.
189ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
190ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
191ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// BindCompoundLiteral - Return the state that has the bindings currently
192ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  in this state plus the bindings for the CompoundLiteral.
193ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *bindCompoundLiteral(const CompoundLiteralExpr *CL,
194ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                     const LocationContext *LC,
195ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                     SVal V) const;
196ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
197ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Create a new state by binding the value 'V' to the statement 'S' in the
198ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// state's environment.
1995eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const ProgramState *BindExpr(const Stmt *S, const LocationContext *LCtx,
2005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                               SVal V, bool Invalidate = true) const;
201ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
202ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Create a new state by binding the value 'V' and location 'locaton' to the
203ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// statement 'S' in the state's environment.
2045eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const ProgramState *bindExprAndLocation(const Stmt *S,
2055eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                          const LocationContext *LCtx,
2065eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                          SVal location, SVal V) const;
207ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
208ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *bindDecl(const VarRegion *VR, SVal V) const;
209ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
210ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *bindDeclWithNoInit(const VarRegion *VR) const;
211ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
212ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *bindLoc(Loc location, SVal V) const;
213ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
214ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *bindLoc(SVal location, SVal V) const;
215ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
216ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *bindDefault(SVal loc, SVal V) const;
217ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
218ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *unbindLoc(Loc LV) const;
219ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
220ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// invalidateRegions - Returns the state with bindings for the given regions
221ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  cleared from the store. The regions are provided as a continuous array
222ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  from Begin to End. Optionally invalidates global regions as well.
223537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  const ProgramState *invalidateRegions(ArrayRef<const MemRegion *> Regions,
224eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks                               const Expr *E, unsigned BlockCount,
225eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks                               StoreManager::InvalidatedSymbols *IS = 0,
226eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks                               const CallOrObjCMessage *Call = 0) const;
227ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
228ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// enterStackFrame - Returns the state for entry to the given stack frame,
229ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  preserving the current state.
230ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *enterStackFrame(const StackFrameContext *frame) const;
231ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
232ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Get the lvalue for a variable reference.
233ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
234ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
235ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Get the lvalue for a StringLiteral.
236ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  Loc getLValue(const StringLiteral *literal) const;
237ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
238ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  Loc getLValue(const CompoundLiteralExpr *literal,
239ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                const LocationContext *LC) const;
240ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
241ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Get the lvalue for an ivar reference.
242ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
243ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
244ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Get the lvalue for a field reference.
245ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getLValue(const FieldDecl *decl, SVal Base) const;
246ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
247ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Get the lvalue for an array index.
248ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
249ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
250ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const llvm::APSInt *getSymVal(SymbolRef sym) const;
251ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
252ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Returns the SVal bound to the statement 'S' in the state's environment.
2535eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal getSVal(const Stmt *S, const LocationContext *LCtx,
2545eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek               bool useOnlyDirectBindings = false) const;
255ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
2565eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
257ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
258ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getSVal(Loc LV, QualType T = QualType()) const;
259ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
260ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Returns the "raw" SVal bound to LV before any value simplfication.
261ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getRawSVal(Loc LV, QualType T= QualType()) const;
262ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
263ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getSVal(const MemRegion* R) const;
264ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
265ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal getSValAsScalarOrLoc(const MemRegion *R) const;
266ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
2675f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// \brief Visits the symbols reachable from the given SVal using the provided
2685f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// SymbolVisitor.
2695f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  ///
2705f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// This is a convenience API. Consider using ScanReachableSymbols class
2715f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// directly when making multiple scans on the same state with the same
2725f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// visitor to avoid repeated initialization cost.
2735f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// \sa ScanReachableSymbols
274ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
275ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
2765f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// \brief Visits the symbols reachable from the SVals in the given range
2775f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// using the provided SymbolVisitor.
278ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool scanReachableSymbols(const SVal *I, const SVal *E,
279ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                            SymbolVisitor &visitor) const;
280ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
2815f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// \brief Visits the symbols reachable from the regions in the given
2825f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  /// MemRegions range using the provided SymbolVisitor.
283ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool scanReachableSymbols(const MemRegion * const *I,
284ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                            const MemRegion * const *E,
285ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                            SymbolVisitor &visitor) const;
286ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
287ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename CB> CB scanReachableSymbols(SVal val) const;
288ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename CB> CB scanReachableSymbols(const SVal *beg,
289ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                                 const SVal *end) const;
290ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
291ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename CB> CB
292ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  scanReachableSymbols(const MemRegion * const *beg,
293ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                       const MemRegion * const *end) const;
294ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
295ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks  /// Create a new state in which the statement is marked as tainted.
2965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const ProgramState* addTaint(const Stmt *S, const LocationContext *LCtx,
297ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks                               TaintTagType Kind = TaintTagGeneric) const;
298ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks
299ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks  /// Create a new state in which the symbol is marked as tainted.
300ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks  const ProgramState* addTaint(SymbolRef S,
301ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks                               TaintTagType Kind = TaintTagGeneric) const;
302ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks
30328fd98d66dab4569316de2b5881d91b534a42461Anna Zaks  /// Create a new state in which the region symbol is marked as tainted.
30428fd98d66dab4569316de2b5881d91b534a42461Anna Zaks  const ProgramState* addTaint(const MemRegion *R,
30528fd98d66dab4569316de2b5881d91b534a42461Anna Zaks                               TaintTagType Kind = TaintTagGeneric) const;
30628fd98d66dab4569316de2b5881d91b534a42461Anna Zaks
307ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks  /// Check if the statement is tainted in the current state.
3085eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  bool isTainted(const Stmt *S, const LocationContext *LCtx,
3095eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                 TaintTagType Kind = TaintTagGeneric) const;
310ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks  bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
311ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks  bool isTainted(const SymExpr* Sym, TaintTagType Kind = TaintTagGeneric) const;
312dcf06fa1fbb9c018e152629ef3f3fa7b1acffe7aAnna Zaks  bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
313ceac1d6e0521161adf7ac9834b1a7ad79d73fea4Anna Zaks
314ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
315ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Accessing the Generic Data Map (GDM).
316ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
317ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
318ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void *const* FindGDM(void *K) const;
319ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
320ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
321ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *add(typename ProgramStateTrait<T>::key_type K) const;
322ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
323ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
324ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typename ProgramStateTrait<T>::data_type
325ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  get() const {
326ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
327ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
328ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
329ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
330ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typename ProgramStateTrait<T>::lookup_type
331ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  get(typename ProgramStateTrait<T>::key_type key) const {
332ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
333ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
334ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
335ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
336ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
337ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typename ProgramStateTrait<T>::context_type get_context() const;
338ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
339ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
340ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
341ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *remove(typename ProgramStateTrait<T>::key_type K) const;
342ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
343ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
344ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *remove(typename ProgramStateTrait<T>::key_type K,
345ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                        typename ProgramStateTrait<T>::context_type C) const;
346ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
347ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *remove() const;
348ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
349ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
350ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *set(typename ProgramStateTrait<T>::data_type D) const;
351ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
352ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
353ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *set(typename ProgramStateTrait<T>::key_type K,
354ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::value_type E) const;
355ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
356ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
357ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *set(typename ProgramStateTrait<T>::key_type K,
358ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::value_type E,
359ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::context_type C) const;
360ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
361ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
362ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool contains(typename ProgramStateTrait<T>::key_type key) const {
363ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
364ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
365ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
366ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
367ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Pretty-printing.
3685eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  void print(raw_ostream &Out, const char *nl = "\n",
369ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek             const char *sep = "") const;
370ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
3715eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  void printDOT(raw_ostream &Out) const;
372ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
373d0167853f46cc78787b06255a44f9dcedd04a8ecAnna Zaks  void dump() const;
374d0167853f46cc78787b06255a44f9dcedd04a8ecAnna Zaks
375ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekprivate:
376ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Increments the number of times this state is referenced by ExplodeNodes.
377ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void incrementReferenceCount() { ++refCount; }
378ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
379ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Decrement the number of times this state is referenced by ExplodeNodes.
380ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void decrementReferenceCount() {
381ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    assert(refCount > 0);
382ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    --refCount;
383ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
384ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
385537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  const ProgramState *
386537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
387537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                        const Expr *E, unsigned BlockCount,
388537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                        StoreManager::InvalidatedSymbols &IS,
389eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks                        const CallOrObjCMessage *Call) const;
390ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek};
391ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
392ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass ProgramStateSet {
393ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typedef llvm::SmallPtrSet<const ProgramState*,5> ImplTy;
394ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ImplTy Impl;
395ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekpublic:
396ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramStateSet() {}
397ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
398ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  inline void Add(const ProgramState *St) {
399ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    Impl.insert(St);
400ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
401ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
402ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typedef ImplTy::const_iterator iterator;
403ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
404ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  inline unsigned size() const { return Impl.size();  }
405ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  inline bool empty()    const { return Impl.empty(); }
406ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
407ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  inline iterator begin() const { return Impl.begin(); }
408ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  inline iterator end() const { return Impl.end();   }
409ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
410ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  class AutoPopulate {
411ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    ProgramStateSet &S;
412ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    unsigned StartSize;
413ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    const ProgramState *St;
414ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  public:
415ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    AutoPopulate(ProgramStateSet &s, const ProgramState *st)
416ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      : S(s), StartSize(S.size()), St(st) {}
417ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
418ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    ~AutoPopulate() {
419ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      if (StartSize == S.size())
420ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek        S.Add(St);
421ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    }
422ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  };
423ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek};
424ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
425ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
426ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// ProgramStateManager - Factory object for ProgramStates.
427ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
428ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
429ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekclass ProgramStateManager {
430ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  friend class ProgramState;
431ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekprivate:
432ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Eng - The SubEngine that owns this state manager.
433ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SubEngine *Eng; /* Can be null. */
434ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
435ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  EnvironmentManager                   EnvMgr;
436ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  llvm::OwningPtr<StoreManager>        StoreMgr;
437ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  llvm::OwningPtr<ConstraintManager>   ConstraintMgr;
438ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
439ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramState::GenericDataMap::Factory     GDMFactory;
440ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
441ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
442ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  GDMContextsTy GDMContexts;
443ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
444ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// StateSet - FoldingSet containing all the states created for analyzing
445ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ///  a particular function.  This is used to unique states.
446ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  llvm::FoldingSet<ProgramState> StateSet;
447ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
448ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Object that manages the data for all created SVals.
449ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  llvm::OwningPtr<SValBuilder> svalBuilder;
450ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
451ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// A BumpPtrAllocator to allocate states.
452ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  llvm::BumpPtrAllocator &Alloc;
453ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
454ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// A vector of recently allocated ProgramStates that can potentially be
455ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// reused.
456ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  std::vector<ProgramState *> recentlyAllocatedStates;
457ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
458ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// A vector of ProgramStates that we can reuse.
459ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  std::vector<ProgramState *> freeStates;
460ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
461ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekpublic:
462ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramStateManager(ASTContext &Ctx,
463ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 StoreManagerCreator CreateStoreManager,
464ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 ConstraintManagerCreator CreateConstraintManager,
465ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 llvm::BumpPtrAllocator& alloc,
466ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 SubEngine &subeng)
467ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    : Eng(&subeng),
468ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      EnvMgr(alloc),
469ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      GDMFactory(alloc),
470ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
471ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      Alloc(alloc) {
472ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    StoreMgr.reset((*CreateStoreManager)(*this));
473ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
474ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
475ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
476ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ProgramStateManager(ASTContext &Ctx,
477ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 StoreManagerCreator CreateStoreManager,
478ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 ConstraintManager* ConstraintManagerPtr,
479ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                 llvm::BumpPtrAllocator& alloc)
480ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    : Eng(0),
481ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      EnvMgr(alloc),
482ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      GDMFactory(alloc),
483ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
484ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek      Alloc(alloc) {
485ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    StoreMgr.reset((*CreateStoreManager)(*this));
486ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    ConstraintMgr.reset(ConstraintManagerPtr);
487ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
488ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
489ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ~ProgramStateManager();
490ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
491ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *getInitialState(const LocationContext *InitLoc);
492ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
493ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ASTContext &getContext() { return svalBuilder->getContext(); }
494ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ASTContext &getContext() const { return svalBuilder->getContext(); }
495ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
496ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  BasicValueFactory &getBasicVals() {
497ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return svalBuilder->getBasicValueFactory();
498ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
499ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const BasicValueFactory& getBasicVals() const {
500ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return svalBuilder->getBasicValueFactory();
501ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
502ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
503ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SValBuilder &getSValBuilder() {
504ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return *svalBuilder;
505ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
506ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
507ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SymbolManager &getSymbolManager() {
508ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return svalBuilder->getSymbolManager();
509ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
510ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const SymbolManager &getSymbolManager() const {
511ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return svalBuilder->getSymbolManager();
512ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
513ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
514ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
515ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
516ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  MemRegionManager& getRegionManager() {
517ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return svalBuilder->getRegionManager();
518ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
519ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const MemRegionManager& getRegionManager() const {
520ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return svalBuilder->getRegionManager();
521ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
522ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
523ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  StoreManager& getStoreManager() { return *StoreMgr; }
524ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
525ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SubEngine* getOwningEngine() { return Eng; }
526ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
527ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *removeDeadBindings(const ProgramState *St,
528ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                    const StackFrameContext *LCtx,
529ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                    SymbolReaper& SymReaper);
530ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
531ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Marshal a new state for the callee in another translation unit.
532ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// 'state' is owned by the caller's engine.
533ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *MarshalState(const ProgramState *state, const StackFrameContext *L);
534ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
535ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekpublic:
536ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
537ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  SVal ArrayToPointer(Loc Array) {
538ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return StoreMgr->ArrayToPointer(Array);
539ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
540ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
541ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Methods that manipulate the GDM.
542ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *addGDM(const ProgramState *St, void *Key, void *Data);
543ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *removeGDM(const ProgramState *state, void *Key);
544ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
545ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Methods that query & manipulate the Store.
546ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
547ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void iterBindings(const ProgramState *state, StoreManager::BindingsHandler& F) {
548ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    StoreMgr->iterBindings(state->getStore(), F);
549ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
550ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
551ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *getPersistentState(ProgramState &Impl);
552ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *getPersistentStateWithGDM(const ProgramState *FromState,
553ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                           const ProgramState *GDMState);
554ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
555ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool haveEqualEnvironments(const ProgramState * S1, const ProgramState * S2) {
556ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return S1->Env == S2->Env;
557ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
558ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
559ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  bool haveEqualStores(const ProgramState * S1, const ProgramState * S2) {
560ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return S1->store == S2->store;
561ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
562ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
563ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// Periodically called by ExprEngine to recycle ProgramStates that were
564ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  /// created but never used for creating an ExplodedNode.
565ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void recycleUnusedStates();
566ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
567ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
568ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Generic Data Map methods.
569ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //==---------------------------------------------------------------------==//
570ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
571ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // ProgramStateManager and ProgramState support a "generic data map" that allows
572ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // different clients of ProgramState objects to embed arbitrary data within a
573ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // ProgramState object.  The generic data map is essentially an immutable map
574ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // from a "tag" (that acts as the "key" for a client) and opaque values.
575ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Tags/keys and values are simply void* values.  The typical way that clients
576ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // generate unique tags are by taking the address of a static variable.
577ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Clients are responsible for ensuring that data values referred to by a
578ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // the data pointer are immutable (and thus are essentially purely functional
579ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // data).
580ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
581ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // The templated methods below use the ProgramStateTrait<T> class
582ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // to resolve keys into the GDM and to return data values to clients.
583ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  //
584ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
585ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  // Trait based GDM dispatch.
586ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
587ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *set(const ProgramState *st, typename ProgramStateTrait<T>::data_type D) {
588ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
589ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                  ProgramStateTrait<T>::MakeVoidPtr(D));
590ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
591ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
592ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template<typename T>
593ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *set(const ProgramState *st,
594ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::key_type K,
595ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::value_type V,
596ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::context_type C) {
597ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
598ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
599ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek     ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
600ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
601ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
602ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
603ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *add(const ProgramState *st,
604ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::key_type K,
605ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     typename ProgramStateTrait<T>::context_type C) {
606ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
607ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek        ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
608ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
609ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
610ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
611ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *remove(const ProgramState *st,
612ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                        typename ProgramStateTrait<T>::key_type K,
613ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                        typename ProgramStateTrait<T>::context_type C) {
614ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
615ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
616ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek     ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
617ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
618ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
619ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
620ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const ProgramState *remove(const ProgramState *st) {
621ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
622ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
623ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
624ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void *FindGDMContext(void *index,
625ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                       void *(*CreateContext)(llvm::BumpPtrAllocator&),
626ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                       void  (*DeleteContext)(void*));
627ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
628ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  template <typename T>
629ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  typename ProgramStateTrait<T>::context_type get_context() {
630ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
631ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                             ProgramStateTrait<T>::CreateContext,
632ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                             ProgramStateTrait<T>::DeleteContext);
633ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
634ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return ProgramStateTrait<T>::MakeContext(p);
635ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
636ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
637ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  const llvm::APSInt* getSymVal(const ProgramState *St, SymbolRef sym) {
638ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return ConstraintMgr->getSymVal(St, sym);
639ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
640ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
641ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  void EndPath(const ProgramState *St) {
642ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    ConstraintMgr->EndPath(St);
643ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
644ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek};
645ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
646ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
647ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
648ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek// Out-of-line method definitions for ProgramState.
649ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek//===----------------------------------------------------------------------===//
650ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
651ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline const VarRegion* ProgramState::getRegion(const VarDecl *D,
6525eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                const LocationContext *LC) const
6535eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek{
654ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().getRegionManager().getVarRegion(D, LC);
655ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
656ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
657ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline const ProgramState *ProgramState::assume(DefinedOrUnknownSVal Cond,
658ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                      bool Assumption) const {
659ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  if (Cond.isUnknown())
660ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return this;
661ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
662ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().ConstraintMgr->assume(this, cast<DefinedSVal>(Cond),
663ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                                 Assumption);
664ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
665ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
666ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline std::pair<const ProgramState*, const ProgramState*>
667ae160f880d183ab938fd7ce3b891694ae2f569c0Ted KremenekProgramState::assume(DefinedOrUnknownSVal Cond) const {
668ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  if (Cond.isUnknown())
669ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return std::make_pair(this, this);
670ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
671ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().ConstraintMgr->assumeDual(this,
672ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                                     cast<DefinedSVal>(Cond));
673ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
674ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
675ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline const ProgramState *ProgramState::bindLoc(SVal LV, SVal V) const {
676ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
677ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
678ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
679ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline Loc ProgramState::getLValue(const VarDecl *VD,
680ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                               const LocationContext *LC) const {
681ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->getLValueVar(VD, LC);
682ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
683ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
684ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline Loc ProgramState::getLValue(const StringLiteral *literal) const {
685ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->getLValueString(literal);
686ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
687ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
688ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
689ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                               const LocationContext *LC) const {
690ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
691ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
692ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
693ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
694ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->getLValueIvar(D, Base);
695ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
696ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
697ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
698ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->getLValueField(D, Base);
699ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
700ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
701ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
702ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
703ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
704ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return UnknownVal();
705ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
706ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
707ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline const llvm::APSInt *ProgramState::getSymVal(SymbolRef sym) const {
708ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().getSymVal(this, sym);
709ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
710ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
7115eca482fe895ea57bc82410222e6426c09e63284Ted Kremenekinline SVal ProgramState::getSVal(const Stmt *Ex, const LocationContext *LCtx,
7125eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                  bool useOnlyDirectBindings) const{
7135eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return Env.getSVal(EnvironmentEntry(Ex, LCtx),
7145eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                     *getStateManager().svalBuilder,
715ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                     useOnlyDirectBindings);
716ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
717ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
7185eca482fe895ea57bc82410222e6426c09e63284Ted Kremenekinline SVal
7195eca482fe895ea57bc82410222e6426c09e63284Ted KremenekProgramState::getSValAsScalarOrLoc(const Stmt *S,
7205eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                   const LocationContext *LCtx) const {
721ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  if (const Expr *Ex = dyn_cast<Expr>(S)) {
722ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    QualType T = Ex->getType();
723ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek    if (Ex->isLValue() || Loc::isLocType(T) || T->isIntegerType())
7245eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      return getSVal(S, LCtx);
725ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  }
726ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
727ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return UnknownVal();
728ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
729ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
730ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
731ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->Retrieve(getStore(), LV, T);
732ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
733ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
734ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline SVal ProgramState::getSVal(const MemRegion* R) const {
735ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().StoreMgr->Retrieve(getStore(), loc::MemRegionVal(R));
736ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
737ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
738ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline BasicValueFactory &ProgramState::getBasicVals() const {
739ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().getBasicVals();
740ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
741ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
742ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekinline SymbolManager &ProgramState::getSymbolManager() const {
743ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().getSymbolManager();
744ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
745ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
746ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate<typename T>
747ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
748ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().add<T>(this, K, get_context<T>());
749ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
750ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
751ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename T>
752ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektypename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
753ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().get_context<T>();
754ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
755ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
756ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate<typename T>
757ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
758ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().remove<T>(this, K, get_context<T>());
759ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
760ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
761ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate<typename T>
762ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
763ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                               typename ProgramStateTrait<T>::context_type C) const {
764ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().remove<T>(this, K, C);
765ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
766ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
767ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename T>
768ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::remove() const {
769ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().remove<T>(this);
770ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
771ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
772ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate<typename T>
773ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
774ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().set<T>(this, D);
775ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
776ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
777ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate<typename T>
778ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::set(typename ProgramStateTrait<T>::key_type K,
779ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                            typename ProgramStateTrait<T>::value_type E) const {
780ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().set<T>(this, K, E, get_context<T>());
781ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
782ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
783ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate<typename T>
784ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenekconst ProgramState *ProgramState::set(typename ProgramStateTrait<T>::key_type K,
785ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                            typename ProgramStateTrait<T>::value_type E,
786ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                            typename ProgramStateTrait<T>::context_type C) const {
787ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return getStateManager().set<T>(this, K, E, C);
788ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
789ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
790ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename CB>
791ae160f880d183ab938fd7ce3b891694ae2f569c0Ted KremenekCB ProgramState::scanReachableSymbols(SVal val) const {
792ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  CB cb(this);
793ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  scanReachableSymbols(val, cb);
794ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return cb;
795ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
796ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
797ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename CB>
798ae160f880d183ab938fd7ce3b891694ae2f569c0Ted KremenekCB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
799ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  CB cb(this);
800ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  scanReachableSymbols(beg, end, cb);
801ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return cb;
802ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
803ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
804ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenektemplate <typename CB>
805ae160f880d183ab938fd7ce3b891694ae2f569c0Ted KremenekCB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
806ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek                                 const MemRegion * const *end) const {
807ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  CB cb(this);
808ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  scanReachableSymbols(beg, end, cb);
809ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek  return cb;
810ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek}
811ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
8125f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks/// \class ScanReachableSymbols
8135f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks/// A Utility class that allows to visit the reachable symbols using a custom
8145f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks/// SymbolVisitor.
8155f625712f622f6e57de17b6f7eec242956b993eeAnna Zaksclass ScanReachableSymbols : public SubRegionMap::Visitor  {
81699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
8175f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
8185f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks
8195f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  VisitedItems visited;
8205f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  const ProgramState *state;
8215f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  SymbolVisitor &visitor;
8225f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  llvm::OwningPtr<SubRegionMap> SRM;
8235f625712f622f6e57de17b6f7eec242956b993eeAnna Zakspublic:
8245f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks
8255f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v)
8265f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks    : state(st), visitor(v) {}
8275f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks
8285f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  bool scan(nonloc::CompoundVal val);
8295f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  bool scan(SVal val);
8305f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  bool scan(const MemRegion *R);
8315f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  bool scan(const SymExpr *sym);
8325f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks
8335f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  // From SubRegionMap::Visitor.
8345f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
8355f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks    return scan(SubRegion);
8365f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  }
8375f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks};
8385f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks
839ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end GR namespace
840ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
841ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek} // end clang namespace
842ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek
843ae160f880d183ab938fd7ce3b891694ae2f569c0Ted Kremenek#endif
844