AnalysisManager.h revision 218887
148734Siwasaki//== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-//
248734Siwasaki//
366830Sobrien//                     The LLVM Compiler Infrastructure
466830Sobrien//
566830Sobrien// This file is distributed under the University of Illinois Open Source
666830Sobrien// License. See LICENSE.TXT for details.
766830Sobrien//
866830Sobrien//===----------------------------------------------------------------------===//
966830Sobrien//
1066830Sobrien// This file defines the AnalysisManager class that manages the data and policy
1166830Sobrien// for path sensitive analysis.
1266830Sobrien//
1366830Sobrien//===----------------------------------------------------------------------===//
1466830Sobrien
1566830Sobrien#ifndef LLVM_CLANG_GR_ANALYSISMANAGER_H
1666830Sobrien#define LLVM_CLANG_GR_ANALYSISMANAGER_H
1766830Sobrien
1866830Sobrien#include "clang/Analysis/AnalysisContext.h"
1966830Sobrien#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
2066830Sobrien#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
2166830Sobrien
2266830Sobriennamespace clang {
2366830Sobrien
2466830Sobriennamespace idx {
2566830Sobrien  class Indexer;
2666830Sobrien  class TranslationUnit;
2750472Speter}
2848734Siwasaki
2966830Sobriennamespace ento {
3048734Siwasaki  class CheckerManager;
3148734Siwasaki
32124001Snjlclass AnalysisManager : public BugReporterData {
33170976Snjl  AnalysisContextManager AnaCtxMgr;
34124001Snjl  LocationContextManager LocCtxMgr;
35124001Snjl
36124001Snjl  ASTContext &Ctx;
37124001Snjl  Diagnostic &Diags;
38124001Snjl  const LangOptions &LangInfo;
39124001Snjl
4051231Ssheldonh  llvm::OwningPtr<PathDiagnosticClient> PD;
4148734Siwasaki
4248734Siwasaki  // Configurable components creators.
43124001Snjl  StoreManagerCreator CreateStoreMgr;
4448734Siwasaki  ConstraintManagerCreator CreateConstraintMgr;
4548734Siwasaki
4648734Siwasaki  CheckerManager *CheckerMgr;
4748734Siwasaki
4851231Ssheldonh  /// \brief Provide function definitions in other translation units. This is
4951231Ssheldonh  /// NULL if we don't have multiple translation units. AnalysisManager does
5048734Siwasaki  /// not own the Indexer.
51170976Snjl  idx::Indexer *Idxer;
52170976Snjl
53170976Snjl  enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
54124001Snjl
55170976Snjl  // The maximum number of exploded nodes the analyzer will generate.
56170976Snjl  unsigned MaxNodes;
57170976Snjl
58170976Snjl  // The maximum number of times the analyzer visit a block.
59124001Snjl  unsigned MaxVisit;
6048734Siwasaki
6148734Siwasaki  bool VisualizeEGDot;
6248734Siwasaki  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
77public:
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
99  ~AnalysisManager() { FlushDiagnostics(); }
100
101  void ClearContexts() {
102    LocCtxMgr.clear();
103    AnaCtxMgr.clear();
104  }
105
106  AnalysisContextManager& getAnalysisContextManager() {
107    return AnaCtxMgr;
108  }
109
110  StoreManagerCreator getStoreManagerCreator() {
111    return CreateStoreMgr;
112  }
113
114  ConstraintManagerCreator getConstraintManagerCreator() {
115    return CreateConstraintMgr;
116  }
117
118  CheckerManager *getCheckerManager() const { return CheckerMgr; }
119
120  idx::Indexer *getIndexer() const { return Idxer; }
121
122  virtual ASTContext &getASTContext() {
123    return Ctx;
124  }
125
126  virtual SourceManager &getSourceManager() {
127    return getASTContext().getSourceManager();
128  }
129
130  virtual Diagnostic &getDiagnostic() {
131    return Diags;
132  }
133
134  const LangOptions &getLangOptions() const {
135    return LangInfo;
136  }
137
138  virtual PathDiagnosticClient *getPathDiagnosticClient() {
139    return PD.get();
140  }
141
142  void FlushDiagnostics() {
143    if (PD.get())
144      PD->FlushDiagnostics();
145  }
146
147  unsigned getMaxNodes() const { return MaxNodes; }
148
149  unsigned getMaxVisit() const { return MaxVisit; }
150
151  bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
152
153  bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
154
155  bool shouldVisualize() const {
156    return VisualizeEGDot || VisualizeEGUbi;
157  }
158
159  bool shouldEagerlyTrimExplodedGraph() const { return EagerlyTrimEGraph; }
160
161  bool shouldTrimGraph() const { return TrimGraph; }
162
163  bool shouldPurgeDead() const { return PurgeDead; }
164
165  bool shouldEagerlyAssume() const { return EagerlyAssume; }
166
167  bool shouldInlineCall() const { return InlineCall; }
168
169  bool hasIndexer() const { return Idxer != 0; }
170
171  AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D);
172
173  CFG *getCFG(Decl const *D) {
174    return AnaCtxMgr.getContext(D)->getCFG();
175  }
176
177  LiveVariables *getLiveVariables(Decl const *D) {
178    return AnaCtxMgr.getContext(D)->getLiveVariables();
179  }
180
181  ParentMap &getParentMap(Decl const *D) {
182    return AnaCtxMgr.getContext(D)->getParentMap();
183  }
184
185  AnalysisContext *getAnalysisContext(const Decl *D) {
186    return AnaCtxMgr.getContext(D);
187  }
188
189  AnalysisContext *getAnalysisContext(const Decl *D, idx::TranslationUnit *TU) {
190    return AnaCtxMgr.getContext(D, TU);
191  }
192
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.
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.
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