]> granicus.if.org Git - clang/commitdiff
[analyzer] Remove LocationContext creation methods from AnalysisManager, and change...
authorTed Kremenek <kremenek@apple.com>
Sun, 23 Oct 2011 02:31:52 +0000 (02:31 +0000)
committerTed Kremenek <kremenek@apple.com>
Sun, 23 Oct 2011 02:31:52 +0000 (02:31 +0000)
WIP to remove/reduce ExprEngine's usage of AnalysisManager.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142739 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/AnalysisContext.h
include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
lib/Analysis/AnalysisContext.cpp
lib/Sema/AnalysisBasedWarnings.cpp
lib/StaticAnalyzer/Core/CoreEngine.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

index 3d0e88a51d8afcbd2edbd6805931fffac3348fad..e769f7f8cf5ac6047de28e85a6559187124c1cdf 100644 (file)
@@ -38,7 +38,9 @@ class PseudoConstantAnalysis;
 class ImplicitParamDecl;
 class LocationContextManager;
 class StackFrameContext;
-  
+class AnalysisContextManager;
+class LocationContext;  
+
 namespace idx { class TranslationUnit; }
 
 /// The base class of a hierarchy of objects representing analyses tied
@@ -61,9 +63,14 @@ public:
   // which creates the analysis object given an AnalysisContext.
 };
   
+  
 /// AnalysisContext contains the context data for the function or method under
 /// analysis.
 class AnalysisContext {
+  /// Backpoint to the AnalysisManager object that created this AnalysisContext.
+  /// This may be null.
+  AnalysisContextManager *Manager;
+  
   const Decl *D;
 
   // TranslationUnit is NULL if we don't have multiple translation units.
@@ -91,10 +98,14 @@ class AnalysisContext {
   void *ManagedAnalyses;
 
 public:
-  AnalysisContext(const Decl *d, idx::TranslationUnit *tu);
+  AnalysisContext(AnalysisContextManager *Mgr,
+                  const Decl *D,
+                  idx::TranslationUnit *TU);
 
-  AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
-                  const CFG::BuildOptions &buildOptions);
+  AnalysisContext(AnalysisContextManager *Mgr,
+                  const Decl *D,
+                  idx::TranslationUnit *TU,
+                  const CFG::BuildOptions &BuildOptions);
 
   ~AnalysisContext();
 
@@ -155,6 +166,11 @@ public:
   /// AnalysisContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
   const ImplicitParamDecl *getSelfDecl() const;
   
+  const StackFrameContext *getStackFrame(LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx);  
+  
   /// Return the specified analysis object, lazily running the analysis if
   /// necessary.  Return NULL if the analysis could not run.
   template <typename T>
@@ -168,31 +184,8 @@ public:
   }
 private:
   ManagedAnalysis *&getAnalysisImpl(const void* tag);
-};
-
-class AnalysisContextManager {
-  typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
-  ContextMap Contexts;
-  CFG::BuildOptions cfgBuildOptions;
-public:
-  AnalysisContextManager(bool useUnoptimizedCFG = false,
-                         bool addImplicitDtors = false,
-                         bool addInitializers = false);
-  
-  ~AnalysisContextManager();
-
-  AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0);
-
-  bool getUseUnoptimizedCFG() const {
-    return !cfgBuildOptions.PruneTriviallyFalseEdges;
-  }
   
-  CFG::BuildOptions &getCFGBuildOptions() {
-    return cfgBuildOptions;
-  }
-
-  /// Discard all previously created AnalysisContexts.
-  void clear();
+  LocationContextManager &getLocationContextManager();
 };
 
 class LocationContext : public llvm::FoldingSetNode {
@@ -375,5 +368,64 @@ private:
                                 const DATA *d);
 };
 
+class AnalysisContextManager {
+  typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
+  
+  ContextMap Contexts;
+  LocationContextManager LocContexts;
+  CFG::BuildOptions cfgBuildOptions;
+  
+public:
+  AnalysisContextManager(bool useUnoptimizedCFG = false,
+                         bool addImplicitDtors = false,
+                         bool addInitializers = false);
+  
+  ~AnalysisContextManager();
+  
+  AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0);
+  
+  bool getUseUnoptimizedCFG() const {
+    return !cfgBuildOptions.PruneTriviallyFalseEdges;
+  }
+  
+  CFG::BuildOptions &getCFGBuildOptions() {
+    return cfgBuildOptions;
+  }
+  
+  const StackFrameContext *getStackFrame(AnalysisContext *Ctx,
+                                         LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
+  }
+  
+  // Get the top level stack frame.
+  const StackFrameContext *getStackFrame(Decl const *D, 
+                                         idx::TranslationUnit *TU) {
+    return LocContexts.getStackFrame(getContext(D, TU), 0, 0, 0, 0);
+  }
+  
+  // Get a stack frame with parent.
+  StackFrameContext const *getStackFrame(const Decl *D, 
+                                         LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
+  }
+
+  
+  /// Discard all previously created AnalysisContexts.
+  void clear();
+
+private:
+  friend class AnalysisContext;
+
+  LocationContextManager &getLocationContextManager() {
+    return LocContexts;
+  }
+};
+
 } // end clang namespace
 #endif
index 6c93f59d2094cf5976ab5d47da08a95a462ced60..2af16d96e3109b90c63232ba87f56030633ff8ad 100644 (file)
@@ -32,7 +32,6 @@ namespace ento {
 
 class AnalysisManager : public BugReporterData {
   AnalysisContextManager AnaCtxMgr;
-  LocationContextManager LocCtxMgr;
 
   ASTContext &Ctx;
   DiagnosticsEngine &Diags;
@@ -97,7 +96,6 @@ public:
   ~AnalysisManager() { FlushDiagnostics(); }
   
   void ClearContexts() {
-    LocCtxMgr.clear();
     AnaCtxMgr.clear();
   }
   
@@ -189,30 +187,9 @@ public:
     return AnaCtxMgr.getContext(D, TU);
   }
 
-  const StackFrameContext *getStackFrame(AnalysisContext *Ctx,
-                                         LocationContext const *Parent,
-                                         const Stmt *S,
-                                         const CFGBlock *Blk, unsigned Idx) {
-    return LocCtxMgr.getStackFrame(Ctx, Parent, S, Blk, Idx);
-  }
-
-  // Get the top level stack frame.
-  const StackFrameContext *getStackFrame(Decl const *D, 
-                                         idx::TranslationUnit *TU) {
-    return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0);
-  }
-
-  // Get a stack frame with parent.
-  StackFrameContext const *getStackFrame(const Decl *D, 
-                                         LocationContext const *Parent,
-                                         const Stmt *S,
-                                         const CFGBlock *Blk, unsigned Idx) {
-    return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S,
-                                   Blk,Idx);
-  }
 };
 
-} // end GR namespace
+} // enAnaCtxMgrspace
 
 } // end clang namespace
 
index df4580aa906d5c5b8ab061f3531742028f9240ec..6aec0d641f198d283b7b6f92a83d2f9a6868586b 100644 (file)
@@ -28,8 +28,9 @@
 
 namespace clang {
 
+class AnalysisContextManager;
 class ObjCForCollectionStmt;
-
+  
 namespace ento {
 
 class AnalysisManager;
@@ -38,6 +39,8 @@ class ObjCMessage;
 
 class ExprEngine : public SubEngine {
   AnalysisManager &AMgr;
+  
+  AnalysisContextManager &AnalysisContexts;
 
   CoreEngine Engine;
 
index 3dd194b8e80a4728b7512c622901cd8a17ecd5e7..424917eba9124ba7843fa5ceee7c3933bc7eb0ca 100644 (file)
@@ -32,10 +32,13 @@ using namespace clang;
 
 typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
 
-AnalysisContext::AnalysisContext(const Decl *d,
+AnalysisContext::AnalysisContext(AnalysisContextManager *Mgr,
+                                 const Decl *d,
                                  idx::TranslationUnit *tu,
                                  const CFG::BuildOptions &buildOptions)
-  : D(d), TU(tu),
+  : Manager(Mgr),
+    D(d),
+    TU(tu),
     cfgBuildOptions(buildOptions),
     forcedBlkExprs(0),
     builtCFG(false),
@@ -46,9 +49,12 @@ AnalysisContext::AnalysisContext(const Decl *d,
   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
 }
 
-AnalysisContext::AnalysisContext(const Decl *d,
+AnalysisContext::AnalysisContext(AnalysisContextManager *Mgr,
+                                 const Decl *d,
                                  idx::TranslationUnit *tu)
-: D(d), TU(tu),
+: Manager(Mgr),
+  D(d),
+  TU(tu),
   forcedBlkExprs(0),
   builtCFG(false),
   builtCompleteCFG(false),
@@ -184,10 +190,22 @@ AnalysisContext *AnalysisContextManager::getContext(const Decl *D,
                                                     idx::TranslationUnit *TU) {
   AnalysisContext *&AC = Contexts[D];
   if (!AC)
-    AC = new AnalysisContext(D, TU, cfgBuildOptions);
+    AC = new AnalysisContext(this, D, TU, cfgBuildOptions);
   return AC;
 }
 
+const StackFrameContext *
+AnalysisContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
+                               const CFGBlock *Blk, unsigned Idx) {
+  return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
+}
+
+LocationContextManager & AnalysisContext::getLocationContextManager() {
+  assert(Manager &&
+         "Cannot create LocationContexts without an AnalysisContextManager!");
+  return Manager->getLocationContextManager();  
+}
+
 //===----------------------------------------------------------------------===//
 // FoldingSet profiling.
 //===----------------------------------------------------------------------===//
index bd34dece6e83cedd26b31c4106a630a5fa116a50..647d61fbfeddf4bf5920c5a20fa13f1f4fc66280 100644 (file)
@@ -830,7 +830,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
   const Stmt *Body = D->getBody();
   assert(Body);
 
-  AnalysisContext AC(D, 0);
+  AnalysisContext AC(/* AnalysisContextManager */ 0,  D, 0);
 
   // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
   // explosion for destrutors that can result and the compile time hit.
index 93eb1423cfd4346e5ceab22e8b89164aca8191b2..20ee5abbe10821001fac264d1e751bcdcee231e4 100644 (file)
@@ -725,14 +725,16 @@ void CallEnterNodeBuilder::generateNode(const ProgramState *state) {
     ExprEngine NewEng(AMgr, GCEnabled);
 
     // Create the new LocationContext.
-    AnalysisContext *NewAnaCtx = AMgr.getAnalysisContext(CalleeCtx->getDecl(), 
-                                               CalleeCtx->getTranslationUnit());
+    AnalysisContext *NewAnaCtx =
+      AMgr.getAnalysisContext(CalleeCtx->getDecl(), 
+                              CalleeCtx->getTranslationUnit());
+
     const StackFrameContext *OldLocCtx = CalleeCtx;
-    const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx, 
-                                               OldLocCtx->getParent(),
-                                               OldLocCtx->getCallSite(),
-                                               OldLocCtx->getCallSiteBlock(), 
-                                               OldLocCtx->getIndex());
+    const StackFrameContext *NewLocCtx =
+      NewAnaCtx->getStackFrame(OldLocCtx->getParent(),
+                               OldLocCtx->getCallSite(),
+                               OldLocCtx->getCallSiteBlock(), 
+                               OldLocCtx->getIndex());
 
     // Now create an initial state for the new engine.
     const ProgramState *NewState =
index 5f1fe1b5e03cabdcfaeb27bd41c001855e487fd4..628ab8566d620f4d044168429fa4b11fd7cf09c0 100644 (file)
@@ -53,6 +53,7 @@ static inline Selector GetNullarySelector(const char* name, ASTContext &Ctx) {
 
 ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
   : AMgr(mgr),
+    AnalysisContexts(mgr.getAnalysisContextManager()),
     Engine(*this),
     G(Engine.getGraph()),
     Builder(NULL),
index acb007490ee19d986d60b095119617c27dab2e06..41c6035709e9439e77b522d23b873a4c102029eb 100644 (file)
@@ -215,17 +215,18 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
 }
 
 void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
-                                      const MemRegion *Dest,
-                                      const Stmt *S,
-                                      ExplodedNode *Pred, 
-                                      ExplodedNodeSet &Dst) {
+                                    const MemRegion *Dest,
+                                    const Stmt *S,
+                                    ExplodedNode *Pred, 
+                                    ExplodedNodeSet &Dst) {
   if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
     return;
+
   // Create the context for 'this' region.
-  const StackFrameContext *SFC = AMgr.getStackFrame(DD,
-                                                    Pred->getLocationContext(),
-                                                    S, Builder->getBlock(),
-                                                    Builder->getIndex());
+  const StackFrameContext *SFC =
+    AnalysisContexts.getContext(DD)->
+      getStackFrame(Pred->getLocationContext(), S,
+                    Builder->getBlock(), Builder->getIndex());
 
   const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
 
index 34a358ff200b079025adc8c5be147f8ccbbf8280..fdf95b4c7e24518e2ab2e015b7f8cc89c6015728 100644 (file)
@@ -318,7 +318,8 @@ static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager &mgr,
   }
 
   // Execute the worklist algorithm.
-  Eng.ExecuteWorkList(mgr.getStackFrame(D, 0), mgr.getMaxNodes());
+  Eng.ExecuteWorkList(mgr.getAnalysisContextManager().getStackFrame(D, 0),
+                      mgr.getMaxNodes());
 
   // Release the auditor (if any) so that it doesn't monitor the graph
   // created BugReporter.