Make AnalysisManager into its own source file and a pure data management class.
authorZhongxing Xu <xuzhongxing@gmail.com>
Thu, 30 Jul 2009 09:11:52 +0000 (09:11 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Thu, 30 Jul 2009 09:11:52 +0000 (09:11 +0000)
Move all components creation code into AnalysisConsumer::DigestAnalyzerOptions().

llvm-svn: 77585

clang/include/clang/Analysis/PathSensitive/AnalysisManager.h [new file with mode: 0644]
clang/lib/Analysis/AnalysisManager.cpp [new file with mode: 0644]
clang/lib/Frontend/AnalysisConsumer.cpp

diff --git a/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h b/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h
new file mode 100644 (file)
index 0000000..f1b4136
--- /dev/null
@@ -0,0 +1,149 @@
+//== AnalysisManager.cpp - Path sensitive analysis data manager ----*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AnalysisManager class that manages the data and policy
+// for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
+
+#include "clang/Analysis/PathSensitive/BugReporter.h"
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
+#include "clang/Analysis/PathDiagnostic.h"
+
+namespace clang {
+
+class AnalysisManager : public BugReporterData {
+  AnalysisContextManager ContextMgr;
+  AnalysisContext *CurrentContext;
+
+  ASTContext &Ctx;
+  Diagnostic &Diags;
+  const LangOptions &LangInfo;
+
+  llvm::OwningPtr<PathDiagnosticClient> PD;
+  
+  // Configurable components creators.
+  StoreManagerCreator CreateStoreMgr;
+  ConstraintManagerCreator CreateConstraintMgr;
+
+  enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
+      
+  bool DisplayedFunction;
+  bool VisualizeEGDot;
+  bool VisualizeEGUbi;
+  bool PurgeDead;
+  bool EagerlyAssume;
+  bool TrimGraph;
+
+public:
+  AnalysisManager(Decl *d, ASTContext &ctx, Diagnostic &diags, 
+                  const LangOptions &lang, PathDiagnosticClient *pd,
+                  StoreManagerCreator storemgr,
+                  ConstraintManagerCreator constraintmgr,
+                  bool displayProgress, bool vizdot, bool vizubi, 
+                  bool purge, bool eager, bool trim)
+
+    : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), 
+      CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
+      AScope(ScopeDecl), DisplayedFunction(!displayProgress),
+      VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
+      EagerlyAssume(eager), TrimGraph(trim) {
+
+    CurrentContext = ContextMgr.getContext(d);
+  }
+    
+  AnalysisManager(ASTContext &ctx, Diagnostic &diags, 
+                  const LangOptions &lang, PathDiagnosticClient *pd,
+                  StoreManagerCreator storemgr,
+                  ConstraintManagerCreator constraintmgr,
+                  bool displayProgress, bool vizdot, bool vizubi, 
+                  bool purge, bool eager, bool trim)
+
+    : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), 
+      CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
+      AScope(ScopeDecl), DisplayedFunction(!displayProgress),
+      VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
+      EagerlyAssume(eager), TrimGraph(trim) {
+
+    CurrentContext = 0;
+  }
+    
+  Decl *getCodeDecl() const { 
+    assert (AScope == ScopeDecl);
+    return CurrentContext->getDecl();
+  }
+    
+  Stmt *getBody() const {
+    assert (AScope == ScopeDecl);
+    return CurrentContext->getBody();
+  }
+    
+  StoreManagerCreator getStoreManagerCreator() {
+    return CreateStoreMgr;
+  };
+
+  ConstraintManagerCreator getConstraintManagerCreator() {
+    return CreateConstraintMgr;
+  }
+    
+  virtual CFG *getCFG() {
+    return CurrentContext->getCFG();
+  }
+    
+  virtual ParentMap &getParentMap() {
+    return CurrentContext->getParentMap();
+  }
+
+  virtual LiveVariables *getLiveVariables() {
+    return CurrentContext->getLiveVariables();
+  }
+    
+  virtual ASTContext &getContext() {
+    return Ctx;
+  }
+    
+  virtual SourceManager &getSourceManager() {
+    return getContext().getSourceManager();
+  }
+    
+  virtual Diagnostic &getDiagnostic() {
+    return Diags;
+  }
+    
+  const LangOptions &getLangOptions() const {
+    return LangInfo;
+  }
+    
+  virtual PathDiagnosticClient *getPathDiagnosticClient() {
+    return PD.get();      
+  }
+    
+  bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
+
+  bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
+
+  bool shouldVisualize() const {
+    return VisualizeEGDot || VisualizeEGUbi;
+  }
+
+  bool shouldTrimGraph() const { return TrimGraph; }
+
+  bool shouldPurgeDead() const { return PurgeDead; }
+
+  bool shouldEagerlyAssume() const { return EagerlyAssume; }
+
+  void DisplayFunction();
+};
+
+}
+
+#endif
diff --git a/clang/lib/Analysis/AnalysisManager.cpp b/clang/lib/Analysis/AnalysisManager.cpp
new file mode 100644 (file)
index 0000000..125c00b
--- /dev/null
@@ -0,0 +1,36 @@
+//== AnalysisManager.cpp - Path sensitive analysis data manager ----*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AnalysisManager class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/AnalysisManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/Streams.h"
+
+using namespace clang;
+
+void AnalysisManager::DisplayFunction() {
+      
+  if (DisplayedFunction)
+    return;
+  
+  DisplayedFunction = true;
+  
+  // FIXME: Is getCodeDecl() always a named decl?
+  if (isa<FunctionDecl>(getCodeDecl()) ||
+      isa<ObjCMethodDecl>(getCodeDecl())) {
+    NamedDecl *ND = cast<NamedDecl>(getCodeDecl());
+    SourceManager &SM = getContext().getSourceManager();
+    llvm::cerr << "ANALYZE: "
+               << SM.getPresumedLoc(ND->getLocation()).getFilename()
+               << ' ' << ND->getNameAsString() << '\n';
+  }
+}
index d631c69..10bb00f 100644 (file)
@@ -25,7 +25,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/Analysis/PathSensitive/AnalysisContext.h"
+#include "clang/Analysis/PathSensitive/AnalysisManager.h"
 #include "clang/Analysis/PathSensitive/BugReporter.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/LocalCheckers.h"
@@ -46,7 +46,6 @@ static ExplodedNodeImpl::Auditor* CreateUbiViz();
 //===----------------------------------------------------------------------===//
 
 namespace {  
-  class AnalysisManager;
   typedef void (*CodeAction)(AnalysisManager& Mgr);
 } // end anonymous namespace
 
@@ -84,7 +83,11 @@ namespace {
     PreprocessorFactory* PPF;
     const std::string OutDir;
     AnalyzerOptions Opts;
-    llvm::OwningPtr<PathDiagnosticClient> PD;
+
+    // PD is owned by AnalysisManager.
+    PathDiagnosticClient *PD;
+    StoreManagerCreator CreateStoreMgr;
+    ConstraintManagerCreator CreateConstraintMgr;
 
     AnalysisConsumer(Diagnostic &diags, Preprocessor* pp,
                      PreprocessorFactory* ppf,
@@ -93,7 +96,47 @@ namespace {
                      const AnalyzerOptions& opts)
       : LOpts(lopts), Diags(diags),
         Ctx(0), PP(pp), PPF(ppf),
-        OutDir(outdir), Opts(opts) {}
+        OutDir(outdir), Opts(opts) {
+      DigestAnalyzerOptions();
+    }
+
+    void DigestAnalyzerOptions() {
+      // Create the PathDiagnosticClient.
+      if (!OutDir.empty()) {
+        switch (Opts.AnalysisDiagOpt) {
+        default:
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
+          case PD_##NAME: PD = CREATEFN(OutDir, PP, PPF); break;
+#include "clang/Frontend/Analyses.def"
+        }
+      }
+
+      // Create the analyzer component creators.
+      if (ManagerRegistry::StoreMgrCreator != 0) {
+        CreateStoreMgr = ManagerRegistry::StoreMgrCreator;
+      }
+      else {
+        switch (Opts.AnalysisStoreOpt) {
+        default:
+          assert(0 && "Unknown store manager.");
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)           \
+          case NAME##Model: CreateStoreMgr = CREATEFN; break;
+#include "clang/Frontend/Analyses.def"
+        }
+      }
+      
+      if (ManagerRegistry::ConstraintMgrCreator != 0)
+        CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator;
+      else {
+        switch (Opts.AnalysisConstraintsOpt) {
+        default:
+          assert(0 && "Unknown store manager.");
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
+          case NAME##Model: CreateConstraintMgr = CREATEFN; break;
+#include "clang/Frontend/Analyses.def"
+        }
+      }
+    }
     
     void addCodeAction(CodeAction action) {
       FunctionActions.push_back(action);
@@ -124,164 +167,6 @@ namespace {
   };
     
   
-  class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData {
-    AnalysisContextManager ContextMgr;
-    AnalysisContext *CurrentContext;
-    
-    enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
-      
-    AnalysisConsumer& C;
-    bool DisplayedFunction;
-    
-    // Configurable components creators.
-    StoreManagerCreator CreateStoreMgr;
-    ConstraintManagerCreator CreateConstraintMgr;
-
-  public:
-    AnalysisManager(AnalysisConsumer& c, Decl* d, bool displayProgress)
-      : AScope(ScopeDecl), C(c), DisplayedFunction(!displayProgress) {
-      setManagerCreators();
-      CurrentContext = ContextMgr.getContext(d);
-    }
-    
-    AnalysisManager(AnalysisConsumer& c, bool displayProgress) 
-      : AScope(ScopeTU), C(c), DisplayedFunction(!displayProgress) {
-      setManagerCreators();
-      CurrentContext = 0;
-    }
-    
-    Decl* getCodeDecl() const { 
-      assert (AScope == ScopeDecl);
-      return CurrentContext->getDecl();
-    }
-    
-    Stmt* getBody() const {
-      assert (AScope == ScopeDecl);
-      return CurrentContext->getBody();
-    }
-    
-    StoreManagerCreator getStoreManagerCreator() {
-      return CreateStoreMgr;
-    };
-
-    ConstraintManagerCreator getConstraintManagerCreator() {
-      return CreateConstraintMgr;
-    }
-    
-    virtual CFG* getCFG() {
-      return CurrentContext->getCFG();
-    }
-    
-    virtual ParentMap& getParentMap() {
-      return CurrentContext->getParentMap();
-    }
-
-    virtual LiveVariables* getLiveVariables() {
-      return CurrentContext->getLiveVariables();
-    }
-    
-    virtual ASTContext& getContext() {
-      return *C.Ctx;
-    }
-    
-    virtual SourceManager& getSourceManager() {
-      return getContext().getSourceManager();
-    }
-    
-    virtual Diagnostic& getDiagnostic() {
-      return C.Diags;
-    }
-    
-    const LangOptions& getLangOptions() const {
-      return C.LOpts;
-    }
-    
-    virtual PathDiagnosticClient* getPathDiagnosticClient() {
-      if (C.PD.get() == 0 && !C.OutDir.empty()) {
-        switch (C.Opts.AnalysisDiagOpt) {
-          default:
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\
-case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break;
-#include "clang/Frontend/Analyses.def"
-        }
-      }
-      return C.PD.get();      
-    }
-    
-    bool shouldVisualizeGraphviz() const { return C.Opts.VisualizeEGDot; }
-
-    bool shouldVisualizeUbigraph() const { return C.Opts.VisualizeEGUbi; }
-
-    bool shouldVisualize() const {
-      return C.Opts.VisualizeEGDot || C.Opts.VisualizeEGUbi;
-    }
-
-    bool shouldTrimGraph() const { return C.Opts.TrimGraph; }
-
-    bool shouldPurgeDead() const { return C.Opts.PurgeDead; }
-
-    bool shouldEagerlyAssume() const { return C.Opts.EagerlyAssume; }
-
-    void DisplayFunction() {
-      
-      if (DisplayedFunction)
-        return;
-      
-      DisplayedFunction = true;
-      
-      // FIXME: Is getCodeDecl() always a named decl?
-      if (isa<FunctionDecl>(getCodeDecl()) ||
-          isa<ObjCMethodDecl>(getCodeDecl())) {
-        NamedDecl *ND = cast<NamedDecl>(getCodeDecl());
-        SourceManager &SM = getContext().getSourceManager();
-        llvm::cerr << "ANALYZE: "
-          << SM.getPresumedLoc(ND->getLocation()).getFilename()
-          << ' ' << ND->getNameAsString() << '\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.Opts.AnalysisStoreOpt) {
-        default:
-          assert(0 && "Unknown store manager.");
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)     \
-          case NAME##Model: CreateStoreMgr = CREATEFN; break;
-#include "clang/Frontend/Analyses.def"
-        }
-      }
-
-      if (ManagerRegistry::ConstraintMgrCreator != 0)
-        CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator;
-      else {
-        switch (C.Opts.AnalysisConstraintsOpt) {
-        default:
-          assert(0 && "Unknown store manager.");
-#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
-          case NAME##Model: CreateConstraintMgr = CREATEFN; break;
-#include "clang/Frontend/Analyses.def"
-        }
-      }
-
-      
-      // Some DiagnosticClients should be created all the time instead of
-      // lazily.  Create those now.
-      switch (C.Opts.AnalysisDiagOpt) {
-        default: break;
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\
-case PD_##NAME: if (AUTOCREATE) getPathDiagnosticClient(); break;
-#include "clang/Frontend/Analyses.def"
-      }      
-    }
-
-  };
 
 } // end anonymous namespace
 
@@ -331,7 +216,11 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
 void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
 
   if(!TranslationUnitActions.empty()) {
-    AnalysisManager mgr(*this, Opts.AnalyzerDisplayProgress);
+    AnalysisManager mgr(*Ctx, Diags, LOpts, PD, 
+                        CreateStoreMgr, CreateConstraintMgr,
+                        Opts.AnalyzerDisplayProgress, Opts.VisualizeEGDot,
+                        Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume,
+                        Opts.TrimGraph);
     for (Actions::iterator I = TranslationUnitActions.begin(), 
          E = TranslationUnitActions.end(); I != E; ++I)
       (*I)(mgr);  
@@ -346,11 +235,6 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
       if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
         HandleCode(ID, 0, ObjCImplementationActions);
   }
-  
-  // Delete the PathDiagnosticClient here just in case the AnalysisConsumer
-  // object doesn't get released.  This will cause any side-effects in the
-  // destructor of the PathDiagnosticClient to get executed.
-  PD.reset();
 }
 
 void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) {
@@ -367,7 +251,11 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) {
 
   // Create an AnalysisManager that will manage the state for analyzing
   // this method/function.
-  AnalysisManager mgr(*this, D, Opts.AnalyzerDisplayProgress);
+  AnalysisManager mgr(D, *Ctx, Diags, LOpts, PD, 
+                      CreateStoreMgr, CreateConstraintMgr,
+                      Opts.AnalyzerDisplayProgress, Opts.VisualizeEGDot,
+                      Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume,
+                      Opts.TrimGraph);
   
   // Dispatch on the actions.  
   for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)