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