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() = default;
     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:
    108   CheckerManager(const LangOptions &langOpts,
    109                  AnalyzerOptionsRef AOptions)
    110     : LangOpts(langOpts),
    111       AOptions(AOptions) {}
    112 
    113   ~CheckerManager();
    114 
    115   void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
    116   CheckName getCurrentCheckName() const { return CurrentCheckName; }
    117 
    118   bool hasPathSensitiveCheckers() const;
    119 
    120   void finishedCheckerRegistration();
    121 
    122   const LangOptions &getLangOpts() const { return LangOpts; }
    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>
    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>
    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
    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.
    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.
    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.
    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>
    516   void _registerListenerForEvent(CheckEventFunc checkfn) {
    517     EventInfo &info = Events[getTag<EVENT>()];
    518     info.Checkers.push_back(checkfn);
    519   }
    520 
    521   template <typename EVENT>
    522   void _registerDispatcherForEvent() {
    523     EventInfo &info = Events[getTag<EVENT>()];
    524     info.HasDispatcher = true;
    525   }
    526 
    527   template <typename 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>
    543   static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
    544 
    545   template <typename T>
    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;
    621     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