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