diff --git a/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h b/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h index 13331fa00080..7141f56d118e 100644 --- a/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/clang/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -65,32 +65,77 @@ public: private: ContextKind Kind; - LocationContext *Parent; AnalysisContext *Ctx; + LocationContext *Parent; protected: - LocationContext(ContextKind k, LocationContext *parent, AnalysisContext *ctx) - : Kind(k), Parent(parent), Ctx(ctx) {} + LocationContext(ContextKind k, AnalysisContext *ctx, LocationContext *parent) + : Kind(k), Ctx(ctx), Parent(parent) {} + +public: + ContextKind getKind() const { return Kind; } + + AnalysisContext *getAnalysisContext() const { return Ctx; } + + LocationContext *getParent() const { return Parent; } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Kind, Ctx, Parent); + } + + static void Profile(llvm::FoldingSetNodeID &ID, ContextKind k, + AnalysisContext *ctx, LocationContext *parent); + + static bool classof(const LocationContext*) { return true; } }; class StackFrameContext : public LocationContext { Stmt *CallSite; public: - StackFrameContext(Stmt *s, LocationContext *parent, AnalysisContext *ctx) - : LocationContext(StackFrame, parent, ctx), CallSite(s) {} + StackFrameContext(AnalysisContext *ctx, LocationContext *parent, Stmt *s) + : LocationContext(StackFrame, ctx, parent), CallSite(s) {} + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getAnalysisContext(), getParent(), CallSite); + } + + static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, + LocationContext *parent, Stmt *s); + + static bool classof(const LocationContext* Ctx) { + return Ctx->getKind() == StackFrame; + } }; class ScopeContext : public LocationContext { Stmt *Enter; public: - ScopeContext(Stmt *s, LocationContext *parent, AnalysisContext *ctx) - : LocationContext(Scope, parent, ctx), Enter(s) {} + ScopeContext(AnalysisContext *ctx, LocationContext *parent, Stmt *s) + : LocationContext(Scope, ctx, parent), Enter(s) {} + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getAnalysisContext(), getParent(), Enter); + } + + static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, + LocationContext *parent, Stmt *s); + + static bool classof(const LocationContext* Ctx) { + return Ctx->getKind() == Scope; + } }; class LocationContextManager { llvm::FoldingSet Contexts; + +public: + StackFrameContext *getStackFrame(AnalysisContext *ctx,LocationContext *parent, + Stmt *s); + + ScopeContext *getScope(AnalysisContext *ctx,LocationContext *parent, Stmt *s); + }; } diff --git a/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h b/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h index 883454fd2e5d..38a2af26284d 100644 --- a/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h +++ b/clang/include/clang/Analysis/PathSensitive/AnalysisManager.h @@ -23,7 +23,9 @@ namespace clang { class AnalysisManager : public BugReporterData { AnalysisContextManager ContextMgr; - AnalysisContext *CurrentContext; + AnalysisContext *RootContext; + + LocationContextManager LocCtxMgr; ASTContext &Ctx; Diagnostic &Diags; @@ -57,7 +59,7 @@ public: VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim) { - CurrentContext = ContextMgr.getContext(d); + RootContext = ContextMgr.getContext(d); } AnalysisManager(ASTContext &ctx, Diagnostic &diags, @@ -73,21 +75,21 @@ public: VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim) { - CurrentContext = 0; + RootContext = 0; } void setContext(Decl *D) { - CurrentContext = ContextMgr.getContext(D); + RootContext = ContextMgr.getContext(D); } Decl *getCodeDecl() const { assert (AScope == ScopeDecl); - return CurrentContext->getDecl(); + return RootContext->getDecl(); } Stmt *getBody() const { assert (AScope == ScopeDecl); - return CurrentContext->getBody(); + return RootContext->getBody(); } StoreManagerCreator getStoreManagerCreator() { @@ -99,15 +101,15 @@ public: } virtual CFG *getCFG() { - return CurrentContext->getCFG(); + return RootContext->getCFG(); } virtual ParentMap &getParentMap() { - return CurrentContext->getParentMap(); + return RootContext->getParentMap(); } virtual LiveVariables *getLiveVariables() { - return CurrentContext->getLiveVariables(); + return RootContext->getLiveVariables(); } virtual ASTContext &getContext() { @@ -129,6 +131,10 @@ public: virtual PathDiagnosticClient *getPathDiagnosticClient() { return PD.get(); } + + StackFrameContext *getRootStackFrame() { + return LocCtxMgr.getStackFrame(RootContext, 0, 0); + } bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } diff --git a/clang/lib/Analysis/AnalysisContext.cpp b/clang/lib/Analysis/AnalysisContext.cpp index b92eb24d7c98..996d5c879acb 100644 --- a/clang/lib/Analysis/AnalysisContext.cpp +++ b/clang/lib/Analysis/AnalysisContext.cpp @@ -72,3 +72,53 @@ AnalysisContext *AnalysisContextManager::getContext(Decl *D) { Ctx.setDecl(D); return &Ctx; } + +void LocationContext::Profile(llvm::FoldingSetNodeID &ID, ContextKind k, + AnalysisContext *ctx, LocationContext *parent) { + ID.AddInteger(k); + ID.AddPointer(ctx); + ID.AddPointer(parent); +} + +void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID,AnalysisContext *ctx, + LocationContext *parent, Stmt *s) { + LocationContext::Profile(ID, StackFrame, ctx, parent); + ID.AddPointer(s); +} + +void ScopeContext::Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, + LocationContext *parent, Stmt *s) { + LocationContext::Profile(ID, Scope, ctx, parent); + ID.AddPointer(s); +} + +StackFrameContext *LocationContextManager::getStackFrame(AnalysisContext *ctx, + LocationContext *parent, Stmt *s) { + llvm::FoldingSetNodeID ID; + StackFrameContext::Profile(ID, ctx, parent, s); + void *InsertPos; + + StackFrameContext *f = + cast_or_null(Contexts.FindNodeOrInsertPos(ID, InsertPos)); + if (!f) { + f = new StackFrameContext(ctx, parent, s); + Contexts.InsertNode(f, InsertPos); + } + return f; +} + +ScopeContext *LocationContextManager::getScope(AnalysisContext *ctx, + LocationContext *parent, Stmt *s) { + llvm::FoldingSetNodeID ID; + ScopeContext::Profile(ID, ctx, parent, s); + void *InsertPos; + + ScopeContext *scope = + cast_or_null(Contexts.FindNodeOrInsertPos(ID, InsertPos)); + + if (!scope) { + scope = new ScopeContext(ctx, parent, s); + Contexts.InsertNode(scope, InsertPos); + } + return scope; +}