[analyzer] NodeBuilder Refactoring: Subclass BranchNodeBuilder from NodeBuilder.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142444 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index b860b34..8663893 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -61,9 +61,9 @@
   const ProgramState *state = Builder.getState();
   SVal X = state->getSVal(Condition);
   if (X.isUndef()) {
-    ExplodedNode *N = Builder.generateNode(Condition, state);
+    // Generate a sink node.
+    ExplodedNode *N = Builder.generateNode(Condition, state, 0, true);
     if (N) {
-      N->markAsSink();
       if (!BT)
         BT.reset(
                new BuiltinBug("Branch condition evaluates to a garbage value"));
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 5f2f4ea..0078922 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -417,14 +417,15 @@
 void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term, 
                                 const CFGBlock * B, ExplodedNode *Pred) {
   assert(B->succ_size() == 2);
-  BranchNodeBuilder Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
-                            Pred, this);
-  SubEng.processBranch(Cond, Term, Builder);
+  NodeBuilderContext Ctx(*this, Pred, B);
+  SubEng.processBranch(Cond, Term, Ctx,
+                       *(B->succ_begin()), *(B->succ_begin()+1));
 }
 
 void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, 
                                   ExplodedNode *Pred) {
-  assert (!B->empty());
+  assert(B);
+  assert(!B->empty());
 
   if (StmtIdx == B->size())
     HandleBlockExit(B, Pred);
@@ -454,6 +455,13 @@
   if (IsNew) WList->enqueue(Node);
 }
 
+void CoreEngine::enqueue(NodeBuilder &NB) {
+  for (NodeBuilder::iterator I = NB.results_begin(),
+                               E = NB.results_end(); I != E; ++I) {
+    WList->enqueue(*I);
+  }
+}
+
 ExplodedNode *
 GenericNodeBuilderImpl::generateNodeImpl(const ProgramState *state,
                                          ExplodedNode *pred,
@@ -475,23 +483,17 @@
   return 0;
 }
 
-NodeBuilder::NodeBuilder(CoreEngine& e, ExplodedNode *N)
-  : Eng(e), Pred(N), Finalized(false) {
-  assert(!N->isSink());
-  Deferred.insert(N);
-}
-
 ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
-                                            const ProgramState *State,
-                                            ExplodedNode *Pred,
-                                            bool MarkAsSink) {
+                                              const ProgramState *State,
+                                              ExplodedNode *FromN,
+                                              bool MarkAsSink) {
   assert(Finalized == false &&
          "We cannot create new nodes after the results have been finalized.");
-                                              
+
   bool IsNew;
-  ExplodedNode *N = Eng.G->getNode(Loc, State, &IsNew);
-  N->addPredecessor(Pred, *Eng.G);
-  Deferred.erase(Pred);
+  ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew);
+  N->addPredecessor(FromN, *C.Eng.G);
+  Deferred.erase(FromN);
 
   if (MarkAsSink)
     N->markAsSink();
@@ -601,61 +603,41 @@
 }
 
 // This function generate a new ExplodedNode but not a new branch(block edge).
+// Creates a transition from the Builder's top predecessor.
 ExplodedNode *BranchNodeBuilder::generateNode(const Stmt *Condition,
                                               const ProgramState *State,
-                                              const ProgramPointTag *Tag) {
-  bool IsNew;
-  ExplodedNode *Succ 
-    = Eng.G->getNode(PostCondition(Condition, Pred->getLocationContext(), Tag),
-                     State, &IsNew);
-  
-  Succ->addPredecessor(Pred, *Eng.G);
-  
-  Pred = Succ;
-  
-  if (IsNew) 
-    return Succ;
-  
-  return NULL;
+                                              const ProgramPointTag *Tag,
+                                              bool MarkAsSink) {
+  ProgramPoint PP = PostCondition(Condition, C.Pred->getLocationContext(), Tag);
+  ExplodedNode *N = generateNodeImpl(PP, State, C.Pred, MarkAsSink);
+  assert(N);
+  // TODO: This needs to go - we should not change Pred!!!
+  C.Pred = N;
+  return N;
 }
 
 ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
-                                              bool branch) {
+                                              bool branch,
+                                              ExplodedNode *NodePred) {
 
   // If the branch has been marked infeasible we should not generate a node.
   if (!isFeasible(branch))
     return NULL;
 
-  bool IsNew;
-
-  ExplodedNode *Succ =
-    Eng.G->getNode(BlockEdge(Src,branch ? DstT:DstF,Pred->getLocationContext()),
-                   State, &IsNew);
-
-  Succ->addPredecessor(Pred, *Eng.G);
+  if (!NodePred)
+    NodePred = C.Pred;
+  ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
+                               NodePred->getLocationContext());
+  ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
 
   if (branch)
     GeneratedTrue = true;
   else
     GeneratedFalse = true;
 
-  if (IsNew) {
-    Deferred.push_back(Succ);
-    return Succ;
-  }
-
-  return NULL;
+  return Succ;
 }
 
-BranchNodeBuilder::~BranchNodeBuilder() {
-  if (!GeneratedTrue) generateNode(Pred->State, true);
-  if (!GeneratedFalse) generateNode(Pred->State, false);
-
-  for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
-    if (!(*I)->isSink()) Eng.WList->enqueue(*I);
-}
-
-
 ExplodedNode*
 IndirectGotoNodeBuilder::generateNode(const iterator &I,
                                       const ProgramState *St,
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index ac9cf0b..cc170bc 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -940,11 +940,17 @@
 }
 
 void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
-                                 BranchNodeBuilder& builder) {
+                               NodeBuilderContext& BldCtx,
+                               const CFGBlock *DstT,
+                               const CFGBlock *DstF) {
+
+  BranchNodeBuilder builder(BldCtx, DstT, DstF);
 
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) {
-    builder.markInfeasible(false);
+    BranchNodeBuilder NullCondBldr(BldCtx, DstT, DstF);
+    NullCondBldr.markInfeasible(false);
+    Engine.enqueue(NullCondBldr);
     return;
   }
 
@@ -952,11 +958,9 @@
                                 Condition->getLocStart(),
                                 "Error evaluating branch");
 
-  getCheckerManager().runCheckersForBranchCondition(Condition, builder, *this);
-
-  // If the branch condition is undefined, return;
-  if (!builder.isFeasible(true) && !builder.isFeasible(false))
-    return;
+  //TODO: This should take the NodeBuiolder.
+  getCheckerManager().runCheckersForBranchCondition(Condition, builder,
+                                                    *this);
 
   const ProgramState *PrevState = builder.getState();
   SVal X = PrevState->getSVal(Condition);
@@ -982,6 +986,8 @@
     if (X.isUnknownOrUndef()) {
       builder.generateNode(MarkBranch(PrevState, Term, true), true);
       builder.generateNode(MarkBranch(PrevState, Term, false), false);
+      // Enqueue the results into the work list.
+      Engine.enqueue(builder);
       return;
     }
   }
@@ -1003,6 +1009,9 @@
     else
       builder.markInfeasible(false);
   }
+
+  // Enqueue the results into the work list.
+  Engine.enqueue(builder);
 }
 
 /// processIndirectGoto - Called by CoreEngine.  Used to generate successor