Introduce a new concept to the static analyzer: SValuator.

GRTransferFuncs had the conflated role of both constructing SVals (symbolic
expressions) as well as handling checker-specific logic. Now SValuator has the
role of constructing SVals from expressions and GRTransferFuncs just handles
checker-specific logic. The motivation is by separating these two concepts we
will be able to much more easily create richer constraint-generating logic
without coupling it to the main checker transfer function logic.

We now have one implementation of SValuator: SimpleSValuator.

SimpleSValuator is essentially the SVal-related logic that was in GRSimpleVals
(which is removed in this patch). This includes the logic for EvalBinOp,
EvalCast, etc. Because SValuator has a narrower role than the old
GRTransferFuncs, the interfaces are much simpler, and so is the implementation
of SimpleSValuator compared to GRSimpleVals. I also did a line-by-line review of
SVal-related logic in GRSimpleVals and cleaned it up while moving it over to
SimpleSValuator.

As a consequence of removing GRSimpleVals, there is no longer a
'-checker-simple' option. The '-checker-cfref' did everything that option did
but also ran the retain/release checker. Of course a user may not always wish to
run the retain/release checker, nor do we wish core analysis logic buried in the
checker-specific logic. The next step is to refactor the logic in CFRefCount.cpp
to separate out these pieces into the core analysis engine.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74229 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index d3df92d..779d706 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -15,7 +15,6 @@
 
 #include "clang/Analysis/PathSensitive/GRExprEngine.h"
 #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -126,6 +125,7 @@
     StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
     SymMgr(StateMgr.getSymbolManager()),
     ValMgr(StateMgr.getValueManager()),
+    SVator(clang::CreateSimpleSValuator(ValMgr)), // FIXME: Generalize later.
     CurrentStmt(NULL),
     NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
     RaiseSel(GetNullarySelector("raise", G.getContext())), 
@@ -1296,9 +1296,8 @@
     SVal oldValueVal = stateLoad->getSVal(oldValueExpr);
         
     // Perform the comparison.
-    SVal Cmp = Engine.EvalBinOp(stateLoad,
-                                BinaryOperator::EQ, theValueVal, oldValueVal,
-                                Engine.getContext().IntTy);
+    SVal Cmp = Engine.EvalBinOp(stateLoad, BinaryOperator::EQ, theValueVal,
+                                oldValueVal, Engine.getContext().IntTy);
 
     const GRState *stateEqual = stateLoad->assume(Cmp, true);
     
@@ -2562,7 +2561,7 @@
             
           case UnaryOperator::Minus:
             // FIXME: Do we need to handle promotions?
-            state = state->bindExpr(U, EvalMinus(U, cast<NonLoc>(V)));
+            state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V)));
             break;   
             
           case UnaryOperator::LNot:   
@@ -2571,25 +2570,21 @@
             //
             //  Note: technically we do "E == 0", but this is the same in the
             //    transfer functions as "0 == E".
+            SVal Result;
             
             if (isa<Loc>(V)) {
               Loc X = ValMgr.makeNull();
-              SVal Result = EvalBinOp(state,BinaryOperator::EQ, cast<Loc>(V), X,
-                                      U->getType());
-              state = state->bindExpr(U, Result);
+              Result = EvalBinOp(state, BinaryOperator::EQ, cast<Loc>(V), X,
+                                 U->getType());
             }
             else {
               nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
-#if 0            
-              SVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X);
-              state = SetSVal(state, U, Result);
-#else
-              EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLoc>(V), X, *I,
-                        U->getType());
-              continue;
-#endif
+              Result = EvalBinOp(BinaryOperator::EQ, cast<NonLoc>(V), X,
+                                 U->getType());
             }
             
+            state = state->bindExpr(U, Result);
+            
             break;
         }
         
@@ -2640,8 +2635,8 @@
                                              Builder->getCurrentBlockCount());
         
         // If the value is a location, ++/-- should always preserve
-        // non-nullness.  Check if the original value was non-null, and if so propagate
-        // that constraint.        
+        // non-nullness.  Check if the original value was non-null, and if so
+        // propagate that constraint.        
         if (Loc::IsLocType(U->getType())) {
           SVal Constraint = EvalBinOp(state, BinaryOperator::EQ, V2,
                                       ValMgr.makeZeroVal(U->getType()),
@@ -2907,9 +2902,8 @@
           if (B->isAssignmentOp())
             break;
           
-          // Process non-assignements except commas or short-circuited
-          // logical expressions (LAnd and LOr).
-          
+          // Process non-assignments except commas or short-circuited
+          // logical expressions (LAnd and LOr).          
           SVal Result = EvalBinOp(state, Op, LeftV, RightV, B->getType());
           
           if (Result.isUnknown()) {
@@ -3024,7 +3018,7 @@
         }
       
         // Compute the result of the operation.      
-        SVal Result = EvalCast(EvalBinOp(state, Op, V, RightV, CTy), 
+        SVal Result = EvalCast(EvalBinOp(state, Op, V, RightV, CTy),
                                B->getType());
           
         if (Result.isUndef()) {
@@ -3073,26 +3067,6 @@
 // Transfer-function Helpers.
 //===----------------------------------------------------------------------===//
 
-void GRExprEngine::EvalBinOp(ExplodedNodeSet<GRState>& Dst, Expr* Ex,
-                             BinaryOperator::Opcode Op,
-                             NonLoc L, NonLoc R,
-                             ExplodedNode<GRState>* Pred, QualType T) {
-
-  GRStateSet OStates;
-  EvalBinOp(OStates, GetState(Pred), Ex, Op, L, R, T);
-
-  for (GRStateSet::iterator I=OStates.begin(), E=OStates.end(); I!=E; ++I)
-    MakeNode(Dst, Ex, Pred, *I);
-}
-
-void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* state,
-                             Expr* Ex, BinaryOperator::Opcode Op,
-                             NonLoc L, NonLoc R, QualType T) {
-  
-  GRStateSet::AutoPopulate AP(OStates, state);
-  if (R.isValid()) getTF().EvalBinOpNN(OStates, *this, state, Ex, Op, L, R, T);
-}
-
 SVal GRExprEngine::EvalBinOp(const GRState* state, BinaryOperator::Opcode Op, 
                              SVal L, SVal R, QualType T) {
   
@@ -3104,9 +3078,9 @@
   
   if (isa<Loc>(L)) {
     if (isa<Loc>(R))
-      return getTF().EvalBinOp(*this, Op, cast<Loc>(L), cast<Loc>(R));
+      return SVator->EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
     else
-      return getTF().EvalBinOp(*this, state, Op, cast<Loc>(L), cast<NonLoc>(R));
+      return SVator->EvalBinOpLN(state, Op, cast<Loc>(L), cast<NonLoc>(R), T);
   }
   
   if (isa<Loc>(R)) {
@@ -3116,11 +3090,10 @@
     assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
     
     // Commute the operands.
-    return getTF().EvalBinOp(*this, state, Op, cast<Loc>(R), cast<NonLoc>(L));
+    return SVator->EvalBinOpLN(state, Op, cast<Loc>(R), cast<NonLoc>(L), T);
   }
   else
-    return getTF().DetermEvalBinOpNN(*this, Op, cast<NonLoc>(L),
-                                     cast<NonLoc>(R), T);
+    return SVator->EvalBinOpNN(Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
 }
 
 //===----------------------------------------------------------------------===//