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