From: Ted Kremenek Date: Sun, 23 Oct 2011 02:31:52 +0000 (+0000) Subject: [analyzer] Remove LocationContext creation methods from AnalysisManager, and change... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b1b5daf30d2597e066936772bd206500232d7d65;p=clang [analyzer] Remove LocationContext creation methods from AnalysisManager, and change clients to use AnalysisContext instead. 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 --- diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 3d0e88a51d..e769f7f8cf 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -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 @@ -168,31 +184,8 @@ public: } private: ManagedAnalysis *&getAnalysisImpl(const void* tag); -}; - -class AnalysisContextManager { - typedef llvm::DenseMap 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 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 diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 6c93f59d20..2af16d96e3 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -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 diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index df4580aa90..6aec0d641f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -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; diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index 3dd194b8e8..424917eba9 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -32,10 +32,13 @@ using namespace clang; typedef llvm::DenseMap 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. //===----------------------------------------------------------------------===// diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index bd34dece6e..647d61fbfe 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -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. diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp index 93eb1423cf..20ee5abbe1 100644 --- a/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -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 = diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5f1fe1b5e0..628ab8566d 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -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), diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index acb007490e..41c6035709 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -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); diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 34a358ff20..fdf95b4c7e 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -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.