Core analysis engine template cleanup step 2:
merge GRCoreEngineImpl and GRCoreEngine.

Introduce a new interface class GRSubEngine as the subengine of GRCoreEngine.
GRExprEngine subclasses GRSubEngine now.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78298 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h
index 9f11cc9..d5e3586 100644
--- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h
+++ b/include/clang/Analysis/PathSensitive/ExplodedGraph.h
@@ -29,7 +29,7 @@
 namespace clang {
 
 class GRState;
-class GRCoreEngineImpl;
+class GRCoreEngine;
 class ExplodedNode;
 class CFG;
 class ASTContext;
@@ -49,7 +49,7 @@
 class ExplodedNode : public llvm::FoldingSetNode {
 protected:
   friend class ExplodedGraph;
-  friend class GRCoreEngineImpl;
+  friend class GRCoreEngine;
   friend class GRStmtNodeBuilderImpl;
   friend class GRBranchNodeBuilderImpl;
   friend class GRIndirectGotoNodeBuilderImpl;
@@ -206,7 +206,7 @@
 
 class ExplodedGraph {
 protected:
-  friend class GRCoreEngineImpl;
+  friend class GRCoreEngine;
   friend class GRStmtNodeBuilderImpl;
   friend class GRBranchNodeBuilderImpl;
   friend class GRIndirectGotoNodeBuilderImpl;
diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
index df49f9b..48613d1 100644
--- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
@@ -20,34 +20,52 @@
 #include "clang/Analysis/PathSensitive/GRWorkList.h"
 #include "clang/Analysis/PathSensitive/GRBlockCounter.h"
 #include "clang/Analysis/PathSensitive/GRAuditor.h"
+#include "clang/Analysis/PathSensitive/GRSubEngine.h"
 #include "llvm/ADT/OwningPtr.h"
 
 namespace clang {
-  
-class GRStmtNodeBuilderImpl;
-class GRBranchNodeBuilderImpl;
-class GRIndirectGotoNodeBuilderImpl;
-class GRSwitchNodeBuilderImpl;
-class GREndPathNodeBuilderImpl;
-class GRWorkList;
 
+class GRState;
+class GRStateManager;
+
+class GRStmtNodeBuilderImpl;
+template<typename STATE> class GRStmtNodeBuilder;
+class GRBranchNodeBuilderImpl;
+template<typename STATE> class GRBranchNodeBuilder;
+class GRIndirectGotoNodeBuilderImpl;
+template<typename STATE> class GRIndirectGotoNodeBuilder;
+class GRSwitchNodeBuilderImpl;
+template<typename STATE> class GRSwitchNodeBuilder;
+class GREndPathNodeBuilderImpl;
+template<typename STATE> class GREndPathNodeBuilder;
+
+class GRWorkList;
+class GRCoreEngine;
 //===----------------------------------------------------------------------===//
-/// GRCoreEngineImpl - Implements the core logic of the graph-reachability 
+/// GRCoreEngine - Implements the core logic of the graph-reachability 
 ///   analysis. It traverses the CFG and generates the ExplodedGraph.
 ///   Program "states" are treated as opaque void pointers.
-///   The template class GRCoreEngine (which subclasses GRCoreEngineImpl)
+///   The template class GRCoreEngine (which subclasses GRCoreEngine)
 ///   provides the matching component to the engine that knows the actual types
 ///   for states.  Note that this engine only dispatches to transfer functions
 ///   at the statement and block-level.  The analyses themselves must implement
 ///   any transfer function logic and the sub-expression level (if any).
-class GRCoreEngineImpl {
-protected:
+class GRCoreEngine {
+public:
+  typedef GRState                       StateTy;
+  typedef GRStateManager                StateManagerTy;
+  typedef ExplodedGraph                 GraphTy;
+  typedef GraphTy::NodeTy               NodeTy;
+
+private:
   friend class GRStmtNodeBuilderImpl;
   friend class GRBranchNodeBuilderImpl;
   friend class GRIndirectGotoNodeBuilderImpl;
   friend class GRSwitchNodeBuilderImpl;
   friend class GREndPathNodeBuilderImpl;
-    
+
+  GRSubEngine& SubEngine;
+
   /// G - The simulation graph.  Each node is a (location,state) pair.
   llvm::OwningPtr<ExplodedGraph> G;
       
@@ -64,12 +82,6 @@
   void GenerateNode(const ProgramPoint& Loc, const GRState* State,
                     ExplodedNode* Pred);
   
-  /// getInitialState - Gets the void* representing the initial 'state'
-  ///  of the analysis.  This is simply a wrapper (implemented
-  ///  in GRCoreEngine) that performs type erasure on the initial
-  ///  state returned by the checker object.
-  virtual const GRState* getInitialState() = 0;
-  
   void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred);
   void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred);
   void HandleBlockExit(CFGBlock* B, ExplodedNode* Pred);
@@ -78,41 +90,70 @@
   
   void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
                     ExplodedNode* Pred);  
-  
-  virtual void ProcessEndPath(GREndPathNodeBuilderImpl& Builder) = 0;  
-  
-  virtual bool ProcessBlockEntrance(CFGBlock* Blk, const void* State,
-                                    GRBlockCounter BC) = 0;
 
-  virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0;
+  /// Get the initial state from the subengine.
+  const GRState* getInitialState() { 
+    return SubEngine.getInitialState();
+  }
 
-  virtual void ProcessBranch(Stmt* Condition, Stmt* Terminator,
-                             GRBranchNodeBuilderImpl& Builder) = 0;
-
-  virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& Builder) = 0;
+  void ProcessEndPath(GREndPathNodeBuilderImpl& BuilderImpl);
   
-  virtual void ProcessSwitch(GRSwitchNodeBuilderImpl& Builder) = 0;
+  void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& BuilderImpl);
+
+  
+  bool ProcessBlockEntrance(CFGBlock* Blk, const GRState* State,
+                            GRBlockCounter BC);
+
+  
+  void ProcessBranch(Stmt* Condition, Stmt* Terminator,
+                     GRBranchNodeBuilderImpl& BuilderImpl);
+
+
+  void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& BuilderImpl);
+
+  
+  void ProcessSwitch(GRSwitchNodeBuilderImpl& BuilderImpl);
 
 private:
-  GRCoreEngineImpl(const GRCoreEngineImpl&); // Do not implement.
-  GRCoreEngineImpl& operator=(const GRCoreEngineImpl&);
-  
-protected:  
-  GRCoreEngineImpl(ExplodedGraph* g, GRWorkList* wl)
-    : G(g), WList(wl), BCounterFactory(g->getAllocator()) {}
+  GRCoreEngine(const GRCoreEngine&); // Do not implement.
+  GRCoreEngine& operator=(const GRCoreEngine&);
   
 public:
+  /// Construct a GRCoreEngine object to analyze the provided CFG using
+  ///  a DFS exploration of the exploded graph.
+  GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRSubEngine& subengine)
+    : SubEngine(subengine), G(new GraphTy(cfg, cd, ctx)), 
+      WList(GRWorkList::MakeBFS()),
+      BCounterFactory(G->getAllocator()) {}
+
+  /// Construct a GRCoreEngine object to analyze the provided CFG and to
+  ///  use the provided worklist object to execute the worklist algorithm.
+  ///  The GRCoreEngine object assumes ownership of 'wlist'.
+  GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRWorkList* wlist,
+               GRSubEngine& subengine)
+    : SubEngine(subengine), G(new GraphTy(cfg, cd, ctx)), WList(wlist),
+      BCounterFactory(G->getAllocator()) {}
+
+  ~GRCoreEngine() {
+    delete WList;
+  }
+
+  /// getGraph - Returns the exploded graph.
+  GraphTy& getGraph() { return *G.get(); }
+  
+  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
+  ///  transfered to the caller.
+  GraphTy* takeGraph() { return G.take(); }
+
   /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
   ///  steps.  Returns true if there is still simulation state on the worklist.
   bool ExecuteWorkList(unsigned Steps);
   
-  virtual ~GRCoreEngineImpl();
-  
   CFG& getCFG() { return G->getCFG(); }
 };
   
 class GRStmtNodeBuilderImpl {
-  GRCoreEngineImpl& Eng;
+  GRCoreEngine& Eng;
   CFGBlock& B;
   const unsigned Idx;
   ExplodedNode* Pred;
@@ -125,7 +166,7 @@
   
 public:
   GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
-                    ExplodedNode* N, GRCoreEngineImpl* e);      
+                    ExplodedNode* N, GRCoreEngine* e);      
   
   ~GRStmtNodeBuilderImpl();
   
@@ -301,7 +342,7 @@
 };
   
 class GRBranchNodeBuilderImpl {
-  GRCoreEngineImpl& Eng;
+  GRCoreEngine& Eng;
   CFGBlock* Src;
   CFGBlock* DstT;
   CFGBlock* DstF;
@@ -317,7 +358,7 @@
   
 public:
   GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
-                          ExplodedNode* pred, GRCoreEngineImpl* e) 
+                          ExplodedNode* pred, GRCoreEngine* e) 
   : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred),
     GeneratedTrue(false), GeneratedFalse(false),
     InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
@@ -391,7 +432,7 @@
 };
   
 class GRIndirectGotoNodeBuilderImpl {
-  GRCoreEngineImpl& Eng;
+  GRCoreEngine& Eng;
   CFGBlock* Src;
   CFGBlock& DispatchBlock;
   Expr* E;
@@ -399,7 +440,7 @@
 public:
   GRIndirectGotoNodeBuilderImpl(ExplodedNode* pred, CFGBlock* src,
                                 Expr* e, CFGBlock* dispatch,
-                                GRCoreEngineImpl* eng)
+                                GRCoreEngine* eng)
   : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
   
 
@@ -460,13 +501,13 @@
 };
   
 class GRSwitchNodeBuilderImpl {
-  GRCoreEngineImpl& Eng;
+  GRCoreEngine& Eng;
   CFGBlock* Src;
   Expr* Condition;
   ExplodedNode* Pred;  
 public:
   GRSwitchNodeBuilderImpl(ExplodedNode* pred, CFGBlock* src,
-                          Expr* condition, GRCoreEngineImpl* eng)
+                          Expr* condition, GRCoreEngine* eng)
   : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
   
   class Iterator {
@@ -534,14 +575,14 @@
   
 
 class GREndPathNodeBuilderImpl {
-  GRCoreEngineImpl& Eng;
+  GRCoreEngine& Eng;
   CFGBlock& B;
   ExplodedNode* Pred;  
   bool HasGeneratedNode;
   
 public:
   GREndPathNodeBuilderImpl(CFGBlock* b, ExplodedNode* N,
-                           GRCoreEngineImpl* e)
+                           GRCoreEngine* e)
     : Eng(*e), B(*b), Pred(N), HasGeneratedNode(false) {}      
   
   ~GREndPathNodeBuilderImpl();
@@ -597,86 +638,6 @@
   }                                
 };
 
-  
-template<typename SUBENGINE>
-class GRCoreEngine : public GRCoreEngineImpl {
-public:
-  typedef SUBENGINE                              SubEngineTy; 
-  typedef typename SubEngineTy::StateTy          StateTy;
-  typedef typename StateTy::ManagerTy            StateManagerTy;
-  typedef ExplodedGraph                          GraphTy;
-  typedef typename GraphTy::NodeTy               NodeTy;
-
-protected:
-  SubEngineTy& SubEngine;
-  
-  virtual const GRState* getInitialState() {
-    return SubEngine.getInitialState();
-  }
-  
-  virtual void ProcessEndPath(GREndPathNodeBuilderImpl& BuilderImpl) {
-    GREndPathNodeBuilder<StateTy> Builder(BuilderImpl);
-    SubEngine.ProcessEndPath(Builder);
-  }
-  
-  virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& BuilderImpl) {
-    GRStmtNodeBuilder<StateTy> Builder(BuilderImpl,SubEngine.getStateManager());
-    SubEngine.ProcessStmt(S, Builder);
-  }
-  
-  virtual bool ProcessBlockEntrance(CFGBlock* Blk, const void* State,
-                                    GRBlockCounter BC) {    
-    return SubEngine.ProcessBlockEntrance(Blk,
-                                          static_cast<const StateTy*>(State),
-                                          BC);
-  }
-
-  virtual void ProcessBranch(Stmt* Condition, Stmt* Terminator,
-                             GRBranchNodeBuilderImpl& BuilderImpl) {
-    GRBranchNodeBuilder<StateTy> Builder(BuilderImpl);
-    SubEngine.ProcessBranch(Condition, Terminator, Builder);    
-  }
-  
-  virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& BuilderImpl) {
-    GRIndirectGotoNodeBuilder<StateTy> Builder(BuilderImpl);
-    SubEngine.ProcessIndirectGoto(Builder);
-  }
-  
-  virtual void ProcessSwitch(GRSwitchNodeBuilderImpl& BuilderImpl) {
-    GRSwitchNodeBuilder<StateTy> Builder(BuilderImpl);
-    SubEngine.ProcessSwitch(Builder);
-  }
-  
-public:  
-  /// Construct a GRCoreEngine object to analyze the provided CFG using
-  ///  a DFS exploration of the exploded graph.
-  GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, SubEngineTy& subengine)
-    : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx),
-                       GRWorkList::MakeBFS()),
-      SubEngine(subengine) {}
-  
-  /// Construct a GRCoreEngine object to analyze the provided CFG and to
-  ///  use the provided worklist object to execute the worklist algorithm.
-  ///  The GRCoreEngine object assumes ownership of 'wlist'.
-  GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, GRWorkList* wlist,
-               SubEngineTy& subengine)
-    : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), wlist),
-      SubEngine(subengine) {}
-  
-  virtual ~GRCoreEngine() {}
-  
-  /// getGraph - Returns the exploded graph.
-  GraphTy& getGraph() {
-    return *static_cast<GraphTy*>(G.get());
-  }
-  
-  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
-  ///  transfered to the caller.
-  GraphTy* takeGraph() { 
-    return static_cast<GraphTy*>(G.take());
-  }
-};
-
 } // end clang namespace
 
 #endif
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index d3a50b0..12c6352 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -16,6 +16,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
 #define LLVM_CLANG_ANALYSIS_GREXPRENGINE
 
+#include "clang/Analysis/PathSensitive/GRSubEngine.h"
 #include "clang/Analysis/PathSensitive/GRCoreEngine.h"
 #include "clang/Analysis/PathSensitive/GRState.h"
 #include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
@@ -31,7 +32,7 @@
   class ObjCForCollectionStmt;
   class Checker;
 
-class GRExprEngine {  
+class GRExprEngine : public GRSubEngine {  
 public:
   typedef GRState                  StateTy;
   typedef ExplodedGraph            GraphTy;
@@ -46,7 +47,7 @@
   typedef ExplodedNodeSet        NodeSet;
     
 protected:
-  GRCoreEngine<GRExprEngine> CoreEngine;
+  GRCoreEngine CoreEngine;
   
   /// G - the simulation graph.
   GraphTy& G;
diff --git a/lib/Analysis/GRCoreEngine.cpp b/lib/Analysis/GRCoreEngine.cpp
index 492b4fe..4f0179a 100644
--- a/lib/Analysis/GRCoreEngine.cpp
+++ b/lib/Analysis/GRCoreEngine.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/PathSensitive/GRCoreEngine.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
 #include "clang/AST/Expr.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Casting.h"
@@ -118,9 +119,38 @@
 //===----------------------------------------------------------------------===//
 // Core analysis engine.
 //===----------------------------------------------------------------------===//
+void GRCoreEngine::ProcessEndPath(GREndPathNodeBuilderImpl& BuilderImpl) {
+  GREndPathNodeBuilder<StateTy> Builder(BuilderImpl);
+  SubEngine.ProcessEndPath(Builder);
+}
 
+void GRCoreEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& BuilderImpl) {
+  GRStmtNodeBuilder<StateTy> Builder(BuilderImpl,SubEngine.getStateManager());
+  SubEngine.ProcessStmt(S, Builder);
+}
+
+bool GRCoreEngine::ProcessBlockEntrance(CFGBlock* Blk, const GRState* State,
+                                        GRBlockCounter BC) {    
+  return SubEngine.ProcessBlockEntrance(Blk, State, BC);
+}
+
+void GRCoreEngine::ProcessBranch(Stmt* Condition, Stmt* Terminator,
+                   GRBranchNodeBuilderImpl& BuilderImpl) {
+  GRBranchNodeBuilder<StateTy> Builder(BuilderImpl);
+  SubEngine.ProcessBranch(Condition, Terminator, Builder);    
+}
+
+void GRCoreEngine::ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& BuilderImpl) {
+  GRIndirectGotoNodeBuilder<GRState> Builder(BuilderImpl);
+  SubEngine.ProcessIndirectGoto(Builder);
+}
+
+void GRCoreEngine::ProcessSwitch(GRSwitchNodeBuilderImpl& BuilderImpl) {
+  GRSwitchNodeBuilder<GRState> Builder(BuilderImpl);
+  SubEngine.ProcessSwitch(Builder);
+}
 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
-bool GRCoreEngineImpl::ExecuteWorkList(unsigned Steps) {
+bool GRCoreEngine::ExecuteWorkList(unsigned Steps) {
   
   if (G->num_roots() == 0) { // Initialize the analysis by constructing
     // the root if none exists.
@@ -182,8 +212,8 @@
   return WList->hasWork();
 }
 
-void GRCoreEngineImpl::HandleBlockEdge(const BlockEdge& L,
-                                       ExplodedNode* Pred) {
+
+void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
   
   CFGBlock* Blk = L.getDst();
   
@@ -207,7 +237,7 @@
     GenerateNode(BlockEntrance(Blk), Pred->State, Pred);
 }
 
-void GRCoreEngineImpl::HandleBlockEntrance(const BlockEntrance& L,
+void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L,
                                            ExplodedNode* Pred) {
   
   // Increment the block counter.
@@ -224,11 +254,7 @@
     HandleBlockExit(L.getBlock(), Pred);
 }
 
-GRCoreEngineImpl::~GRCoreEngineImpl() {
-  delete WList;
-}
-
-void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
+void GRCoreEngine::HandleBlockExit(CFGBlock * B, ExplodedNode* Pred) {
   
   if (Stmt* Term = B->getTerminator()) {
     switch (Term->getStmtClass()) {
@@ -316,8 +342,8 @@
   GenerateNode(BlockEdge(B, *(B->succ_begin())), Pred->State, Pred);
 }
 
-void GRCoreEngineImpl::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
-                                    ExplodedNode* Pred) {
+void GRCoreEngine::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
+                                ExplodedNode* Pred) {
   assert (B->succ_size() == 2);
 
   GRBranchNodeBuilderImpl Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
@@ -326,7 +352,7 @@
   ProcessBranch(Cond, Term, Builder);
 }
 
-void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
+void GRCoreEngine::HandlePostStmt(const PostStmt& L, CFGBlock* B,
                                   unsigned StmtIdx, ExplodedNode* Pred) {
   
   assert (!B->empty());
@@ -341,8 +367,8 @@
 
 /// GenerateNode - Utility method to generate nodes, hook up successors,
 ///  and add nodes to the worklist.
-void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, 
-                                    const GRState* State, ExplodedNode* Pred) {
+void GRCoreEngine::GenerateNode(const ProgramPoint& Loc, 
+                                const GRState* State, ExplodedNode* Pred) {
   
   bool IsNew;
   ExplodedNode* Node = G->getNode(Loc, State, &IsNew);
@@ -359,7 +385,7 @@
 }
 
 GRStmtNodeBuilderImpl::GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
-                                     ExplodedNode* N, GRCoreEngineImpl* e)
+                                             ExplodedNode* N, GRCoreEngine* e)
   : Eng(*e), B(*b), Idx(idx), Pred(N), LastNode(N) {
   Deferred.insert(N);
 }