This patch collects all analysis context data into a new class
authorZhongxing Xu <xuzhongxing@gmail.com>
Thu, 30 Jul 2009 01:17:21 +0000 (01:17 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Thu, 30 Jul 2009 01:17:21 +0000 (01:17 +0000)
AnalysisContext.

llvm-svn: 77563

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

diff --git a/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h b/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h
new file mode 100644 (file)
index 0000000..2d3f159
--- /dev/null
@@ -0,0 +1,63 @@
+//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- 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 AnalysisContext, a class that manages the analysis context
+// data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include <map>
+
+namespace clang {
+
+class Decl;
+class Stmt;
+class CFG;
+class LiveVariables;
+class ParentMap;
+
+/// AnalysisContext contains the context data for the function or method under
+/// analysis.
+class AnalysisContext {
+  Decl *D;
+  Stmt *Body;
+
+  // AnalysisContext owns the following data.
+  CFG *cfg;
+  LiveVariables *liveness;
+  ParentMap *PM;
+
+public:
+  AnalysisContext() : D(0), Body(0), cfg(0), liveness(0), PM(0) {}
+  ~AnalysisContext();
+
+  void setDecl(Decl* d) { D = d; }
+  Decl *getDecl() { return D; }
+  Stmt *getBody();
+  CFG *getCFG();
+  ParentMap &getParentMap();
+  LiveVariables *getLiveVariables();
+};
+
+class AnalysisContextManager {
+  std::map<Decl*, AnalysisContext> Contexts;
+
+public:
+  typedef std::map<Decl*, AnalysisContext>::iterator iterator;
+
+  AnalysisContext *getContext(Decl *D);
+};
+
+}
+
+#endif
diff --git a/clang/lib/Analysis/AnalysisContext.cpp b/clang/lib/Analysis/AnalysisContext.cpp
new file mode 100644 (file)
index 0000000..ba1b5ae
--- /dev/null
@@ -0,0 +1,73 @@
+//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- 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 AnalysisContext, a class that manages the analysis context
+// data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ParentMap.h"
+
+using namespace clang;
+
+AnalysisContext::~AnalysisContext() {
+  delete cfg;
+  delete liveness;
+  delete PM;
+}
+
+Stmt *AnalysisContext::getBody() {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    return FD->getBody();
+  else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+    return MD->getBody();
+
+  assert(0 && "unknown code decl");
+}
+
+CFG *AnalysisContext::getCFG() {
+  if (!cfg) 
+    cfg = CFG::buildCFG(getBody(), &D->getASTContext());
+  return cfg;
+}
+
+ParentMap &AnalysisContext::getParentMap() {
+  if (!PM) 
+    PM = new ParentMap(getBody());
+  return *PM;
+}
+
+LiveVariables *AnalysisContext::getLiveVariables() {
+  if (!liveness) {
+    CFG *c = getCFG();
+    if (!c)
+      return 0;
+    
+    liveness = new LiveVariables(D->getASTContext(), *c);
+    liveness->runOnCFG(*c);
+    liveness->runOnAllBlocks(*c, 0, true);
+  }
+  
+  return liveness;
+}
+
+AnalysisContext *AnalysisContextManager::getContext(Decl *D) {
+  iterator I = Contexts.find(D);
+  if (I != Contexts.end())
+    return &(I->second);
+
+  AnalysisContext &Ctx = Contexts[D];
+  Ctx.setDecl(D);
+  return &Ctx;
+}
index 2031174..d631c69 100644 (file)
@@ -25,6 +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/BugReporter.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/LocalCheckers.h"
@@ -124,42 +125,39 @@ namespace {
     
   
   class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData {
-    Decl* D; Stmt* Body; 
+    AnalysisContextManager ContextMgr;
+    AnalysisContext *CurrentContext;
     
     enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
       
     AnalysisConsumer& C;
     bool DisplayedFunction;
     
-    llvm::OwningPtr<CFG> cfg;
-    llvm::OwningPtr<LiveVariables> liveness;
-    llvm::OwningPtr<ParentMap> PM;
-
     // Configurable components creators.
     StoreManagerCreator CreateStoreMgr;
     ConstraintManagerCreator CreateConstraintMgr;
 
   public:
-    AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b, bool displayProgress) 
-      : D(d), Body(b), AScope(ScopeDecl), C(c), 
-        DisplayedFunction(!displayProgress) {
+    AnalysisManager(AnalysisConsumer& c, Decl* d, bool displayProgress)
+      : AScope(ScopeDecl), C(c), DisplayedFunction(!displayProgress) {
       setManagerCreators();
+      CurrentContext = ContextMgr.getContext(d);
     }
     
     AnalysisManager(AnalysisConsumer& c, bool displayProgress) 
-      : D(0), Body(0), AScope(ScopeTU), C(c),
-        DisplayedFunction(!displayProgress) {
+      : AScope(ScopeTU), C(c), DisplayedFunction(!displayProgress) {
       setManagerCreators();
+      CurrentContext = 0;
     }
     
     Decl* getCodeDecl() const { 
       assert (AScope == ScopeDecl);
-      return D;
+      return CurrentContext->getDecl();
     }
     
     Stmt* getBody() const {
       assert (AScope == ScopeDecl);
-      return Body;
+      return CurrentContext->getBody();
     }
     
     StoreManagerCreator getStoreManagerCreator() {
@@ -171,14 +169,15 @@ namespace {
     }
     
     virtual CFG* getCFG() {
-      if (!cfg) cfg.reset(CFG::buildCFG(getBody(), &getContext()));
-      return cfg.get();
+      return CurrentContext->getCFG();
     }
     
     virtual ParentMap& getParentMap() {
-      if (!PM) 
-        PM.reset(new ParentMap(getBody()));
-      return *PM.get();
+      return CurrentContext->getParentMap();
+    }
+
+    virtual LiveVariables* getLiveVariables() {
+      return CurrentContext->getLiveVariables();
     }
     
     virtual ASTContext& getContext() {
@@ -208,19 +207,6 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break;
       }
       return C.PD.get();      
     }
-      
-    virtual LiveVariables* getLiveVariables() {
-      if (!liveness) {
-        CFG* c = getCFG();
-        if (!c) return 0;
-        
-        liveness.reset(new LiveVariables(getContext(), *c));
-        liveness->runOnCFG(*c);
-        liveness->runOnAllBlocks(*c, 0, true);
-      }
-      
-      return liveness.get();
-    }
     
     bool shouldVisualizeGraphviz() const { return C.Opts.VisualizeEGDot; }
 
@@ -381,7 +367,7 @@ 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, Body, Opts.AnalyzerDisplayProgress);
+  AnalysisManager mgr(*this, D, Opts.AnalyzerDisplayProgress);
   
   // Dispatch on the actions.  
   for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)