clang API Documentation

ProgramState.h
Go to the documentation of this file.
00001 //== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines SymbolRef, ExprBindKey, and ProgramState*.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_GR_VALUESTATE_H
00015 #define LLVM_CLANG_GR_VALUESTATE_H
00016 
00017 #include "clang/Basic/LLVM.h"
00018 #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
00019 #include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
00020 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
00021 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
00022 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
00023 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
00024 #include "llvm/ADT/PointerIntPair.h"
00025 #include "llvm/ADT/FoldingSet.h"
00026 #include "llvm/ADT/ImmutableMap.h"
00027 
00028 namespace llvm {
00029 class APSInt;
00030 class BumpPtrAllocator;
00031 }
00032 
00033 namespace clang {
00034 class ASTContext;
00035 
00036 namespace ento {
00037 
00038 class CallOrObjCMessage;
00039 
00040 typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
00041                                                        SubEngine&);
00042 typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
00043 
00044 //===----------------------------------------------------------------------===//
00045 // ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
00046 //===----------------------------------------------------------------------===//
00047 
00048 template <typename T> struct ProgramStatePartialTrait;
00049 
00050 template <typename T> struct ProgramStateTrait {
00051   typedef typename T::data_type data_type;
00052   static inline void *GDMIndex() { return &T::TagInt; }
00053   static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
00054   static inline data_type MakeData(void *const* P) {
00055     return P ? (data_type) *P : (data_type) 0;
00056   }
00057 };
00058 
00059 /// \class ProgramState
00060 /// ProgramState - This class encapsulates:
00061 ///
00062 ///    1. A mapping from expressions to values (Environment)
00063 ///    2. A mapping from locations to values (Store)
00064 ///    3. Constraints on symbolic values (GenericDataMap)
00065 ///
00066 ///  Together these represent the "abstract state" of a program.
00067 ///
00068 ///  ProgramState is intended to be used as a functional object; that is,
00069 ///  once it is created and made "persistent" in a FoldingSet, its
00070 ///  values will never change.
00071 class ProgramState : public llvm::FoldingSetNode {
00072 public:
00073   typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
00074   typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;
00075 
00076 private:
00077   void operator=(const ProgramState& R) const; // Do not implement.
00078 
00079   friend class ProgramStateManager;
00080   friend class ExplodedGraph;
00081   friend class ExplodedNode;
00082 
00083   ProgramStateManager *stateMgr;
00084   Environment Env;           // Maps a Stmt to its current SVal.
00085   Store store;               // Maps a location to its current value.
00086   GenericDataMap   GDM;      // Custom data stored by a client of this class.
00087   unsigned refCount;
00088 
00089   /// makeWithStore - Return a ProgramState with the same values as the current
00090   ///  state with the exception of using the specified Store.
00091   ProgramStateRef makeWithStore(const StoreRef &store) const;
00092 
00093   void setStore(const StoreRef &storeRef);
00094 
00095 public:
00096   /// This ctor is used when creating the first ProgramState object.
00097   ProgramState(ProgramStateManager *mgr, const Environment& env,
00098           StoreRef st, GenericDataMap gdm);
00099     
00100   /// Copy ctor - We must explicitly define this or else the "Next" ptr
00101   ///  in FoldingSetNode will also get copied.
00102   ProgramState(const ProgramState &RHS);
00103   
00104   ~ProgramState();
00105 
00106   /// Return the ProgramStateManager associated with this state.
00107   ProgramStateManager &getStateManager() const { return *stateMgr; }
00108 
00109   /// getEnvironment - Return the environment associated with this state.
00110   ///  The environment is the mapping from expressions to values.
00111   const Environment& getEnvironment() const { return Env; }
00112 
00113   /// Return the store associated with this state.  The store
00114   ///  is a mapping from locations to values.
00115   Store getStore() const { return store; }
00116 
00117   
00118   /// getGDM - Return the generic data map associated with this state.
00119   GenericDataMap getGDM() const { return GDM; }
00120 
00121   void setGDM(GenericDataMap gdm) { GDM = gdm; }
00122 
00123   /// Profile - Profile the contents of a ProgramState object for use in a
00124   ///  FoldingSet.  Two ProgramState objects are considered equal if they
00125   ///  have the same Environment, Store, and GenericDataMap.
00126   static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
00127     V->Env.Profile(ID);
00128     ID.AddPointer(V->store);
00129     V->GDM.Profile(ID);
00130   }
00131 
00132   /// Profile - Used to profile the contents of this object for inclusion
00133   ///  in a FoldingSet.
00134   void Profile(llvm::FoldingSetNodeID& ID) const {
00135     Profile(ID, this);
00136   }
00137 
00138   BasicValueFactory &getBasicVals() const;
00139   SymbolManager &getSymbolManager() const;
00140 
00141   //==---------------------------------------------------------------------==//
00142   // Constraints on values.
00143   //==---------------------------------------------------------------------==//
00144   //
00145   // Each ProgramState records constraints on symbolic values.  These constraints
00146   // are managed using the ConstraintManager associated with a ProgramStateManager.
00147   // As constraints gradually accrue on symbolic values, added constraints
00148   // may conflict and indicate that a state is infeasible (as no real values
00149   // could satisfy all the constraints).  This is the principal mechanism
00150   // for modeling path-sensitivity in ExprEngine/ProgramState.
00151   //
00152   // Various "assume" methods form the interface for adding constraints to
00153   // symbolic values.  A call to 'assume' indicates an assumption being placed
00154   // on one or symbolic values.  'assume' methods take the following inputs:
00155   //
00156   //  (1) A ProgramState object representing the current state.
00157   //
00158   //  (2) The assumed constraint (which is specific to a given "assume" method).
00159   //
00160   //  (3) A binary value "Assumption" that indicates whether the constraint is
00161   //      assumed to be true or false.
00162   //
00163   // The output of "assume*" is a new ProgramState object with the added constraints.
00164   // If no new state is feasible, NULL is returned.
00165   //
00166 
00167   ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
00168 
00169   /// This method assumes both "true" and "false" for 'cond', and
00170   ///  returns both corresponding states.  It's shorthand for doing
00171   ///  'assume' twice.
00172   std::pair<ProgramStateRef , ProgramStateRef >
00173   assume(DefinedOrUnknownSVal cond) const;
00174 
00175   ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
00176                                DefinedOrUnknownSVal upperBound,
00177                                bool assumption,
00178                                QualType IndexType = QualType()) const;
00179 
00180   /// Utility method for getting regions.
00181   const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
00182 
00183   //==---------------------------------------------------------------------==//
00184   // Binding and retrieving values to/from the environment and symbolic store.
00185   //==---------------------------------------------------------------------==//
00186 
00187   /// BindCompoundLiteral - Return the state that has the bindings currently
00188   ///  in this state plus the bindings for the CompoundLiteral.
00189   ProgramStateRef bindCompoundLiteral(const CompoundLiteralExpr *CL,
00190                                      const LocationContext *LC,
00191                                      SVal V) const;
00192 
00193   /// Create a new state by binding the value 'V' to the statement 'S' in the
00194   /// state's environment.
00195   ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
00196                                SVal V, bool Invalidate = true) const;
00197 
00198   /// Create a new state by binding the value 'V' and location 'locaton' to the
00199   /// statement 'S' in the state's environment.
00200   ProgramStateRef bindExprAndLocation(const Stmt *S,
00201                                           const LocationContext *LCtx,
00202                                           SVal location, SVal V) const;
00203   
00204   ProgramStateRef bindDecl(const VarRegion *VR, SVal V) const;
00205 
00206   ProgramStateRef bindDeclWithNoInit(const VarRegion *VR) const;
00207 
00208   ProgramStateRef bindLoc(Loc location, SVal V) const;
00209 
00210   ProgramStateRef bindLoc(SVal location, SVal V) const;
00211 
00212   ProgramStateRef bindDefault(SVal loc, SVal V) const;
00213 
00214   ProgramStateRef unbindLoc(Loc LV) const;
00215 
00216   /// invalidateRegions - Returns the state with bindings for the given regions
00217   ///  cleared from the store. The regions are provided as a continuous array
00218   ///  from Begin to End. Optionally invalidates global regions as well.
00219   ProgramStateRef invalidateRegions(ArrayRef<const MemRegion *> Regions,
00220                                const Expr *E, unsigned BlockCount,
00221                                const LocationContext *LCtx,
00222                                StoreManager::InvalidatedSymbols *IS = 0,
00223                                const CallOrObjCMessage *Call = 0) const;
00224 
00225   /// enterStackFrame - Returns the state for entry to the given stack frame,
00226   ///  preserving the current state.
00227   ProgramStateRef enterStackFrame(const LocationContext *callerCtx,
00228                                       const StackFrameContext *calleeCtx) const;
00229 
00230   /// Get the lvalue for a variable reference.
00231   Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
00232 
00233   Loc getLValue(const CompoundLiteralExpr *literal, 
00234                 const LocationContext *LC) const;
00235 
00236   /// Get the lvalue for an ivar reference.
00237   SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
00238 
00239   /// Get the lvalue for a field reference.
00240   SVal getLValue(const FieldDecl *decl, SVal Base) const;
00241 
00242   /// Get the lvalue for an array index.
00243   SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
00244 
00245   const llvm::APSInt *getSymVal(SymbolRef sym) const;
00246 
00247   /// Returns the SVal bound to the statement 'S' in the state's environment.
00248   SVal getSVal(const Stmt *S, const LocationContext *LCtx,
00249                bool useOnlyDirectBindings = false) const;
00250   
00251   SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
00252 
00253   /// \brief Return the value bound to the specified location.
00254   /// Returns UnknownVal() if none found.
00255   SVal getSVal(Loc LV, QualType T = QualType()) const;
00256 
00257   /// Returns the "raw" SVal bound to LV before any value simplfication.
00258   SVal getRawSVal(Loc LV, QualType T= QualType()) const;
00259 
00260   /// \brief Return the value bound to the specified location.
00261   /// Returns UnknownVal() if none found.
00262   SVal getSVal(const MemRegion* R) const;
00263 
00264   SVal getSValAsScalarOrLoc(const MemRegion *R) const;
00265   
00266   /// \brief Visits the symbols reachable from the given SVal using the provided
00267   /// SymbolVisitor.
00268   ///
00269   /// This is a convenience API. Consider using ScanReachableSymbols class
00270   /// directly when making multiple scans on the same state with the same
00271   /// visitor to avoid repeated initialization cost.
00272   /// \sa ScanReachableSymbols
00273   bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
00274   
00275   /// \brief Visits the symbols reachable from the SVals in the given range
00276   /// using the provided SymbolVisitor.
00277   bool scanReachableSymbols(const SVal *I, const SVal *E,
00278                             SymbolVisitor &visitor) const;
00279   
00280   /// \brief Visits the symbols reachable from the regions in the given
00281   /// MemRegions range using the provided SymbolVisitor.
00282   bool scanReachableSymbols(const MemRegion * const *I, 
00283                             const MemRegion * const *E,
00284                             SymbolVisitor &visitor) const;
00285 
00286   template <typename CB> CB scanReachableSymbols(SVal val) const;
00287   template <typename CB> CB scanReachableSymbols(const SVal *beg,
00288                                                  const SVal *end) const;
00289   
00290   template <typename CB> CB
00291   scanReachableSymbols(const MemRegion * const *beg,
00292                        const MemRegion * const *end) const;
00293 
00294   /// Create a new state in which the statement is marked as tainted.
00295   ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
00296                                TaintTagType Kind = TaintTagGeneric) const;
00297 
00298   /// Create a new state in which the symbol is marked as tainted.
00299   ProgramStateRef addTaint(SymbolRef S,
00300                                TaintTagType Kind = TaintTagGeneric) const;
00301 
00302   /// Create a new state in which the region symbol is marked as tainted.
00303   ProgramStateRef addTaint(const MemRegion *R,
00304                                TaintTagType Kind = TaintTagGeneric) const;
00305 
00306   /// Check if the statement is tainted in the current state.
00307   bool isTainted(const Stmt *S, const LocationContext *LCtx,
00308                  TaintTagType Kind = TaintTagGeneric) const;
00309   bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
00310   bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
00311   bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
00312 
00313   //==---------------------------------------------------------------------==//
00314   // Accessing the Generic Data Map (GDM).
00315   //==---------------------------------------------------------------------==//
00316 
00317   void *const* FindGDM(void *K) const;
00318 
00319   template<typename T>
00320   ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
00321 
00322   template <typename T>
00323   typename ProgramStateTrait<T>::data_type
00324   get() const {
00325     return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
00326   }
00327 
00328   template<typename T>
00329   typename ProgramStateTrait<T>::lookup_type
00330   get(typename ProgramStateTrait<T>::key_type key) const {
00331     void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
00332     return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
00333   }
00334 
00335   template <typename T>
00336   typename ProgramStateTrait<T>::context_type get_context() const;
00337 
00338 
00339   template<typename T>
00340   ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const;
00341 
00342   template<typename T>
00343   ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K,
00344                         typename ProgramStateTrait<T>::context_type C) const;
00345   template <typename T>
00346   ProgramStateRef remove() const;
00347 
00348   template<typename T>
00349   ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const;
00350 
00351   template<typename T>
00352   ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
00353                      typename ProgramStateTrait<T>::value_type E) const;
00354 
00355   template<typename T>
00356   ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
00357                      typename ProgramStateTrait<T>::value_type E,
00358                      typename ProgramStateTrait<T>::context_type C) const;
00359 
00360   template<typename T>
00361   bool contains(typename ProgramStateTrait<T>::key_type key) const {
00362     void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
00363     return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
00364   }
00365 
00366   // Pretty-printing.
00367   void print(raw_ostream &Out, const char *nl = "\n",
00368              const char *sep = "") const;
00369   void printDOT(raw_ostream &Out) const;
00370   void printTaint(raw_ostream &Out, const char *nl = "\n",
00371                   const char *sep = "") const;
00372 
00373   void dump() const;
00374   void dumpTaint() const;
00375 
00376 private:
00377   friend void ProgramStateRetain(const ProgramState *state);
00378   friend void ProgramStateRelease(const ProgramState *state);
00379   
00380   ProgramStateRef 
00381   invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
00382                         const Expr *E, unsigned BlockCount,
00383                         const LocationContext *LCtx,
00384                         StoreManager::InvalidatedSymbols &IS,
00385                         const CallOrObjCMessage *Call) const;
00386 };
00387 
00388 //===----------------------------------------------------------------------===//
00389 // ProgramStateManager - Factory object for ProgramStates.
00390 //===----------------------------------------------------------------------===//
00391 
00392 class ProgramStateManager {
00393   friend class ProgramState;
00394   friend void ProgramStateRelease(const ProgramState *state);
00395 private:
00396   /// Eng - The SubEngine that owns this state manager.
00397   SubEngine *Eng; /* Can be null. */
00398 
00399   EnvironmentManager                   EnvMgr;
00400   OwningPtr<StoreManager>              StoreMgr;
00401   OwningPtr<ConstraintManager>         ConstraintMgr;
00402 
00403   ProgramState::GenericDataMap::Factory     GDMFactory;
00404 
00405   typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
00406   GDMContextsTy GDMContexts;
00407 
00408   /// StateSet - FoldingSet containing all the states created for analyzing
00409   ///  a particular function.  This is used to unique states.
00410   llvm::FoldingSet<ProgramState> StateSet;
00411 
00412   /// Object that manages the data for all created SVals.
00413   OwningPtr<SValBuilder> svalBuilder;
00414 
00415   /// A BumpPtrAllocator to allocate states.
00416   llvm::BumpPtrAllocator &Alloc;
00417   
00418   /// A vector of ProgramStates that we can reuse.
00419   std::vector<ProgramState *> freeStates;
00420 
00421 public:
00422   ProgramStateManager(ASTContext &Ctx,
00423                  StoreManagerCreator CreateStoreManager,
00424                  ConstraintManagerCreator CreateConstraintManager,
00425                  llvm::BumpPtrAllocator& alloc,
00426                  SubEngine &subeng)
00427     : Eng(&subeng),
00428       EnvMgr(alloc),
00429       GDMFactory(alloc),
00430       svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
00431       Alloc(alloc) {
00432     StoreMgr.reset((*CreateStoreManager)(*this));
00433     ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
00434   }
00435 
00436   ProgramStateManager(ASTContext &Ctx,
00437                  StoreManagerCreator CreateStoreManager,
00438                  ConstraintManager* ConstraintManagerPtr,
00439                  llvm::BumpPtrAllocator& alloc)
00440     : Eng(0),
00441       EnvMgr(alloc),
00442       GDMFactory(alloc),
00443       svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
00444       Alloc(alloc) {
00445     StoreMgr.reset((*CreateStoreManager)(*this));
00446     ConstraintMgr.reset(ConstraintManagerPtr);
00447   }
00448 
00449   ~ProgramStateManager();
00450 
00451   ProgramStateRef getInitialState(const LocationContext *InitLoc);
00452 
00453   ASTContext &getContext() { return svalBuilder->getContext(); }
00454   const ASTContext &getContext() const { return svalBuilder->getContext(); }
00455 
00456   BasicValueFactory &getBasicVals() {
00457     return svalBuilder->getBasicValueFactory();
00458   }
00459   const BasicValueFactory& getBasicVals() const {
00460     return svalBuilder->getBasicValueFactory();
00461   }
00462 
00463   SValBuilder &getSValBuilder() {
00464     return *svalBuilder;
00465   }
00466 
00467   SymbolManager &getSymbolManager() {
00468     return svalBuilder->getSymbolManager();
00469   }
00470   const SymbolManager &getSymbolManager() const {
00471     return svalBuilder->getSymbolManager();
00472   }
00473 
00474   llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
00475 
00476   MemRegionManager& getRegionManager() {
00477     return svalBuilder->getRegionManager();
00478   }
00479   const MemRegionManager& getRegionManager() const {
00480     return svalBuilder->getRegionManager();
00481   }
00482 
00483   StoreManager& getStoreManager() { return *StoreMgr; }
00484   ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
00485   SubEngine* getOwningEngine() { return Eng; }
00486 
00487   ProgramStateRef removeDeadBindings(ProgramStateRef St,
00488                                     const StackFrameContext *LCtx,
00489                                     SymbolReaper& SymReaper);
00490 
00491   /// Marshal a new state for the callee in another translation unit.
00492   /// 'state' is owned by the caller's engine.
00493   ProgramStateRef MarshalState(ProgramStateRef state, const StackFrameContext *L);
00494 
00495 public:
00496 
00497   SVal ArrayToPointer(Loc Array) {
00498     return StoreMgr->ArrayToPointer(Array);
00499   }
00500 
00501   // Methods that manipulate the GDM.
00502   ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
00503   ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
00504 
00505   // Methods that query & manipulate the Store.
00506 
00507   void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
00508     StoreMgr->iterBindings(state->getStore(), F);
00509   }
00510 
00511   ProgramStateRef getPersistentState(ProgramState &Impl);
00512   ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
00513                                            ProgramStateRef GDMState);
00514 
00515   bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
00516     return S1->Env == S2->Env;
00517   }
00518 
00519   bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
00520     return S1->store == S2->store;
00521   }
00522 
00523   //==---------------------------------------------------------------------==//
00524   // Generic Data Map methods.
00525   //==---------------------------------------------------------------------==//
00526   //
00527   // ProgramStateManager and ProgramState support a "generic data map" that allows
00528   // different clients of ProgramState objects to embed arbitrary data within a
00529   // ProgramState object.  The generic data map is essentially an immutable map
00530   // from a "tag" (that acts as the "key" for a client) and opaque values.
00531   // Tags/keys and values are simply void* values.  The typical way that clients
00532   // generate unique tags are by taking the address of a static variable.
00533   // Clients are responsible for ensuring that data values referred to by a
00534   // the data pointer are immutable (and thus are essentially purely functional
00535   // data).
00536   //
00537   // The templated methods below use the ProgramStateTrait<T> class
00538   // to resolve keys into the GDM and to return data values to clients.
00539   //
00540 
00541   // Trait based GDM dispatch.
00542   template <typename T>
00543   ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
00544     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
00545                   ProgramStateTrait<T>::MakeVoidPtr(D));
00546   }
00547 
00548   template<typename T>
00549   ProgramStateRef set(ProgramStateRef st,
00550                      typename ProgramStateTrait<T>::key_type K,
00551                      typename ProgramStateTrait<T>::value_type V,
00552                      typename ProgramStateTrait<T>::context_type C) {
00553 
00554     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
00555      ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
00556   }
00557 
00558   template <typename T>
00559   ProgramStateRef add(ProgramStateRef st,
00560                      typename ProgramStateTrait<T>::key_type K,
00561                      typename ProgramStateTrait<T>::context_type C) {
00562     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
00563         ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
00564   }
00565 
00566   template <typename T>
00567   ProgramStateRef remove(ProgramStateRef st,
00568                         typename ProgramStateTrait<T>::key_type K,
00569                         typename ProgramStateTrait<T>::context_type C) {
00570 
00571     return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
00572      ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
00573   }
00574 
00575   template <typename T>
00576   ProgramStateRef remove(ProgramStateRef st) {
00577     return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
00578   }
00579 
00580   void *FindGDMContext(void *index,
00581                        void *(*CreateContext)(llvm::BumpPtrAllocator&),
00582                        void  (*DeleteContext)(void*));
00583 
00584   template <typename T>
00585   typename ProgramStateTrait<T>::context_type get_context() {
00586     void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
00587                              ProgramStateTrait<T>::CreateContext,
00588                              ProgramStateTrait<T>::DeleteContext);
00589 
00590     return ProgramStateTrait<T>::MakeContext(p);
00591   }
00592 
00593   const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) {
00594     return ConstraintMgr->getSymVal(St, sym);
00595   }
00596 
00597   void EndPath(ProgramStateRef St) {
00598     ConstraintMgr->EndPath(St);
00599   }
00600 };
00601 
00602 
00603 //===----------------------------------------------------------------------===//
00604 // Out-of-line method definitions for ProgramState.
00605 //===----------------------------------------------------------------------===//
00606 
00607 inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
00608                                                 const LocationContext *LC) const 
00609 {
00610   return getStateManager().getRegionManager().getVarRegion(D, LC);
00611 }
00612 
00613 inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
00614                                       bool Assumption) const {
00615   if (Cond.isUnknown())
00616     return this;
00617   
00618   return getStateManager().ConstraintMgr->assume(this, cast<DefinedSVal>(Cond),
00619                                                  Assumption);
00620 }
00621   
00622 inline std::pair<ProgramStateRef , ProgramStateRef >
00623 ProgramState::assume(DefinedOrUnknownSVal Cond) const {
00624   if (Cond.isUnknown())
00625     return std::make_pair(this, this);
00626   
00627   return getStateManager().ConstraintMgr->assumeDual(this,
00628                                                      cast<DefinedSVal>(Cond));
00629 }
00630 
00631 inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
00632   return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
00633 }
00634 
00635 inline Loc ProgramState::getLValue(const VarDecl *VD,
00636                                const LocationContext *LC) const {
00637   return getStateManager().StoreMgr->getLValueVar(VD, LC);
00638 }
00639 
00640 inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
00641                                const LocationContext *LC) const {
00642   return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
00643 }
00644 
00645 inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
00646   return getStateManager().StoreMgr->getLValueIvar(D, Base);
00647 }
00648 
00649 inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
00650   return getStateManager().StoreMgr->getLValueField(D, Base);
00651 }
00652 
00653 inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
00654   if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
00655     return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
00656   return UnknownVal();
00657 }
00658 
00659 inline const llvm::APSInt *ProgramState::getSymVal(SymbolRef sym) const {
00660   return getStateManager().getSymVal(this, sym);
00661 }
00662 
00663 inline SVal ProgramState::getSVal(const Stmt *Ex, const LocationContext *LCtx,
00664                                   bool useOnlyDirectBindings) const{
00665   return Env.getSVal(EnvironmentEntry(Ex, LCtx),
00666                      *getStateManager().svalBuilder,
00667                      useOnlyDirectBindings);
00668 }
00669 
00670 inline SVal
00671 ProgramState::getSValAsScalarOrLoc(const Stmt *S,
00672                                    const LocationContext *LCtx) const {
00673   if (const Expr *Ex = dyn_cast<Expr>(S)) {
00674     QualType T = Ex->getType();
00675     if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegerType())
00676       return getSVal(S, LCtx);
00677   }
00678 
00679   return UnknownVal();
00680 }
00681 
00682 inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
00683   return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
00684 }
00685 
00686 inline SVal ProgramState::getSVal(const MemRegion* R) const {
00687   return getStateManager().StoreMgr->getBinding(getStore(),
00688                                                 loc::MemRegionVal(R));
00689 }
00690 
00691 inline BasicValueFactory &ProgramState::getBasicVals() const {
00692   return getStateManager().getBasicVals();
00693 }
00694 
00695 inline SymbolManager &ProgramState::getSymbolManager() const {
00696   return getStateManager().getSymbolManager();
00697 }
00698 
00699 template<typename T>
00700 ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
00701   return getStateManager().add<T>(this, K, get_context<T>());
00702 }
00703 
00704 template <typename T>
00705 typename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
00706   return getStateManager().get_context<T>();
00707 }
00708 
00709 template<typename T>
00710 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
00711   return getStateManager().remove<T>(this, K, get_context<T>());
00712 }
00713 
00714 template<typename T>
00715 ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
00716                                typename ProgramStateTrait<T>::context_type C) const {
00717   return getStateManager().remove<T>(this, K, C);
00718 }
00719 
00720 template <typename T>
00721 ProgramStateRef ProgramState::remove() const {
00722   return getStateManager().remove<T>(this);
00723 }
00724 
00725 template<typename T>
00726 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
00727   return getStateManager().set<T>(this, D);
00728 }
00729 
00730 template<typename T>
00731 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
00732                             typename ProgramStateTrait<T>::value_type E) const {
00733   return getStateManager().set<T>(this, K, E, get_context<T>());
00734 }
00735 
00736 template<typename T>
00737 ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
00738                             typename ProgramStateTrait<T>::value_type E,
00739                             typename ProgramStateTrait<T>::context_type C) const {
00740   return getStateManager().set<T>(this, K, E, C);
00741 }
00742 
00743 template <typename CB>
00744 CB ProgramState::scanReachableSymbols(SVal val) const {
00745   CB cb(this);
00746   scanReachableSymbols(val, cb);
00747   return cb;
00748 }
00749   
00750 template <typename CB>
00751 CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
00752   CB cb(this);
00753   scanReachableSymbols(beg, end, cb);
00754   return cb;
00755 }
00756 
00757 template <typename CB>
00758 CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
00759                                  const MemRegion * const *end) const {
00760   CB cb(this);
00761   scanReachableSymbols(beg, end, cb);
00762   return cb;
00763 }
00764 
00765 /// \class ScanReachableSymbols
00766 /// A Utility class that allows to visit the reachable symbols using a custom
00767 /// SymbolVisitor.
00768 class ScanReachableSymbols : public SubRegionMap::Visitor  {
00769   virtual void anchor();
00770   typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
00771 
00772   VisitedItems visited;
00773   ProgramStateRef state;
00774   SymbolVisitor &visitor;
00775   OwningPtr<SubRegionMap> SRM;
00776 public:
00777 
00778   ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
00779     : state(st), visitor(v) {}
00780 
00781   bool scan(nonloc::CompoundVal val);
00782   bool scan(SVal val);
00783   bool scan(const MemRegion *R);
00784   bool scan(const SymExpr *sym);
00785 
00786   // From SubRegionMap::Visitor.
00787   bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
00788     return scan(SubRegion);
00789   }
00790 };
00791 
00792 } // end GR namespace
00793 
00794 } // end clang namespace
00795 
00796 #endif