Implemented casts for ConcreteInt and ConcreteIntLValue.
Implemented '==' and '!=' for ConcreteIntLValue.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46630 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp
index 2229e47..895f0e1 100644
--- a/Analysis/GRConstants.cpp
+++ b/Analysis/GRConstants.cpp
@@ -778,7 +778,22 @@
 
 GRConstants::StateTy GRConstants::Assume(StateTy St, LValue Cond, bool Assumption, 
                                          bool& isFeasible) {    
-  return St;
+  
+  switch (Cond.getSubKind()) {
+    default:
+      assert (false && "'Assume' not implemented for this NonLValue.");
+      return St;
+      
+    case LValueDeclKind:
+      isFeasible = Assumption;
+      return St;
+      
+    case ConcreteIntLValueKind: {
+      bool b = cast<ConcreteIntLValue>(Cond).getValue() != 0;
+      isFeasible = b ? Assumption : !Assumption;      
+      return St;
+    }
+  }
 }
 
 GRConstants::StateTy GRConstants::Assume(StateTy St, NonLValue Cond, bool Assumption, 
diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp
index 4008e76..f41051e 100644
--- a/Analysis/RValues.cpp
+++ b/Analysis/RValues.cpp
@@ -79,20 +79,56 @@
   return getValue(V);
 }
 
+//===----------------------------------------------------------------------===//
+// Transfer function for Casts.
+//===----------------------------------------------------------------------===//
+
+RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+  switch (getBaseKind()) {
+    default: assert(false && "Invalid RValue."); break;
+    case LValueKind: return cast<LValue>(this)->Cast(ValMgr, CastExpr);
+    case NonLValueKind: return cast<NonLValue>(this)->Cast(ValMgr, CastExpr);      
+    case UninitializedKind: case InvalidKind: break;
+  }
+  
+  return *this;
+}
+ 
+RValue LValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+  if (CastExpr->getType()->isPointerType())
+    return *this;
+  
+  assert (CastExpr->getType()->isIntegerType());
+
+  if (!isa<ConcreteIntLValue>(*this))
+    return InvalidValue();
+  
+  APSInt V = cast<ConcreteIntLValue>(this)->getValue();
+  QualType T = CastExpr->getType();
+  V.setIsUnsigned(T->isUnsignedIntegerType());
+  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+  return ConcreteInt(ValMgr.getValue(V));
+}
+
+RValue NonLValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
+  if (!isa<ConcreteInt>(this))
+    return InvalidValue();
+    
+  APSInt V = cast<ConcreteInt>(this)->getValue();
+  QualType T = CastExpr->getType();
+  V.setIsUnsigned(T->isUnsignedIntegerType());
+  V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+  
+  if (CastExpr->getType()->isPointerType())
+    return ConcreteIntLValue(ValMgr.getValue(V));
+  else
+    return ConcreteInt(ValMgr.getValue(V));
+}
 
 //===----------------------------------------------------------------------===//
 // Transfer function dispatch for Non-LValues.
 //===----------------------------------------------------------------------===//
 
-RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
-  switch (getSubKind()) {
-    case ConcreteIntKind:
-      return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
-    default:
-      return InvalidValue();
-  }
-}
-
 NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
   switch (getSubKind()) {
     case ConcreteIntKind:
@@ -162,6 +198,13 @@
     default:
       assert(false && "EQ not implemented for this LValue.");
       return cast<NonLValue>(InvalidValue());
+    
+    case ConcreteIntLValueKind: {
+      bool b = cast<ConcreteIntLValue>(this)->getValue() ==
+               cast<ConcreteIntLValue>(RHS).getValue();
+            
+      return NonLValue::GetIntTruthValue(ValMgr, b);
+    }
       
     case LValueDeclKind: {
       bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
@@ -179,6 +222,13 @@
       assert(false && "EQ not implemented for this LValue.");
       return cast<NonLValue>(InvalidValue());
       
+    case ConcreteIntLValueKind: {
+      bool b = cast<ConcreteIntLValue>(this)->getValue() !=
+               cast<ConcreteIntLValue>(RHS).getValue();
+      
+      return NonLValue::GetIntTruthValue(ValMgr, b);
+    }  
+      
     case LValueDeclKind: {
       bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
       return NonLValue::GetIntTruthValue(ValMgr, b);
@@ -255,7 +305,12 @@
 }
 
 void LValue::print(std::ostream& Out) const {
-  switch (getSubKind()) {  
+  switch (getSubKind()) {        
+    case ConcreteIntLValueKind:
+      Out << cast<ConcreteIntLValue>(this)->getValue().toString() 
+          << " (LValue)";
+      break;
+      
     case SymbolicLValueKind:
       Out << '$' << cast<SymbolicLValue>(this)->getSymbolID();
       break;
diff --git a/Analysis/RValues.h b/Analysis/RValues.h
index 989c60b..c5ad8a5 100644
--- a/Analysis/RValues.h
+++ b/Analysis/RValues.h
@@ -187,6 +187,8 @@
 public:
   void print(std::ostream& Out) const;
   
+  RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
+
   // Arithmetic operators.
   NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
   NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
@@ -199,6 +201,7 @@
   NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const;
   NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const;
   
+  
   // Utility methods to create NonLValues.
   static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
                             SourceLocation Loc = SourceLocation());
@@ -223,6 +226,8 @@
 public:
   void print(std::ostream& Out) const;
   
+  RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
+
   // Equality operators.
   NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
   NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
@@ -237,8 +242,7 @@
 //  Subclasses of NonLValue.
 //==------------------------------------------------------------------------==// 
 
-enum NonLValueKind { SymbolicNonLValueKind, ConcreteIntKind,
-NumNonLValueKind };
+enum NonLValueKind { SymbolicNonLValueKind, ConcreteIntKind, NumNonLValueKind };
 
 class SymbolicNonLValue : public NonLValue {
 public:
@@ -326,9 +330,9 @@
 //  Subclasses of LValue.
 //==------------------------------------------------------------------------==// 
 
-enum LValueKind { SymbolicLValueKind, LValueDeclKind,
-ConcreteIntLValueKind, NumLValueKind };
-
+enum LValueKind { SymbolicLValueKind, LValueDeclKind, ConcreteIntLValueKind,
+                  NumLValueKind };
+  
 class SymbolicLValue : public LValue {
 public:
   SymbolicLValue(unsigned SymID)