AnalysisManager.h revision 3bbd8cd831788c506f2980293eb3c7e1b3ca2501
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
23namespace clang {
24
25namespace idx {
26  class Indexer;
27  class TranslationUnit;
28}
29
30namespace ento {
31  class CheckerManager;
32
33typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
34
35class FunctionSummariesTy {
36  struct FunctionSummary {
37    /// True if this function has reached a max block count while inlined from
38    /// at least one call site.
39    bool MayReachMaxBlockCount;
40    FunctionSummary() : MayReachMaxBlockCount(false) {}
41  };
42
43  typedef llvm::DenseMap<const Decl*, FunctionSummary> MapTy;
44  MapTy Map;
45
46public:
47  void markReachedMaxBlockCount(const Decl* D) {
48    Map[D].MayReachMaxBlockCount = true;
49  }
50
51  bool hasReachedMaxBlockCount(const Decl* D) {
52  MapTy::const_iterator I = Map.find(D);
53    if (I != Map.end())
54      return I->second.MayReachMaxBlockCount;
55    return false;
56  }
57
58};
59
60class AnalysisManager : public BugReporterData {
61  virtual void anchor();
62  AnalysisDeclContextManager AnaCtxMgr;
63
64  ASTContext &Ctx;
65  DiagnosticsEngine &Diags;
66  const LangOptions &LangOpts;
67
68  OwningPtr<PathDiagnosticConsumer> PD;
69
70  // Configurable components creators.
71  StoreManagerCreator CreateStoreMgr;
72  ConstraintManagerCreator CreateConstraintMgr;
73
74  CheckerManager *CheckerMgr;
75
76  /// \brief Provide function definitions in other translation units. This is
77  /// NULL if we don't have multiple translation units. AnalysisManager does
78  /// not own the Indexer.
79  idx::Indexer *Idxer;
80
81  enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
82
83  /// \brief The maximum number of exploded nodes the analyzer will generate.
84  unsigned MaxNodes;
85
86  /// \brief The maximum number of times the analyzer visits a block.
87  unsigned MaxVisit;
88
89  bool VisualizeEGDot;
90  bool VisualizeEGUbi;
91  AnalysisPurgeMode PurgeDead;
92
93  /// \brief The flag regulates if we should eagerly assume evaluations of
94  /// conditionals, thus, bifurcating the path.
95  ///
96  /// EagerlyAssume - A flag indicating how the engine should handle
97  ///   expressions such as: 'x = (y != 0)'.  When this flag is true then
98  ///   the subexpression 'y != 0' will be eagerly assumed to be true or false,
99  ///   thus evaluating it to the integers 0 or 1 respectively.  The upside
100  ///   is that this can increase analysis precision until we have a better way
101  ///   to lazily evaluate such logic.  The downside is that it eagerly
102  ///   bifurcates paths.
103  bool EagerlyAssume;
104  bool TrimGraph;
105  bool EagerlyTrimEGraph;
106
107public:
108  // \brief inter-procedural analysis mode.
109  AnalysisIPAMode IPAMode;
110
111  // Settings for inlining tuning.
112  /// \brief The inlining stack depth limit.
113  unsigned InlineMaxStackDepth;
114  /// \brief The max number of basic blocks in a function being inlined.
115  unsigned InlineMaxFunctionSize;
116  /// \brief The mode of function selection used during inlining.
117  AnalysisInliningMode InliningMode;
118
119  /// \brief Do not re-analyze paths leading to exhausted nodes with a different
120  /// strategy. We get better code coverage when retry is enabled.
121  bool NoRetryExhausted;
122
123public:
124  AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
125                  const LangOptions &lang, PathDiagnosticConsumer *pd,
126                  StoreManagerCreator storemgr,
127                  ConstraintManagerCreator constraintmgr,
128                  CheckerManager *checkerMgr,
129                  idx::Indexer *idxer,
130                  unsigned maxnodes, unsigned maxvisit,
131                  bool vizdot, bool vizubi, AnalysisPurgeMode purge,
132                  bool eager, bool trim,
133                  bool useUnoptimizedCFG,
134                  bool addImplicitDtors, bool addInitializers,
135                  bool eagerlyTrimEGraph,
136                  AnalysisIPAMode ipa,
137                  unsigned inlineMaxStack,
138                  unsigned inlineMaxFunctionSize,
139                  AnalysisInliningMode inliningMode,
140                  bool NoRetry);
141
142  /// Construct a clone of the given AnalysisManager with the given ASTContext
143  /// and DiagnosticsEngine.
144  AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
145                  AnalysisManager &ParentAM);
146
147  ~AnalysisManager() { FlushDiagnostics(); }
148
149  void ClearContexts() {
150    AnaCtxMgr.clear();
151  }
152
153  AnalysisDeclContextManager& getAnalysisDeclContextManager() {
154    return AnaCtxMgr;
155  }
156
157  StoreManagerCreator getStoreManagerCreator() {
158    return CreateStoreMgr;
159  }
160
161  ConstraintManagerCreator getConstraintManagerCreator() {
162    return CreateConstraintMgr;
163  }
164
165  CheckerManager *getCheckerManager() const { return CheckerMgr; }
166
167  idx::Indexer *getIndexer() const { return Idxer; }
168
169  virtual ASTContext &getASTContext() {
170    return Ctx;
171  }
172
173  virtual SourceManager &getSourceManager() {
174    return getASTContext().getSourceManager();
175  }
176
177  virtual DiagnosticsEngine &getDiagnostic() {
178    return Diags;
179  }
180
181  const LangOptions &getLangOpts() const {
182    return LangOpts;
183  }
184
185  virtual PathDiagnosticConsumer *getPathDiagnosticConsumer() {
186    return PD.get();
187  }
188
189  void FlushDiagnostics() {
190    if (PD.get())
191      PD->FlushDiagnostics(0);
192  }
193
194  unsigned getMaxNodes() const { return MaxNodes; }
195
196  unsigned getMaxVisit() const { return MaxVisit; }
197
198  bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
199
200  bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
201
202  bool shouldVisualize() const {
203    return VisualizeEGDot || VisualizeEGUbi;
204  }
205
206  bool shouldEagerlyTrimExplodedGraph() const { return EagerlyTrimEGraph; }
207
208  bool shouldTrimGraph() const { return TrimGraph; }
209
210  AnalysisPurgeMode getPurgeMode() const { return PurgeDead; }
211
212  bool shouldEagerlyAssume() const { return EagerlyAssume; }
213
214  bool shouldInlineCall() const { return (IPAMode == Inlining); }
215
216  bool hasIndexer() const { return Idxer != 0; }
217
218  AnalysisDeclContext *getAnalysisDeclContextInAnotherTU(const Decl *D);
219
220  CFG *getCFG(Decl const *D) {
221    return AnaCtxMgr.getContext(D)->getCFG();
222  }
223
224  template <typename T>
225  T *getAnalysis(Decl const *D) {
226    return AnaCtxMgr.getContext(D)->getAnalysis<T>();
227  }
228
229  ParentMap &getParentMap(Decl const *D) {
230    return AnaCtxMgr.getContext(D)->getParentMap();
231  }
232
233  AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) {
234    return AnaCtxMgr.getContext(D);
235  }
236
237  AnalysisDeclContext *getAnalysisDeclContext(const Decl *D, idx::TranslationUnit *TU) {
238    return AnaCtxMgr.getContext(D, TU);
239  }
240
241};
242
243} // enAnaCtxMgrspace
244
245} // end clang namespace
246
247#endif
248