From fda7832b000ff8927386f093b52c067641679469 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Thu, 30 Jul 2009 09:11:52 +0000 Subject: [PATCH] Make AnalysisManager into its own source file and a pure data management class. Move all components creation code into AnalysisConsumer::DigestAnalyzerOptions(). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77585 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/AnalysisManager.h | 149 ++++++++++++ lib/Analysis/AnalysisManager.cpp | 36 +++ lib/Frontend/AnalysisConsumer.cpp | 226 +++++------------- 3 files changed, 242 insertions(+), 169 deletions(-) create mode 100644 include/clang/Analysis/PathSensitive/AnalysisManager.h create mode 100644 lib/Analysis/AnalysisManager.cpp diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h new file mode 100644 index 0000000000..f1b413633e --- /dev/null +++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h @@ -0,0 +1,149 @@ +//== AnalysisManager.cpp - Path sensitive analysis data manager ----*- 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 the AnalysisManager class that manages the data and policy +// for path sensitive analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H +#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H + +#include "clang/Analysis/PathSensitive/BugReporter.h" +#include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/Analysis/PathDiagnostic.h" + +namespace clang { + +class AnalysisManager : public BugReporterData { + AnalysisContextManager ContextMgr; + AnalysisContext *CurrentContext; + + ASTContext &Ctx; + Diagnostic &Diags; + const LangOptions &LangInfo; + + llvm::OwningPtr PD; + + // Configurable components creators. + StoreManagerCreator CreateStoreMgr; + ConstraintManagerCreator CreateConstraintMgr; + + enum AnalysisScope { ScopeTU, ScopeDecl } AScope; + + bool DisplayedFunction; + bool VisualizeEGDot; + bool VisualizeEGUbi; + bool PurgeDead; + bool EagerlyAssume; + bool TrimGraph; + +public: + AnalysisManager(Decl *d, ASTContext &ctx, Diagnostic &diags, + const LangOptions &lang, PathDiagnosticClient *pd, + StoreManagerCreator storemgr, + ConstraintManagerCreator constraintmgr, + bool displayProgress, bool vizdot, bool vizubi, + bool purge, bool eager, bool trim) + + : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), + CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), + AScope(ScopeDecl), DisplayedFunction(!displayProgress), + VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), + EagerlyAssume(eager), TrimGraph(trim) { + + CurrentContext = ContextMgr.getContext(d); + } + + AnalysisManager(ASTContext &ctx, Diagnostic &diags, + const LangOptions &lang, PathDiagnosticClient *pd, + StoreManagerCreator storemgr, + ConstraintManagerCreator constraintmgr, + bool displayProgress, bool vizdot, bool vizubi, + bool purge, bool eager, bool trim) + + : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), + CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), + AScope(ScopeDecl), DisplayedFunction(!displayProgress), + VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), + EagerlyAssume(eager), TrimGraph(trim) { + + CurrentContext = 0; + } + + Decl *getCodeDecl() const { + assert (AScope == ScopeDecl); + return CurrentContext->getDecl(); + } + + Stmt *getBody() const { + assert (AScope == ScopeDecl); + return CurrentContext->getBody(); + } + + StoreManagerCreator getStoreManagerCreator() { + return CreateStoreMgr; + }; + + ConstraintManagerCreator getConstraintManagerCreator() { + return CreateConstraintMgr; + } + + virtual CFG *getCFG() { + return CurrentContext->getCFG(); + } + + virtual ParentMap &getParentMap() { + return CurrentContext->getParentMap(); + } + + virtual LiveVariables *getLiveVariables() { + return CurrentContext->getLiveVariables(); + } + + virtual ASTContext &getContext() { + return Ctx; + } + + virtual SourceManager &getSourceManager() { + return getContext().getSourceManager(); + } + + virtual Diagnostic &getDiagnostic() { + return Diags; + } + + const LangOptions &getLangOptions() const { + return LangInfo; + } + + virtual PathDiagnosticClient *getPathDiagnosticClient() { + return PD.get(); + } + + bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } + + bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } + + bool shouldVisualize() const { + return VisualizeEGDot || VisualizeEGUbi; + } + + bool shouldTrimGraph() const { return TrimGraph; } + + bool shouldPurgeDead() const { return PurgeDead; } + + bool shouldEagerlyAssume() const { return EagerlyAssume; } + + void DisplayFunction(); +}; + +} + +#endif diff --git a/lib/Analysis/AnalysisManager.cpp b/lib/Analysis/AnalysisManager.cpp new file mode 100644 index 0000000000..125c00bfee --- /dev/null +++ b/lib/Analysis/AnalysisManager.cpp @@ -0,0 +1,36 @@ +//== AnalysisManager.cpp - Path sensitive analysis data manager ----*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the AnalysisManager class. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/PathSensitive/AnalysisManager.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/Support/Streams.h" + +using namespace clang; + +void AnalysisManager::DisplayFunction() { + + if (DisplayedFunction) + return; + + DisplayedFunction = true; + + // FIXME: Is getCodeDecl() always a named decl? + if (isa(getCodeDecl()) || + isa(getCodeDecl())) { + NamedDecl *ND = cast(getCodeDecl()); + SourceManager &SM = getContext().getSourceManager(); + llvm::cerr << "ANALYZE: " + << SM.getPresumedLoc(ND->getLocation()).getFilename() + << ' ' << ND->getNameAsString() << '\n'; + } +} diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index d631c69749..10bb00fa33 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -25,7 +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/AnalysisManager.h" #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/LocalCheckers.h" @@ -46,7 +46,6 @@ static ExplodedNodeImpl::Auditor* CreateUbiViz(); //===----------------------------------------------------------------------===// namespace { - class AnalysisManager; typedef void (*CodeAction)(AnalysisManager& Mgr); } // end anonymous namespace @@ -84,7 +83,11 @@ namespace { PreprocessorFactory* PPF; const std::string OutDir; AnalyzerOptions Opts; - llvm::OwningPtr PD; + + // PD is owned by AnalysisManager. + PathDiagnosticClient *PD; + StoreManagerCreator CreateStoreMgr; + ConstraintManagerCreator CreateConstraintMgr; AnalysisConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, @@ -93,7 +96,47 @@ namespace { const AnalyzerOptions& opts) : LOpts(lopts), Diags(diags), Ctx(0), PP(pp), PPF(ppf), - OutDir(outdir), Opts(opts) {} + OutDir(outdir), Opts(opts) { + DigestAnalyzerOptions(); + } + + void DigestAnalyzerOptions() { + // Create the PathDiagnosticClient. + if (!OutDir.empty()) { + switch (Opts.AnalysisDiagOpt) { + default: +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \ + case PD_##NAME: PD = CREATEFN(OutDir, PP, PPF); break; +#include "clang/Frontend/Analyses.def" + } + } + + // Create the analyzer component creators. + if (ManagerRegistry::StoreMgrCreator != 0) { + CreateStoreMgr = ManagerRegistry::StoreMgrCreator; + } + else { + switch (Opts.AnalysisStoreOpt) { + default: + assert(0 && "Unknown store manager."); +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ + case NAME##Model: CreateStoreMgr = CREATEFN; break; +#include "clang/Frontend/Analyses.def" + } + } + + if (ManagerRegistry::ConstraintMgrCreator != 0) + CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator; + else { + switch (Opts.AnalysisConstraintsOpt) { + default: + assert(0 && "Unknown store manager."); +#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ + case NAME##Model: CreateConstraintMgr = CREATEFN; break; +#include "clang/Frontend/Analyses.def" + } + } + } void addCodeAction(CodeAction action) { FunctionActions.push_back(action); @@ -124,164 +167,6 @@ namespace { }; - class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData { - AnalysisContextManager ContextMgr; - AnalysisContext *CurrentContext; - - enum AnalysisScope { ScopeTU, ScopeDecl } AScope; - - AnalysisConsumer& C; - bool DisplayedFunction; - - // Configurable components creators. - StoreManagerCreator CreateStoreMgr; - ConstraintManagerCreator CreateConstraintMgr; - - public: - AnalysisManager(AnalysisConsumer& c, Decl* d, bool displayProgress) - : AScope(ScopeDecl), C(c), DisplayedFunction(!displayProgress) { - setManagerCreators(); - CurrentContext = ContextMgr.getContext(d); - } - - AnalysisManager(AnalysisConsumer& c, bool displayProgress) - : AScope(ScopeTU), C(c), DisplayedFunction(!displayProgress) { - setManagerCreators(); - CurrentContext = 0; - } - - Decl* getCodeDecl() const { - assert (AScope == ScopeDecl); - return CurrentContext->getDecl(); - } - - Stmt* getBody() const { - assert (AScope == ScopeDecl); - return CurrentContext->getBody(); - } - - StoreManagerCreator getStoreManagerCreator() { - return CreateStoreMgr; - }; - - ConstraintManagerCreator getConstraintManagerCreator() { - return CreateConstraintMgr; - } - - virtual CFG* getCFG() { - return CurrentContext->getCFG(); - } - - virtual ParentMap& getParentMap() { - return CurrentContext->getParentMap(); - } - - virtual LiveVariables* getLiveVariables() { - return CurrentContext->getLiveVariables(); - } - - virtual ASTContext& getContext() { - return *C.Ctx; - } - - virtual SourceManager& getSourceManager() { - return getContext().getSourceManager(); - } - - virtual Diagnostic& getDiagnostic() { - return C.Diags; - } - - const LangOptions& getLangOptions() const { - return C.LOpts; - } - - virtual PathDiagnosticClient* getPathDiagnosticClient() { - if (C.PD.get() == 0 && !C.OutDir.empty()) { - switch (C.Opts.AnalysisDiagOpt) { - default: -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\ -case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; -#include "clang/Frontend/Analyses.def" - } - } - return C.PD.get(); - } - - bool shouldVisualizeGraphviz() const { return C.Opts.VisualizeEGDot; } - - bool shouldVisualizeUbigraph() const { return C.Opts.VisualizeEGUbi; } - - bool shouldVisualize() const { - return C.Opts.VisualizeEGDot || C.Opts.VisualizeEGUbi; - } - - bool shouldTrimGraph() const { return C.Opts.TrimGraph; } - - bool shouldPurgeDead() const { return C.Opts.PurgeDead; } - - bool shouldEagerlyAssume() const { return C.Opts.EagerlyAssume; } - - void DisplayFunction() { - - if (DisplayedFunction) - return; - - DisplayedFunction = true; - - // FIXME: Is getCodeDecl() always a named decl? - if (isa(getCodeDecl()) || - isa(getCodeDecl())) { - NamedDecl *ND = cast(getCodeDecl()); - SourceManager &SM = getContext().getSourceManager(); - llvm::cerr << "ANALYZE: " - << SM.getPresumedLoc(ND->getLocation()).getFilename() - << ' ' << ND->getNameAsString() << '\n'; - } - } - - private: - /// Set configurable analyzer components creators. First check if there are - /// components registered at runtime. Otherwise fall back to builtin - /// components. - void setManagerCreators() { - if (ManagerRegistry::StoreMgrCreator != 0) { - CreateStoreMgr = ManagerRegistry::StoreMgrCreator; - } - else { - switch (C.Opts.AnalysisStoreOpt) { - default: - assert(0 && "Unknown store manager."); -#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ - case NAME##Model: CreateStoreMgr = CREATEFN; break; -#include "clang/Frontend/Analyses.def" - } - } - - if (ManagerRegistry::ConstraintMgrCreator != 0) - CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator; - else { - switch (C.Opts.AnalysisConstraintsOpt) { - default: - assert(0 && "Unknown store manager."); -#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ - case NAME##Model: CreateConstraintMgr = CREATEFN; break; -#include "clang/Frontend/Analyses.def" - } - } - - - // Some DiagnosticClients should be created all the time instead of - // lazily. Create those now. - switch (C.Opts.AnalysisDiagOpt) { - default: break; -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\ -case PD_##NAME: if (AUTOCREATE) getPathDiagnosticClient(); break; -#include "clang/Frontend/Analyses.def" - } - } - - }; } // end anonymous namespace @@ -331,7 +216,11 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { if(!TranslationUnitActions.empty()) { - AnalysisManager mgr(*this, Opts.AnalyzerDisplayProgress); + AnalysisManager mgr(*Ctx, Diags, LOpts, PD, + CreateStoreMgr, CreateConstraintMgr, + Opts.AnalyzerDisplayProgress, Opts.VisualizeEGDot, + Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume, + Opts.TrimGraph); for (Actions::iterator I = TranslationUnitActions.begin(), E = TranslationUnitActions.end(); I != E; ++I) (*I)(mgr); @@ -346,11 +235,6 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { if (ObjCImplementationDecl* ID = dyn_cast(*I)) HandleCode(ID, 0, ObjCImplementationActions); } - - // Delete the PathDiagnosticClient here just in case the AnalysisConsumer - // object doesn't get released. This will cause any side-effects in the - // destructor of the PathDiagnosticClient to get executed. - PD.reset(); } void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { @@ -367,7 +251,11 @@ 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, Opts.AnalyzerDisplayProgress); + AnalysisManager mgr(D, *Ctx, Diags, LOpts, PD, + CreateStoreMgr, CreateConstraintMgr, + Opts.AnalyzerDisplayProgress, Opts.VisualizeEGDot, + Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume, + Opts.TrimGraph); // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) -- 2.40.0