| //== AnalysisManager.h - 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_GR_ANALYSISMANAGER_H |
| #define LLVM_CLANG_GR_ANALYSISMANAGER_H |
| |
| #include "clang/Analysis/AnalysisContext.h" |
| #include "clang/Frontend/AnalyzerOptions.h" |
| #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" |
| #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" |
| |
| namespace clang { |
| |
| namespace idx { |
| class Indexer; |
| class TranslationUnit; |
| } |
| |
| namespace ento { |
| class CheckerManager; |
| |
| typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls; |
| |
| class AnalysisManager : public BugReporterData { |
| virtual void anchor(); |
| AnalysisDeclContextManager AnaCtxMgr; |
| |
| ASTContext &Ctx; |
| DiagnosticsEngine &Diags; |
| const LangOptions &LangOpts; |
| |
| OwningPtr<PathDiagnosticConsumer> PD; |
| |
| // Configurable components creators. |
| StoreManagerCreator CreateStoreMgr; |
| ConstraintManagerCreator CreateConstraintMgr; |
| |
| CheckerManager *CheckerMgr; |
| |
| /// \brief Provide function definitions in other translation units. This is |
| /// NULL if we don't have multiple translation units. AnalysisManager does |
| /// not own the Indexer. |
| idx::Indexer *Idxer; |
| |
| enum AnalysisScope { ScopeTU, ScopeDecl } AScope; |
| |
| /// \brief The maximum number of exploded nodes the analyzer will generate. |
| unsigned MaxNodes; |
| |
| /// \brief The maximum number of times the analyzer visits a block. |
| unsigned MaxVisit; |
| |
| bool VisualizeEGDot; |
| bool VisualizeEGUbi; |
| AnalysisPurgeMode PurgeDead; |
| |
| /// \brief The flag regulates if we should eagerly assume evaluations of |
| /// conditionals, thus, bifurcating the path. |
| /// |
| /// EagerlyAssume - A flag indicating how the engine should handle |
| /// expressions such as: 'x = (y != 0)'. When this flag is true then |
| /// the subexpression 'y != 0' will be eagerly assumed to be true or false, |
| /// thus evaluating it to the integers 0 or 1 respectively. The upside |
| /// is that this can increase analysis precision until we have a better way |
| /// to lazily evaluate such logic. The downside is that it eagerly |
| /// bifurcates paths. |
| bool EagerlyAssume; |
| bool TrimGraph; |
| bool EagerlyTrimEGraph; |
| |
| public: |
| // \brief inter-procedural analysis mode. |
| AnalysisIPAMode IPAMode; |
| |
| // Settings for inlining tuning. |
| /// \brief The inlining stack depth limit. |
| unsigned InlineMaxStackDepth; |
| /// \brief The max number of basic blocks in a function being inlined. |
| unsigned InlineMaxFunctionSize; |
| /// \brief The mode of function selection used during inlining. |
| AnalysisInliningMode InliningMode; |
| |
| /// \brief Re-analyze paths leading to exhausted nodes with a different |
| /// strategy for better code coverage. |
| bool RetryExhausted; |
| |
| public: |
| AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, |
| const LangOptions &lang, PathDiagnosticConsumer *pd, |
| StoreManagerCreator storemgr, |
| ConstraintManagerCreator constraintmgr, |
| CheckerManager *checkerMgr, |
| idx::Indexer *idxer, |
| unsigned maxnodes, unsigned maxvisit, |
| bool vizdot, bool vizubi, AnalysisPurgeMode purge, |
| bool eager, bool trim, |
| bool useUnoptimizedCFG, |
| bool addImplicitDtors, bool addInitializers, |
| bool eagerlyTrimEGraph, |
| AnalysisIPAMode ipa, |
| unsigned inlineMaxStack, |
| unsigned inlineMaxFunctionSize, |
| AnalysisInliningMode inliningMode, |
| bool retry); |
| |
| /// Construct a clone of the given AnalysisManager with the given ASTContext |
| /// and DiagnosticsEngine. |
| AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, |
| AnalysisManager &ParentAM); |
| |
| ~AnalysisManager() { FlushDiagnostics(); } |
| |
| void ClearContexts() { |
| AnaCtxMgr.clear(); |
| } |
| |
| AnalysisDeclContextManager& getAnalysisDeclContextManager() { |
| return AnaCtxMgr; |
| } |
| |
| StoreManagerCreator getStoreManagerCreator() { |
| return CreateStoreMgr; |
| } |
| |
| ConstraintManagerCreator getConstraintManagerCreator() { |
| return CreateConstraintMgr; |
| } |
| |
| CheckerManager *getCheckerManager() const { return CheckerMgr; } |
| |
| idx::Indexer *getIndexer() const { return Idxer; } |
| |
| virtual ASTContext &getASTContext() { |
| return Ctx; |
| } |
| |
| virtual SourceManager &getSourceManager() { |
| return getASTContext().getSourceManager(); |
| } |
| |
| virtual DiagnosticsEngine &getDiagnostic() { |
| return Diags; |
| } |
| |
| const LangOptions &getLangOpts() const { |
| return LangOpts; |
| } |
| |
| virtual PathDiagnosticConsumer *getPathDiagnosticConsumer() { |
| return PD.get(); |
| } |
| |
| void FlushDiagnostics() { |
| if (PD.get()) |
| PD->FlushDiagnostics(0); |
| } |
| |
| unsigned getMaxNodes() const { return MaxNodes; } |
| |
| unsigned getMaxVisit() const { return MaxVisit; } |
| |
| bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } |
| |
| bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } |
| |
| bool shouldVisualize() const { |
| return VisualizeEGDot || VisualizeEGUbi; |
| } |
| |
| bool shouldEagerlyTrimExplodedGraph() const { return EagerlyTrimEGraph; } |
| |
| bool shouldTrimGraph() const { return TrimGraph; } |
| |
| AnalysisPurgeMode getPurgeMode() const { return PurgeDead; } |
| |
| bool shouldEagerlyAssume() const { return EagerlyAssume; } |
| |
| bool shouldInlineCall() const { return (IPAMode == Inlining); } |
| |
| bool hasIndexer() const { return Idxer != 0; } |
| |
| AnalysisDeclContext *getAnalysisDeclContextInAnotherTU(const Decl *D); |
| |
| CFG *getCFG(Decl const *D) { |
| return AnaCtxMgr.getContext(D)->getCFG(); |
| } |
| |
| template <typename T> |
| T *getAnalysis(Decl const *D) { |
| return AnaCtxMgr.getContext(D)->getAnalysis<T>(); |
| } |
| |
| ParentMap &getParentMap(Decl const *D) { |
| return AnaCtxMgr.getContext(D)->getParentMap(); |
| } |
| |
| AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) { |
| return AnaCtxMgr.getContext(D); |
| } |
| |
| AnalysisDeclContext *getAnalysisDeclContext(const Decl *D, idx::TranslationUnit *TU) { |
| return AnaCtxMgr.getContext(D, TU); |
| } |
| |
| }; |
| |
| } // enAnaCtxMgrspace |
| |
| } // end clang namespace |
| |
| #endif |