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