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
// 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.
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();
/// 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>
}
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 {
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
class AnalysisManager : public BugReporterData {
AnalysisContextManager AnaCtxMgr;
- LocationContextManager LocCtxMgr;
ASTContext &Ctx;
DiagnosticsEngine &Diags;
~AnalysisManager() { FlushDiagnostics(); }
void ClearContexts() {
- LocCtxMgr.clear();
AnaCtxMgr.clear();
}
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
namespace clang {
+class AnalysisContextManager;
class ObjCForCollectionStmt;
-
+
namespace ento {
class AnalysisManager;
class ExprEngine : public SubEngine {
AnalysisManager &AMgr;
+
+ AnalysisContextManager &AnalysisContexts;
CoreEngine Engine;
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),
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),
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.
//===----------------------------------------------------------------------===//
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.
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 =
ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
: AMgr(mgr),
+ AnalysisContexts(mgr.getAnalysisContextManager()),
Engine(*this),
G(Engine.getGraph()),
Builder(NULL),
}
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);
}
// 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.