Add code for get the lvalue for string literals. Now we return a StringRegion
for StringLiteral lvalue evaluation, instead of directly returning a
loc::StringLiteralVal by the Environment.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58138 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index e12b9ea..67d919a 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -47,6 +47,7 @@
   }
   
   SVal getLValueVar(const GRState* St, const VarDecl* VD);
+  SVal getLValueString(const GRState* St, const StringLiteral* S);
   SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base);
   SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D);  
   SVal getLValueElement(const GRState* St, SVal Base, SVal Offset);
@@ -88,6 +89,11 @@
 SVal BasicStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) {
   return loc::MemRegionVal(MRMgr.getVarRegion(VD));
 }
+
+SVal BasicStoreManager::getLValueString(const GRState* St, 
+                                        const StringLiteral* S) {
+  return loc::MemRegionVal(MRMgr.getStringRegion(S));
+}
   
 SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
                                       SVal Base) {
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
index a9afa6d..f220ee7 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -42,13 +42,10 @@
         return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
       }
         
-      case Stmt::StringLiteralClass:
-        return Loc::MakeVal(cast<StringLiteral>(E));
-        
-        // Casts where the source and target type are the same
-        // are no-ops.  We blast through these to get the descendant
-        // subexpression that has a value.
-        
+      // Casts where the source and target type are the same
+      // are no-ops.  We blast through these to get the descendant
+      // subexpression that has a value.
+       
       case Stmt::ImplicitCastExprClass:
       case Stmt::ExplicitCastExprClass: {
         CastExpr* C = cast<CastExpr>(E);
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index ae1db6c..7d60dec 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -444,6 +444,13 @@
       //  have "locations" in the sense that we can take their address.
       Dst.Add(Pred);
       return;
+
+    case Stmt::StringLiteralClass: {
+      const GRState* St = GetState(Pred);
+      SVal V = StateMgr.GetLValue(St, cast<StringLiteral>(Ex));
+      MakeNode(Dst, Ex, Pred, SetSVal(St, Ex, V));
+      return;
+    }
       
     default:
       // Arbitrary subexpressions can return aggregate temporaries that
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index e2b6b13..eabe462 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -46,6 +46,8 @@
     return Retrieve(St, loc::MemRegionVal(R));
   }
 
+  SVal getLValueString(const GRState* St, const StringLiteral* S);
+
   SVal getLValueVar(const GRState* St, const VarDecl* VD);
   
   SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base);
@@ -110,6 +112,11 @@
   return new RegionStoreManager(StMgr);
 }
 
+SVal RegionStoreManager::getLValueString(const GRState* St, 
+                                         const StringLiteral* S) {
+  return loc::MemRegionVal(MRMgr.getStringRegion(S));
+}
+
 SVal RegionStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) {
   return loc::MemRegionVal(MRMgr.getVarRegion(VD));
 }
@@ -188,6 +195,15 @@
 
 SVal RegionStoreManager::ArrayToPointer(SVal Array) {
   const MemRegion* ArrayR = cast<loc::MemRegionVal>(&Array)->getRegion();
+  BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+
+  if (const StringRegion* StringR = dyn_cast<StringRegion>(ArrayR)) {
+    // FIXME: Find a better way to get bit width.
+    nonloc::ConcreteInt Idx(BasicVals.getValue(0, 32, false));
+    ElementRegion* ER = MRMgr.getElementRegion(Idx, ArrayR);
+    
+    return loc::MemRegionVal(ER);                    
+  }
 
   const Decl* D = cast<DeclRegion>(ArrayR)->getDecl();
 
@@ -201,12 +217,9 @@
 
   if (const ConstantArrayType* CAT = 
       dyn_cast<ConstantArrayType>(ArrayTy.getTypePtr())) {
-
-    BasicValueFactory& BasicVals = StateMgr.getBasicVals();
     
     nonloc::ConcreteInt Idx(BasicVals.getValue(0, CAT->getSize().getBitWidth(),
                                                false));
-
     ElementRegion* ER = MRMgr.getElementRegion(Idx, ArrayR);
     
     return loc::MemRegionVal(ER);