From: Zhongxing Xu Date: Thu, 30 Jul 2009 01:17:21 +0000 (+0000) Subject: This patch collects all analysis context data into a new class X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=97ab3941effe1f508c7113d9aa0c2887774f6fa8;p=clang This patch collects all analysis context data into a new class AnalysisContext. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77563 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h new file mode 100644 index 0000000000..2d3f15933c --- /dev/null +++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -0,0 +1,63 @@ +//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines AnalysisContext, a class that manages the analysis context +// data for path sensitive analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H +#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H + +#include "llvm/ADT/OwningPtr.h" +#include + +namespace clang { + +class Decl; +class Stmt; +class CFG; +class LiveVariables; +class ParentMap; + +/// AnalysisContext contains the context data for the function or method under +/// analysis. +class AnalysisContext { + Decl *D; + Stmt *Body; + + // AnalysisContext owns the following data. + CFG *cfg; + LiveVariables *liveness; + ParentMap *PM; + +public: + AnalysisContext() : D(0), Body(0), cfg(0), liveness(0), PM(0) {} + ~AnalysisContext(); + + void setDecl(Decl* d) { D = d; } + Decl *getDecl() { return D; } + Stmt *getBody(); + CFG *getCFG(); + ParentMap &getParentMap(); + LiveVariables *getLiveVariables(); +}; + +class AnalysisContextManager { + std::map Contexts; + +public: + typedef std::map::iterator iterator; + + AnalysisContext *getContext(Decl *D); +}; + +} + +#endif diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp new file mode 100644 index 0000000000..ba1b5ae23f --- /dev/null +++ b/lib/Analysis/AnalysisContext.cpp @@ -0,0 +1,73 @@ +//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines AnalysisContext, a class that manages the analysis context +// data for path sensitive analysis. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/Analysis/Analyses/LiveVariables.h" +#include "clang/Analysis/CFG.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/ParentMap.h" + +using namespace clang; + +AnalysisContext::~AnalysisContext() { + delete cfg; + delete liveness; + delete PM; +} + +Stmt *AnalysisContext::getBody() { + if (FunctionDecl *FD = dyn_cast(D)) + return FD->getBody(); + else if (ObjCMethodDecl *MD = dyn_cast(D)) + return MD->getBody(); + + assert(0 && "unknown code decl"); +} + +CFG *AnalysisContext::getCFG() { + if (!cfg) + cfg = CFG::buildCFG(getBody(), &D->getASTContext()); + return cfg; +} + +ParentMap &AnalysisContext::getParentMap() { + if (!PM) + PM = new ParentMap(getBody()); + return *PM; +} + +LiveVariables *AnalysisContext::getLiveVariables() { + if (!liveness) { + CFG *c = getCFG(); + if (!c) + return 0; + + liveness = new LiveVariables(D->getASTContext(), *c); + liveness->runOnCFG(*c); + liveness->runOnAllBlocks(*c, 0, true); + } + + return liveness; +} + +AnalysisContext *AnalysisContextManager::getContext(Decl *D) { + iterator I = Contexts.find(D); + if (I != Contexts.end()) + return &(I->second); + + AnalysisContext &Ctx = Contexts[D]; + Ctx.setDecl(D); + return &Ctx; +} diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 2031174cab..d631c69749 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -25,6 +25,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" #include "clang/AST/ParentMap.h" +#include "clang/Analysis/PathSensitive/AnalysisContext.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/LocalCheckers.h" @@ -124,42 +125,39 @@ namespace { class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData { - Decl* D; Stmt* Body; + AnalysisContextManager ContextMgr; + AnalysisContext *CurrentContext; enum AnalysisScope { ScopeTU, ScopeDecl } AScope; AnalysisConsumer& C; bool DisplayedFunction; - llvm::OwningPtr cfg; - llvm::OwningPtr liveness; - llvm::OwningPtr PM; - // Configurable components creators. StoreManagerCreator CreateStoreMgr; ConstraintManagerCreator CreateConstraintMgr; public: - AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b, bool displayProgress) - : D(d), Body(b), AScope(ScopeDecl), C(c), - DisplayedFunction(!displayProgress) { + AnalysisManager(AnalysisConsumer& c, Decl* d, bool displayProgress) + : AScope(ScopeDecl), C(c), DisplayedFunction(!displayProgress) { setManagerCreators(); + CurrentContext = ContextMgr.getContext(d); } AnalysisManager(AnalysisConsumer& c, bool displayProgress) - : D(0), Body(0), AScope(ScopeTU), C(c), - DisplayedFunction(!displayProgress) { + : AScope(ScopeTU), C(c), DisplayedFunction(!displayProgress) { setManagerCreators(); + CurrentContext = 0; } Decl* getCodeDecl() const { assert (AScope == ScopeDecl); - return D; + return CurrentContext->getDecl(); } Stmt* getBody() const { assert (AScope == ScopeDecl); - return Body; + return CurrentContext->getBody(); } StoreManagerCreator getStoreManagerCreator() { @@ -171,14 +169,15 @@ namespace { } virtual CFG* getCFG() { - if (!cfg) cfg.reset(CFG::buildCFG(getBody(), &getContext())); - return cfg.get(); + return CurrentContext->getCFG(); } virtual ParentMap& getParentMap() { - if (!PM) - PM.reset(new ParentMap(getBody())); - return *PM.get(); + return CurrentContext->getParentMap(); + } + + virtual LiveVariables* getLiveVariables() { + return CurrentContext->getLiveVariables(); } virtual ASTContext& getContext() { @@ -208,19 +207,6 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; } return C.PD.get(); } - - virtual LiveVariables* getLiveVariables() { - if (!liveness) { - CFG* c = getCFG(); - if (!c) return 0; - - liveness.reset(new LiveVariables(getContext(), *c)); - liveness->runOnCFG(*c); - liveness->runOnAllBlocks(*c, 0, true); - } - - return liveness.get(); - } bool shouldVisualizeGraphviz() const { return C.Opts.VisualizeEGDot; } @@ -381,7 +367,7 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { // Create an AnalysisManager that will manage the state for analyzing // this method/function. - AnalysisManager mgr(*this, D, Body, Opts.AnalyzerDisplayProgress); + AnalysisManager mgr(*this, D, Opts.AnalyzerDisplayProgress); // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)