Static Analyzer driver/options (partial) cleanup:
- Move all analyzer options logic to AnalysisConsumer.cpp.
- Unified specification of stores/constraints/output to be:
   -analyzer-output=...
   -analyzer-store=...
   -analyzer-constraints=...
  instead of -analyzer-range-constraints, -analyzer-store-basic, etc.
- Updated drivers (ccc-analyzer, scan-builds, new ccc) to obey this new
  interface
- Updated test cases to conform to new driver options


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64737 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp
index 5c1e3d8..66fe299 100644
--- a/Driver/AnalysisConsumer.cpp
+++ b/Driver/AnalysisConsumer.cpp
@@ -42,18 +42,124 @@
 
 static ExplodedNodeImpl::Auditor* CreateUbiViz();
 
-// Analyzer options.
+//===----------------------------------------------------------------------===//
+// Analyzer Options: available analyses.
+//===----------------------------------------------------------------------===//
+
+/// Analysis - Set of available source code analyses.
+enum Analyses {
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
+#include "Analyses.def"
+NumAnalyses
+};
+
+static llvm::cl::list<Analyses>
+AnalysisList(llvm::cl::desc("Source Code Analysis - Checks and Analyses"),
+llvm::cl::values(
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
+clEnumValN(NAME, CMDFLAG, DESC),
+#include "Analyses.def"
+clEnumValEnd));
+
+//===----------------------------------------------------------------------===//
+// Analyzer Options: store model.
+//===----------------------------------------------------------------------===//
+
+/// AnalysisStores - Set of available analysis store models.
+enum AnalysisStores {
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "Analyses.def"
+NumStores
+};
+
+static llvm::cl::opt<AnalysisStores> 
+AnalysisStoreOpt("analyzer-store",
+  llvm::cl::desc("Source Code Analysis - Abstract Memory Store Models"),
+  llvm::cl::init(BasicStoreModel),
+  llvm::cl::values(
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)\
+clEnumValN(NAME##Model, CMDFLAG, DESC),
+#include "Analyses.def"
+clEnumValEnd));
+
+//===----------------------------------------------------------------------===//
+// Analyzer Options: constraint engines.
+//===----------------------------------------------------------------------===//
+
+/// AnalysisConstraints - Set of available constraint models.
+enum AnalysisConstraints {
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "Analyses.def"
+NumConstraints
+};
+
+static llvm::cl::opt<AnalysisConstraints> 
+AnalysisConstraintsOpt("analyzer-constraints",
+  llvm::cl::desc("Source Code Analysis - Symbolic Constraint Engines"),
+  llvm::cl::init(BasicConstraintsModel),
+  llvm::cl::values(
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)\
+clEnumValN(NAME##Model, CMDFLAG, DESC),
+#include "Analyses.def"
+clEnumValEnd));
+
+//===----------------------------------------------------------------------===//
+// Analyzer Options: diagnostic clients.
+//===----------------------------------------------------------------------===//
+
+/// AnalysisDiagClients - Set of available diagnostic clients for rendering
+///  analysis results.
+enum AnalysisDiagClients {
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME,
+#include "Analyses.def"
+NUM_ANALYSIS_DIAG_CLIENTS
+};
+
+static llvm::cl::opt<AnalysisDiagClients>
+AnalysisDiagOpt("analyzer-output",
+                llvm::cl::desc("Source Code Analysis - Output Options"),
+                llvm::cl::init(PD_HTML),
+                llvm::cl::values(
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\
+clEnumValN(PD_##NAME, CMDFLAG, DESC),
+#include "Analyses.def"
+clEnumValEnd));
+
+//===----------------------------------------------------------------------===//
+//  Misc. fun options.
+//===----------------------------------------------------------------------===//
+
+static llvm::cl::opt<bool>
+VisualizeEGDot("analyzer-viz-egraph-graphviz",
+               llvm::cl::desc("Display exploded graph using GraphViz"));
+
+static llvm::cl::opt<bool>
+VisualizeEGUbi("analyzer-viz-egraph-ubigraph",
+               llvm::cl::desc("Display exploded graph using Ubigraph"));
+
+static llvm::cl::opt<bool>
+AnalyzeAll("analyzer-opt-analyze-headers",
+    llvm::cl::desc("Force the static analyzer to analyze "
+                   "functions defined in header files"));
+
+static llvm::cl::opt<bool>
+AnalyzerDisplayProgress("analyzer-display-progress",
+          llvm::cl::desc("Emit verbose output about the analyzer's progress."));
+
 static llvm::cl::opt<bool>
 PurgeDead("analyzer-purge-dead",
           llvm::cl::init(true),
           llvm::cl::desc("Remove dead symbols, bindings, and constraints before"
                          " processing a statement."));
+
+static llvm::cl::opt<std::string>
+AnalyzeSpecificFunction("analyze-function",
+               llvm::cl::desc("Run analysis on specific function"));
+
 static llvm::cl::opt<bool>
-UseRanges("analyzer-range-constraints",
-          llvm::cl::init(false),
-          llvm::cl::desc("Use the range constraint manager instead of the basic"
-                         " constraint manager"));
-  
+TrimGraph("trim-egraph",
+     llvm::cl::desc("Only show error-related paths in the analysis graph"));
+
 //===----------------------------------------------------------------------===//
 // Basic type definitions.
 //===----------------------------------------------------------------------===//
@@ -77,37 +183,21 @@
     Actions TranslationUnitActions;
     
   public:
-    const bool VisGraphviz;
-    const bool VisUbigraph;
-    const bool TrimGraph;
     const LangOptions& LOpts;    
     Diagnostic &Diags;
     ASTContext* Ctx;
     Preprocessor* PP;
     PreprocessorFactory* PPF;
-    const std::string HTMLDir;
-    const std::string FName;
+    const std::string OutDir;
     llvm::OwningPtr<PathDiagnosticClient> PD;
-    bool AnalyzeAll;  
-    AnalysisStores SM;
-    AnalysisDiagClients DC;
-    const bool DisplayProgress;
 
     AnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
                      PreprocessorFactory* ppf,
                      const LangOptions& lopts,
-                     const std::string& fname,
-                     const std::string& htmldir,
-                     AnalysisStores sm, AnalysisDiagClients dc,
-                     bool visgraphviz, bool visubi, bool trim, bool analyzeAll,
-                     bool displayProgress)
-      : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim),
-        LOpts(lopts), Diags(diags),
+                     const std::string& outdir)
+      : LOpts(lopts), Diags(diags),
         Ctx(0), PP(pp), PPF(ppf),
-        HTMLDir(htmldir),
-        FName(fname),
-        AnalyzeAll(analyzeAll), SM(sm), DC(dc),
-        DisplayProgress(displayProgress) {}
+        OutDir(outdir) {}
     
     void addCodeAction(CodeAction action) {
       FunctionActions.push_back(action);
@@ -215,11 +305,11 @@
     }
     
     virtual PathDiagnosticClient* getPathDiagnosticClient() {
-      if (C.PD.get() == 0 && !C.HTMLDir.empty()) {
-        switch (C.DC) {
+      if (C.PD.get() == 0 && !C.OutDir.empty()) {
+        switch (AnalysisDiagOpt) {
           default:
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\
-case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break;
+case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break;
 #include "Analyses.def"
         }
       }
@@ -239,22 +329,16 @@
       return liveness.get();
     }
     
-    bool shouldVisualizeGraphviz() const {
-      return C.VisGraphviz;
+    bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
+
+    bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
+
+    bool shouldVisualize() const {
+      return VisualizeEGDot || VisualizeEGUbi;
     }
 
-    bool shouldVisualizeUbigraph() const {
-      return C.VisUbigraph;
-    }
-    
-    bool shouldVisualize() const {
-      return C.VisGraphviz || C.VisUbigraph;
-    }
-    
-    bool shouldTrimGraph() const {
-      return C.TrimGraph;
-    }
-    
+    bool shouldTrimGraph() const { return TrimGraph; }
+
     void DisplayFunction() {
       
       if (DisplayedFunction)
@@ -282,25 +366,31 @@
         CreateStoreMgr = ManagerRegistry::StoreMgrCreator;
       }
       else {
-        switch (C.SM) {
+        switch (AnalysisStoreOpt) {
         default:
           assert(0 && "Unknown store manager.");
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)     \
-          case NAME##Model: CreateStoreMgr = Create##NAME##Manager; break;
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)     \
+          case NAME##Model: CreateStoreMgr = CREATEFN; break;
 #include "Analyses.def"
         }
       }
 
       if (ManagerRegistry::ConstraintMgrCreator != 0)
         CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator;
-      else if (UseRanges)
-        CreateConstraintMgr = CreateRangeConstraintManager;
-      else
-        CreateConstraintMgr = CreateBasicConstraintManager;
+      else {
+        switch (AnalysisConstraintsOpt) {
+        default:
+          assert(0 && "Unknown store manager.");
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
+          case NAME##Model: CreateConstraintMgr = CREATEFN; break;
+#include "Analyses.def"
+        }
+      }
+
       
       // Some DiagnosticClients should be created all the time instead of
       // lazily.  Create those now.
-      switch (C.DC) {
+      switch (AnalysisDiagOpt) {
         default: break;
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\
 case PD_##NAME: if (AUTOCREATE) getPathDiagnosticClient(); break;
@@ -329,7 +419,8 @@
     case Decl::Function: {
       FunctionDecl* FD = cast<FunctionDecl>(D);
 
-      if (FName.size() > 0 && FName != FD->getIdentifier()->getName())
+      if (AnalyzeSpecificFunction.size() > 0 && 
+          AnalyzeSpecificFunction != FD->getIdentifier()->getName())
         break;
       
       Stmt* Body = FD->getBody();
@@ -340,7 +431,8 @@
     case Decl::ObjCMethod: {
       ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
       
-      if (FName.size() > 0 && FName != MD->getSelector().getAsString())
+      if (AnalyzeSpecificFunction.size() > 0 &&
+          AnalyzeSpecificFunction != MD->getSelector().getAsString())
         return;
       
       Stmt* Body = MD->getBody();
@@ -356,7 +448,7 @@
 void AnalysisConsumer::HandleTranslationUnit(TranslationUnit& TU) {
 
   if(!TranslationUnitActions.empty()) {
-    AnalysisManager mgr(*this, &TU, DisplayProgress);
+    AnalysisManager mgr(*this, &TU, AnalyzerDisplayProgress);
     for (Actions::iterator I = TranslationUnitActions.begin(), 
          E = TranslationUnitActions.end(); I != E; ++I)
       (*I)(mgr);  
@@ -386,7 +478,7 @@
 
   // Create an AnalysisManager that will manage the state for analyzing
   // this method/function.
-  AnalysisManager mgr(*this, D, Body, DisplayProgress);
+  AnalysisManager mgr(*this, D, Body, AnalyzerDisplayProgress);
   
   // Dispatch on the actions.  
   for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
@@ -538,26 +630,16 @@
 // AnalysisConsumer creation.
 //===----------------------------------------------------------------------===//
 
-ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End,
-                                           AnalysisStores SM,
-                                           AnalysisDiagClients DC,
-                                           Diagnostic &diags, Preprocessor* pp,
+ASTConsumer* clang::CreateAnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
                                            PreprocessorFactory* ppf,
                                            const LangOptions& lopts,
-                                           const std::string& fname,
-                                           const std::string& htmldir,
-                                           bool VisGraphviz, bool VisUbi,
-                                           bool trim,
-                                           bool analyzeAll,
-                                           bool displayProgress) {
-  
-  llvm::OwningPtr<AnalysisConsumer>
-  C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM, DC,
-                         VisGraphviz, VisUbi, trim, analyzeAll,
-                         displayProgress));
-  
-  for ( ; Beg != End ; ++Beg)
-    switch (*Beg) {
+                                           const std::string& OutDir) {
+
+  llvm::OwningPtr<AnalysisConsumer> C(new AnalysisConsumer(diags, pp, ppf,
+                                                           lopts, OutDir));
+
+  for (unsigned i = 0; i < AnalysisList.size(); ++i)
+    switch (AnalysisList[i]) {
 #define ANALYSIS(NAME, CMD, DESC, SCOPE)\
       case NAME:\
         C->add ## SCOPE ## Action(&Action ## NAME);\
@@ -565,7 +647,7 @@
 #include "Analyses.def"
       default: break;
     }
-  
+
   return C.take();
 }