CheckerManager.h revision e9a906b99286b44dcf5eb896f17df74d588e4ce9
1//===--- CheckerManager.h - Static Analyzer Checker 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// Defines the Static Analyzer Checker Manager.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
15#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
16
17#include "clang/Analysis/ProgramPoint.h"
18#include "clang/Basic/LangOptions.h"
19#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
20#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/SmallVector.h"
23#include <vector>
24
25namespace clang {
26  class Decl;
27  class Stmt;
28  class CallExpr;
29
30namespace ento {
31  class CheckerBase;
32  class ExprEngine;
33  class AnalysisManager;
34  class BugReporter;
35  class CheckerContext;
36  class SimpleCall;
37  class ObjCMethodCall;
38  class SVal;
39  class ExplodedNode;
40  class ExplodedNodeSet;
41  class ExplodedGraph;
42  class ProgramState;
43  class NodeBuilder;
44  struct NodeBuilderContext;
45  class MemRegion;
46  class SymbolReaper;
47
48template <typename T> class CheckerFn;
49
50template <typename RET, typename P1, typename P2, typename P3, typename P4,
51          typename P5>
52class CheckerFn<RET(P1, P2, P3, P4, P5)> {
53  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
54  Func Fn;
55public:
56  CheckerBase *Checker;
57  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
58  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
59    return Fn(Checker, p1, p2, p3, p4, p5);
60  }
61};
62
63template <typename RET, typename P1, typename P2, typename P3, typename P4>
64class CheckerFn<RET(P1, P2, P3, P4)> {
65  typedef RET (*Func)(void *, P1, P2, P3, P4);
66  Func Fn;
67public:
68  CheckerBase *Checker;
69  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
70  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
71    return Fn(Checker, p1, p2, p3, p4);
72  }
73};
74
75template <typename RET, typename P1, typename P2, typename P3>
76class CheckerFn<RET(P1, P2, P3)> {
77  typedef RET (*Func)(void *, P1, P2, P3);
78  Func Fn;
79public:
80  CheckerBase *Checker;
81  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
82  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
83};
84
85template <typename RET, typename P1, typename P2>
86class CheckerFn<RET(P1, P2)> {
87  typedef RET (*Func)(void *, P1, P2);
88  Func Fn;
89public:
90  CheckerBase *Checker;
91  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
92  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
93};
94
95template <typename RET, typename P1>
96class CheckerFn<RET(P1)> {
97  typedef RET (*Func)(void *, P1);
98  Func Fn;
99public:
100  CheckerBase *Checker;
101  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
102  RET operator()(P1 p1) const { return Fn(Checker, p1); }
103};
104
105template <typename RET>
106class CheckerFn<RET()> {
107  typedef RET (*Func)(void *);
108  Func Fn;
109public:
110  CheckerBase *Checker;
111  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
112  RET operator()() const { return Fn(Checker); }
113};
114
115/// \brief Describes the different reasons a pointer escapes
116/// during analysis.
117enum PointerEscapeKind {
118  /// A pointer escapes due to binding its value to a location
119  /// that the analyzer cannot track.
120  PSK_EscapeOnBind,
121
122  /// The pointer has been passed to a function call directly.
123  PSK_DirectEscapeOnCall,
124
125  /// The pointer has been passed to a function indirectly.
126  /// For example, the pointer is accessible through an
127  /// argument to a function.
128  PSK_IndirectEscapeOnCall,
129
130  /// The reason for pointer escape is unknown. For example,
131  /// a region containing this pointer is invalidated.
132  PSK_EscapeOther
133};
134
135class CheckerManager {
136  const LangOptions LangOpts;
137  AnalyzerOptionsRef AOptions;
138public:
139  CheckerManager(const LangOptions &langOpts,
140                 AnalyzerOptionsRef AOptions)
141    : LangOpts(langOpts),
142      AOptions(AOptions) {}
143
144  ~CheckerManager();
145
146  bool hasPathSensitiveCheckers() const;
147
148  void finishedCheckerRegistration();
149
150  const LangOptions &getLangOpts() const { return LangOpts; }
151  AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
152
153  typedef CheckerBase *CheckerRef;
154  typedef const void *CheckerTag;
155  typedef CheckerFn<void ()> CheckerDtor;
156
157//===----------------------------------------------------------------------===//
158// registerChecker
159//===----------------------------------------------------------------------===//
160
161  /// \brief Used to register checkers.
162  ///
163  /// \returns a pointer to the checker object.
164  template <typename CHECKER>
165  CHECKER *registerChecker() {
166    CheckerTag tag = getTag<CHECKER>();
167    CheckerRef &ref = CheckerTags[tag];
168    if (ref)
169      return static_cast<CHECKER *>(ref); // already registered.
170
171    CHECKER *checker = new CHECKER();
172    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
173    CHECKER::_register(checker, *this);
174    ref = checker;
175    return checker;
176  }
177
178  template <typename CHECKER>
179  CHECKER *registerChecker(AnalyzerOptions &AOpts) {
180    CheckerTag tag = getTag<CHECKER>();
181    CheckerRef &ref = CheckerTags[tag];
182    if (ref)
183      return static_cast<CHECKER *>(ref); // already registered.
184
185    CHECKER *checker = new CHECKER(AOpts);
186    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
187    CHECKER::_register(checker, *this);
188    ref = checker;
189    return checker;
190  }
191
192//===----------------------------------------------------------------------===//
193// Functions for running checkers for AST traversing..
194//===----------------------------------------------------------------------===//
195
196  /// \brief Run checkers handling Decls.
197  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
198                            BugReporter &BR);
199
200  /// \brief Run checkers handling Decls containing a Stmt body.
201  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
202                            BugReporter &BR);
203
204//===----------------------------------------------------------------------===//
205// Functions for running checkers for path-sensitive checking.
206//===----------------------------------------------------------------------===//
207
208  /// \brief Run checkers for pre-visiting Stmts.
209  ///
210  /// The notification is performed for every explored CFGElement, which does
211  /// not include the control flow statements such as IfStmt.
212  ///
213  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
214  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
215                             const ExplodedNodeSet &Src,
216                             const Stmt *S,
217                             ExprEngine &Eng) {
218    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
219  }
220
221  /// \brief Run checkers for post-visiting Stmts.
222  ///
223  /// The notification is performed for every explored CFGElement, which does
224  /// not include the control flow statements such as IfStmt.
225  ///
226  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
227  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
228                              const ExplodedNodeSet &Src,
229                              const Stmt *S,
230                              ExprEngine &Eng,
231                              bool wasInlined = false) {
232    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
233  }
234
235  /// \brief Run checkers for visiting Stmts.
236  void runCheckersForStmt(bool isPreVisit,
237                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
238                          const Stmt *S, ExprEngine &Eng,
239                          bool wasInlined = false);
240
241  /// \brief Run checkers for pre-visiting obj-c messages.
242  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
243                                    const ExplodedNodeSet &Src,
244                                    const ObjCMethodCall &msg,
245                                    ExprEngine &Eng) {
246    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
247  }
248
249  /// \brief Run checkers for post-visiting obj-c messages.
250  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
251                                     const ExplodedNodeSet &Src,
252                                     const ObjCMethodCall &msg,
253                                     ExprEngine &Eng,
254                                     bool wasInlined = false) {
255    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
256                              wasInlined);
257  }
258
259  /// \brief Run checkers for visiting obj-c messages.
260  void runCheckersForObjCMessage(bool isPreVisit,
261                                 ExplodedNodeSet &Dst,
262                                 const ExplodedNodeSet &Src,
263                                 const ObjCMethodCall &msg, ExprEngine &Eng,
264                                 bool wasInlined = false);
265
266  /// \brief Run checkers for pre-visiting obj-c messages.
267  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
268                             const CallEvent &Call, ExprEngine &Eng) {
269    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
270  }
271
272  /// \brief Run checkers for post-visiting obj-c messages.
273  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
274                              const CallEvent &Call, ExprEngine &Eng,
275                              bool wasInlined = false) {
276    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
277                            wasInlined);
278  }
279
280  /// \brief Run checkers for visiting obj-c messages.
281  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
282                               const ExplodedNodeSet &Src,
283                               const CallEvent &Call, ExprEngine &Eng,
284                               bool wasInlined = false);
285
286  /// \brief Run checkers for load/store of a location.
287  void runCheckersForLocation(ExplodedNodeSet &Dst,
288                              const ExplodedNodeSet &Src,
289                              SVal location,
290                              bool isLoad,
291                              const Stmt *NodeEx,
292                              const Stmt *BoundEx,
293                              ExprEngine &Eng);
294
295  /// \brief Run checkers for binding of a value to a location.
296  void runCheckersForBind(ExplodedNodeSet &Dst,
297                          const ExplodedNodeSet &Src,
298                          SVal location, SVal val,
299                          const Stmt *S, ExprEngine &Eng,
300                          const ProgramPoint &PP);
301
302  /// \brief Run checkers for end of analysis.
303  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
304                                 ExprEngine &Eng);
305
306  /// \brief Run checkers on end of function.
307  void runCheckersForEndFunction(NodeBuilderContext &BC,
308                                 ExplodedNodeSet &Dst,
309                                 ExplodedNode *Pred,
310                                 ExprEngine &Eng);
311
312  /// \brief Run checkers for branch condition.
313  void runCheckersForBranchCondition(const Stmt *condition,
314                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
315                                     ExprEngine &Eng);
316
317  /// \brief Run checkers for live symbols.
318  ///
319  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
320  /// register symbols of interest as live. These symbols will not be marked
321  /// dead and removed.
322  void runCheckersForLiveSymbols(ProgramStateRef state,
323                                 SymbolReaper &SymReaper);
324
325  /// \brief Run checkers for dead symbols.
326  ///
327  /// Notifies checkers when symbols become dead. For example, this allows
328  /// checkers to aggressively clean up/reduce the checker state and produce
329  /// precise diagnostics.
330  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
331                                 const ExplodedNodeSet &Src,
332                                 SymbolReaper &SymReaper, const Stmt *S,
333                                 ExprEngine &Eng,
334                                 ProgramPoint::Kind K);
335
336  /// \brief True if at least one checker wants to check region changes.
337  bool wantsRegionChangeUpdate(ProgramStateRef state);
338
339  /// \brief Run checkers for region changes.
340  ///
341  /// This corresponds to the check::RegionChanges callback.
342  /// \param state The current program state.
343  /// \param invalidated A set of all symbols potentially touched by the change.
344  /// \param ExplicitRegions The regions explicitly requested for invalidation.
345  ///   For example, in the case of a function call, these would be arguments.
346  /// \param Regions The transitive closure of accessible regions,
347  ///   i.e. all regions that may have been touched by this change.
348  /// \param Call The call expression wrapper if the regions are invalidated
349  ///   by a call.
350  ProgramStateRef
351  runCheckersForRegionChanges(ProgramStateRef state,
352                              const InvalidatedSymbols *invalidated,
353                              ArrayRef<const MemRegion *> ExplicitRegions,
354                              ArrayRef<const MemRegion *> Regions,
355                              const CallEvent *Call);
356
357  /// \brief Run checkers when pointers escape.
358  ///
359  /// This notifies the checkers about pointer escape, which occurs whenever
360  /// the analyzer cannot track the symbol any more. For example, as a
361  /// result of assigning a pointer into a global or when it's passed to a
362  /// function call the analyzer cannot model.
363  ///
364  /// \param State The state at the point of escape.
365  /// \param Escaped The list of escaped symbols.
366  /// \param Call The corresponding CallEvent, if the symbols escape as
367  ///        parameters to the given call.
368  /// \param IsConst Specifies if the pointer is const.
369  /// \returns Checkers can modify the state by returning a new one.
370  ProgramStateRef
371  runCheckersForPointerEscape(ProgramStateRef State,
372                              const InvalidatedSymbols &Escaped,
373                              const CallEvent *Call,
374                              PointerEscapeKind Kind,
375                              bool IsConst = false);
376
377  /// \brief Run checkers for handling assumptions on symbolic values.
378  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
379                                           SVal Cond, bool Assumption);
380
381  /// \brief Run checkers for evaluating a call.
382  ///
383  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
384  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
385                              const ExplodedNodeSet &Src,
386                              const CallEvent &CE, ExprEngine &Eng);
387
388  /// \brief Run checkers for the entire Translation Unit.
389  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
390                                         AnalysisManager &mgr,
391                                         BugReporter &BR);
392
393  /// \brief Run checkers for debug-printing a ProgramState.
394  ///
395  /// Unlike most other callbacks, any checker can simply implement the virtual
396  /// method CheckerBase::printState if it has custom data to print.
397  /// \param Out The output stream
398  /// \param State The state being printed
399  /// \param NL The preferred representation of a newline.
400  /// \param Sep The preferred separator between different kinds of data.
401  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
402                                const char *NL, const char *Sep);
403
404//===----------------------------------------------------------------------===//
405// Internal registration functions for AST traversing.
406//===----------------------------------------------------------------------===//
407
408  // Functions used by the registration mechanism, checkers should not touch
409  // these directly.
410
411  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
412      CheckDeclFunc;
413
414  typedef bool (*HandlesDeclFunc)(const Decl *D);
415  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
416
417  void _registerForBody(CheckDeclFunc checkfn);
418
419//===----------------------------------------------------------------------===//
420// Internal registration functions for path-sensitive checking.
421//===----------------------------------------------------------------------===//
422
423  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
424
425  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
426      CheckObjCMessageFunc;
427
428  typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
429      CheckCallFunc;
430
431  typedef CheckerFn<void (const SVal &location, bool isLoad,
432                          const Stmt *S,
433                          CheckerContext &)>
434      CheckLocationFunc;
435
436  typedef CheckerFn<void (const SVal &location, const SVal &val,
437                          const Stmt *S, CheckerContext &)>
438      CheckBindFunc;
439
440  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
441      CheckEndAnalysisFunc;
442
443  typedef CheckerFn<void (CheckerContext &)>
444      CheckEndFunctionFunc;
445
446  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
447      CheckBranchConditionFunc;
448
449  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
450      CheckDeadSymbolsFunc;
451
452  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
453
454  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
455                                const InvalidatedSymbols *symbols,
456                                ArrayRef<const MemRegion *> ExplicitRegions,
457                                ArrayRef<const MemRegion *> Regions,
458                                const CallEvent *Call)>
459      CheckRegionChangesFunc;
460
461  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
462
463  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
464                                     const InvalidatedSymbols &Escaped,
465                                     const CallEvent *Call,
466                                     PointerEscapeKind Kind,
467                                     bool IsConst)>
468      CheckPointerEscapeFunc;
469
470  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
471                                          const SVal &cond, bool assumption)>
472      EvalAssumeFunc;
473
474  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
475      EvalCallFunc;
476
477  typedef CheckerFn<void (const TranslationUnitDecl *,
478                          AnalysisManager&, BugReporter &)>
479      CheckEndOfTranslationUnit;
480
481  typedef bool (*HandlesStmtFunc)(const Stmt *D);
482  void _registerForPreStmt(CheckStmtFunc checkfn,
483                           HandlesStmtFunc isForStmtFn);
484  void _registerForPostStmt(CheckStmtFunc checkfn,
485                            HandlesStmtFunc isForStmtFn);
486
487  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
488  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
489
490  void _registerForPreCall(CheckCallFunc checkfn);
491  void _registerForPostCall(CheckCallFunc checkfn);
492
493  void _registerForLocation(CheckLocationFunc checkfn);
494
495  void _registerForBind(CheckBindFunc checkfn);
496
497  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
498
499  void _registerForEndFunction(CheckEndFunctionFunc checkfn);
500
501  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
502
503  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
504
505  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
506
507  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
508                                 WantsRegionChangeUpdateFunc wantUpdateFn);
509
510  void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
511
512  void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
513
514  void _registerForEvalAssume(EvalAssumeFunc checkfn);
515
516  void _registerForEvalCall(EvalCallFunc checkfn);
517
518  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
519
520//===----------------------------------------------------------------------===//
521// Internal registration functions for events.
522//===----------------------------------------------------------------------===//
523
524  typedef void *EventTag;
525  typedef CheckerFn<void (const void *event)> CheckEventFunc;
526
527  template <typename EVENT>
528  void _registerListenerForEvent(CheckEventFunc checkfn) {
529    EventInfo &info = Events[getTag<EVENT>()];
530    info.Checkers.push_back(checkfn);
531  }
532
533  template <typename EVENT>
534  void _registerDispatcherForEvent() {
535    EventInfo &info = Events[getTag<EVENT>()];
536    info.HasDispatcher = true;
537  }
538
539  template <typename EVENT>
540  void _dispatchEvent(const EVENT &event) const {
541    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
542    if (I == Events.end())
543      return;
544    const EventInfo &info = I->second;
545    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
546      info.Checkers[i](&event);
547  }
548
549//===----------------------------------------------------------------------===//
550// Implementation details.
551//===----------------------------------------------------------------------===//
552
553private:
554  template <typename CHECKER>
555  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
556
557  template <typename T>
558  static void *getTag() { static int tag; return &tag; }
559
560  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
561
562  std::vector<CheckerDtor> CheckerDtors;
563
564  struct DeclCheckerInfo {
565    CheckDeclFunc CheckFn;
566    HandlesDeclFunc IsForDeclFn;
567  };
568  std::vector<DeclCheckerInfo> DeclCheckers;
569
570  std::vector<CheckDeclFunc> BodyCheckers;
571
572  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
573  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
574  CachedDeclCheckersMapTy CachedDeclCheckersMap;
575
576  struct StmtCheckerInfo {
577    CheckStmtFunc CheckFn;
578    HandlesStmtFunc IsForStmtFn;
579    bool IsPreVisit;
580  };
581  std::vector<StmtCheckerInfo> StmtCheckers;
582
583  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
584  typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
585  CachedStmtCheckersMapTy CachedStmtCheckersMap;
586
587  const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
588                                                     bool isPreVisit);
589
590  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
591  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
592
593  std::vector<CheckCallFunc> PreCallCheckers;
594  std::vector<CheckCallFunc> PostCallCheckers;
595
596  std::vector<CheckLocationFunc> LocationCheckers;
597
598  std::vector<CheckBindFunc> BindCheckers;
599
600  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
601
602  std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
603
604  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
605
606  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
607
608  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
609
610  struct RegionChangesCheckerInfo {
611    CheckRegionChangesFunc CheckFn;
612    WantsRegionChangeUpdateFunc WantUpdateFn;
613  };
614  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
615
616  std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
617
618  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
619
620  std::vector<EvalCallFunc> EvalCallCheckers;
621
622  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
623
624  struct EventInfo {
625    SmallVector<CheckEventFunc, 4> Checkers;
626    bool HasDispatcher;
627    EventInfo() : HasDispatcher(false) { }
628  };
629
630  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
631  EventsTy Events;
632};
633
634} // end ento namespace
635
636} // end clang namespace
637
638#endif
639