]> granicus.if.org Git - clang/commitdiff
[analyzer] Subclassing StmtBuilder from the NodeBuilder
authorAnna Zaks <ganna@apple.com>
Tue, 18 Oct 2011 23:06:33 +0000 (23:06 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 18 Oct 2011 23:06:33 +0000 (23:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142451 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
lib/StaticAnalyzer/Core/CoreEngine.cpp
lib/StaticAnalyzer/Core/ExprEngineObjC.cpp

index 1bbc66ced708772a1b0badcbc1dfac4792050967..1d0d716944e4e94358a9cc55ee925917427345fb 100644 (file)
@@ -50,7 +50,7 @@ public:
       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()));
index 8433f4cd283217ed453b7f946f531bb97edcbdd6..6e9f54fca7687bb2c97225483bb690df00424fb5 100644 (file)
@@ -181,7 +181,12 @@ protected:
   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 @@ public:
     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 @@ public:
 class CommonNodeBuilder {
 protected:
   ExplodedNode *Pred;
-public:
-  // TODO: make protected.
   CoreEngine& Eng;
 
   CommonNodeBuilder(CoreEngine* E, ExplodedNode *P) : Pred(P), Eng(*E) {}
@@ -281,49 +287,36 @@ public:
 };
 
 
-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 @@ public:
   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 @@ public:
     if (NB.hasGeneratedNodes()) {
       Deferred.erase(NBPred);
       Deferred.insert(NB.Deferred.begin(), NB.Deferred.end());
-      hasGeneratedNode = true;
     }
   }
 };
index 91aa9a567c98f6e84eaacdac1cd71f7e8745e837..fda7bbdf4c6aca3190e9fa01bc922f6d3533fdf3 100644 (file)
@@ -314,7 +314,8 @@ void CoreEngine::HandleBlockEntrance(const BlockEntrance &L,
 
   // 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 @@ void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
   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 @@ GenericNodeBuilderImpl::generateNodeImpl(const ProgramState *state,
 }
 
 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 @@ ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
 }
 
 
-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 @@ void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode *N) {
   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 @@ void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode *N) {
   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 *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst,
                                         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) {
index e0560fdfe4604029fff0c1c16a6061ffca481bbf..7827873e9d4a4e626b709d3ac52355e4ccc8fa0b 100644 (file)
@@ -226,7 +226,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
       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