forked from OSchip/llvm-project
[analyzer] Remove LocationContext creation methods from AnalysisManager, and change clients to use AnalysisContext instead.
WIP to remove/reduce ExprEngine's usage of AnalysisManager. llvm-svn: 142739
This commit is contained in:
parent
e94d277db8
commit
142adc492b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue