summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2019-07-02 16:25:20 -0700
committerAli B <abittin@gmail.com>2019-07-05 19:33:16 +0300
commit9afee4e65dc5f9f5eb371683729ff67b8df81d03 (patch)
tree4cf241d6c9044f91ee8c06e6920174d06f8de0b6 /clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h
parent2f19bd722c4c825320d1511c1ed83161b7f95d51 (diff)
Update prebuilt Clang to r353983e.HEADq10.0
clang 9.0.5 (based on r353983e) from build 5696680. Bug: http://b/135931688 Bug: http://b/136008926 Test: N/A Change-Id: I922d17410047d2e2df4625615352c588ee71b203
Diffstat (limited to 'clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h')
-rw-r--r--clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h657
1 files changed, 657 insertions, 0 deletions
diff --git a/clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h
new file mode 100644
index 00000000..b4de26d7
--- /dev/null
+++ b/clang-r353983e/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -0,0 +1,657 @@
+//===- 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/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 CXXNewExpr;
+class Decl;
+class LocationContext;
+class Stmt;
+class TranslationUnitDecl;
+
+namespace ento {
+
+class AnalysisManager;
+class BugReporter;
+class CallEvent;
+class CheckerBase;
+class CheckerContext;
+class CheckerRegistry;
+class ExplodedGraph;
+class ExplodedNode;
+class ExplodedNodeSet;
+class ExprEngine;
+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,
+
+ /// 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 check
+// name strings have a lifetime that keeps them alive at least until the path
+// diagnostics have been processed.
+class CheckName {
+ friend class ::clang::ento::CheckerRegistry;
+
+ StringRef Name;
+
+ explicit CheckName(StringRef Name) : Name(Name) {}
+
+public:
+ CheckName() = default;
+
+ StringRef getName() const { return Name; }
+};
+
+enum class ObjCMessageVisitKind {
+ Pre,
+ Post,
+ MessageNil
+};
+
+class CheckerManager {
+ ASTContext &Context;
+ const LangOptions LangOpts;
+ AnalyzerOptions &AOptions;
+ CheckName CurrentCheckName;
+
+public:
+ CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions)
+ : Context(Context), LangOpts(Context.getLangOpts()), AOptions(AOptions) {}
+
+ ~CheckerManager();
+
+ void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
+ CheckName getCurrentCheckName() const { return CurrentCheckName; }
+
+ bool hasPathSensitiveCheckers() const;
+
+ void finishedCheckerRegistration();
+
+ const LangOptions &getLangOpts() const { return LangOpts; }
+ AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
+ ASTContext &getASTContext() { return Context; }
+
+ 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 = CurrentCheckName;
+ 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 CXXNewExpr *NE, SVal Target,
+ 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);
+
+ /// 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 Sep The preferred separator between different kinds of data.
+ void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
+ const char *NL, const char *Sep);
+
+//===----------------------------------------------------------------------===//
+// 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 CXXNewExpr *, SVal, 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 CallExpr *, 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);
+
+ 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