1221339Sdim//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
2221339Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6221339Sdim//
7221339Sdim//===----------------------------------------------------------------------===//
8221339Sdim//
9221339Sdim//  This file defines Checker, used to create and register checkers.
10221339Sdim//
11221339Sdim//===----------------------------------------------------------------------===//
12221339Sdim
13280031Sdim#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
14280031Sdim#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
15221339Sdim
16226633Sdim#include "clang/Analysis/ProgramPoint.h"
17353358Sdim#include "clang/Basic/LangOptions.h"
18221339Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h"
19221339Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
20221339Sdim#include "llvm/Support/Casting.h"
21221339Sdim
22221339Sdimnamespace clang {
23221339Sdimnamespace ento {
24221339Sdim  class BugReporter;
25221339Sdim
26221339Sdimnamespace check {
27221339Sdim
28221339Sdimtemplate <typename DECL>
29221339Sdimclass ASTDecl {
30221339Sdim  template <typename CHECKER>
31221339Sdim  static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
32221339Sdim                         BugReporter &BR) {
33249423Sdim    ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
34221339Sdim  }
35221339Sdim
36221339Sdim  static bool _handlesDecl(const Decl *D) {
37249423Sdim    return isa<DECL>(D);
38221339Sdim  }
39221339Sdimpublic:
40221339Sdim  template <typename CHECKER>
41221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
42221339Sdim    mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
43221339Sdim                                                       _checkDecl<CHECKER>),
44221339Sdim                         _handlesDecl);
45221339Sdim  }
46221339Sdim};
47221339Sdim
48221339Sdimclass ASTCodeBody {
49221339Sdim  template <typename CHECKER>
50221339Sdim  static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
51221339Sdim                         BugReporter &BR) {
52221339Sdim    ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
53221339Sdim  }
54221339Sdim
55221339Sdimpublic:
56221339Sdim  template <typename CHECKER>
57221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
58221339Sdim    mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
59221339Sdim                                                       _checkBody<CHECKER>));
60221339Sdim  }
61221339Sdim};
62221339Sdim
63223017Sdimclass EndOfTranslationUnit {
64223017Sdim  template <typename CHECKER>
65223017Sdim  static void _checkEndOfTranslationUnit(void *checker,
66341825Sdim                                         const TranslationUnitDecl *TU,
67223017Sdim                                         AnalysisManager& mgr,
68223017Sdim                                         BugReporter &BR) {
69223017Sdim    ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
70223017Sdim  }
71223017Sdim
72223017Sdimpublic:
73223017Sdim  template <typename CHECKER>
74223017Sdim  static void _register(CHECKER *checker, CheckerManager &mgr){
75223017Sdim    mgr._registerForEndOfTranslationUnit(
76223017Sdim                              CheckerManager::CheckEndOfTranslationUnit(checker,
77223017Sdim                                          _checkEndOfTranslationUnit<CHECKER>));
78223017Sdim  }
79223017Sdim};
80223017Sdim
81221339Sdimtemplate <typename STMT>
82221339Sdimclass PreStmt {
83221339Sdim  template <typename CHECKER>
84221339Sdim  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
85249423Sdim    ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
86221339Sdim  }
87221339Sdim
88221339Sdim  static bool _handlesStmt(const Stmt *S) {
89249423Sdim    return isa<STMT>(S);
90221339Sdim  }
91221339Sdimpublic:
92221339Sdim  template <typename CHECKER>
93221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
94221339Sdim    mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
95221339Sdim                                                          _checkStmt<CHECKER>),
96221339Sdim                            _handlesStmt);
97221339Sdim  }
98221339Sdim};
99221339Sdim
100221339Sdimtemplate <typename STMT>
101221339Sdimclass PostStmt {
102221339Sdim  template <typename CHECKER>
103221339Sdim  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
104249423Sdim    ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
105221339Sdim  }
106221339Sdim
107221339Sdim  static bool _handlesStmt(const Stmt *S) {
108249423Sdim    return isa<STMT>(S);
109221339Sdim  }
110221339Sdimpublic:
111221339Sdim  template <typename CHECKER>
112221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
113221339Sdim    mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
114221339Sdim                                                           _checkStmt<CHECKER>),
115221339Sdim                             _handlesStmt);
116221339Sdim  }
117221339Sdim};
118221339Sdim
119221339Sdimclass PreObjCMessage {
120221339Sdim  template <typename CHECKER>
121239462Sdim  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
122221339Sdim                                CheckerContext &C) {
123221339Sdim    ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
124221339Sdim  }
125221339Sdim
126221339Sdimpublic:
127221339Sdim  template <typename CHECKER>
128221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
129221339Sdim    mgr._registerForPreObjCMessage(
130221339Sdim     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
131221339Sdim  }
132221339Sdim};
133221339Sdim
134296417Sdimclass ObjCMessageNil {
135296417Sdim  template <typename CHECKER>
136296417Sdim  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
137296417Sdim                                CheckerContext &C) {
138296417Sdim    ((const CHECKER *)checker)->checkObjCMessageNil(msg, C);
139296417Sdim  }
140296417Sdim
141296417Sdimpublic:
142296417Sdim  template <typename CHECKER>
143296417Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
144296417Sdim    mgr._registerForObjCMessageNil(
145296417Sdim     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
146296417Sdim  }
147296417Sdim};
148296417Sdim
149221339Sdimclass PostObjCMessage {
150221339Sdim  template <typename CHECKER>
151239462Sdim  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
152221339Sdim                                CheckerContext &C) {
153221339Sdim    ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
154221339Sdim  }
155221339Sdim
156221339Sdimpublic:
157221339Sdim  template <typename CHECKER>
158221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
159221339Sdim    mgr._registerForPostObjCMessage(
160221339Sdim     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
161221339Sdim  }
162221339Sdim};
163221339Sdim
164239462Sdimclass PreCall {
165239462Sdim  template <typename CHECKER>
166239462Sdim  static void _checkCall(void *checker, const CallEvent &msg,
167239462Sdim                         CheckerContext &C) {
168239462Sdim    ((const CHECKER *)checker)->checkPreCall(msg, C);
169239462Sdim  }
170239462Sdim
171239462Sdimpublic:
172239462Sdim  template <typename CHECKER>
173239462Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
174239462Sdim    mgr._registerForPreCall(
175239462Sdim     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
176239462Sdim  }
177239462Sdim};
178239462Sdim
179239462Sdimclass PostCall {
180239462Sdim  template <typename CHECKER>
181239462Sdim  static void _checkCall(void *checker, const CallEvent &msg,
182239462Sdim                         CheckerContext &C) {
183239462Sdim    ((const CHECKER *)checker)->checkPostCall(msg, C);
184239462Sdim  }
185239462Sdim
186239462Sdimpublic:
187239462Sdim  template <typename CHECKER>
188239462Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
189239462Sdim    mgr._registerForPostCall(
190239462Sdim     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
191239462Sdim  }
192239462Sdim};
193239462Sdim
194221339Sdimclass Location {
195221339Sdim  template <typename CHECKER>
196226633Sdim  static void _checkLocation(void *checker,
197226633Sdim                             const SVal &location, bool isLoad, const Stmt *S,
198221339Sdim                             CheckerContext &C) {
199226633Sdim    ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
200221339Sdim  }
201221339Sdim
202221339Sdimpublic:
203221339Sdim  template <typename CHECKER>
204221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
205221339Sdim    mgr._registerForLocation(
206221339Sdim           CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
207221339Sdim  }
208221339Sdim};
209221339Sdim
210221339Sdimclass Bind {
211221339Sdim  template <typename CHECKER>
212226633Sdim  static void _checkBind(void *checker,
213226633Sdim                         const SVal &location, const SVal &val, const Stmt *S,
214221339Sdim                         CheckerContext &C) {
215226633Sdim    ((const CHECKER *)checker)->checkBind(location, val, S, C);
216221339Sdim  }
217221339Sdim
218221339Sdimpublic:
219221339Sdim  template <typename CHECKER>
220221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
221221339Sdim    mgr._registerForBind(
222221339Sdim           CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
223221339Sdim  }
224221339Sdim};
225221339Sdim
226221339Sdimclass EndAnalysis {
227221339Sdim  template <typename CHECKER>
228221339Sdim  static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
229221339Sdim                                BugReporter &BR, ExprEngine &Eng) {
230221339Sdim    ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
231221339Sdim  }
232221339Sdim
233221339Sdimpublic:
234221339Sdim  template <typename CHECKER>
235221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
236221339Sdim    mgr._registerForEndAnalysis(
237221339Sdim     CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
238221339Sdim  }
239221339Sdim};
240221339Sdim
241309124Sdimclass BeginFunction {
242309124Sdim  template <typename CHECKER>
243309124Sdim  static void _checkBeginFunction(void *checker, CheckerContext &C) {
244309124Sdim    ((const CHECKER *)checker)->checkBeginFunction(C);
245309124Sdim  }
246309124Sdim
247309124Sdimpublic:
248309124Sdim  template <typename CHECKER>
249309124Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
250309124Sdim    mgr._registerForBeginFunction(CheckerManager::CheckBeginFunctionFunc(
251309124Sdim        checker, _checkBeginFunction<CHECKER>));
252309124Sdim  }
253309124Sdim};
254309124Sdim
255249423Sdimclass EndFunction {
256221339Sdim  template <typename CHECKER>
257341825Sdim  static void _checkEndFunction(void *checker, const ReturnStmt *RS,
258249423Sdim                                CheckerContext &C) {
259341825Sdim    ((const CHECKER *)checker)->checkEndFunction(RS, C);
260221339Sdim  }
261221339Sdim
262221339Sdimpublic:
263221339Sdim  template <typename CHECKER>
264221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
265249423Sdim    mgr._registerForEndFunction(
266249423Sdim     CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
267221339Sdim  }
268221339Sdim};
269221339Sdim
270221339Sdimclass BranchCondition {
271221339Sdim  template <typename CHECKER>
272234353Sdim  static void _checkBranchCondition(void *checker, const Stmt *Condition,
273234353Sdim                                    CheckerContext & C) {
274234353Sdim    ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
275221339Sdim  }
276221339Sdim
277221339Sdimpublic:
278221339Sdim  template <typename CHECKER>
279221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
280221339Sdim    mgr._registerForBranchCondition(
281221339Sdim      CheckerManager::CheckBranchConditionFunc(checker,
282221339Sdim                                               _checkBranchCondition<CHECKER>));
283221339Sdim  }
284221339Sdim};
285221339Sdim
286341825Sdimclass NewAllocator {
287341825Sdim  template <typename CHECKER>
288341825Sdim  static void _checkNewAllocator(void *checker, const CXXNewExpr *NE,
289341825Sdim                                 SVal Target, CheckerContext &C) {
290341825Sdim    ((const CHECKER *)checker)->checkNewAllocator(NE, Target, C);
291341825Sdim  }
292341825Sdim
293341825Sdimpublic:
294341825Sdim  template <typename CHECKER>
295341825Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
296341825Sdim    mgr._registerForNewAllocator(
297341825Sdim        CheckerManager::CheckNewAllocatorFunc(checker,
298341825Sdim                                              _checkNewAllocator<CHECKER>));
299341825Sdim  }
300341825Sdim};
301341825Sdim
302221339Sdimclass LiveSymbols {
303221339Sdim  template <typename CHECKER>
304234353Sdim  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
305221339Sdim                                SymbolReaper &SR) {
306221339Sdim    ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
307221339Sdim  }
308221339Sdim
309221339Sdimpublic:
310221339Sdim  template <typename CHECKER>
311221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
312221339Sdim    mgr._registerForLiveSymbols(
313221339Sdim     CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
314221339Sdim  }
315221339Sdim};
316221339Sdim
317221339Sdimclass DeadSymbols {
318221339Sdim  template <typename CHECKER>
319221339Sdim  static void _checkDeadSymbols(void *checker,
320221339Sdim                                SymbolReaper &SR, CheckerContext &C) {
321221339Sdim    ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
322221339Sdim  }
323221339Sdim
324221339Sdimpublic:
325221339Sdim  template <typename CHECKER>
326221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
327221339Sdim    mgr._registerForDeadSymbols(
328221339Sdim     CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
329221339Sdim  }
330221339Sdim};
331221339Sdim
332221339Sdimclass RegionChanges {
333221339Sdim  template <typename CHECKER>
334341825Sdim  static ProgramStateRef
335226633Sdim  _checkRegionChanges(void *checker,
336234353Sdim                      ProgramStateRef state,
337249423Sdim                      const InvalidatedSymbols *invalidated,
338226633Sdim                      ArrayRef<const MemRegion *> Explicits,
339234353Sdim                      ArrayRef<const MemRegion *> Regions,
340321369Sdim                      const LocationContext *LCtx,
341239462Sdim                      const CallEvent *Call) {
342321369Sdim    return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
343321369Sdim                                                           Explicits, Regions,
344321369Sdim                                                           LCtx, Call);
345221339Sdim  }
346221339Sdim
347221339Sdimpublic:
348221339Sdim  template <typename CHECKER>
349221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
350221339Sdim    mgr._registerForRegionChanges(
351221339Sdim          CheckerManager::CheckRegionChangesFunc(checker,
352314564Sdim                                                 _checkRegionChanges<CHECKER>));
353221339Sdim  }
354221339Sdim};
355221339Sdim
356249423Sdimclass PointerEscape {
357249423Sdim  template <typename CHECKER>
358249423Sdim  static ProgramStateRef
359261991Sdim  _checkPointerEscape(void *Checker,
360249423Sdim                     ProgramStateRef State,
361249423Sdim                     const InvalidatedSymbols &Escaped,
362249423Sdim                     const CallEvent *Call,
363249423Sdim                     PointerEscapeKind Kind,
364261991Sdim                     RegionAndSymbolInvalidationTraits *ETraits) {
365261991Sdim
366261991Sdim    if (!ETraits)
367261991Sdim      return ((const CHECKER *)Checker)->checkPointerEscape(State,
368249423Sdim                                                            Escaped,
369249423Sdim                                                            Call,
370249423Sdim                                                            Kind);
371261991Sdim
372261991Sdim    InvalidatedSymbols RegularEscape;
373341825Sdim    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
374261991Sdim                                            E = Escaped.end(); I != E; ++I)
375261991Sdim      if (!ETraits->hasTrait(*I,
376261991Sdim              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
377261991Sdim          !ETraits->hasTrait(*I,
378261991Sdim              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
379261991Sdim        RegularEscape.insert(*I);
380261991Sdim
381261991Sdim    if (RegularEscape.empty())
382261991Sdim      return State;
383261991Sdim
384261991Sdim    return ((const CHECKER *)Checker)->checkPointerEscape(State,
385261991Sdim                                                          RegularEscape,
386261991Sdim                                                          Call,
387261991Sdim                                                          Kind);
388249423Sdim  }
389249423Sdim
390249423Sdimpublic:
391249423Sdim  template <typename CHECKER>
392249423Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
393249423Sdim    mgr._registerForPointerEscape(
394249423Sdim          CheckerManager::CheckPointerEscapeFunc(checker,
395249423Sdim                                                _checkPointerEscape<CHECKER>));
396249423Sdim  }
397249423Sdim};
398249423Sdim
399249423Sdimclass ConstPointerEscape {
400249423Sdim  template <typename CHECKER>
401249423Sdim  static ProgramStateRef
402261991Sdim  _checkConstPointerEscape(void *Checker,
403249423Sdim                      ProgramStateRef State,
404249423Sdim                      const InvalidatedSymbols &Escaped,
405249423Sdim                      const CallEvent *Call,
406249423Sdim                      PointerEscapeKind Kind,
407261991Sdim                      RegionAndSymbolInvalidationTraits *ETraits) {
408261991Sdim
409261991Sdim    if (!ETraits)
410261991Sdim      return State;
411261991Sdim
412261991Sdim    InvalidatedSymbols ConstEscape;
413341825Sdim    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
414261991Sdim                                            E = Escaped.end(); I != E; ++I)
415261991Sdim      if (ETraits->hasTrait(*I,
416261991Sdim              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
417261991Sdim          !ETraits->hasTrait(*I,
418261991Sdim              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
419261991Sdim        ConstEscape.insert(*I);
420261991Sdim
421261991Sdim    if (ConstEscape.empty())
422261991Sdim      return State;
423261991Sdim
424261991Sdim    return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
425261991Sdim                                                               ConstEscape,
426261991Sdim                                                               Call,
427261991Sdim                                                               Kind);
428249423Sdim  }
429249423Sdim
430249423Sdimpublic:
431249423Sdim  template <typename CHECKER>
432249423Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
433249423Sdim    mgr._registerForPointerEscape(
434249423Sdim      CheckerManager::CheckPointerEscapeFunc(checker,
435249423Sdim                                            _checkConstPointerEscape<CHECKER>));
436249423Sdim  }
437249423Sdim};
438249423Sdim
439341825Sdim
440221339Sdimtemplate <typename EVENT>
441221339Sdimclass Event {
442221339Sdim  template <typename CHECKER>
443221339Sdim  static void _checkEvent(void *checker, const void *event) {
444221339Sdim    ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
445221339Sdim  }
446221339Sdimpublic:
447221339Sdim  template <typename CHECKER>
448221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
449221339Sdim    mgr._registerListenerForEvent<EVENT>(
450221339Sdim                 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
451221339Sdim  }
452221339Sdim};
453221339Sdim
454221339Sdim} // end check namespace
455221339Sdim
456221339Sdimnamespace eval {
457221339Sdim
458221339Sdimclass Assume {
459221339Sdim  template <typename CHECKER>
460234353Sdim  static ProgramStateRef _evalAssume(void *checker,
461234353Sdim                                         ProgramStateRef state,
462226633Sdim                                         const SVal &cond,
463226633Sdim                                         bool assumption) {
464221339Sdim    return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
465221339Sdim  }
466221339Sdim
467221339Sdimpublic:
468221339Sdim  template <typename CHECKER>
469221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
470221339Sdim    mgr._registerForEvalAssume(
471221339Sdim                 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
472221339Sdim  }
473221339Sdim};
474221339Sdim
475221339Sdimclass Call {
476221339Sdim  template <typename CHECKER>
477353358Sdim  static bool _evalCall(void *checker, const CallEvent &Call,
478353358Sdim                        CheckerContext &C) {
479353358Sdim    return ((const CHECKER *)checker)->evalCall(Call, C);
480221339Sdim  }
481221339Sdim
482221339Sdimpublic:
483221339Sdim  template <typename CHECKER>
484221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
485221339Sdim    mgr._registerForEvalCall(
486221339Sdim                     CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
487221339Sdim  }
488221339Sdim};
489221339Sdim
490221339Sdim} // end eval namespace
491221339Sdim
492226633Sdimclass CheckerBase : public ProgramPointTag {
493360784Sdim  CheckerNameRef Name;
494276479Sdim  friend class ::clang::ento::CheckerManager;
495276479Sdim
496226633Sdimpublic:
497276479Sdim  StringRef getTagDescription() const override;
498360784Sdim  CheckerNameRef getCheckerName() const;
499226633Sdim
500226633Sdim  /// See CheckerManager::runCheckersForPrintState.
501234353Sdim  virtual void printState(raw_ostream &Out, ProgramStateRef State,
502226633Sdim                          const char *NL, const char *Sep) const { }
503226633Sdim};
504276479Sdim
505276479Sdim/// Dump checker name to stream.
506276479Sdimraw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
507276479Sdim
508341825Sdim/// Tag that can use a checker name as a message provider
509276479Sdim/// (see SimpleProgramPointTag).
510276479Sdimclass CheckerProgramPointTag : public SimpleProgramPointTag {
511276479Sdimpublic:
512276479Sdim  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
513276479Sdim  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
514276479Sdim};
515276479Sdim
516288943Sdimtemplate <typename CHECK1, typename... CHECKs>
517288943Sdimclass Checker : public CHECK1, public CHECKs..., public CheckerBase {
518221339Sdimpublic:
519288943Sdim  template <typename CHECKER>
520288943Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
521288943Sdim    CHECK1::_register(checker, mgr);
522288943Sdim    Checker<CHECKs...>::_register(checker, mgr);
523288943Sdim  }
524221339Sdim};
525221339Sdim
526288943Sdimtemplate <typename CHECK1>
527288943Sdimclass Checker<CHECK1> : public CHECK1, public CheckerBase {
528221339Sdimpublic:
529221339Sdim  template <typename CHECKER>
530221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
531221339Sdim    CHECK1::_register(checker, mgr);
532221339Sdim  }
533221339Sdim};
534221339Sdim
535221339Sdimtemplate <typename EVENT>
536221339Sdimclass EventDispatcher {
537221339Sdim  CheckerManager *Mgr;
538221339Sdimpublic:
539276479Sdim  EventDispatcher() : Mgr(nullptr) { }
540221339Sdim
541221339Sdim  template <typename CHECKER>
542221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
543221339Sdim    mgr._registerDispatcherForEvent<EVENT>();
544221339Sdim    static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
545221339Sdim  }
546221339Sdim
547221339Sdim  void dispatchEvent(const EVENT &event) const {
548221339Sdim    Mgr->_dispatchEvent(event);
549221339Sdim  }
550221339Sdim};
551221339Sdim
552341825Sdim/// We dereferenced a location that may be null.
553221339Sdimstruct ImplicitNullDerefEvent {
554221339Sdim  SVal Location;
555221339Sdim  bool IsLoad;
556221339Sdim  ExplodedNode *SinkNode;
557221339Sdim  BugReporter *BR;
558296417Sdim  // When true, the dereference is in the source code directly. When false, the
559296417Sdim  // dereference might happen later (for example pointer passed to a parameter
560296417Sdim  // that is marked with nonnull attribute.)
561296417Sdim  bool IsDirectDereference;
562344779Sdim
563344779Sdim  static int Tag;
564221339Sdim};
565221339Sdim
566341825Sdim/// A helper class which wraps a boolean value set to false by default.
567261991Sdim///
568261991Sdim/// This class should behave exactly like 'bool' except that it doesn't need to
569261991Sdim/// be explicitly initialized.
570249423Sdimstruct DefaultBool {
571249423Sdim  bool val;
572249423Sdim  DefaultBool() : val(false) {}
573261991Sdim  /*implicit*/ operator bool&() { return val; }
574261991Sdim  /*implicit*/ operator const bool&() const { return val; }
575249423Sdim  DefaultBool &operator=(bool b) { val = b; return *this; }
576249423Sdim};
577249423Sdim
578221339Sdim} // end ento namespace
579221339Sdim
580221339Sdim} // end clang namespace
581221339Sdim
582221339Sdim#endif
583