Make the analyzer store (memory model) a command line option.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58056 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/Analyses.def b/Driver/Analyses.def
index 841f0c1..0661a4e 100644
--- a/Driver/Analyses.def
+++ b/Driver/Analyses.def
@@ -11,6 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef ANALYSIS
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
+#endif
+
+#ifndef ANALYSIS_STORE
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)
+#endif
+
 ANALYSIS(CFGDump, "cfg-dump",
          "Display Control-Flow Graphs", Code)
 
@@ -43,4 +51,9 @@
 ANALYSIS(CheckerCFRef, "checker-cfref",
          "Run the [Core] Foundation reference count checker", Code)
 
+
+ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store")
+ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store")
+
 #undef ANALYSIS
+#undef ANALYSIS_STORE
diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp
index e22178b..12ba732 100644
--- a/Driver/AnalysisConsumer.cpp
+++ b/Driver/AnalysisConsumer.cpp
@@ -65,7 +65,7 @@
     const bool VisGraphviz;
     const bool VisUbigraph;
     const bool TrimGraph;
-    const LangOptions& LOpts;
+    const LangOptions& LOpts;    
     Diagnostic &Diags;
     ASTContext* Ctx;
     Preprocessor* PP;
@@ -74,19 +74,21 @@
     const std::string FName;
     llvm::OwningPtr<PathDiagnosticClient> PD;
     bool AnalyzeAll;  
+    AnalysisStores SM;
 
     AnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
                      PreprocessorFactory* ppf,
                      const LangOptions& lopts,
                      const std::string& fname,
                      const std::string& htmldir,
+                     AnalysisStores sm,
                      bool visgraphviz, bool visubi, bool trim, bool analyzeAll) 
       : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim),
         LOpts(lopts), Diags(diags),
         Ctx(0), PP(pp), PPF(ppf),
         HTMLDir(htmldir),
         FName(fname),
-        AnalyzeAll(analyzeAll) {}
+        AnalyzeAll(analyzeAll), SM(sm) {}
     
     void addCodeAction(CodeAction action) {
       FunctionActions.push_back(action);
@@ -126,6 +128,15 @@
     Decl* getCodeDecl() const { return D; }
     Stmt* getBody() const { return Body; }
     
+    GRStateManager::StoreManagerCreator getStoreManagerCreator() {
+      switch (C.SM) {
+        default:
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)\
+case NAME##Model: return Create##NAME##Manager;
+#include "Analyses.def"
+      }
+    };
+    
     virtual CFG* getCFG() {
       if (!cfg) cfg.reset(CFG::buildCFG(getBody()));
       return cfg.get();
@@ -324,7 +335,9 @@
   // Display progress.
   mgr.DisplayFunction();
   
-  GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L);
+  GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L,
+                   mgr.getStoreManagerCreator());
+
   Eng.setTransferFunctions(tf);
   
   if (StandardWarnings) {
@@ -436,6 +449,7 @@
 //===----------------------------------------------------------------------===//
 
 ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
+                                           AnalysisStores SM,
                                            Diagnostic &diags, Preprocessor* pp,
                                            PreprocessorFactory* ppf,
                                            const LangOptions& lopts,
@@ -446,7 +460,7 @@
                                            bool analyzeAll) {
   
   llvm::OwningPtr<AnalysisConsumer>
-  C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir,
+  C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM,
                          VisGraphviz, VisUbi, trim, analyzeAll));
   
   for ( ; Beg != End ; ++Beg)
diff --git a/Driver/AnalysisConsumer.h b/Driver/AnalysisConsumer.h
index daec6f3..420714f 100644
--- a/Driver/AnalysisConsumer.h
+++ b/Driver/AnalysisConsumer.h
@@ -21,8 +21,15 @@
 #include "Analyses.def"
 NumAnalyses
 };
+  
+enum AnalysisStores {
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC) NAME##Model,
+#include "Analyses.def"
+NumStores
+};
 
 ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
+                                    AnalysisStores SM,
                                     Diagnostic &diags, Preprocessor* pp,
                                     PreprocessorFactory* ppf,
                                     const LangOptions& lopts,
@@ -30,7 +37,7 @@
                                     const std::string& htmldir,
                                     bool VisualizeGraphViz,
                                     bool VisualizeUbi,
-                                    bool VizTrimGraph,
+                                    bool VizTrimGraph,                                    
                                     bool AnalyzeAll);
 } // end clang namespace
 
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index 47d422d..e6c6962 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -203,13 +203,22 @@
                    "functions defined in header files"));
 
 static llvm::cl::list<Analyses>
-AnalysisList(llvm::cl::desc("Available Source Code Analyses:"),
+AnalysisList(llvm::cl::desc("SCA Checks/Analyses:"),
 llvm::cl::values(
 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
 clEnumValN(NAME, CMDFLAG, DESC),
 #include "Analyses.def"
 clEnumValEnd));
 
+static llvm::cl::opt<AnalysisStores> 
+AnalysisStoreOpt(llvm::cl::desc("SCA Low-Level Options (Store):"),
+                  llvm::cl::init(BasicStoreModel),
+                  llvm::cl::values(
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)\
+clEnumValN(NAME##Model, "analyzer-store-" CMDFLAG, DESC),
+#include "Analyses.def"
+clEnumValEnd));
+
 //===----------------------------------------------------------------------===//
 // Language Options
 //===----------------------------------------------------------------------===//
@@ -1190,6 +1199,7 @@
       assert (!AnalysisList.empty());
       return CreateAnalysisConsumer(&AnalysisList[0],
                                     &AnalysisList[0]+AnalysisList.size(),
+                                    AnalysisStoreOpt,
                                     Diag, PP, PPF, LangOpts,
                                     AnalyzeSpecificFunction,
                                     OutputFile, VisualizeEGDot, VisualizeEGUbi,
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 4483eec..8c5e6ed 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -167,7 +167,10 @@
   UndefArgsTy MsgExprUndefArgs;
   
 public:
-  GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L);
+  GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L,
+               GRStateManager::StoreManagerCreator SMC =
+                CreateBasicStoreManager);
+  
   ~GRExprEngine();
   
   void ExecuteWorkList(unsigned Steps = 150000) {
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index f4f0415..5e3fa8d 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -88,6 +88,7 @@
 };
   
 StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
+StoreManager* CreateRegionStoreManager(GRStateManager& StMgr);
   
 } // end clang namespace
 
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index cbda7be..1840482 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -115,12 +115,13 @@
 
 
 GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
-                           LiveVariables& L)
+                           LiveVariables& L,
+                           GRStateManager::StoreManagerCreator SMC)
   : CoreEngine(cfg, CD, Ctx, *this), 
     G(CoreEngine.getGraph()),
     Liveness(L),
     Builder(NULL),
-    StateMgr(G.getContext(), CreateBasicStoreManager,
+    StateMgr(G.getContext(), SMC,
              CreateBasicConstraintManager, G.getAllocator(), G.getCFG(), L),
     SymMgr(StateMgr.getSymbolManager()),
     CurrentStmt(NULL),
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 9183fd7..1bd29ad 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -66,6 +66,11 @@
 
 } // end anonymous namespace
 
+StoreManager* clang::CreateRegionStoreManager(GRStateManager& StMgr) {
+  // return new RegionStoreManager(StMgr);
+  return 0; // Uncomment the above line when RegionStoreManager is not abstract.
+}
+
 Loc RegionStoreManager::getElementLoc(const VarDecl* VD, SVal Idx) {
   MemRegion* R = MRMgr.getVarRegion(VD);
   ElementRegion* ER = MRMgr.getElementRegion(Idx, R);