This is the first step to build a better evaluation model for GRExprEngine.  A
new VisitLValue method is added to replace the old VisitLVal. The semantics
model becomes more explicit to separate rvalue evaluation from lvalue
evaluation.  


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57627 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 47e2905..f97f8b2 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -42,9 +42,12 @@
 
   virtual MemRegionManager& getRegionManager() { return MRMgr; }
 
+  // FIXME: Investigate what is using this. This method should be removed.
   virtual LVal getLVal(const VarDecl* VD) {
     return lval::MemRegionVal(MRMgr.getVarRegion(VD));
   }
+
+  virtual RVal getLValue(const GRState* St, const Expr* Ex);
   
   virtual Store
   RemoveDeadBindings(Store store, Stmt* Loc, const LiveVariables& Live,
@@ -73,6 +76,35 @@
   return new BasicStoreManager(StMgr);
 }
 
+// FIXME: replace ArrayOffset and FieldOffset with some region value.
+RVal BasicStoreManager::getLValue(const GRState* St, const Expr* Ex) {
+  if (const DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(Ex)) {
+    const VarDecl* VD = cast<VarDecl>(DRE->getDecl());
+    QualType T = VD->getType();
+
+    // Array and struct variable have no lvalue.
+    assert(!T->isArrayType());
+
+    return lval::MemRegionVal(MRMgr.getVarRegion(VD));
+
+  } else if (const ArraySubscriptExpr* A = dyn_cast<ArraySubscriptExpr>(Ex)) {
+    const Expr* Base = A->getBase()->IgnoreParens();
+    const Expr* Idx  = A->getIdx()->IgnoreParens();
+    RVal BaseV = StateMgr.GetRVal(St, Base);
+    RVal IdxV = StateMgr.GetRVal(St, Idx);
+    return lval::ArrayOffset::Make(StateMgr.getBasicVals(), BaseV, IdxV);
+
+  } else if (const MemberExpr* M = dyn_cast<MemberExpr>(Ex)) {
+    Expr* Base = M->getBase()->IgnoreParens();
+    RVal BaseV = StateMgr.GetRVal(St, Base);
+    return lval::FieldOffset::Make(StateMgr.getBasicVals(), BaseV, 
+                                   M->getMemberDecl());
+  } else {
+    Ex->dump();
+    assert(0);
+  }
+}
+
 RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
   
   if (isa<UnknownVal>(LV))