• 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 <utility>
24 #include <vector>
25 
26 namespace clang {
27   class Decl;
28   class Stmt;
29   class CallExpr;
30 
31 namespace 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 
49 template <typename T> class CheckerFn;
50 
51 template <typename RET, typename... Ps>
52 class CheckerFn<RET(Ps...)> {
53   typedef RET (*Func)(void *, Ps...);
54   Func Fn;
55 public:
56   CheckerBase *Checker;
CheckerFn(CheckerBase * checker,Func fn)57   CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
operator()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.
65 enum 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.
87 class CheckName {
88   StringRef Name;
89   friend class ::clang::ento::CheckerRegistry;
CheckName(StringRef Name)90   explicit CheckName(StringRef Name) : Name(Name) {}
91 
92 public:
93   CheckName() = default;
getName()94   StringRef getName() const { return Name; }
95 };
96 
97 enum class ObjCMessageVisitKind {
98   Pre,
99   Post,
100   MessageNil
101 };
102 
103 class CheckerManager {
104   const LangOptions LangOpts;
105   AnalyzerOptionsRef AOptions;
106   CheckName CurrentCheckName;
107 
108 public:
CheckerManager(const LangOptions & langOpts,AnalyzerOptionsRef AOptions)109   CheckerManager(const LangOptions &langOpts, AnalyzerOptionsRef AOptions)
110       : LangOpts(langOpts), AOptions(std::move(AOptions)) {}
111 
112   ~CheckerManager();
113 
setCurrentCheckName(CheckName name)114   void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
getCurrentCheckName()115   CheckName getCurrentCheckName() const { return CurrentCheckName; }
116 
117   bool hasPathSensitiveCheckers() const;
118 
119   void finishedCheckerRegistration();
120 
getLangOpts()121   const LangOptions &getLangOpts() const { return LangOpts; }
getAnalyzerOptions()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>
registerChecker()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>
registerChecker(AnalyzerOptions & AOpts)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
runCheckersForPreStmt(ExplodedNodeSet & Dst,const ExplodedNodeSet & Src,const Stmt * S,ExprEngine & Eng)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.
runCheckersForPreObjCMessage(ExplodedNodeSet & Dst,const ExplodedNodeSet & Src,const ObjCMethodCall & msg,ExprEngine & Eng)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.
runCheckersForObjCMessageNil(ExplodedNodeSet & Dst,const ExplodedNodeSet & Src,const ObjCMethodCall & msg,ExprEngine & Eng)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.
runCheckersForPreCall(ExplodedNodeSet & Dst,const ExplodedNodeSet & Src,const CallEvent & Call,ExprEngine & Eng)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 True if at least one checker wants to check region changes.
326   bool wantsRegionChangeUpdate(ProgramStateRef state);
327 
328   /// \brief Run checkers for region changes.
329   ///
330   /// This corresponds to the check::RegionChanges callback.
331   /// \param state The current program state.
332   /// \param invalidated A set of all symbols potentially touched by the change.
333   /// \param ExplicitRegions The regions explicitly requested for invalidation.
334   ///   For example, in the case of a function call, these would be arguments.
335   /// \param Regions The transitive closure of accessible regions,
336   ///   i.e. all regions that may have been touched by this change.
337   /// \param Call The call expression wrapper if the regions are invalidated
338   ///   by a call.
339   ProgramStateRef
340   runCheckersForRegionChanges(ProgramStateRef state,
341                               const InvalidatedSymbols *invalidated,
342                               ArrayRef<const MemRegion *> ExplicitRegions,
343                               ArrayRef<const MemRegion *> Regions,
344                               const CallEvent *Call);
345 
346   /// \brief Run checkers when pointers escape.
347   ///
348   /// This notifies the checkers about pointer escape, which occurs whenever
349   /// the analyzer cannot track the symbol any more. For example, as a
350   /// result of assigning a pointer into a global or when it's passed to a
351   /// function call the analyzer cannot model.
352   ///
353   /// \param State The state at the point of escape.
354   /// \param Escaped The list of escaped symbols.
355   /// \param Call The corresponding CallEvent, if the symbols escape as
356   ///        parameters to the given call.
357   /// \param Kind The reason of pointer escape.
358   /// \param ITraits Information about invalidation for a particular
359   ///        region/symbol.
360   /// \returns Checkers can modify the state by returning a new one.
361   ProgramStateRef
362   runCheckersForPointerEscape(ProgramStateRef State,
363                               const InvalidatedSymbols &Escaped,
364                               const CallEvent *Call,
365                               PointerEscapeKind Kind,
366                              RegionAndSymbolInvalidationTraits *ITraits);
367 
368   /// \brief Run checkers for handling assumptions on symbolic values.
369   ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
370                                            SVal Cond, bool Assumption);
371 
372   /// \brief Run checkers for evaluating a call.
373   ///
374   /// Warning: Currently, the CallEvent MUST come from a CallExpr!
375   void runCheckersForEvalCall(ExplodedNodeSet &Dst,
376                               const ExplodedNodeSet &Src,
377                               const CallEvent &CE, ExprEngine &Eng);
378 
379   /// \brief Run checkers for the entire Translation Unit.
380   void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
381                                          AnalysisManager &mgr,
382                                          BugReporter &BR);
383 
384   /// \brief Run checkers for debug-printing a ProgramState.
385   ///
386   /// Unlike most other callbacks, any checker can simply implement the virtual
387   /// method CheckerBase::printState if it has custom data to print.
388   /// \param Out The output stream
389   /// \param State The state being printed
390   /// \param NL The preferred representation of a newline.
391   /// \param Sep The preferred separator between different kinds of data.
392   void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
393                                 const char *NL, const char *Sep);
394 
395 //===----------------------------------------------------------------------===//
396 // Internal registration functions for AST traversing.
397 //===----------------------------------------------------------------------===//
398 
399   // Functions used by the registration mechanism, checkers should not touch
400   // these directly.
401 
402   typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
403       CheckDeclFunc;
404 
405   typedef bool (*HandlesDeclFunc)(const Decl *D);
406   void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
407 
408   void _registerForBody(CheckDeclFunc checkfn);
409 
410 //===----------------------------------------------------------------------===//
411 // Internal registration functions for path-sensitive checking.
412 //===----------------------------------------------------------------------===//
413 
414   typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
415 
416   typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
417       CheckObjCMessageFunc;
418 
419   typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
420       CheckCallFunc;
421 
422   typedef CheckerFn<void (const SVal &location, bool isLoad,
423                           const Stmt *S,
424                           CheckerContext &)>
425       CheckLocationFunc;
426 
427   typedef CheckerFn<void (const SVal &location, const SVal &val,
428                           const Stmt *S, CheckerContext &)>
429       CheckBindFunc;
430 
431   typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
432       CheckEndAnalysisFunc;
433 
434   typedef CheckerFn<void (CheckerContext &)>
435       CheckBeginFunctionFunc;
436 
437   typedef CheckerFn<void (CheckerContext &)>
438       CheckEndFunctionFunc;
439 
440   typedef CheckerFn<void (const Stmt *, CheckerContext &)>
441       CheckBranchConditionFunc;
442 
443   typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
444       CheckDeadSymbolsFunc;
445 
446   typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
447 
448   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
449                                 const InvalidatedSymbols *symbols,
450                                 ArrayRef<const MemRegion *> ExplicitRegions,
451                                 ArrayRef<const MemRegion *> Regions,
452                                 const CallEvent *Call)>
453       CheckRegionChangesFunc;
454 
455   typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
456 
457   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
458                                      const InvalidatedSymbols &Escaped,
459                                      const CallEvent *Call,
460                                      PointerEscapeKind Kind,
461                                      RegionAndSymbolInvalidationTraits *ITraits)>
462       CheckPointerEscapeFunc;
463 
464   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
465                                           const SVal &cond, bool assumption)>
466       EvalAssumeFunc;
467 
468   typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
469       EvalCallFunc;
470 
471   typedef CheckerFn<void (const TranslationUnitDecl *,
472                           AnalysisManager&, BugReporter &)>
473       CheckEndOfTranslationUnit;
474 
475   typedef bool (*HandlesStmtFunc)(const Stmt *D);
476   void _registerForPreStmt(CheckStmtFunc checkfn,
477                            HandlesStmtFunc isForStmtFn);
478   void _registerForPostStmt(CheckStmtFunc checkfn,
479                             HandlesStmtFunc isForStmtFn);
480 
481   void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
482   void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
483 
484   void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);
485 
486   void _registerForPreCall(CheckCallFunc checkfn);
487   void _registerForPostCall(CheckCallFunc checkfn);
488 
489   void _registerForLocation(CheckLocationFunc checkfn);
490 
491   void _registerForBind(CheckBindFunc checkfn);
492 
493   void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
494 
495   void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
496   void _registerForEndFunction(CheckEndFunctionFunc checkfn);
497 
498   void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
499 
500   void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
501 
502   void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
503 
504   void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
505                                  WantsRegionChangeUpdateFunc wantUpdateFn);
506 
507   void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
508 
509   void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
510 
511   void _registerForEvalAssume(EvalAssumeFunc checkfn);
512 
513   void _registerForEvalCall(EvalCallFunc checkfn);
514 
515   void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
516 
517 //===----------------------------------------------------------------------===//
518 // Internal registration functions for events.
519 //===----------------------------------------------------------------------===//
520 
521   typedef void *EventTag;
522   typedef CheckerFn<void (const void *event)> CheckEventFunc;
523 
524   template <typename EVENT>
_registerListenerForEvent(CheckEventFunc checkfn)525   void _registerListenerForEvent(CheckEventFunc checkfn) {
526     EventInfo &info = Events[getTag<EVENT>()];
527     info.Checkers.push_back(checkfn);
528   }
529 
530   template <typename EVENT>
_registerDispatcherForEvent()531   void _registerDispatcherForEvent() {
532     EventInfo &info = Events[getTag<EVENT>()];
533     info.HasDispatcher = true;
534   }
535 
536   template <typename EVENT>
_dispatchEvent(const EVENT & event)537   void _dispatchEvent(const EVENT &event) const {
538     EventsTy::const_iterator I = Events.find(getTag<EVENT>());
539     if (I == Events.end())
540       return;
541     const EventInfo &info = I->second;
542     for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
543       info.Checkers[i](&event);
544   }
545 
546 //===----------------------------------------------------------------------===//
547 // Implementation details.
548 //===----------------------------------------------------------------------===//
549 
550 private:
551   template <typename CHECKER>
destruct(void * obj)552   static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
553 
554   template <typename T>
getTag()555   static void *getTag() { static int tag; return &tag; }
556 
557   llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
558 
559   std::vector<CheckerDtor> CheckerDtors;
560 
561   struct DeclCheckerInfo {
562     CheckDeclFunc CheckFn;
563     HandlesDeclFunc IsForDeclFn;
564   };
565   std::vector<DeclCheckerInfo> DeclCheckers;
566 
567   std::vector<CheckDeclFunc> BodyCheckers;
568 
569   typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
570   typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
571   CachedDeclCheckersMapTy CachedDeclCheckersMap;
572 
573   struct StmtCheckerInfo {
574     CheckStmtFunc CheckFn;
575     HandlesStmtFunc IsForStmtFn;
576     bool IsPreVisit;
577   };
578   std::vector<StmtCheckerInfo> StmtCheckers;
579 
580   typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
581   typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
582   CachedStmtCheckersMapTy CachedStmtCheckersMap;
583 
584   const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
585                                                      bool isPreVisit);
586 
587   /// Returns the checkers that have registered for callbacks of the
588   /// given \p Kind.
589   const std::vector<CheckObjCMessageFunc> &
590   getObjCMessageCheckers(ObjCMessageVisitKind Kind);
591 
592   std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
593   std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
594   std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;
595 
596   std::vector<CheckCallFunc> PreCallCheckers;
597   std::vector<CheckCallFunc> PostCallCheckers;
598 
599   std::vector<CheckLocationFunc> LocationCheckers;
600 
601   std::vector<CheckBindFunc> BindCheckers;
602 
603   std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
604 
605   std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers;
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;
EventInfoEventInfo631     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 
642 #endif
643