diff options
| author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-12-24 03:34:38 +0000 |
|---|---|---|
| committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-12-24 03:34:38 +0000 |
| commit | 51f1ca852fcba427f4a83a1a90203f0b04051d10 (patch) | |
| tree | 56c37f35c5658b35aea6bf2ecb91d371d5da8aa2 | |
| parent | fd97ce6573ef56b9e0f062a5f1fc4b8357bd46b2 (diff) | |
| download | bcm5719-llvm-51f1ca852fcba427f4a83a1a90203f0b04051d10.tar.gz bcm5719-llvm-51f1ca852fcba427f4a83a1a90203f0b04051d10.zip | |
As Ted suggested, record the callsite information with the StackFrameContext.
llvm-svn: 92121
| -rw-r--r-- | clang/include/clang/Analysis/PathSensitive/AnalysisContext.h | 25 | ||||
| -rw-r--r-- | clang/include/clang/Analysis/PathSensitive/AnalysisManager.h | 7 | ||||
| -rw-r--r-- | clang/lib/Analysis/AnalysisContext.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/Analysis/CallInliner.cpp | 22 |
4 files changed, 46 insertions, 24 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h b/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h index abc33b77848..63ba558e3d5 100644 --- a/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -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, diff --git a/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h b/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h index 70a5082821a..8288864f2b6 100644 --- a/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h +++ b/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h @@ -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); } }; diff --git a/clang/lib/Analysis/AnalysisContext.cpp b/clang/lib/Analysis/AnalysisContext.cpp index 05e5196c5b9..97e6d914d45 100644 --- a/clang/lib/Analysis/AnalysisContext.cpp +++ b/clang/lib/Analysis/AnalysisContext.cpp @@ -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 * diff --git a/clang/lib/Analysis/CallInliner.cpp b/clang/lib/Analysis/CallInliner.cpp index 618d82354ed..d18bbcc0174 100644 --- a/clang/lib/Analysis/CallInliner.cpp +++ b/clang/lib/Analysis/CallInliner.cpp @@ -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; @@ -43,7 +38,7 @@ bool CallInliner::EvalCallExpr(CheckerContext &C, const CallExpr *CE) { const GRState *state = C.getState(); const Expr *Callee = CE->getCallee(); SVal L = state->getSVal(Callee); - + const FunctionDecl *FD = L.getAsFunctionDecl(); if (!FD) return false; @@ -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; } |

