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