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