AnalysisManager.h revision a5937bbfd19e61d651a58b0f0ffeef68457902a5
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
33class 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
78public:
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