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