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 <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;
     57   CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
     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;
     90   explicit CheckName(StringRef Name) : Name(Name) {}
     91 
     92 public:
     93   CheckName() = default;
     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:
    109   CheckerManager(const LangOptions &langOpts, AnalyzerOptionsRef AOptions)
    110       : LangOpts(langOpts), AOptions(std::move(AOptions)) {}
    111 
    112   ~CheckerManager();
    113 
    114   void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
    115   CheckName getCurrentCheckName() const { return CurrentCheckName; }
    116 
    117   bool hasPathSensitiveCheckers() const;
    118 
    119   void finishedCheckerRegistration();
    120 
    121   const LangOptions &getLangOpts() const { return LangOpts; }
    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>
    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>
    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
    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.
    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.
    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.
    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>
    525   void _registerListenerForEvent(CheckEventFunc checkfn) {
    526     EventInfo &info = Events[getTag<EVENT>()];
    527     info.Checkers.push_back(checkfn);
    528   }
    529 
    530   template <typename EVENT>
    531   void _registerDispatcherForEvent() {
    532     EventInfo &info = Events[getTag<EVENT>()];
    533     info.HasDispatcher = true;
    534   }
    535 
    536   template <typename 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>
    552   static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
    553 
    554   template <typename T>
    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;
    631     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