As Ted suggested, record the callsite information with the StackFrameContext.
llvm-svn: 92121
This commit is contained in:
parent
fd97ce6573
commit
51f1ca852f
|
@ -27,6 +27,7 @@ namespace clang {
|
|||
class Decl;
|
||||
class Stmt;
|
||||
class CFG;
|
||||
class CFGBlock;
|
||||
class LiveVariables;
|
||||
class ParentMap;
|
||||
class ImplicitParamDecl;
|
||||
|
@ -136,23 +137,38 @@ public:
|
|||
};
|
||||
|
||||
class StackFrameContext : public LocationContext {
|
||||
// The callsite where this stack frame is established.
|
||||
const Stmt *CallSite;
|
||||
|
||||
// The parent block of the callsite.
|
||||
const CFGBlock *Block;
|
||||
|
||||
// The index of the callsite in the CFGBlock.
|
||||
unsigned Index;
|
||||
|
||||
friend class LocationContextManager;
|
||||
StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
|
||||
const Stmt *s)
|
||||
: LocationContext(StackFrame, ctx, parent), CallSite(s) {}
|
||||
const Stmt *s, const CFGBlock *blk, unsigned idx)
|
||||
: LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
|
||||
Index(idx) {}
|
||||
|
||||
public:
|
||||
~StackFrameContext() {}
|
||||
|
||||
const Stmt *getCallSite() const { return CallSite; }
|
||||
|
||||
const CFGBlock *getCallSiteBlock() const { return Block; }
|
||||
|
||||
unsigned getIndex() const { return Index; }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID);
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
|
||||
const LocationContext *parent, const Stmt *s) {
|
||||
const LocationContext *parent, const Stmt *s,
|
||||
const CFGBlock *blk, unsigned idx) {
|
||||
ProfileCommon(ID, StackFrame, ctx, parent, s);
|
||||
ID.AddPointer(blk);
|
||||
ID.AddInteger(idx);
|
||||
}
|
||||
|
||||
static bool classof(const LocationContext* Ctx) {
|
||||
|
@ -230,7 +246,8 @@ public:
|
|||
|
||||
const StackFrameContext *getStackFrame(AnalysisContext *ctx,
|
||||
const LocationContext *parent,
|
||||
const Stmt *s);
|
||||
const Stmt *s, const CFGBlock *blk,
|
||||
unsigned idx);
|
||||
|
||||
const ScopeContext *getScope(AnalysisContext *ctx,
|
||||
const LocationContext *parent,
|
||||
|
|
|
@ -132,14 +132,15 @@ public:
|
|||
|
||||
// Get the top level stack frame.
|
||||
const StackFrameContext *getStackFrame(Decl const *D) {
|
||||
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0);
|
||||
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Get a stack frame with parent.
|
||||
StackFrameContext const *getStackFrame(Decl const *D,
|
||||
LocationContext const *Parent,
|
||||
Stmt const *S) {
|
||||
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S);
|
||||
Stmt const *S, const CFGBlock *Blk,
|
||||
unsigned Idx) {
|
||||
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
|
|||
}
|
||||
|
||||
void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getAnalysisContext(), getParent(), CallSite);
|
||||
Profile(ID, getAnalysisContext(), getParent(), CallSite, Block, Index);
|
||||
}
|
||||
|
||||
void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
|
||||
|
@ -145,8 +145,18 @@ LocationContextManager::getLocationContext(AnalysisContext *ctx,
|
|||
const StackFrameContext*
|
||||
LocationContextManager::getStackFrame(AnalysisContext *ctx,
|
||||
const LocationContext *parent,
|
||||
const Stmt *s) {
|
||||
return getLocationContext<StackFrameContext, Stmt>(ctx, parent, s);
|
||||
const Stmt *s, const CFGBlock *blk,
|
||||
unsigned idx) {
|
||||
llvm::FoldingSetNodeID ID;
|
||||
StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
|
||||
void *InsertPos;
|
||||
StackFrameContext *L =
|
||||
cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
|
||||
if (!L) {
|
||||
L = new StackFrameContext(ctx, parent, s, blk, idx);
|
||||
Contexts.InsertNode(L, InsertPos);
|
||||
}
|
||||
return L;
|
||||
}
|
||||
|
||||
const ScopeContext *
|
||||
|
|
|
@ -19,11 +19,6 @@ using namespace clang;
|
|||
|
||||
namespace {
|
||||
class CallInliner : public Checker {
|
||||
|
||||
/// CallSitePosition - Map the call site to its CFG block and stmt index. This
|
||||
/// is used when exiting from a callee.
|
||||
llvm::DenseMap<const Stmt *, std::pair<CFGBlock*,unsigned> > CallSitePosition;
|
||||
|
||||
public:
|
||||
static void *getTag() {
|
||||
static int x;
|
||||
|
@ -51,9 +46,11 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
|||
if (!FD->isThisDeclarationADefinition())
|
||||
return false;
|
||||
|
||||
GRStmtNodeBuilder &Builder = C.getNodeBuilder();
|
||||
// Make a new LocationContext.
|
||||
const StackFrameContext *LocCtx = C.getAnalysisManager().getStackFrame(FD,
|
||||
C.getPredecessor()->getLocationContext(), CE);
|
||||
C.getPredecessor()->getLocationContext(), CE,
|
||||
Builder.getBlock(), Builder.getIndex());
|
||||
|
||||
CFGBlock const *Entry = &(LocCtx->getCFG()->getEntry());
|
||||
|
||||
|
@ -72,7 +69,7 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
|||
bool isNew;
|
||||
GRExprEngine &Eng = C.getEngine();
|
||||
ExplodedNode *Pred = C.getPredecessor();
|
||||
GRStmtNodeBuilder &Builder = C.getNodeBuilder();
|
||||
|
||||
|
||||
ExplodedNode *SuccN = Eng.getGraph().getNode(Loc, state, &isNew);
|
||||
SuccN->addPredecessor(Pred, Eng.getGraph());
|
||||
|
@ -83,8 +80,6 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
|
|||
|
||||
Builder.HasGeneratedNode = true;
|
||||
|
||||
// Record the call site position.
|
||||
CallSitePosition[CE] = std::make_pair(Builder.getBlock(), Builder.getIndex());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -107,13 +102,12 @@ void CallInliner::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
|
|||
ExplodedNode *Succ = Eng.getGraph().getNode(NodeLoc, state, &isNew);
|
||||
Succ->addPredecessor(Pred, Eng.getGraph());
|
||||
|
||||
assert(CallSitePosition.find(CE) != CallSitePosition.end());
|
||||
|
||||
// When creating the new work list unit, increment the statement index to
|
||||
// point to the statement after the CallExpr.
|
||||
if (isNew)
|
||||
B.getWorkList().Enqueue(Succ, *CallSitePosition[CE].first,
|
||||
CallSitePosition[CE].second + 1);
|
||||
B.getWorkList().Enqueue(Succ,
|
||||
*const_cast<CFGBlock*>(LocCtx->getCallSiteBlock()),
|
||||
LocCtx->getIndex() + 1);
|
||||
|
||||
B.HasGeneratedNode = true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue