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