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