Add support for pluggable components of static analyzer.
 - Creator function pointers are saved in ManagerRegistry.
 - The Register* class is used to notify ManagerRegistry new module is 
   available.
 - AnalysisManager queries ManagerRegistry for configurable module. Then it
   passes them to GRExprEngine, in turn to GRStateManager.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60143 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/AnalysisConsumer.cpp b/Driver/AnalysisConsumer.cpp
index df46322..14b4440 100644
--- a/Driver/AnalysisConsumer.cpp
+++ b/Driver/AnalysisConsumer.cpp
@@ -13,6 +13,7 @@
 
 #include "ASTConsumers.h"
 #include "clang/Driver/PathDiagnosticClients.h"
+#include "clang/Driver/ManagerRegistry.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -129,12 +130,20 @@
     llvm::OwningPtr<LiveVariables> liveness;
     llvm::OwningPtr<ParentMap> PM;
 
+    // Configurable components creators.
+    StoreManagerCreator CreateStoreMgr;
+    ConstraintManagerCreator CreateConstraintMgr;
+
   public:
     AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b) 
-    : D(d), Body(b), TU(0), AScope(ScopeDecl), C(c), DisplayedFunction(false) {}
+    : D(d), Body(b), TU(0), AScope(ScopeDecl), C(c), DisplayedFunction(false) {
+      setManagerCreators();
+    }
     
     AnalysisManager(AnalysisConsumer& c, TranslationUnit* tu) 
-    : D(0), Body(0), TU(tu), AScope(ScopeTU), C(c), DisplayedFunction(false) {}    
+    : D(0), Body(0), TU(tu), AScope(ScopeTU), C(c), DisplayedFunction(false) {
+      setManagerCreators();
+    }
     
     Decl* getCodeDecl() const { 
       assert (AScope == ScopeDecl);
@@ -151,14 +160,13 @@
       return TU;
     }    
     
-    GRStateManager::StoreManagerCreator getStoreManagerCreator() {
-      switch (C.SM) {
-        default:
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)\
-case NAME##Model: return Create##NAME##Manager;
-#include "Analyses.def"
-      }
+    StoreManagerCreator getStoreManagerCreator() {
+      return CreateStoreMgr;
     };
+
+    ConstraintManagerCreator getConstraintManagerCreator() {
+      return CreateConstraintMgr;
+    }
     
     virtual CFG* getCFG() {
       if (!cfg) cfg.reset(CFG::buildCFG(getBody()));
@@ -215,7 +223,7 @@
     bool shouldVisualizeGraphviz() const {
       return C.VisGraphviz;
     }
-    
+
     bool shouldVisualizeUbigraph() const {
       return C.VisUbigraph;
     }
@@ -249,8 +257,33 @@
         << MD->getSelector().getAsString() << "'\n";
       }
     }
+
+  private:
+    /// Set configurable analyzer components creators. First check if there are
+    /// components registered at runtime. Otherwise fall back to builtin
+    /// components.
+    void setManagerCreators() {
+      if (ManagerRegistry::StoreMgrCreator != 0) {
+        CreateStoreMgr = ManagerRegistry::StoreMgrCreator;
+      }
+      else {
+        switch (C.SM) {
+        default:
+          assert(0 && "Unknown store manager.");
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)     \
+          case NAME##Model: CreateStoreMgr = Create##NAME##Manager; break;
+#include "Analyses.def"
+        }
+      }
+
+      if (ManagerRegistry::ConstraintMgrCreator != 0)
+        CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator;
+      else
+        CreateConstraintMgr = CreateBasicConstraintManager;
+    }
+
   };
-  
+
 } // end anonymous namespace
 
 namespace llvm {
@@ -370,7 +403,8 @@
   if (!L) return;
 
   GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L,
-                   mgr.getStoreManagerCreator());
+                   mgr.getStoreManagerCreator(), 
+                   mgr.getConstraintManagerCreator());
 
   Eng.setTransferFunctions(tf);