Begin major changes to EvalXXX methods in GRTransferFuncs.  Currently some of the methods only return an RVal; we want them to be able to create an arbitrary number of states.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53739 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index fa8009f..e32fd0b 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -121,7 +121,7 @@
     Liveness(L),
     Builder(NULL),
     StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()),
-             G.getAllocator()),
+             G.getAllocator(), G.getCFG()),
     BasicVals(StateMgr.getBasicValueFactory()),
     TF(NULL), // FIXME
     SymMgr(StateMgr.getSymbolManager()),
@@ -242,7 +242,10 @@
   
   Builder = &builder;
   EntryNode = builder.getLastNode();
+  
+  // FIXME: Consolidate.
   CurrentStmt = S;
+  StateMgr.CurrentStmt = S;
   
   // Set up our simple checks.
   if (BatchAuditor)
@@ -296,7 +299,11 @@
   // NULL out these variables to cleanup.
   CleanedState = NULL;
   EntryNode = NULL;
-  CurrentStmt = NULL;
+
+  // FIXME: Consolidate.
+  StateMgr.CurrentStmt = 0;
+  CurrentStmt = 0;
+  
   Builder = NULL;
 }
 
@@ -1802,8 +1809,13 @@
             }
             else {
               nonlval::ConcreteInt X(BasicVals.getValue(0, Ex->getType()));
+#if 0            
               RVal Result = EvalBinOp(BinaryOperator::EQ, cast<NonLVal>(V), X);
               St = SetRVal(St, U, Result);
+#else
+              EvalBinOp(Dst, U, BinaryOperator::EQ, cast<NonLVal>(V), X, *I);
+              continue;
+#endif
             }
             
             break;
@@ -2226,6 +2238,31 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Transfer-function Helpers.
+//===----------------------------------------------------------------------===//
+
+void GRExprEngine::EvalBinOp(ExplodedNodeSet<ValueState>& Dst, Expr* Ex,
+                             BinaryOperator::Opcode Op,
+                             NonLVal L, NonLVal R,
+                             ExplodedNode<ValueState>* Pred) {
+  
+  if (!R.isValid()) {
+    MakeNode(Dst, Ex, Pred, SetRVal(GetState(Pred), Ex, R));
+    return;
+  }
+  
+  assert (Builder && "GRStmtNodeBuilder must be defined.");    
+  unsigned size = Dst.size();
+  SaveOr OldHasGen(Builder->HasGeneratedNode);
+  
+  TF->EvalBinOpNN(Dst, *this, *Builder, Op, Ex, L, R, Pred);
+  
+  if (!Builder->BuildSinks && Dst.size() == size &&
+      !Builder->HasGeneratedNode)
+    MakeNode(Dst, Ex, Pred, GetState(Pred));
+}
+
+//===----------------------------------------------------------------------===//
 // "Assume" logic.
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Analysis/GRTransferFuncs.cpp b/lib/Analysis/GRTransferFuncs.cpp
index a31f8aa..cf32a07 100644
--- a/lib/Analysis/GRTransferFuncs.cpp
+++ b/lib/Analysis/GRTransferFuncs.cpp
@@ -37,3 +37,18 @@
     Builder.MakeNode(Dst, E, Pred,
                 Eng.getStateManager().SetRVal(St, cast<LVal>(TargetLV), Val));    
 }
+
+void GRTransferFuncs::EvalBinOpNN(ExplodedNodeSet<ValueState>& Dst,
+                                  GRExprEngine& Engine,
+                                  GRStmtNodeBuilder<ValueState>& Builder,
+                                  BinaryOperator::Opcode Op,
+                                  Expr* Ex,
+                                  NonLVal L, NonLVal R,
+                                  ExplodedNode<ValueState>* Pred) {
+
+  ValueStateManager& StateMgr = Engine.getStateManager();
+  const ValueState* St = Builder.GetState(Pred);
+  
+  RVal Result = EvalBinOp(Engine, Op, L, R);
+  Builder.MakeNode(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, Result));
+}