[analyzer] Make NodeBuilder and Pred node loosely coupled

NodeBuilder should not assume it's dealing with a single predecessor. Remove predecessor getters. Modify the BranchNodeBuilder to not be responsible for doing auto-transitions (which depend on a predecessor).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142453 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 451fa91..d030469 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -50,26 +50,26 @@
 
 public:
   void checkBranchCondition(const Stmt *Condition, NodeBuilder &Builder,
-                            ExprEngine &Eng) const;
+                            ExplodedNode *Pred, ExprEngine &Eng) const;
 };
 
 }
 
 void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
                                               NodeBuilder &Builder,
+                                              ExplodedNode *Pred,
                                               ExprEngine &Eng) const {
-  const ProgramState *state = Builder.getState();
+  const ProgramState *state = Pred->getState();
   SVal X = state->getSVal(Condition);
   if (X.isUndef()) {
     // TODO: The PP will be generated with the correct tag by the CheckerManager
     // after we migrate the callback to CheckerContext.
     const ProgramPointTag *Tag = 0;
-    ProgramPoint PP = PostCondition(Condition,
-                        Builder.getPredecessor()->getLocationContext(), Tag);
+    ProgramPoint PP = PostCondition(Condition, Pred->getLocationContext(), Tag);
     // Generate a sink node, which implicitly marks both outgoing branches as
     // infeasible.
     ExplodedNode *N = Builder.generateNode(PP, state,
-                                           Builder.getPredecessor(), true);
+                                           Pred, true);
     if (N) {
       if (!BT)
         BT.reset(
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index d47033a..aa6a51e 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -298,10 +298,11 @@
 /// \brief Run checkers for branch condition.
 void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
                                                    NodeBuilder &B,
+                                                   ExplodedNode *Pred,
                                                    ExprEngine &Eng) {
   for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
     CheckBranchConditionFunc fn = BranchConditionCheckers[i];
-    fn(condition, B, Eng);
+    fn(condition, B, Pred, Eng);
   }
 }
 
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 0a30867..a40a0dc 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -316,7 +316,7 @@
   if (CFGElement E = L.getFirstElement()) {
     NodeBuilderContext Ctx(*this, L.getBlock());
     StmtNodeBuilder Builder(Pred, 0, Ctx);
-    SubEng.processCFGElement(E, Builder);
+    SubEng.processCFGElement(E, Builder, Pred);
   }
   else
     HandleBlockExit(L.getBlock(), Pred);
@@ -433,7 +433,7 @@
   else {
     NodeBuilderContext Ctx(*this, B);
     StmtNodeBuilder Builder(Pred, StmtIdx, Ctx);
-    SubEng.processCFGElement((*B)[StmtIdx], Builder);
+    SubEng.processCFGElement((*B)[StmtIdx], Builder, Pred);
   }
 }
 
@@ -489,6 +489,8 @@
                                             const ProgramState *State,
                                             ExplodedNode *FromN,
                                             bool MarkAsSink) {
+  HasGeneratedNodes = true;
+
   bool IsNew;
   ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew);
   N->addPredecessor(FromN, *C.Eng.G);
@@ -567,9 +569,6 @@
 ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
                                               bool branch,
                                               ExplodedNode *NodePred) {
-  assert(Finalized == false &&
-         "We cannot create new nodes after the results have been finalized.");
-
   // If the branch has been marked infeasible we should not generate a node.
   if (!isFeasible(branch))
     return NULL;
@@ -579,12 +578,6 @@
   ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
                                NodePred->getLocationContext());
   ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
-
-  if (branch)
-    GeneratedTrue = true;
-  else
-    GeneratedFalse = true;
-
   return Succ;
 }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 2cce041..19b1a2f 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -196,26 +196,29 @@
 }
 
 void ExprEngine::processCFGElement(const CFGElement E, 
-                                  StmtNodeBuilder& builder) {
+                                  StmtNodeBuilder& Bldr,
+                                  ExplodedNode *Pred) {
   switch (E.getKind()) {
     case CFGElement::Invalid:
       llvm_unreachable("Unexpected CFGElement kind.");
     case CFGElement::Statement:
-      ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), builder);
+      ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Bldr, Pred);
       return;
     case CFGElement::Initializer:
-      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), builder);
+      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(),
+                         Bldr, Pred);
       return;
     case CFGElement::AutomaticObjectDtor:
     case CFGElement::BaseDtor:
     case CFGElement::MemberDtor:
     case CFGElement::TemporaryDtor:
-      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), builder);
+      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Bldr, Pred);
       return;
   }
 }
 
-void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder) {
+void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder,
+                             ExplodedNode *Pred) {
   // TODO: Use RAII to remove the unnecessary, tagged nodes.
   //RegisterCreatedNodes registerCreatedNodes(getGraph());
 
@@ -232,7 +235,7 @@
   // A tag to track convenience transitions, which can be removed at cleanup.
   static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
   Builder = &builder;
-  EntryNode = builder.getPredecessor();
+  EntryNode = Pred;
 
   const ProgramState *EntryState = EntryNode->getState();
   CleanedState = EntryState;
@@ -320,12 +323,10 @@
 }
 
 void ExprEngine::ProcessInitializer(const CFGInitializer Init,
-                                    StmtNodeBuilder &builder) {
+                                    StmtNodeBuilder &builder,
+                                    ExplodedNode *pred) {
   // We don't set EntryNode and currentStmt. And we don't clean up state.
   const CXXCtorInitializer *BMI = Init.getInitializer();
-
-  ExplodedNode *pred = builder.getPredecessor();
-
   const StackFrameContext *stackFrame = cast<StackFrameContext>(pred->getLocationContext());
   const CXXConstructorDecl *decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
   const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame);
@@ -373,12 +374,13 @@
 }
 
 void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
-                                       StmtNodeBuilder &builder) {
+                                       StmtNodeBuilder &builder,
+                                       ExplodedNode *Pred) {
   Builder = &builder;
 
   switch (D.getKind()) {
   case CFGElement::AutomaticObjectDtor:
-    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), builder);
+    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), builder, Pred);
     break;
   case CFGElement::BaseDtor:
     ProcessBaseDtor(cast<CFGBaseDtor>(D), builder);
@@ -395,8 +397,8 @@
 }
 
 void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor dtor,
-                                           StmtNodeBuilder &builder) {
-  ExplodedNode *pred = builder.getPredecessor();
+                                         StmtNodeBuilder &builder,
+                                         ExplodedNode *pred) {
   const ProgramState *state = pred->getState();
   const VarDecl *varDecl = dtor.getVarDecl();
 
@@ -949,6 +951,7 @@
   if (!Condition) {
     BranchNodeBuilder NullCondBldr(Pred, BldCtx, DstT, DstF);
     NullCondBldr.markInfeasible(false);
+    NullCondBldr.generateNode(Pred->getState(), true, Pred);
     Engine.enqueue(NullCondBldr);
     return;
   }
@@ -959,7 +962,7 @@
 
   NodeBuilder CheckerBldr(Pred, BldCtx);
   getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
-                                                    *this);
+                                                    Pred, *this);
 
   for (NodeBuilder::iterator I = CheckerBldr.results_begin(),
                              E = CheckerBldr.results_end(); E != I; ++I) {
@@ -969,7 +972,7 @@
       continue;
 
     BranchNodeBuilder builder(PredI, BldCtx, DstT, DstF);
-    const ProgramState *PrevState = builder.getState();
+    const ProgramState *PrevState = Pred->getState();
     SVal X = PrevState->getSVal(Condition);
 
     if (X.isUnknownOrUndef()) {
@@ -992,8 +995,8 @@
     }
     // If the condition is still unknown, give up.
     if (X.isUnknownOrUndef()) {
-      builder.generateNode(MarkBranch(PrevState, Term, true), true);
-      builder.generateNode(MarkBranch(PrevState, Term, false), false);
+      builder.generateNode(MarkBranch(PrevState, Term, true), true, PredI);
+      builder.generateNode(MarkBranch(PrevState, Term, false), false, PredI);
       // Enqueue the results into the work list.
       Engine.enqueue(builder);
       continue;
@@ -1004,7 +1007,7 @@
     // Process the true branch.
     if (builder.isFeasible(true)) {
       if (const ProgramState *state = PrevState->assume(V, true))
-        builder.generateNode(MarkBranch(state, Term, true), true);
+        builder.generateNode(MarkBranch(state, Term, true), true, PredI);
       else
         builder.markInfeasible(true);
     }
@@ -1012,7 +1015,7 @@
     // Process the false branch.
     if (builder.isFeasible(false)) {
       if (const ProgramState *state = PrevState->assume(V, false))
-        builder.generateNode(MarkBranch(state, Term, false), false);
+        builder.generateNode(MarkBranch(state, Term, false), false, PredI);
       else
         builder.markInfeasible(false);
     }