[analyzer] Subclassing StmtBuilder from the NodeBuilder

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142451 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 1bbc66c..1d0d716 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -50,7 +50,7 @@
       Location(loc),
       ST(st),
       size(Dst.size()),
-      Ctx(builder.Eng, builder.getBlock()),
+      Ctx(builder.C.Eng, builder.getBlock()),
       NB(pred, Ctx),
       respondsToCallback(respondsToCB) {
     assert(!(ST && ST != Pred->getState()));
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 8433f4c..6e9f54f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -181,7 +181,12 @@
   friend class StmtNodeBuilder;
 
   ExplodedNode *BuilderPred;
+
+// TODO: Context should become protected after refactoring is done.
+public:
   const NodeBuilderContext &C;
+protected:
+
   bool Finalized;
 
   /// \brief The frontier set - a set of nodes which need to be propagated after
@@ -254,6 +259,9 @@
     return Deferred.end();
   }
 
+  /// \brief Return the CFGBlock associated with this builder.
+  const CFGBlock *getBlock() const { return C.Block; }
+
   /// \brief Returns the number of times the current basic block has been
   /// visited on the exploded graph path.
   unsigned getCurrentBlockCount() const {
@@ -272,8 +280,6 @@
 class CommonNodeBuilder {
 protected:
   ExplodedNode *Pred;
-public:
-  // TODO: make protected.
   CoreEngine& Eng;
 
   CommonNodeBuilder(CoreEngine* E, ExplodedNode *P) : Pred(P), Eng(*E) {}
@@ -281,49 +287,36 @@
 };
 
 
-class StmtNodeBuilder: public CommonNodeBuilder {
-  const CFGBlock &B;
+class StmtNodeBuilder: public NodeBuilder {
   const unsigned Idx;
 
 public:
   bool PurgingDeadSymbols;
   bool BuildSinks;
+  // TODO: Remove the flag. We should be able to use the method in the parent.
   bool hasGeneratedNode;
   ProgramPoint::Kind PointKind;
   const ProgramPointTag *Tag;
 
-  typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
-  DeferredTy Deferred;
-
   void GenerateAutoTransition(ExplodedNode *N);
 
 public:
-  StmtNodeBuilder(const CFGBlock *b,
-                  unsigned idx,
-                  ExplodedNode *N,
-                  CoreEngine* e);
+  StmtNodeBuilder(ExplodedNode *N, unsigned idx, NodeBuilderContext &Ctx);
 
   ~StmtNodeBuilder();
-
-  ExplodedNode *getPredecessor() const { return Pred; }
   
-  unsigned getCurrentBlockCount() const {
-    return getBlockCounter().getNumVisited(
-                            Pred->getLocationContext()->getCurrentStackFrame(),
-                                           B.getBlockID());
-  }
-
   ExplodedNode *generateNode(const Stmt *S,
                              const ProgramState *St,
                              ExplodedNode *Pred,
                              ProgramPoint::Kind K,
-                             const ProgramPointTag *tag = 0) {
-    hasGeneratedNode = true;
-
+                             const ProgramPointTag *tag = 0,
+                             bool MarkAsSink = false) {
     if (PurgingDeadSymbols)
       K = ProgramPoint::PostPurgeDeadSymbolsKind;
 
-    return generateNodeInternal(S, St, Pred, K, tag ? tag : Tag);
+    const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
+                                  Pred->getLocationContext(), tag ? tag : Tag);
+    return generateNodeImpl(L, St, Pred, MarkAsSink);
   }
 
   ExplodedNode *generateNode(const Stmt *S,
@@ -336,33 +329,16 @@
   ExplodedNode *generateNode(const ProgramPoint &PP,
                              const ProgramState *State,
                              ExplodedNode *Pred) {
-    hasGeneratedNode = true;
-    return generateNodeInternal(PP, State, Pred);
+    return generateNodeImpl(PP, State, Pred, false);
   }
 
-  ExplodedNode*
-  generateNodeInternal(const ProgramPoint &PP,
-                       const ProgramState *State,
-                       ExplodedNode *Pred);
-
-  ExplodedNode*
-  generateNodeInternal(const Stmt *S,
-                       const ProgramState *State,
-                       ExplodedNode *Pred,
-                       ProgramPoint::Kind K,
-                       const ProgramPointTag *tag = 0);
-
   /// getStmt - Return the current block-level expression associated with
   ///  this builder.
   const Stmt *getStmt() const { 
-    const CFGStmt *CS = B[Idx].getAs<CFGStmt>();
+    const CFGStmt *CS = (*C.Block)[Idx].getAs<CFGStmt>();
     return CS ? CS->getStmt() : 0;
   }
 
-  /// getBlock - Return the CFGBlock associated with the block-level expression
-  ///  of this builder.
-  const CFGBlock *getBlock() const { return &B; }
-
   unsigned getIndex() const { return Idx; }
 
   ExplodedNode *MakeNode(ExplodedNodeSet &Dst,
@@ -394,7 +370,6 @@
     if (NB.hasGeneratedNodes()) {
       Deferred.erase(NBPred);
       Deferred.insert(NB.Deferred.begin(), NB.Deferred.end());
-      hasGeneratedNode = true;
     }
   }
 };
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 91aa9a5..fda7bbd 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -314,7 +314,8 @@
 
   // Process the entrance of the block.
   if (CFGElement E = L.getFirstElement()) {
-    StmtNodeBuilder Builder(L.getBlock(), 0, Pred, this);
+    NodeBuilderContext Ctx(*this, L.getBlock());
+    StmtNodeBuilder Builder(Pred, 0, Ctx);
     SubEng.processCFGElement(E, Builder);
   }
   else
@@ -430,7 +431,8 @@
   if (StmtIdx == B->size())
     HandleBlockExit(B, Pred);
   else {
-    StmtNodeBuilder Builder(B, StmtIdx, Pred, this);
+    NodeBuilderContext Ctx(*this, B);
+    StmtNodeBuilder Builder(Pred, StmtIdx, Ctx);
     SubEng.processCFGElement((*B)[StmtIdx], Builder);
   }
 }
@@ -484,9 +486,9 @@
 }
 
 ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
-                                              const ProgramState *State,
-                                              ExplodedNode *FromN,
-                                              bool MarkAsSink) {
+                                            const ProgramState *State,
+                                            ExplodedNode *FromN,
+                                            bool MarkAsSink) {
   assert(Finalized == false &&
          "We cannot create new nodes after the results have been finalized.");
 
@@ -505,11 +507,9 @@
 }
 
 
-StmtNodeBuilder::StmtNodeBuilder(const CFGBlock *b,
-                                 unsigned idx,
-                                 ExplodedNode *N,
-                                 CoreEngine* e)
-  : CommonNodeBuilder(e, N), B(*b), Idx(idx),
+StmtNodeBuilder::StmtNodeBuilder(ExplodedNode *N, unsigned idx,
+                                 NodeBuilderContext &Ctx)
+  : NodeBuilder(N, Ctx), Idx(idx),
     PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
     PointKind(ProgramPoint::PostStmtKind), Tag(0) {
   Deferred.insert(N);
@@ -528,13 +528,13 @@
   if (isa<CallEnter>(N->getLocation())) {
     // Still use the index of the CallExpr. It's needed to create the callee
     // StackFrameContext.
-    Eng.WList->enqueue(N, &B, Idx);
+    C.Eng.WList->enqueue(N, C.Block, Idx);
     return;
   }
 
   // Do not create extra nodes. Move to the next CFG element.
   if (isa<PostInitializer>(N->getLocation())) {
-    Eng.WList->enqueue(N, &B, Idx+1);
+    C.Eng.WList->enqueue(N, C.Block, Idx+1);
     return;
   }
 
@@ -543,16 +543,16 @@
   if (Loc == N->getLocation()) {
     // Note: 'N' should be a fresh node because otherwise it shouldn't be
     // a member of Deferred.
-    Eng.WList->enqueue(N, &B, Idx+1);
+    C.Eng.WList->enqueue(N, C.Block, Idx+1);
     return;
   }
 
   bool IsNew;
-  ExplodedNode *Succ = Eng.G->getNode(Loc, N->State, &IsNew);
-  Succ->addPredecessor(N, *Eng.G);
+  ExplodedNode *Succ = C.Eng.G->getNode(Loc, N->State, &IsNew);
+  Succ->addPredecessor(N, *C.Eng.G);
 
   if (IsNew)
-    Eng.WList->enqueue(Succ, &B, Idx+1);
+    C.Eng.WList->enqueue(Succ, C.Block, Idx+1);
 }
 
 ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst,
@@ -560,48 +560,13 @@
                                         ExplodedNode *Pred,
                                         const ProgramState *St,
                                         ProgramPoint::Kind K) {
-
-  ExplodedNode *N = generateNode(S, St, Pred, K);
-
-  if (N) {
-    if (BuildSinks)
-      N->markAsSink();
-    else
+  ExplodedNode *N = generateNode(S, St, Pred, K, 0, BuildSinks);
+  if (N && !BuildSinks){
       Dst.Add(N);
   }
-  
   return N;
 }
 
-ExplodedNode*
-StmtNodeBuilder::generateNodeInternal(const Stmt *S,
-                                      const ProgramState *state,
-                                      ExplodedNode *Pred,
-                                      ProgramPoint::Kind K,
-                                      const ProgramPointTag *tag) {
-  
-  const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
-                                        Pred->getLocationContext(), tag);
-  return generateNodeInternal(L, state, Pred);
-}
-
-ExplodedNode*
-StmtNodeBuilder::generateNodeInternal(const ProgramPoint &Loc,
-                                      const ProgramState *State,
-                                      ExplodedNode *Pred) {
-  bool IsNew;
-  ExplodedNode *N = Eng.G->getNode(Loc, State, &IsNew);
-  N->addPredecessor(Pred, *Eng.G);
-  Deferred.erase(Pred);
-
-  if (IsNew) {
-    Deferred.insert(N);
-    return N;
-  }
-
-  return NULL;
-}
-
 ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
                                               bool branch,
                                               ExplodedNode *NodePred) {
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index e0560fd..7827873 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -226,7 +226,7 @@
       evalObjCMessage(dstEval, msg, Pred, Pred->getState());
     }
 
-    assert(Builder->BuildSinks || Builder->hasGeneratedNode);
+    assert(Builder->BuildSinks || Builder->hasGeneratedNodes());
   }
   
   // Finally, perform the post-condition check of the ObjCMessageExpr and store