//===- CheckerManager.h - Static Analyzer Checker Manager -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Defines the Static Analyzer Checker Manager.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H

#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <vector>

namespace clang {

class AnalyzerOptions;
class CallExpr;
class Decl;
class LocationContext;
class Stmt;
class TranslationUnitDecl;

namespace ento {

class AnalysisManager;
class CXXAllocatorCall;
class BugReporter;
class CallEvent;
class CheckerBase;
class CheckerContext;
class CheckerRegistry;
struct CheckerRegistryData;
class ExplodedGraph;
class ExplodedNode;
class ExplodedNodeSet;
class ExprEngine;
struct EvalCallOptions;
class MemRegion;
struct NodeBuilderContext;
class ObjCMethodCall;
class RegionAndSymbolInvalidationTraits;
class SVal;
class SymbolReaper;

template <typename T> class CheckerFn;

template <typename RET, typename... Ps>
class CheckerFn<RET(Ps...)> {
  using Func = RET (*)(void *, Ps...);

  Func Fn;

public:
  CheckerBase *Checker;

  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) {}

  RET operator()(Ps... ps) const {
    return Fn(Checker, ps...);
  }
};

/// Describes the different reasons a pointer escapes
/// during analysis.
enum PointerEscapeKind {
  /// A pointer escapes due to binding its value to a location
  /// that the analyzer cannot track.
  PSK_EscapeOnBind,

  /// The pointer has been passed to a function call directly.
  PSK_DirectEscapeOnCall,

  /// The pointer has been passed to a function indirectly.
  /// For example, the pointer is accessible through an
  /// argument to a function.
  PSK_IndirectEscapeOnCall,


  /// Escape for a new symbol that was generated into a region
  /// that the analyzer cannot follow during a conservative call.
  PSK_EscapeOutParameters,

  /// The reason for pointer escape is unknown. For example,
  /// a region containing this pointer is invalidated.
  PSK_EscapeOther
};

/// This wrapper is used to ensure that only StringRefs originating from the
/// CheckerRegistry are used as check names. We want to make sure all checker
/// name strings have a lifetime that keeps them alive at least until the path
/// diagnostics have been processed, since they are expected to be constexpr
/// string literals (most likely generated by TblGen).
class CheckerNameRef {
  friend class ::clang::ento::CheckerRegistry;

  StringRef Name;

  explicit CheckerNameRef(StringRef Name) : Name(Name) {}

public:
  CheckerNameRef() = default;

  StringRef getName() const { return Name; }
  operator StringRef() const { return Name; }
};

enum class ObjCMessageVisitKind {
  Pre,
  Post,
  MessageNil
};

class CheckerManager {
  ASTContext *Context = nullptr;
  const LangOptions LangOpts;
  const AnalyzerOptions &AOptions;
  const Preprocessor *PP = nullptr;
  CheckerNameRef CurrentCheckerName;
  DiagnosticsEngine &Diags;
  std::unique_ptr<CheckerRegistryData> RegistryData;

public:
  // These constructors are defined in the Frontend library, because
  // CheckerRegistry, a crucial component of the initialization is in there.
  // CheckerRegistry cannot be moved to the Core library, because the checker
  // registration functions are defined in the Checkers library, and the library
  // dependencies look like this: Core -> Checkers -> Frontend.

  CheckerManager(
      ASTContext &Context, AnalyzerOptions &AOptions, const Preprocessor &PP,
      ArrayRef<std::string> plugins,
      ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns);

  /// Constructs a CheckerManager that ignores all non TblGen-generated
  /// checkers. Useful for unit testing, unless the checker infrastructure
  /// itself is tested.
  CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions,
                 const Preprocessor &PP)
      : CheckerManager(Context, AOptions, PP, {}, {}) {}

  /// Constructs a CheckerManager without requiring an AST. No checker
  /// registration will take place. Only useful when one needs to print the
  /// help flags through CheckerRegistryData, and the AST is unavalaible.
  CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts,
                 DiagnosticsEngine &Diags, ArrayRef<std::string> plugins);

  ~CheckerManager();

  void setCurrentCheckerName(CheckerNameRef name) { CurrentCheckerName = name; }
  CheckerNameRef getCurrentCheckerName() const { return CurrentCheckerName; }

  bool hasPathSensitiveCheckers() const;

  void finishedCheckerRegistration();

  const LangOptions &getLangOpts() const { return LangOpts; }
  const AnalyzerOptions &getAnalyzerOptions() const { return AOptions; }
  const Preprocessor &getPreprocessor() const {
    assert(PP);
    return *PP;
  }
  const CheckerRegistryData &getCheckerRegistryData() const {
    return *RegistryData;
  }
  DiagnosticsEngine &getDiagnostics() const { return Diags; }
  ASTContext &getASTContext() const {
    assert(Context);
    return *Context;
  }

  /// Emits an error through a DiagnosticsEngine about an invalid user supplied
  /// checker option value.
  void reportInvalidCheckerOptionValue(const CheckerBase *C,
                                       StringRef OptionName,
                                       StringRef ExpectedValueDesc) const;

  using CheckerRef = CheckerBase *;
  using CheckerTag = const void *;
  using CheckerDtor = CheckerFn<void ()>;

//===----------------------------------------------------------------------===//
// Checker registration.
//===----------------------------------------------------------------------===//

  /// Used to register checkers.
  /// All arguments are automatically passed through to the checker
  /// constructor.
  ///
  /// \returns a pointer to the checker object.
  template <typename CHECKER, typename... AT>
  CHECKER *registerChecker(AT &&... Args) {
    CheckerTag tag = getTag<CHECKER>();
    CheckerRef &ref = CheckerTags[tag];
    assert(!ref && "Checker already registered, use getChecker!");

    CHECKER *checker = new CHECKER(std::forward<AT>(Args)...);
    checker->Name = CurrentCheckerName;
    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
    CHECKER::_register(checker, *this);
    ref = checker;
    return checker;
  }

  template <typename CHECKER>
  CHECKER *getChecker() {
    CheckerTag tag = getTag<CHECKER>();
    assert(CheckerTags.count(tag) != 0 &&
           "Requested checker is not registered! Maybe you should add it as a "
           "dependency in Checkers.td?");
    return static_cast<CHECKER *>(CheckerTags[tag]);
  }

//===----------------------------------------------------------------------===//
// Functions for running checkers for AST traversing.
//===----------------------------------------------------------------------===//

  /// Run checkers handling Decls.
  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
                            BugReporter &BR);

  /// Run checkers handling Decls containing a Stmt body.
  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
                            BugReporter &BR);

//===----------------------------------------------------------------------===//
// Functions for running checkers for path-sensitive checking.
//===----------------------------------------------------------------------===//

  /// Run checkers for pre-visiting Stmts.
  ///
  /// The notification is performed for every explored CFGElement, which does
  /// not include the control flow statements such as IfStmt.
  ///
  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
                             const ExplodedNodeSet &Src,
                             const Stmt *S,
                             ExprEngine &Eng) {
    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
  }

  /// Run checkers for post-visiting Stmts.
  ///
  /// The notification is performed for every explored CFGElement, which does
  /// not include the control flow statements such as IfStmt.
  ///
  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
                              const ExplodedNodeSet &Src,
                              const Stmt *S,
                              ExprEngine &Eng,
                              bool wasInlined = false) {
    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
  }

  /// Run checkers for visiting Stmts.
  void runCheckersForStmt(bool isPreVisit,
                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
                          const Stmt *S, ExprEngine &Eng,
                          bool wasInlined = false);

  /// Run checkers for pre-visiting obj-c messages.
  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
                                    const ExplodedNodeSet &Src,
                                    const ObjCMethodCall &msg,
                                    ExprEngine &Eng) {
    runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng);
  }

  /// Run checkers for post-visiting obj-c messages.
  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
                                     const ExplodedNodeSet &Src,
                                     const ObjCMethodCall &msg,
                                     ExprEngine &Eng,
                                     bool wasInlined = false) {
    runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng,
                              wasInlined);
  }

  /// Run checkers for visiting an obj-c message to nil.
  void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst,
                                    const ExplodedNodeSet &Src,
                                    const ObjCMethodCall &msg,
                                    ExprEngine &Eng) {
    runCheckersForObjCMessage(ObjCMessageVisitKind::MessageNil, Dst, Src, msg,
                              Eng);
  }

  /// Run checkers for visiting obj-c messages.
  void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind,
                                 ExplodedNodeSet &Dst,
                                 const ExplodedNodeSet &Src,
                                 const ObjCMethodCall &msg, ExprEngine &Eng,
                                 bool wasInlined = false);

  /// Run checkers for pre-visiting obj-c messages.
  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
                             const CallEvent &Call, ExprEngine &Eng) {
    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
  }

  /// Run checkers for post-visiting obj-c messages.
  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
                              const CallEvent &Call, ExprEngine &Eng,
                              bool wasInlined = false) {
    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
                            wasInlined);
  }

  /// Run checkers for visiting obj-c messages.
  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
                               const ExplodedNodeSet &Src,
                               const CallEvent &Call, ExprEngine &Eng,
                               bool wasInlined = false);

  /// Run checkers for load/store of a location.
  void runCheckersForLocation(ExplodedNodeSet &Dst,
                              const ExplodedNodeSet &Src,
                              SVal location,
                              bool isLoad,
                              const Stmt *NodeEx,
                              const Stmt *BoundEx,
                              ExprEngine &Eng);

  /// Run checkers for binding of a value to a location.
  void runCheckersForBind(ExplodedNodeSet &Dst,
                          const ExplodedNodeSet &Src,
                          SVal location, SVal val,
                          const Stmt *S, ExprEngine &Eng,
                          const ProgramPoint &PP);

  /// Run checkers for end of analysis.
  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
                                 ExprEngine &Eng);

  /// Run checkers on beginning of function.
  void runCheckersForBeginFunction(ExplodedNodeSet &Dst,
                                   const BlockEdge &L,
                                   ExplodedNode *Pred,
                                   ExprEngine &Eng);

  /// Run checkers on end of function.
  void runCheckersForEndFunction(NodeBuilderContext &BC,
                                 ExplodedNodeSet &Dst,
                                 ExplodedNode *Pred,
                                 ExprEngine &Eng,
                                 const ReturnStmt *RS);

  /// Run checkers for branch condition.
  void runCheckersForBranchCondition(const Stmt *condition,
                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
                                     ExprEngine &Eng);

  /// Run checkers between C++ operator new and constructor calls.
  void runCheckersForNewAllocator(const CXXAllocatorCall &Call,
                                  ExplodedNodeSet &Dst, ExplodedNode *Pred,
                                  ExprEngine &Eng, bool wasInlined = false);

  /// Run checkers for live symbols.
  ///
  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
  /// register symbols of interest as live. These symbols will not be marked
  /// dead and removed.
  void runCheckersForLiveSymbols(ProgramStateRef state,
                                 SymbolReaper &SymReaper);

  /// Run checkers for dead symbols.
  ///
  /// Notifies checkers when symbols become dead. For example, this allows
  /// checkers to aggressively clean up/reduce the checker state and produce
  /// precise diagnostics.
  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
                                 const ExplodedNodeSet &Src,
                                 SymbolReaper &SymReaper, const Stmt *S,
                                 ExprEngine &Eng,
                                 ProgramPoint::Kind K);

  /// Run checkers for region changes.
  ///
  /// This corresponds to the check::RegionChanges callback.
  /// \param state The current program state.
  /// \param invalidated A set of all symbols potentially touched by the change.
  /// \param ExplicitRegions The regions explicitly requested for invalidation.
  ///   For example, in the case of a function call, these would be arguments.
  /// \param Regions The transitive closure of accessible regions,
  ///   i.e. all regions that may have been touched by this change.
  /// \param Call The call expression wrapper if the regions are invalidated
  ///   by a call.
  ProgramStateRef
  runCheckersForRegionChanges(ProgramStateRef state,
                              const InvalidatedSymbols *invalidated,
                              ArrayRef<const MemRegion *> ExplicitRegions,
                              ArrayRef<const MemRegion *> Regions,
                              const LocationContext *LCtx,
                              const CallEvent *Call);

  /// Run checkers when pointers escape.
  ///
  /// This notifies the checkers about pointer escape, which occurs whenever
  /// the analyzer cannot track the symbol any more. For example, as a
  /// result of assigning a pointer into a global or when it's passed to a
  /// function call the analyzer cannot model.
  ///
  /// \param State The state at the point of escape.
  /// \param Escaped The list of escaped symbols.
  /// \param Call The corresponding CallEvent, if the symbols escape as
  ///        parameters to the given call.
  /// \param Kind The reason of pointer escape.
  /// \param ITraits Information about invalidation for a particular
  ///        region/symbol.
  /// \returns Checkers can modify the state by returning a new one.
  ProgramStateRef
  runCheckersForPointerEscape(ProgramStateRef State,
                              const InvalidatedSymbols &Escaped,
                              const CallEvent *Call,
                              PointerEscapeKind Kind,
                              RegionAndSymbolInvalidationTraits *ITraits);

  /// Run checkers for handling assumptions on symbolic values.
  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
                                           SVal Cond, bool Assumption);

  /// Run checkers for evaluating a call.
  ///
  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
  void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
                              const CallEvent &CE, ExprEngine &Eng,
                              const EvalCallOptions &CallOpts);

  /// Run checkers for the entire Translation Unit.
  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
                                         AnalysisManager &mgr,
                                         BugReporter &BR);

  /// Run checkers for debug-printing a ProgramState.
  ///
  /// Unlike most other callbacks, any checker can simply implement the virtual
  /// method CheckerBase::printState if it has custom data to print.
  ///
  /// \param Out   The output stream
  /// \param State The state being printed
  /// \param NL    The preferred representation of a newline.
  /// \param Space The preferred space between the left side and the message.
  /// \param IsDot Whether the message will be printed in 'dot' format.
  void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State,
                                    const char *NL = "\n",
                                    unsigned int Space = 0,
                                    bool IsDot = false) const;

  //===----------------------------------------------------------------------===//
  // Internal registration functions for AST traversing.
  //===----------------------------------------------------------------------===//

  // Functions used by the registration mechanism, checkers should not touch
  // these directly.

  using CheckDeclFunc =
      CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>;

  using HandlesDeclFunc = bool (*)(const Decl *D);

  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);

  void _registerForBody(CheckDeclFunc checkfn);

//===----------------------------------------------------------------------===//
// Internal registration functions for path-sensitive checking.
//===----------------------------------------------------------------------===//

  using CheckStmtFunc = CheckerFn<void (const Stmt *, CheckerContext &)>;

  using CheckObjCMessageFunc =
      CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>;

  using CheckCallFunc =
      CheckerFn<void (const CallEvent &, CheckerContext &)>;

  using CheckLocationFunc =
      CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S,
                      CheckerContext &)>;

  using CheckBindFunc =
      CheckerFn<void (const SVal &location, const SVal &val, const Stmt *S,
                      CheckerContext &)>;

  using CheckEndAnalysisFunc =
      CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>;

  using CheckBeginFunctionFunc = CheckerFn<void (CheckerContext &)>;

  using CheckEndFunctionFunc =
      CheckerFn<void (const ReturnStmt *, CheckerContext &)>;

  using CheckBranchConditionFunc =
      CheckerFn<void (const Stmt *, CheckerContext &)>;

  using CheckNewAllocatorFunc =
      CheckerFn<void(const CXXAllocatorCall &Call, CheckerContext &)>;

  using CheckDeadSymbolsFunc =
      CheckerFn<void (SymbolReaper &, CheckerContext &)>;

  using CheckLiveSymbolsFunc = CheckerFn<void (ProgramStateRef,SymbolReaper &)>;

  using CheckRegionChangesFunc =
      CheckerFn<ProgramStateRef (ProgramStateRef,
                                 const InvalidatedSymbols *symbols,
                                 ArrayRef<const MemRegion *> ExplicitRegions,
                                 ArrayRef<const MemRegion *> Regions,
                                 const LocationContext *LCtx,
                                 const CallEvent *Call)>;

  using CheckPointerEscapeFunc =
      CheckerFn<ProgramStateRef (ProgramStateRef,
                                 const InvalidatedSymbols &Escaped,
                                 const CallEvent *Call, PointerEscapeKind Kind,
                                 RegionAndSymbolInvalidationTraits *ITraits)>;

  using EvalAssumeFunc =
      CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond,
                                 bool assumption)>;

  using EvalCallFunc = CheckerFn<bool (const CallEvent &, CheckerContext &)>;

  using CheckEndOfTranslationUnit =
      CheckerFn<void (const TranslationUnitDecl *, AnalysisManager &,
                      BugReporter &)>;

  using HandlesStmtFunc = bool (*)(const Stmt *D);

  void _registerForPreStmt(CheckStmtFunc checkfn,
                           HandlesStmtFunc isForStmtFn);
  void _registerForPostStmt(CheckStmtFunc checkfn,
                            HandlesStmtFunc isForStmtFn);

  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);

  void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn);

  void _registerForPreCall(CheckCallFunc checkfn);
  void _registerForPostCall(CheckCallFunc checkfn);

  void _registerForLocation(CheckLocationFunc checkfn);

  void _registerForBind(CheckBindFunc checkfn);

  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);

  void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
  void _registerForEndFunction(CheckEndFunctionFunc checkfn);

  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);

  void _registerForNewAllocator(CheckNewAllocatorFunc checkfn);

  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);

  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);

  void _registerForRegionChanges(CheckRegionChangesFunc checkfn);

  void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);

  void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);

  void _registerForEvalAssume(EvalAssumeFunc checkfn);

  void _registerForEvalCall(EvalCallFunc checkfn);

  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);

//===----------------------------------------------------------------------===//
// Internal registration functions for events.
//===----------------------------------------------------------------------===//

  using EventTag = void *;
  using CheckEventFunc = CheckerFn<void (const void *event)>;

  template <typename EVENT>
  void _registerListenerForEvent(CheckEventFunc checkfn) {
    EventInfo &info = Events[&EVENT::Tag];
    info.Checkers.push_back(checkfn);
  }

  template <typename EVENT>
  void _registerDispatcherForEvent() {
    EventInfo &info = Events[&EVENT::Tag];
    info.HasDispatcher = true;
  }

  template <typename EVENT>
  void _dispatchEvent(const EVENT &event) const {
    EventsTy::const_iterator I = Events.find(&EVENT::Tag);
    if (I == Events.end())
      return;
    const EventInfo &info = I->second;
    for (const auto &Checker : info.Checkers)
      Checker(&event);
  }

//===----------------------------------------------------------------------===//
// Implementation details.
//===----------------------------------------------------------------------===//

private:
  template <typename CHECKER>
  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }

  template <typename T>
  static void *getTag() { static int tag; return &tag; }

  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;

  std::vector<CheckerDtor> CheckerDtors;

  struct DeclCheckerInfo {
    CheckDeclFunc CheckFn;
    HandlesDeclFunc IsForDeclFn;
  };
  std::vector<DeclCheckerInfo> DeclCheckers;

  std::vector<CheckDeclFunc> BodyCheckers;

  using CachedDeclCheckers = SmallVector<CheckDeclFunc, 4>;
  using CachedDeclCheckersMapTy = llvm::DenseMap<unsigned, CachedDeclCheckers>;
  CachedDeclCheckersMapTy CachedDeclCheckersMap;

  struct StmtCheckerInfo {
    CheckStmtFunc CheckFn;
    HandlesStmtFunc IsForStmtFn;
    bool IsPreVisit;
  };
  std::vector<StmtCheckerInfo> StmtCheckers;

  using CachedStmtCheckers = SmallVector<CheckStmtFunc, 4>;
  using CachedStmtCheckersMapTy = llvm::DenseMap<unsigned, CachedStmtCheckers>;
  CachedStmtCheckersMapTy CachedStmtCheckersMap;

  const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
                                                     bool isPreVisit);

  /// Returns the checkers that have registered for callbacks of the
  /// given \p Kind.
  const std::vector<CheckObjCMessageFunc> &
  getObjCMessageCheckers(ObjCMessageVisitKind Kind) const;

  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
  std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers;

  std::vector<CheckCallFunc> PreCallCheckers;
  std::vector<CheckCallFunc> PostCallCheckers;

  std::vector<CheckLocationFunc> LocationCheckers;

  std::vector<CheckBindFunc> BindCheckers;

  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;

  std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers;
  std::vector<CheckEndFunctionFunc> EndFunctionCheckers;

  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;

  std::vector<CheckNewAllocatorFunc> NewAllocatorCheckers;

  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;

  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;

  std::vector<CheckRegionChangesFunc> RegionChangesCheckers;

  std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;

  std::vector<EvalAssumeFunc> EvalAssumeCheckers;

  std::vector<EvalCallFunc> EvalCallCheckers;

  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;

  struct EventInfo {
    SmallVector<CheckEventFunc, 4> Checkers;
    bool HasDispatcher = false;

    EventInfo() = default;
  };

  using EventsTy = llvm::DenseMap<EventTag, EventInfo>;
  EventsTy Events;
};

} // namespace ento

} // namespace clang

#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H
