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