Refactored most of the "Store" piece of ValueState into a Store type. The
current store implementation is now encapsulated by BasicStore.

These changes prompted some long due constification of ValueState. Much of the
diffs in this patch include adding "const" qualifiers.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53423 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index 1667a21..4475ed2 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -107,7 +107,7 @@
   typedef std::vector<BugReport*> ErrorsTy;
   ErrorsTy Errors;
       
-  RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
+  RVal GetRVal(const ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
       
   bool isNSString(ObjCInterfaceType* T, const char* suffix);
   bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
@@ -338,8 +338,8 @@
   IdentifierInfo* II;
   ValueStateManager* VMgr;
     
-  RVal GetRVal(ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
-  RVal GetRVal(ValueState* St, LVal LV) { return VMgr->GetRVal(St, LV); }
+  RVal GetRVal(const ValueState* St, Expr* E) { return VMgr->GetRVal(St, E); }
+  RVal GetRVal(const ValueState* St, LVal LV) { return VMgr->GetRVal(St, LV); }
   
 public:
 
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
new file mode 100644
index 0000000..38c1db7
--- /dev/null
+++ b/lib/Analysis/BasicStore.cpp
@@ -0,0 +1,141 @@
+//== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the BasicStore and BasicStoreManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/BasicStore.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace clang;
+
+namespace {
+  
+class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
+  typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;  
+  VarBindingsTy::Factory VBFactory;
+  
+public:
+  BasicStoreManager(llvm::BumpPtrAllocator& A) : VBFactory(A) {}
+  virtual ~BasicStoreManager() {}
+
+  virtual RVal GetRVal(Store St, LVal LV, QualType T);  
+  virtual Store SetRVal(Store St, LVal LV, RVal V);  
+  virtual Store Remove(Store St, LVal LV);
+
+  virtual Store getInitialStore() {
+    return VBFactory.GetEmptyMap().getRoot();
+  }
+};  
+  
+} // end anonymous namespace
+
+
+StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A) {
+  return new BasicStoreManager(A);
+}
+
+RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
+  
+  if (isa<UnknownVal>(LV))
+    return UnknownVal();
+  
+  assert (!isa<UndefinedVal>(LV));
+  
+  switch (LV.getSubKind()) {
+
+    case lval::DeclValKind: {      
+      VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));      
+      VarBindingsTy::data_type* T = B.lookup(cast<lval::DeclVal>(LV).getDecl());      
+      return T ? *T : UnknownVal();
+    }
+      
+    case lval::SymbolValKind: {
+      
+      // FIXME: This is a broken representation of memory, and is prone
+      //  to crashing the analyzer when addresses to symbolic values are
+      //  passed through casts.  We need a better representation of symbolic
+      //  memory (or just memory in general); probably we should do this
+      //  as a plugin class (similar to GRTransferFuncs).
+      
+#if 0      
+      const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
+      assert (T.getTypePtr());
+      
+      // Punt on "symbolic" function pointers.
+      if (T->isFunctionType())
+        return UnknownVal();      
+      
+      if (T->isPointerType())
+        return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
+      else
+        return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
+#endif
+      
+      return UnknownVal();
+    }
+      
+    case lval::ConcreteIntKind:
+      // Some clients may call GetRVal with such an option simply because
+      // they are doing a quick scan through their LVals (potentially to
+      // invalidate their bindings).  Just return Undefined.
+      return UndefinedVal();
+      
+    case lval::ArrayOffsetKind:
+    case lval::FieldOffsetKind:
+      return UnknownVal();
+      
+    case lval::FuncValKind:
+      return LV;
+      
+    case lval::StringLiteralValKind:
+      // FIXME: Implement better support for fetching characters from strings.
+      return UnknownVal();
+      
+    default:
+      assert (false && "Invalid LVal.");
+      break;
+  }
+  
+  return UnknownVal();
+}
+
+Store BasicStoreManager::SetRVal(Store St, LVal LV, RVal V) {    
+  
+  VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+  
+  switch (LV.getSubKind()) {
+      
+    case lval::DeclValKind:        
+      return V.isUnknown()
+        ? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
+        : VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
+      
+    default:
+      assert ("SetRVal for given LVal type not yet implemented.");
+      return St;
+  }
+}
+
+Store BasicStoreManager::Remove(Store St, LVal LV) {
+  
+  VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
+  
+  switch (LV.getSubKind()) {
+      
+    case lval::DeclValKind:
+      return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
+
+    default:
+      assert ("Remove for given LVal type not yet implemented.");
+      return St;
+  }
+}
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index fba31f8..081e792 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -327,7 +327,7 @@
                                 PathDiagnostic& PD) {
   
   ExplodedNode<ValueState>* Pred = N->pred_empty() ? 0 : *N->pred_begin();
-  ValueState* PrevSt = Pred ? Pred->getState() : 0;
+  const ValueState* PrevSt = Pred ? Pred->getState() : 0;
   
   if (!PrevSt)
     return;
@@ -335,7 +335,7 @@
   // Look at the variable bindings of the current state that map to the
   // specified symbol.  Are any of them not in the previous state.
   
-  ValueState* St = N->getState();
+  const ValueState* St = N->getState();
   ValueStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
   
   // FIXME: Later generalize for a broader memory model.
@@ -633,7 +633,7 @@
     
     if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
       
-      ValueState* St = N->getState();
+      const ValueState* St = N->getState();
       
       // Scan the lval bindings, and see if a "notable" symbol has a new
       // lval binding.
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 1a57306..4de91da 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1135,8 +1135,8 @@
 
 public:
   
-  static RefBindings GetRefBindings(ValueState& StImpl) {
-    return RefBindings((RefBindings::TreeTy*) StImpl.CheckerState);
+  static RefBindings GetRefBindings(const ValueState& StImpl) {
+    return RefBindings((const RefBindings::TreeTy*) StImpl.CheckerState);
   }
 
 private:
@@ -1156,14 +1156,15 @@
                            GRStmtNodeBuilder<ValueState>& Builder,
                            Expr* NodeExpr, Expr* ErrorExpr,                        
                            ExplodedNode<ValueState>* Pred,
-                           ValueState* St,
+                           const ValueState* St,
                            RefVal::Kind hasErr, SymbolID Sym);
   
-  ValueState* HandleSymbolDeath(ValueStateManager& VMgr, ValueState* St,
-                                SymbolID sid, RefVal V, bool& hasLeak);
+  const ValueState* HandleSymbolDeath(ValueStateManager& VMgr,
+                                      const ValueState* St,
+                                      SymbolID sid, RefVal V, bool& hasLeak);
   
-  ValueState* NukeBinding(ValueStateManager& VMgr, ValueState* St,
-                          SymbolID sid);
+  const ValueState* NukeBinding(ValueStateManager& VMgr, const ValueState* St,
+                                SymbolID sid);
   
 public:
   
@@ -1226,7 +1227,7 @@
                          GRExprEngine& Engine,
                          GRStmtNodeBuilder<ValueState>& Builder,
                          Expr* E, ExplodedNode<ValueState>* Pred,
-                         ValueState* St, RVal TargetLV, RVal Val);
+                         const ValueState* St, RVal TargetLV, RVal Val);
   // End-of-path.
   
   virtual void EvalEndPath(GRExprEngine& Engine,
@@ -1237,7 +1238,7 @@
                                GRStmtNodeBuilder<ValueState>& Builder,
                                ExplodedNode<ValueState>* Pred,
                                Stmt* S,
-                               ValueState* St,
+                               const ValueState* St,
                                const ValueStateManager::DeadSymbolsTy& Dead);
   // Return statements.
   
@@ -1249,8 +1250,9 @@
 
   // Assumptions.
 
-  virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* St,
-                                 RVal Cond, bool Assumption, bool& isFeasible);
+  virtual const ValueState* EvalAssume(GRExprEngine& Engine,
+                                       const ValueState* St, RVal Cond,
+                                       bool Assumption, bool& isFeasible);
 
   // Error iterators.
 
@@ -1304,7 +1306,7 @@
                                      GRStmtNodeBuilder<ValueState>& Builder,
                                      Expr* NodeExpr, Expr* ErrorExpr,                        
                                      ExplodedNode<ValueState>* Pred,
-                                     ValueState* St,
+                                     const ValueState* St,
                                      RefVal::Kind hasErr, SymbolID Sym) {
   Builder.BuildSinks = true;
   GRExprEngine::NodeTy* N  = Builder.MakeNode(Dst, NodeExpr, Pred, St);
@@ -1368,7 +1370,7 @@
   
   // Get the state.
   ValueStateManager& StateMgr = Eng.getStateManager();  
-  ValueState* St = Builder.GetState(Pred);
+  const ValueState* St = Builder.GetState(Pred);
 
   // Evaluate the effect of the arguments.
   ValueState StVals = *St;
@@ -1429,7 +1431,7 @@
         unsigned Count = Builder.getCurrentBlockCount();
         SymbolID NewSym = Eng.getSymbolManager().getConjuredSymbol(*I, Count);
       
-        StateMgr.BindVar(StVals, DV->getDecl(),
+        StateMgr.SetRVal(StVals, *DV,
                          LVal::IsLValType(DV->getDecl()->getType())
                          ? cast<RVal>(lval::SymbolVal(NewSym))
                          : cast<RVal>(nonlval::SymbolVal(NewSym)));
@@ -1596,7 +1598,7 @@
 
     // FIXME: Wouldn't it be great if this code could be reduced?  It's just
     // a chain of lookups.
-    ValueState* St = Builder.GetState(Pred);
+    const ValueState* St = Builder.GetState(Pred);
     RVal V = Eng.getStateManager().GetRVal(St, Receiver );
 
     if (isa<lval::SymbolVal>(V)) {
@@ -1630,7 +1632,7 @@
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<ValueState>& Builder,
                            Expr* E, ExplodedNode<ValueState>* Pred,
-                           ValueState* St, RVal TargetLV, RVal Val) {
+                           const ValueState* St, RVal TargetLV, RVal Val) {
   
   // Check if we have a binding for "Val" and if we are storing it to something
   // we don't understand or otherwise the value "escapes" the function.
@@ -1663,8 +1665,9 @@
 }
 
 
-ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr, ValueState* St,
-                                    SymbolID sid) {
+const ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr,
+                                          const ValueState* St,
+                                          SymbolID sid) {
   ValueState StImpl = *St;
   RefBindings B = GetRefBindings(StImpl);
   StImpl.CheckerState = RefBFactory.Remove(B, sid).getRoot();
@@ -1673,8 +1676,8 @@
 
 // End-of-path.
 
-ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr,
-                                          ValueState* St, SymbolID sid,
+const ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr,
+                                          const ValueState* St, SymbolID sid,
                                           RefVal V, bool& hasLeak) {
     
   hasLeak = V.isOwned() || 
@@ -1693,7 +1696,7 @@
 void CFRefCount::EvalEndPath(GRExprEngine& Eng,
                              GREndPathNodeBuilder<ValueState>& Builder) {
   
-  ValueState* St = Builder.getState();
+  const ValueState* St = Builder.getState();
   RefBindings B = GetRefBindings(*St);
   
   llvm::SmallVector<SymbolID, 10> Leaked;
@@ -1731,7 +1734,7 @@
                                  GRStmtNodeBuilder<ValueState>& Builder,
                                  ExplodedNode<ValueState>* Pred,
                                  Stmt* S,
-                                 ValueState* St,
+                                 const ValueState* St,
                                  const ValueStateManager::DeadSymbolsTy& Dead) {
     
   // FIXME: a lot of copy-and-paste from EvalEndPath.  Refactor.
@@ -1784,7 +1787,7 @@
   if (!RetE) return;
   
   ValueStateManager& StateMgr = Eng.getStateManager();
-  ValueState* St = Builder.GetState(Pred);
+  const ValueState* St = Builder.GetState(Pred);
   RVal V = StateMgr.GetRVal(St, RetE);
   
   if (!isa<lval::SymbolVal>(V))
@@ -1831,9 +1834,10 @@
 
 // Assumptions.
 
-ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng, ValueState* St,
-                                   RVal Cond, bool Assumption,
-                                   bool& isFeasible) {
+const ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng,
+                                         const ValueState* St,
+                                         RVal Cond, bool Assumption,
+                                         bool& isFeasible) {
 
   // FIXME: We may add to the interface of EvalAssume the list of symbols
   //  whose assumptions have changed.  For now we just iterate through the
@@ -2136,8 +2140,8 @@
 
   // Check if the type state has changed.
   
-  ValueState* PrevSt = PrevN->getState();
-  ValueState* CurrSt = N->getState();
+  const ValueState* PrevSt = PrevN->getState();
+  const ValueState* CurrSt = N->getState();
   
   CFRefCount::RefBindings PrevB = CFRefCount::GetRefBindings(*PrevSt);
   CFRefCount::RefBindings CurrB = CFRefCount::GetRefBindings(*CurrSt);
@@ -2275,7 +2279,7 @@
   VarDecl* FirstDecl = 0;
   
   while (N) {
-    ValueState* St = N->getState();
+    const ValueState* St = N->getState();
     RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
     
     if (!B.lookup(Sym))
diff --git a/lib/Analysis/GRCoreEngine.cpp b/lib/Analysis/GRCoreEngine.cpp
index a4bb7fa..548c4bf 100644
--- a/lib/Analysis/GRCoreEngine.cpp
+++ b/lib/Analysis/GRCoreEngine.cpp
@@ -255,8 +255,8 @@
 
 /// GenerateNode - Utility method to generate nodes, hook up successors,
 ///  and add nodes to the worklist.
-void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, void* State,
-                                ExplodedNodeImpl* Pred) {
+void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State,
+                                    ExplodedNodeImpl* Pred) {
   
   bool IsNew;
   ExplodedNodeImpl* Node = G->getNodeImpl(Loc, State, &IsNew);
@@ -321,7 +321,7 @@
 }
 
 ExplodedNodeImpl*
-GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, void* State,
+GRStmtNodeBuilderImpl::generateNodeImpl(Stmt* S, const void* State,
                                         ExplodedNodeImpl* Pred,
                                         ProgramPoint::Kind K) {
   
@@ -342,7 +342,7 @@
   return NULL;  
 }
 
-ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(void* State,
+ExplodedNodeImpl* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State,
                                                             bool branch) {  
   bool IsNew;
   
@@ -374,7 +374,7 @@
 
 ExplodedNodeImpl*
 GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I,
-                                                void* St,
+                                                const void* St,
                                                 bool isSink) {
   bool IsNew;
   
@@ -399,7 +399,8 @@
 
 
 ExplodedNodeImpl*
-GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, void* St) {
+GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I,
+                                                  const void* St) {
 
   bool IsNew;
   
@@ -418,7 +419,8 @@
 
 
 ExplodedNodeImpl*
-GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(void* St, bool isSink) {
+GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St,
+                                                     bool isSink) {
   
   // Get the block for the default case.
   assert (Src->succ_rbegin() != Src->succ_rend());
@@ -448,7 +450,7 @@
   if (!HasGeneratedNode) generateNodeImpl(Pred->State);
 }
 
-ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(void* State) {
+ExplodedNodeImpl* GREndPathNodeBuilderImpl::generateNodeImpl(const void* State){
   HasGeneratedNode = true;
     
   bool IsNew;
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index c4eddb9..96e7fae 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -18,6 +18,8 @@
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/Streams.h"
 
+#include "clang/Analysis/PathSensitive/BasicStore.h"
+
 #ifndef NDEBUG
 #include "llvm/Support/GraphWriter.h"
 #include <sstream>
@@ -44,7 +46,8 @@
     G(CoreEngine.getGraph()),
     Liveness(L),
     Builder(NULL),
-    StateMgr(G.getContext(), G.getAllocator()),
+    StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()),
+             G.getAllocator()),
     BasicVals(StateMgr.getBasicValueFactory()),
     TF(NULL), // FIXME
     SymMgr(StateMgr.getSymbolManager()),
@@ -127,7 +130,7 @@
   MsgExprChecks.push_back(A);
 }
 
-ValueState* GRExprEngine::getInitialState() {
+const ValueState* GRExprEngine::getInitialState() {
 
   // The LiveVariables information already has a compilation of all VarDecls
   // used in the function.  Iterate through this set, and "symbolicate"
@@ -144,11 +147,11 @@
     if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
       if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
         RVal X = RVal::GetSymbolValue(SymMgr, VD);
-        StateMgr.BindVar(StateImpl, VD, X);
+        StateMgr.SetRVal(StateImpl, lval::DeclVal(VD), X);
       }
     } else if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(SD)) {
         RVal X = RVal::GetSymbolValue(SymMgr, IPD);
-        StateMgr.BindVar(StateImpl, IPD, X);
+      StateMgr.SetRVal(StateImpl, lval::DeclVal(IPD), X);
     }
       
 
@@ -157,7 +160,8 @@
   return StateMgr.getPersistentState(StateImpl);
 }      
       
-ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) {
+const ValueState* GRExprEngine::SetRVal(const ValueState* St, Expr* Ex,
+                                        RVal V) {
 
   bool isBlkExpr = false;
     
@@ -285,7 +289,7 @@
         break;
       }
       else if (B->getOpcode() == BinaryOperator::Comma) {
-        ValueState* St = GetState(Pred);
+        const ValueState* St = GetState(Pred);
         MakeNode(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS())));
         break;
       }
@@ -364,7 +368,7 @@
     case Stmt::StmtExprClass: {
       StmtExpr* SE = cast<StmtExpr>(S);
       
-      ValueState* St = GetState(Pred);
+      const ValueState* St = GetState(Pred);
       
       // FIXME: Not certain if we can have empty StmtExprs.  If so, we should
       // probably just remove these from the CFG.
@@ -420,7 +424,7 @@
 // Block entrance.  (Update counters).
 //===----------------------------------------------------------------------===//
 
-bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*,
+bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ValueState*,
                                         GRBlockCounter BC) {
   
   return BC.getNumVisited(B->getBlockID()) < 3;
@@ -430,8 +434,9 @@
 // Branch processing.
 //===----------------------------------------------------------------------===//
 
-ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator,
-                                     bool branchTaken) {
+const ValueState* GRExprEngine::MarkBranch(const ValueState* St,
+                                           Stmt* Terminator,
+                                           bool branchTaken) {
   
   switch (Terminator->getStmtClass()) {
     default:
@@ -488,7 +493,8 @@
                                  BranchNodeBuilder& builder) {
 
   // Remove old bindings for subexpressions.
-  ValueState* PrevState = StateMgr.RemoveSubExprBindings(builder.getState());
+  const ValueState* PrevState =
+    StateMgr.RemoveSubExprBindings(builder.getState());
   
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) { 
@@ -523,7 +529,7 @@
   // Process the true branch.
 
   bool isFeasible = false;  
-  ValueState* St = Assume(PrevState, V, true, isFeasible);
+  const ValueState* St = Assume(PrevState, V, true, isFeasible);
 
   if (isFeasible)
     builder.generateNode(MarkBranch(St, Term, true), true);
@@ -545,7 +551,7 @@
 ///  nodes by processing the 'effects' of a computed goto jump.
 void GRExprEngine::ProcessIndirectGoto(IndirectGotoNodeBuilder& builder) {
 
-  ValueState* St = builder.getState();  
+  const ValueState* St = builder.getState();  
   RVal V = GetRVal(St, builder.getTarget());
   
   // Three possibilities:
@@ -592,7 +598,7 @@
   
   assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex));
   
-  ValueState* St = GetState(Pred);
+  const ValueState* St = GetState(Pred);
   RVal X = GetBlkExprRVal(St, Ex);
   
   assert (X.isUndef());
@@ -613,7 +619,7 @@
   
   typedef SwitchNodeBuilder::iterator iterator;
   
-  ValueState* St = builder.getState();  
+  const ValueState* St = builder.getState();  
   Expr* CondE = builder.getCondition();
   RVal  CondV = GetRVal(St, CondE);
 
@@ -623,7 +629,7 @@
     return;
   }
   
-  ValueState*  DefaultSt = St;
+  const ValueState*  DefaultSt = St;
   
   // While most of this can be assumed (such as the signedness), having it
   // just computed makes sure everything makes the same assumptions end-to-end.
@@ -670,7 +676,7 @@
       // Now "assume" that the case matches.
       
       bool isFeasible = false;      
-      ValueState* StNew = Assume(St, Res, true, isFeasible);
+      const ValueState* StNew = Assume(St, Res, true, isFeasible);
       
       if (isFeasible) {
         builder.generateCaseStmtNode(I, StNew);
@@ -720,7 +726,7 @@
   
   assert (B == CurrentStmt && getCFG().isBlkExpr(B));
   
-  ValueState* St = GetState(Pred);
+  const ValueState* St = GetState(Pred);
   RVal X = GetBlkExprRVal(St, B);
   
   assert (X.isUndef());
@@ -748,7 +754,7 @@
     // the payoff is not likely to be large.  Instead, we do eager evaluation.
         
     bool isFeasible = false;
-    ValueState* NewState = Assume(St, X, true, isFeasible);
+    const ValueState* NewState = Assume(St, X, true, isFeasible);
     
     if (isFeasible)
       MakeNode(Dst, B, Pred,
@@ -778,7 +784,7 @@
 void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst,
                                     bool asLVal) {
   
-  ValueState* St = GetState(Pred);
+  const ValueState* St = GetState(Pred);
   RVal X = RVal::MakeVal(BasicVals, D);
   
   if (asLVal)
@@ -814,7 +820,7 @@
       
     for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2!=E2; ++I2) {
 
-      ValueState* St = GetState(*I2);
+      const ValueState* St = GetState(*I2);
       RVal BaseV = GetRVal(St, Base);
       RVal IdxV  = GetRVal(St, Idx);      
       
@@ -853,7 +859,7 @@
       VisitLVal(Base, Pred, Tmp);
   
     for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-      ValueState* St = GetState(*I);
+      const ValueState* St = GetState(*I);
       RVal BaseV = GetRVal(St, Base);      
       
       RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base),
@@ -871,7 +877,7 @@
   
   for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
 
-    ValueState* St = GetState(*I);
+    const ValueState* St = GetState(*I);
     RVal BaseV = GetRVal(St, Base);
     
     if (LVal::IsLValType(Base->getType())) {
@@ -900,7 +906,7 @@
 }
 
 void GRExprEngine::EvalStore(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
-                             ValueState* St, RVal location, RVal Val) {
+                             const ValueState* St, RVal location, RVal Val) {
   
   assert (Builder && "GRStmtNodeBuilder must be defined.");
   
@@ -930,7 +936,8 @@
 }
 
 void GRExprEngine::EvalLoad(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
-                            ValueState* St, RVal location, bool CheckOnly) {
+                            const ValueState* St, RVal location,
+                            bool CheckOnly) {
 
   // Evaluate the location (checks for bad dereferences).
   
@@ -958,9 +965,9 @@
                                                     Ex->getType())));  
 }
 
-ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
-                                       ValueState* St, RVal location,
-                                       bool isLoad) {
+const ValueState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred,
+                                             const ValueState* St,
+                                             RVal location, bool isLoad) {
   
   // Check for loads/stores from/to undefined values.  
   if (location.isUndef()) {
@@ -990,12 +997,12 @@
   // "Assume" that the pointer is not NULL.
   
   bool isFeasibleNotNull = false;
-  ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull);
+  const ValueState* StNotNull = Assume(St, LV, true, isFeasibleNotNull);
   
   // "Assume" that the pointer is NULL.
   
   bool isFeasibleNull = false;
-  ValueState* StNull = Assume(St, LV, false, isFeasibleNull);
+  const ValueState* StNull = Assume(St, LV, false, isFeasibleNull);
   
   if (isFeasibleNull) {
     
@@ -1053,7 +1060,7 @@
   // Finally, evaluate the function call.
   for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
 
-    ValueState* St = GetState(*DI);
+    const ValueState* St = GetState(*DI);
     RVal L = GetRVal(St, Callee);
 
     // FIXME: Add support for symbolic function calls (calls involving
@@ -1246,7 +1253,7 @@
   
   // FIXME: More logic for the processing the method call. 
   
-  ValueState* St = GetState(Pred);
+  const ValueState* St = GetState(Pred);
   bool RaisesException = false;
   
   
@@ -1391,7 +1398,7 @@
   
   for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) {
     NodeTy* N = *I1;
-    ValueState* St = GetState(N);
+    const ValueState* St = GetState(N);
     RVal V = GetRVal(St, Ex);
 
     // Unknown?
@@ -1470,7 +1477,7 @@
   
   for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
       
-    ValueState* St = GetState(*I);
+    const ValueState* St = GetState(*I);
 
     if (!Ex && VD->hasGlobalStorage()) {
       
@@ -1601,7 +1608,7 @@
       
       for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
         
-        ValueState* St = GetState(*I);
+        const ValueState* St = GetState(*I);
         RVal location = GetRVal(St, Ex);
         
         if (asLVal)
@@ -1630,7 +1637,7 @@
         
         // For all other types, UnaryOperator::Real is an identity operation.
         assert (U->getType() == Ex->getType());
-        ValueState* St = GetState(*I);
+        const ValueState* St = GetState(*I);
         MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
       } 
       
@@ -1653,7 +1660,7 @@
         
         // For all other types, UnaryOperator::Float returns 0.
         assert (Ex->getType()->isIntegerType());
-        ValueState* St = GetState(*I);
+        const ValueState* St = GetState(*I);
         RVal X = NonLVal::MakeVal(BasicVals, 0, Ex->getType());
         MakeNode(Dst, U, *I, SetRVal(St, U, X));
       }
@@ -1679,7 +1686,7 @@
       Visit(Ex, Pred, Tmp);
       
       for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {        
-        ValueState* St = GetState(*I);
+        const ValueState* St = GetState(*I);
         MakeNode(Dst, U, *I, SetRVal(St, U, GetRVal(St, Ex)));
       }
       
@@ -1694,7 +1701,7 @@
       VisitLVal(Ex, Pred, Tmp);
      
       for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {        
-        ValueState* St = GetState(*I);
+        const ValueState* St = GetState(*I);
         RVal V = GetRVal(St, Ex);
         St = SetRVal(St, U, V);
         MakeNode(Dst, U, *I, St);
@@ -1713,7 +1720,7 @@
       Visit(Ex, Pred, Tmp);
       
       for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {        
-        ValueState* St = GetState(*I);
+        const ValueState* St = GetState(*I);
         RVal V = GetRVal(St, Ex);
         
         if (V.isUnknownOrUndef()) {
@@ -1771,7 +1778,7 @@
         return;
         
       uint64_t size = getContext().getTypeSize(T) / 8;                
-      ValueState* St = GetState(Pred);
+      const ValueState* St = GetState(Pred);
       St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, size, U->getType()));
         
       MakeNode(Dst, U, Pred, St);
@@ -1788,7 +1795,7 @@
   
   for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) {
     
-    ValueState* St = GetState(*I);
+    const ValueState* St = GetState(*I);
     RVal V1 = GetRVal(St, Ex);
     
     // Perform a load.      
@@ -1855,7 +1862,7 @@
     // which interprets the inline asm and stores proper results in the
     // outputs.
     
-    ValueState* St = GetState(Pred);
+    const ValueState* St = GetState(Pred);
     
     for (AsmStmt::outputs_iterator OI = A->begin_outputs(),
                                    OE = A->end_outputs(); OI != OE; ++OI) {
@@ -1949,7 +1956,7 @@
 // Transfer functions: Binary operators.
 //===----------------------------------------------------------------------===//
 
-bool GRExprEngine::CheckDivideZero(Expr* Ex, ValueState* St,
+bool GRExprEngine::CheckDivideZero(Expr* Ex, const ValueState* St,
                                    NodeTy* Pred, RVal Denom) {
   
   // Divide by undefined? (potentially zero)
@@ -1969,7 +1976,7 @@
   // First, "assume" that the denominator is 0 or undefined.            
   
   bool isFeasibleZero = false;
-  ValueState* ZeroSt =  Assume(St, Denom, false, isFeasibleZero);
+  const ValueState* ZeroSt =  Assume(St, Denom, false, isFeasibleZero);
   
   // Second, "assume" that the denominator cannot be 0.            
   
@@ -2018,7 +2025,7 @@
     
     for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
 
-      ValueState* St = GetState(*I2);
+      const ValueState* St = GetState(*I2);
       RVal RightV = GetRVal(St, RHS);
       BinaryOperator::Opcode Op = B->getOpcode();
       
@@ -2175,8 +2182,8 @@
 // "Assume" logic.
 //===----------------------------------------------------------------------===//
 
-ValueState* GRExprEngine::Assume(ValueState* St, LVal Cond,
-                                 bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::Assume(const ValueState* St, LVal Cond,
+                                       bool Assumption, bool& isFeasible) {
                                              
   St = AssumeAux(St, Cond, Assumption, isFeasible);
   
@@ -2184,8 +2191,8 @@
                     : St;
 }
 
-ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
-                                    bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeAux(const ValueState* St, LVal Cond,
+                                          bool Assumption, bool& isFeasible) {
                                        
   switch (Cond.getSubKind()) {
     default:
@@ -2224,8 +2231,8 @@
   }
 }
 
-ValueState* GRExprEngine::Assume(ValueState* St, NonLVal Cond,
-                                 bool Assumption, bool& isFeasible) {
+const ValueState* GRExprEngine::Assume(const ValueState* St, NonLVal Cond,
+                                       bool Assumption, bool& isFeasible) {
 
   St = AssumeAux(St, Cond, Assumption, isFeasible);
 
@@ -2233,8 +2240,8 @@
                     : St;
 }
 
-ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond,
-                                    bool Assumption, bool& isFeasible) {  
+const ValueState* GRExprEngine::AssumeAux(const ValueState* St, NonLVal Cond,
+                                          bool Assumption, bool& isFeasible) {  
   switch (Cond.getSubKind()) {
     default:
       assert (false && "'Assume' not implemented for this NonLVal.");
@@ -2272,9 +2279,9 @@
   }
 }
 
-ValueState*
-GRExprEngine::AssumeSymNE(ValueState* St, SymbolID sym,
-                         const llvm::APSInt& V, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeSymNE(const ValueState* St,
+                                            SymbolID sym, const llvm::APSInt& V,
+                                            bool& isFeasible) {
   
   // First, determine if sym == X, where X != V.
   if (const llvm::APSInt* X = St->getSymVal(sym)) {
@@ -2295,9 +2302,8 @@
   return StateMgr.AddNE(St, sym, V);
 }
 
-ValueState*
-GRExprEngine::AssumeSymEQ(ValueState* St, SymbolID sym,
-                         const llvm::APSInt& V, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeSymEQ(const ValueState* St, SymbolID sym,
+                                            const llvm::APSInt& V, bool& isFeasible) {
   
   // First, determine if sym == X, where X != V.
   if (const llvm::APSInt* X = St->getSymVal(sym)) {
@@ -2318,9 +2324,10 @@
   return StateMgr.AddEQ(St, sym, V);
 }
 
-ValueState*
-GRExprEngine::AssumeSymInt(ValueState* St, bool Assumption,
-                          const SymIntConstraint& C, bool& isFeasible) {
+const ValueState* GRExprEngine::AssumeSymInt(const ValueState* St,
+                                             bool Assumption,
+                                             const SymIntConstraint& C,
+                                             bool& isFeasible) {
   
   switch (C.getOpcode()) {
     default:
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index 926bcc8..7d7afe3 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -265,9 +265,9 @@
 
 struct VISIBILITY_HIDDEN FindUndefExpr {
   ValueStateManager& VM;
-  ValueState* St;
+  const ValueState* St;
   
-  FindUndefExpr(ValueStateManager& V, ValueState* S) : VM(V), St(S) {}
+  FindUndefExpr(ValueStateManager& V, const ValueState* S) : VM(V), St(S) {}
   
   Expr* FindExpr(Expr* Ex) {
     
@@ -319,7 +319,7 @@
     ExplodedNode<ValueState> *N = *(*I)->pred_begin();
     ProgramPoint P = N->getLocation();
 
-    ValueState* St = (*I)->getState();
+    const ValueState* St = (*I)->getState();
     
     if (PostStmt* PS = dyn_cast<PostStmt>(&P))
       if (PS->getStmt() == Ex)
@@ -652,7 +652,7 @@
                             ExplodedNode<ValueState>* Pred) {
   
   ValueStateManager& StateMgr = Eng.getStateManager();
-  ValueState* St = Builder.GetState(Pred);
+  const ValueState* St = Builder.GetState(Pred);
   
   // Invalidate all arguments passed in by reference (LVals).
 
@@ -700,7 +700,7 @@
   // We just invalidate all arguments passed in by references.
   
   ValueStateManager& StateMgr = Eng.getStateManager();
-  ValueState* St = Builder.GetState(Pred);
+  const ValueState* St = Builder.GetState(Pred);
   
   for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
        I != E; ++I) {
diff --git a/lib/Analysis/GRTransferFuncs.cpp b/lib/Analysis/GRTransferFuncs.cpp
index 9c96e3d..a31f8aa 100644
--- a/lib/Analysis/GRTransferFuncs.cpp
+++ b/lib/Analysis/GRTransferFuncs.cpp
@@ -23,7 +23,7 @@
                                 GRExprEngine& Eng,
                                 GRStmtNodeBuilder<ValueState>& Builder,
                                 Expr* E, ExplodedNode<ValueState>* Pred,
-                                ValueState* St, RVal TargetLV, RVal Val) {
+                                const ValueState* St, RVal TargetLV, RVal Val) {
   
   // This code basically matches the "safety-net" logic of GRExprEngine:
   //  bind Val to TargetLV, and create a new node.  We replicate it here
diff --git a/lib/Analysis/ValueState.cpp b/lib/Analysis/ValueState.cpp
index cc77edc..72ff498 100644
--- a/lib/Analysis/ValueState.cpp
+++ b/lib/Analysis/ValueState.cpp
@@ -30,8 +30,8 @@
   return T ? *T : NULL;  
 }
 
-ValueState*
-ValueStateManager::RemoveDeadBindings(ValueState* St, Stmt* Loc,
+const ValueState*
+ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc,
                                       const LiveVariables& Liveness,
                                       DeadSymbolsTy& DeadSymbols) {  
   
@@ -126,7 +126,7 @@
   
   for (ValueState::vb_iterator I = St->vb_begin(), E = St->vb_end(); I!=E ; ++I)
     if (!Marked.count(I.getKey())) {
-      NewSt.VarBindings = Remove(NewSt, I.getKey());
+      NewSt.St = StMgr->Remove(NewSt.St, lval::DeclVal(I.getKey()));
       
       RVal X = I.getData();
       
@@ -160,77 +160,35 @@
   return getPersistentState(NewSt);
 }
 
-
-RVal ValueStateManager::GetRVal(ValueState* St, LVal LV, QualType T) {
+const ValueState* ValueStateManager::SetRVal(const ValueState* St, LVal LV,
+                                             RVal V) {
   
-  if (isa<UnknownVal>(LV))
-    return UnknownVal();
+  Store OldStore = St->getStore();
+  Store NewStore = StMgr->SetRVal(OldStore, LV, V);
   
-  assert (!isa<UndefinedVal>(LV));
+  if (NewStore == OldStore)
+    return St;
   
-  switch (LV.getSubKind()) {
-    case lval::DeclValKind: {
-      ValueState::VarBindingsTy::data_type* T =
-        St->VarBindings.lookup(cast<lval::DeclVal>(LV).getDecl());
-      
-      return T ? *T : UnknownVal();
-    }
-     
-      // FIXME: We should limit how far a "ContentsOf" will go...
-      
-    case lval::SymbolValKind: {
-      
-      
-      // FIXME: This is a broken representation of memory, and is prone
-      //  to crashing the analyzer when addresses to symbolic values are
-      //  passed through casts.  We need a better representation of symbolic
-      //  memory (or just memory in general); probably we should do this
-      //  as a plugin class (similar to GRTransferFuncs).
-      
-#if 0      
-      const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
-      assert (T.getTypePtr());
-      
-      // Punt on "symbolic" function pointers.
-      if (T->isFunctionType())
-        return UnknownVal();      
-
-      if (T->isPointerType())
-        return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
-      else
-        return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
-#endif
-      
-      return UnknownVal();
-    }
-    
-    case lval::ConcreteIntKind:
-      // Some clients may call GetRVal with such an option simply because
-      // they are doing a quick scan through their LVals (potentially to
-      // invalidate their bindings).  Just return Undefined.
-      return UndefinedVal();
-      
-    case lval::ArrayOffsetKind:
-    case lval::FieldOffsetKind:
-      return UnknownVal();
-      
-    case lval::FuncValKind:
-      return LV;
-      
-    case lval::StringLiteralValKind:
-      // FIXME: Implement better support for fetching characters from strings.
-      return UnknownVal();
-      
-    default:
-      assert (false && "Invalid LVal.");
-      break;
-  }
-  
-  return UnknownVal();
+  ValueState NewSt = *St;
+  NewSt.St = NewStore;
+  return getPersistentState(NewSt);    
 }
 
-ValueState* ValueStateManager::AddNE(ValueState* St, SymbolID sym,
-                                     const llvm::APSInt& V) {
+const ValueState* ValueStateManager::Unbind(const ValueState* St, LVal LV) {
+  Store OldStore = St->getStore();
+  Store NewStore = StMgr->Remove(OldStore, LV);
+  
+  if (NewStore == OldStore)
+    return St;
+  
+  ValueState NewSt = *St;
+  NewSt.St = NewStore;
+  return getPersistentState(NewSt);    
+}
+
+
+const ValueState* ValueStateManager::AddNE(const ValueState* St, SymbolID sym,
+                                           const llvm::APSInt& V) {
 
   // First, retrieve the NE-set associated with the given symbol.
   ValueState::ConstNotEqTy::data_type* T = St->ConstNotEq.lookup(sym);  
@@ -247,8 +205,8 @@
   return getPersistentState(NewSt);
 }
 
-ValueState* ValueStateManager::AddEQ(ValueState* St, SymbolID sym,
-                                     const llvm::APSInt& V) {
+const ValueState* ValueStateManager::AddEQ(const ValueState* St, SymbolID sym,
+                                           const llvm::APSInt& V) {
 
   // Create a new state with the old binding replaced.
   ValueState NewSt = *St;
@@ -258,66 +216,17 @@
   return getPersistentState(NewSt);
 }
 
+const ValueState* ValueStateManager::getInitialState() {
 
-ValueState* ValueStateManager::SetRVal(ValueState* St, LVal LV, RVal V) {
-  
-  switch (LV.getSubKind()) {
-      
-    case lval::DeclValKind:        
-      return V.isUnknown()
-             ? UnbindVar(St, cast<lval::DeclVal>(LV).getDecl())
-             : BindVar(St, cast<lval::DeclVal>(LV).getDecl(), V);
-      
-    default:
-      assert ("SetRVal for given LVal type not yet implemented.");
-      return St;
-  }
-}
-
-void ValueStateManager::BindVar(ValueState& StImpl, VarDecl* D, RVal V) {
-  StImpl.VarBindings = VBFactory.Add(StImpl.VarBindings, D, V);
-}
-
-ValueState* ValueStateManager::BindVar(ValueState* St, VarDecl* D, RVal V) {
-  
-  // Create a new state with the old binding removed.
-  ValueState NewSt = *St;  
-  NewSt.VarBindings = VBFactory.Add(NewSt.VarBindings, D, V);
-  
-  // Get the persistent copy.
-  return getPersistentState(NewSt);
-}
-
-ValueState* ValueStateManager::UnbindVar(ValueState* St, VarDecl* D) {
-  
-  // Create a new state with the old binding removed.
-  ValueState NewSt = *St;
-  NewSt.VarBindings = VBFactory.Remove(NewSt.VarBindings, D);
-  
-  // Get the persistent copy.
-  return getPersistentState(NewSt);
-}
-
-void ValueStateManager::Unbind(ValueState& StImpl, LVal LV) {
-  
-  if (isa<lval::DeclVal>(LV))
-    StImpl.VarBindings = VBFactory.Remove(StImpl.VarBindings,
-                                          cast<lval::DeclVal>(LV).getDecl());
-  
-}
-
-ValueState* ValueStateManager::getInitialState() {
-
-  // Create a state with empty variable bindings.
   ValueState StateImpl(EnvMgr.getInitialEnvironment(),
-                       VBFactory.GetEmptyMap(),
+                       StMgr->getInitialStore(),
                        CNEFactory.GetEmptyMap(),
                        CEFactory.GetEmptyMap());
   
   return getPersistentState(StateImpl);
 }
 
-ValueState* ValueStateManager::getPersistentState(ValueState& State) {
+const ValueState* ValueStateManager::getPersistentState(ValueState& State) {
   
   llvm::FoldingSetNodeID ID;
   State.Profile(ID);