Home | History | Annotate | Download | only in PathSensitive
      1 //== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the AnalysisManager class that manages the data and policy
     11 // for path sensitive analysis.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_GR_ANALYSISMANAGER_H
     16 #define LLVM_CLANG_GR_ANALYSISMANAGER_H
     17 
     18 #include "clang/Analysis/AnalysisContext.h"
     19 #include "clang/Frontend/AnalyzerOptions.h"
     20 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
     21 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
     22 
     23 namespace clang {
     24 
     25 namespace idx {
     26   class Indexer;
     27   class TranslationUnit;
     28 }
     29 
     30 namespace ento {
     31   class CheckerManager;
     32 
     33 class AnalysisManager : public BugReporterData {
     34   AnalysisContextManager AnaCtxMgr;
     35   LocationContextManager LocCtxMgr;
     36 
     37   ASTContext &Ctx;
     38   DiagnosticsEngine &Diags;
     39   const LangOptions &LangInfo;
     40 
     41   llvm::OwningPtr<PathDiagnosticConsumer> PD;
     42 
     43   // Configurable components creators.
     44   StoreManagerCreator CreateStoreMgr;
     45   ConstraintManagerCreator CreateConstraintMgr;
     46 
     47   CheckerManager *CheckerMgr;
     48 
     49   /// \brief Provide function definitions in other translation units. This is
     50   /// NULL if we don't have multiple translation units. AnalysisManager does
     51   /// not own the Indexer.
     52   idx::Indexer *Idxer;
     53 
     54   enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
     55 
     56   // The maximum number of exploded nodes the analyzer will generate.
     57   unsigned MaxNodes;
     58 
     59   // The maximum number of times the analyzer visit a block.
     60   unsigned MaxVisit;
     61 
     62   bool VisualizeEGDot;
     63   bool VisualizeEGUbi;
     64   AnalysisPurgeMode PurgeDead;
     65 
     66   /// EargerlyAssume - A flag indicating how the engine should handle
     67   //   expressions such as: 'x = (y != 0)'.  When this flag is true then
     68   //   the subexpression 'y != 0' will be eagerly assumed to be true or false,
     69   //   thus evaluating it to the integers 0 or 1 respectively.  The upside
     70   //   is that this can increase analysis precision until we have a better way
     71   //   to lazily evaluate such logic.  The downside is that it eagerly
     72   //   bifurcates paths.
     73   bool EagerlyAssume;
     74   bool TrimGraph;
     75   bool InlineCall;
     76   bool EagerlyTrimEGraph;
     77 
     78 public:
     79   AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
     80                   const LangOptions &lang, PathDiagnosticConsumer *pd,
     81                   StoreManagerCreator storemgr,
     82                   ConstraintManagerCreator constraintmgr,
     83                   CheckerManager *checkerMgr,
     84                   idx::Indexer *idxer,
     85                   unsigned maxnodes, unsigned maxvisit,
     86                   bool vizdot, bool vizubi, AnalysisPurgeMode purge,
     87                   bool eager, bool trim,
     88                   bool inlinecall, bool useUnoptimizedCFG,
     89                   bool addImplicitDtors, bool addInitializers,
     90                   bool eagerlyTrimEGraph);
     91 
     92   /// Construct a clone of the given AnalysisManager with the given ASTContext
     93   /// and DiagnosticsEngine.
     94   AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
     95                   AnalysisManager &ParentAM);
     96 
     97   ~AnalysisManager() { FlushDiagnostics(); }
     98 
     99   void ClearContexts() {
    100     LocCtxMgr.clear();
    101     AnaCtxMgr.clear();
    102   }
    103 
    104   AnalysisContextManager& getAnalysisContextManager() {
    105     return AnaCtxMgr;
    106   }
    107 
    108   StoreManagerCreator getStoreManagerCreator() {
    109     return CreateStoreMgr;
    110   }
    111 
    112   ConstraintManagerCreator getConstraintManagerCreator() {
    113     return CreateConstraintMgr;
    114   }
    115 
    116   CheckerManager *getCheckerManager() const { return CheckerMgr; }
    117 
    118   idx::Indexer *getIndexer() const { return Idxer; }
    119 
    120   virtual ASTContext &getASTContext() {
    121     return Ctx;
    122   }
    123 
    124   virtual SourceManager &getSourceManager() {
    125     return getASTContext().getSourceManager();
    126   }
    127 
    128   virtual DiagnosticsEngine &getDiagnostic() {
    129     return Diags;
    130   }
    131 
    132   const LangOptions &getLangOptions() const {
    133     return LangInfo;
    134   }
    135 
    136   virtual PathDiagnosticConsumer *getPathDiagnosticConsumer() {
    137     return PD.get();
    138   }
    139 
    140   void FlushDiagnostics() {
    141     if (PD.get())
    142       PD->FlushDiagnostics();
    143   }
    144 
    145   unsigned getMaxNodes() const { return MaxNodes; }
    146 
    147   unsigned getMaxVisit() const { return MaxVisit; }
    148 
    149   bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
    150 
    151   bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
    152 
    153   bool shouldVisualize() const {
    154     return VisualizeEGDot || VisualizeEGUbi;
    155   }
    156 
    157   bool shouldEagerlyTrimExplodedGraph() const { return EagerlyTrimEGraph; }
    158 
    159   bool shouldTrimGraph() const { return TrimGraph; }
    160 
    161   AnalysisPurgeMode getPurgeMode() const { return PurgeDead; }
    162 
    163   bool shouldEagerlyAssume() const { return EagerlyAssume; }
    164 
    165   bool shouldInlineCall() const { return InlineCall; }
    166 
    167   bool hasIndexer() const { return Idxer != 0; }
    168 
    169   AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D);
    170 
    171   CFG *getCFG(Decl const *D) {
    172     return AnaCtxMgr.getContext(D)->getCFG();
    173   }
    174 
    175   template <typename T>
    176   T *getAnalysis(Decl const *D) {
    177     return AnaCtxMgr.getContext(D)->getAnalysis<T>();
    178   }
    179 
    180   ParentMap &getParentMap(Decl const *D) {
    181     return AnaCtxMgr.getContext(D)->getParentMap();
    182   }
    183 
    184   AnalysisContext *getAnalysisContext(const Decl *D) {
    185     return AnaCtxMgr.getContext(D);
    186   }
    187 
    188   AnalysisContext *getAnalysisContext(const Decl *D, idx::TranslationUnit *TU) {
    189     return AnaCtxMgr.getContext(D, TU);
    190   }
    191 
    192   const StackFrameContext *getStackFrame(AnalysisContext *Ctx,
    193                                          LocationContext const *Parent,
    194                                          const Stmt *S,
    195                                          const CFGBlock *Blk, unsigned Idx) {
    196     return LocCtxMgr.getStackFrame(Ctx, Parent, S, Blk, Idx);
    197   }
    198 
    199   // Get the top level stack frame.
    200   const StackFrameContext *getStackFrame(Decl const *D,
    201                                          idx::TranslationUnit *TU) {
    202     return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0);
    203   }
    204 
    205   // Get a stack frame with parent.
    206   StackFrameContext const *getStackFrame(const Decl *D,
    207                                          LocationContext const *Parent,
    208                                          const Stmt *S,
    209                                          const CFGBlock *Blk, unsigned Idx) {
    210     return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S,
    211                                    Blk,Idx);
    212   }
    213 };
    214 
    215 } // end GR namespace
    216 
    217 } // end clang namespace
    218 
    219 #endif
    220