1221339Sdim//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
2221339Sdim//
3221339Sdim//                     The LLVM Compiler Infrastructure
4221339Sdim//
5221339Sdim// This file is distributed under the University of Illinois Open Source
6221339Sdim// License. See LICENSE.TXT for details.
7221339Sdim//
8221339Sdim//===----------------------------------------------------------------------===//
9221339Sdim//
10221339Sdim//  This file defines Checker, used to create and register checkers.
11221339Sdim//
12221339Sdim//===----------------------------------------------------------------------===//
13221339Sdim
14221339Sdim#ifndef LLVM_CLANG_SA_CORE_CHECKER
15221339Sdim#define LLVM_CLANG_SA_CORE_CHECKER
16221339Sdim
17226633Sdim#include "clang/Analysis/ProgramPoint.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
28221339Sdimstruct _VoidCheck {
29221339Sdim  static void _register(void *checker, CheckerManager &mgr) { }
30221339Sdim};
31221339Sdim
32221339Sdimtemplate <typename DECL>
33221339Sdimclass ASTDecl {
34221339Sdim  template <typename CHECKER>
35221339Sdim  static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
36221339Sdim                         BugReporter &BR) {
37249423Sdim    ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
38221339Sdim  }
39221339Sdim
40221339Sdim  static bool _handlesDecl(const Decl *D) {
41249423Sdim    return isa<DECL>(D);
42221339Sdim  }
43221339Sdimpublic:
44221339Sdim  template <typename CHECKER>
45221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
46221339Sdim    mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
47221339Sdim                                                       _checkDecl<CHECKER>),
48221339Sdim                         _handlesDecl);
49221339Sdim  }
50221339Sdim};
51221339Sdim
52221339Sdimclass ASTCodeBody {
53221339Sdim  template <typename CHECKER>
54221339Sdim  static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
55221339Sdim                         BugReporter &BR) {
56221339Sdim    ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
57221339Sdim  }
58221339Sdim
59221339Sdimpublic:
60221339Sdim  template <typename CHECKER>
61221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
62221339Sdim    mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
63221339Sdim                                                       _checkBody<CHECKER>));
64221339Sdim  }
65221339Sdim};
66221339Sdim
67223017Sdimclass EndOfTranslationUnit {
68223017Sdim  template <typename CHECKER>
69223017Sdim  static void _checkEndOfTranslationUnit(void *checker,
70223017Sdim                                         const TranslationUnitDecl *TU,
71223017Sdim                                         AnalysisManager& mgr,
72223017Sdim                                         BugReporter &BR) {
73223017Sdim    ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
74223017Sdim  }
75223017Sdim
76223017Sdimpublic:
77223017Sdim  template <typename CHECKER>
78223017Sdim  static void _register(CHECKER *checker, CheckerManager &mgr){
79223017Sdim    mgr._registerForEndOfTranslationUnit(
80223017Sdim                              CheckerManager::CheckEndOfTranslationUnit(checker,
81223017Sdim                                          _checkEndOfTranslationUnit<CHECKER>));
82223017Sdim  }
83223017Sdim};
84223017Sdim
85221339Sdimtemplate <typename STMT>
86221339Sdimclass PreStmt {
87221339Sdim  template <typename CHECKER>
88221339Sdim  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
89249423Sdim    ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
90221339Sdim  }
91221339Sdim
92221339Sdim  static bool _handlesStmt(const Stmt *S) {
93249423Sdim    return isa<STMT>(S);
94221339Sdim  }
95221339Sdimpublic:
96221339Sdim  template <typename CHECKER>
97221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
98221339Sdim    mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
99221339Sdim                                                          _checkStmt<CHECKER>),
100221339Sdim                            _handlesStmt);
101221339Sdim  }
102221339Sdim};
103221339Sdim
104221339Sdimtemplate <typename STMT>
105221339Sdimclass PostStmt {
106221339Sdim  template <typename CHECKER>
107221339Sdim  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
108249423Sdim    ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
109221339Sdim  }
110221339Sdim
111221339Sdim  static bool _handlesStmt(const Stmt *S) {
112249423Sdim    return isa<STMT>(S);
113221339Sdim  }
114221339Sdimpublic:
115221339Sdim  template <typename CHECKER>
116221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
117221339Sdim    mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
118221339Sdim                                                           _checkStmt<CHECKER>),
119221339Sdim                             _handlesStmt);
120221339Sdim  }
121221339Sdim};
122221339Sdim
123221339Sdimclass PreObjCMessage {
124221339Sdim  template <typename CHECKER>
125239462Sdim  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
126221339Sdim                                CheckerContext &C) {
127221339Sdim    ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
128221339Sdim  }
129221339Sdim
130221339Sdimpublic:
131221339Sdim  template <typename CHECKER>
132221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
133221339Sdim    mgr._registerForPreObjCMessage(
134221339Sdim     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
135221339Sdim  }
136221339Sdim};
137221339Sdim
138221339Sdimclass PostObjCMessage {
139221339Sdim  template <typename CHECKER>
140239462Sdim  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
141221339Sdim                                CheckerContext &C) {
142221339Sdim    ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
143221339Sdim  }
144221339Sdim
145221339Sdimpublic:
146221339Sdim  template <typename CHECKER>
147221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
148221339Sdim    mgr._registerForPostObjCMessage(
149221339Sdim     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
150221339Sdim  }
151221339Sdim};
152221339Sdim
153239462Sdimclass PreCall {
154239462Sdim  template <typename CHECKER>
155239462Sdim  static void _checkCall(void *checker, const CallEvent &msg,
156239462Sdim                         CheckerContext &C) {
157239462Sdim    ((const CHECKER *)checker)->checkPreCall(msg, C);
158239462Sdim  }
159239462Sdim
160239462Sdimpublic:
161239462Sdim  template <typename CHECKER>
162239462Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
163239462Sdim    mgr._registerForPreCall(
164239462Sdim     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
165239462Sdim  }
166239462Sdim};
167239462Sdim
168239462Sdimclass PostCall {
169239462Sdim  template <typename CHECKER>
170239462Sdim  static void _checkCall(void *checker, const CallEvent &msg,
171239462Sdim                         CheckerContext &C) {
172239462Sdim    ((const CHECKER *)checker)->checkPostCall(msg, C);
173239462Sdim  }
174239462Sdim
175239462Sdimpublic:
176239462Sdim  template <typename CHECKER>
177239462Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
178239462Sdim    mgr._registerForPostCall(
179239462Sdim     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
180239462Sdim  }
181239462Sdim};
182239462Sdim
183221339Sdimclass Location {
184221339Sdim  template <typename CHECKER>
185226633Sdim  static void _checkLocation(void *checker,
186226633Sdim                             const SVal &location, bool isLoad, const Stmt *S,
187221339Sdim                             CheckerContext &C) {
188226633Sdim    ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
189221339Sdim  }
190221339Sdim
191221339Sdimpublic:
192221339Sdim  template <typename CHECKER>
193221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
194221339Sdim    mgr._registerForLocation(
195221339Sdim           CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
196221339Sdim  }
197221339Sdim};
198221339Sdim
199221339Sdimclass Bind {
200221339Sdim  template <typename CHECKER>
201226633Sdim  static void _checkBind(void *checker,
202226633Sdim                         const SVal &location, const SVal &val, const Stmt *S,
203221339Sdim                         CheckerContext &C) {
204226633Sdim    ((const CHECKER *)checker)->checkBind(location, val, S, C);
205221339Sdim  }
206221339Sdim
207221339Sdimpublic:
208221339Sdim  template <typename CHECKER>
209221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
210221339Sdim    mgr._registerForBind(
211221339Sdim           CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
212221339Sdim  }
213221339Sdim};
214221339Sdim
215221339Sdimclass EndAnalysis {
216221339Sdim  template <typename CHECKER>
217221339Sdim  static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
218221339Sdim                                BugReporter &BR, ExprEngine &Eng) {
219221339Sdim    ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
220221339Sdim  }
221221339Sdim
222221339Sdimpublic:
223221339Sdim  template <typename CHECKER>
224221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
225221339Sdim    mgr._registerForEndAnalysis(
226221339Sdim     CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
227221339Sdim  }
228221339Sdim};
229221339Sdim
230249423Sdimclass EndFunction {
231221339Sdim  template <typename CHECKER>
232249423Sdim  static void _checkEndFunction(void *checker,
233249423Sdim                                CheckerContext &C) {
234249423Sdim    ((const CHECKER *)checker)->checkEndFunction(C);
235221339Sdim  }
236221339Sdim
237221339Sdimpublic:
238221339Sdim  template <typename CHECKER>
239221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
240249423Sdim    mgr._registerForEndFunction(
241249423Sdim     CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
242221339Sdim  }
243221339Sdim};
244221339Sdim
245221339Sdimclass BranchCondition {
246221339Sdim  template <typename CHECKER>
247234353Sdim  static void _checkBranchCondition(void *checker, const Stmt *Condition,
248234353Sdim                                    CheckerContext & C) {
249234353Sdim    ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
250221339Sdim  }
251221339Sdim
252221339Sdimpublic:
253221339Sdim  template <typename CHECKER>
254221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
255221339Sdim    mgr._registerForBranchCondition(
256221339Sdim      CheckerManager::CheckBranchConditionFunc(checker,
257221339Sdim                                               _checkBranchCondition<CHECKER>));
258221339Sdim  }
259221339Sdim};
260221339Sdim
261221339Sdimclass LiveSymbols {
262221339Sdim  template <typename CHECKER>
263234353Sdim  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
264221339Sdim                                SymbolReaper &SR) {
265221339Sdim    ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
266221339Sdim  }
267221339Sdim
268221339Sdimpublic:
269221339Sdim  template <typename CHECKER>
270221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
271221339Sdim    mgr._registerForLiveSymbols(
272221339Sdim     CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
273221339Sdim  }
274221339Sdim};
275221339Sdim
276221339Sdimclass DeadSymbols {
277221339Sdim  template <typename CHECKER>
278221339Sdim  static void _checkDeadSymbols(void *checker,
279221339Sdim                                SymbolReaper &SR, CheckerContext &C) {
280221339Sdim    ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
281221339Sdim  }
282221339Sdim
283221339Sdimpublic:
284221339Sdim  template <typename CHECKER>
285221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
286221339Sdim    mgr._registerForDeadSymbols(
287221339Sdim     CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
288221339Sdim  }
289221339Sdim};
290221339Sdim
291221339Sdimclass RegionChanges {
292221339Sdim  template <typename CHECKER>
293234353Sdim  static ProgramStateRef
294226633Sdim  _checkRegionChanges(void *checker,
295234353Sdim                      ProgramStateRef state,
296249423Sdim                      const InvalidatedSymbols *invalidated,
297226633Sdim                      ArrayRef<const MemRegion *> Explicits,
298234353Sdim                      ArrayRef<const MemRegion *> Regions,
299239462Sdim                      const CallEvent *Call) {
300223017Sdim    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
301234353Sdim                                                      Explicits, Regions, Call);
302221339Sdim  }
303221339Sdim  template <typename CHECKER>
304226633Sdim  static bool _wantsRegionChangeUpdate(void *checker,
305234353Sdim                                       ProgramStateRef state) {
306221339Sdim    return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
307221339Sdim  }
308221339Sdim
309221339Sdimpublic:
310221339Sdim  template <typename CHECKER>
311221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
312221339Sdim    mgr._registerForRegionChanges(
313221339Sdim          CheckerManager::CheckRegionChangesFunc(checker,
314221339Sdim                                                 _checkRegionChanges<CHECKER>),
315221339Sdim          CheckerManager::WantsRegionChangeUpdateFunc(checker,
316221339Sdim                                            _wantsRegionChangeUpdate<CHECKER>));
317221339Sdim  }
318221339Sdim};
319221339Sdim
320249423Sdimclass PointerEscape {
321249423Sdim  template <typename CHECKER>
322249423Sdim  static ProgramStateRef
323263508Sdim  _checkPointerEscape(void *Checker,
324249423Sdim                     ProgramStateRef State,
325249423Sdim                     const InvalidatedSymbols &Escaped,
326249423Sdim                     const CallEvent *Call,
327249423Sdim                     PointerEscapeKind Kind,
328263508Sdim                     RegionAndSymbolInvalidationTraits *ETraits) {
329263508Sdim
330263508Sdim    if (!ETraits)
331263508Sdim      return ((const CHECKER *)Checker)->checkPointerEscape(State,
332249423Sdim                                                            Escaped,
333249423Sdim                                                            Call,
334249423Sdim                                                            Kind);
335263508Sdim
336263508Sdim    InvalidatedSymbols RegularEscape;
337263508Sdim    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
338263508Sdim                                            E = Escaped.end(); I != E; ++I)
339263508Sdim      if (!ETraits->hasTrait(*I,
340263508Sdim              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
341263508Sdim          !ETraits->hasTrait(*I,
342263508Sdim              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
343263508Sdim        RegularEscape.insert(*I);
344263508Sdim
345263508Sdim    if (RegularEscape.empty())
346263508Sdim      return State;
347263508Sdim
348263508Sdim    return ((const CHECKER *)Checker)->checkPointerEscape(State,
349263508Sdim                                                          RegularEscape,
350263508Sdim                                                          Call,
351263508Sdim                                                          Kind);
352249423Sdim  }
353249423Sdim
354249423Sdimpublic:
355249423Sdim  template <typename CHECKER>
356249423Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
357249423Sdim    mgr._registerForPointerEscape(
358249423Sdim          CheckerManager::CheckPointerEscapeFunc(checker,
359249423Sdim                                                _checkPointerEscape<CHECKER>));
360249423Sdim  }
361249423Sdim};
362249423Sdim
363249423Sdimclass ConstPointerEscape {
364249423Sdim  template <typename CHECKER>
365249423Sdim  static ProgramStateRef
366263508Sdim  _checkConstPointerEscape(void *Checker,
367249423Sdim                      ProgramStateRef State,
368249423Sdim                      const InvalidatedSymbols &Escaped,
369249423Sdim                      const CallEvent *Call,
370249423Sdim                      PointerEscapeKind Kind,
371263508Sdim                      RegionAndSymbolInvalidationTraits *ETraits) {
372263508Sdim
373263508Sdim    if (!ETraits)
374263508Sdim      return State;
375263508Sdim
376263508Sdim    InvalidatedSymbols ConstEscape;
377263508Sdim    for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
378263508Sdim                                            E = Escaped.end(); I != E; ++I)
379263508Sdim      if (ETraits->hasTrait(*I,
380263508Sdim              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
381263508Sdim          !ETraits->hasTrait(*I,
382263508Sdim              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
383263508Sdim        ConstEscape.insert(*I);
384263508Sdim
385263508Sdim    if (ConstEscape.empty())
386263508Sdim      return State;
387263508Sdim
388263508Sdim    return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
389263508Sdim                                                               ConstEscape,
390263508Sdim                                                               Call,
391263508Sdim                                                               Kind);
392249423Sdim  }
393249423Sdim
394249423Sdimpublic:
395249423Sdim  template <typename CHECKER>
396249423Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
397249423Sdim    mgr._registerForPointerEscape(
398249423Sdim      CheckerManager::CheckPointerEscapeFunc(checker,
399249423Sdim                                            _checkConstPointerEscape<CHECKER>));
400249423Sdim  }
401249423Sdim};
402249423Sdim
403249423Sdim
404221339Sdimtemplate <typename EVENT>
405221339Sdimclass Event {
406221339Sdim  template <typename CHECKER>
407221339Sdim  static void _checkEvent(void *checker, const void *event) {
408221339Sdim    ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
409221339Sdim  }
410221339Sdimpublic:
411221339Sdim  template <typename CHECKER>
412221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
413221339Sdim    mgr._registerListenerForEvent<EVENT>(
414221339Sdim                 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
415221339Sdim  }
416221339Sdim};
417221339Sdim
418221339Sdim} // end check namespace
419221339Sdim
420221339Sdimnamespace eval {
421221339Sdim
422221339Sdimclass Assume {
423221339Sdim  template <typename CHECKER>
424234353Sdim  static ProgramStateRef _evalAssume(void *checker,
425234353Sdim                                         ProgramStateRef state,
426226633Sdim                                         const SVal &cond,
427226633Sdim                                         bool assumption) {
428221339Sdim    return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
429221339Sdim  }
430221339Sdim
431221339Sdimpublic:
432221339Sdim  template <typename CHECKER>
433221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
434221339Sdim    mgr._registerForEvalAssume(
435221339Sdim                 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
436221339Sdim  }
437221339Sdim};
438221339Sdim
439221339Sdimclass Call {
440221339Sdim  template <typename CHECKER>
441221339Sdim  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
442221339Sdim    return ((const CHECKER *)checker)->evalCall(CE, C);
443221339Sdim  }
444221339Sdim
445221339Sdimpublic:
446221339Sdim  template <typename CHECKER>
447221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
448221339Sdim    mgr._registerForEvalCall(
449221339Sdim                     CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
450221339Sdim  }
451221339Sdim};
452221339Sdim
453221339Sdim} // end eval namespace
454221339Sdim
455226633Sdimclass CheckerBase : public ProgramPointTag {
456226633Sdimpublic:
457226633Sdim  StringRef getTagDescription() const;
458226633Sdim
459226633Sdim  /// See CheckerManager::runCheckersForPrintState.
460234353Sdim  virtual void printState(raw_ostream &Out, ProgramStateRef State,
461226633Sdim                          const char *NL, const char *Sep) const { }
462226633Sdim};
463226633Sdim
464221339Sdimtemplate <typename CHECK1, typename CHECK2=check::_VoidCheck,
465221339Sdim          typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
466221339Sdim          typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
467221339Sdim          typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
468221339Sdim          typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
469226633Sdim          typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck,
470226633Sdim          typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck,
471234353Sdim          typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck,
472239462Sdim          typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck,
473239462Sdim          typename CHECK19=check::_VoidCheck,typename CHECK20=check::_VoidCheck,
474239462Sdim          typename CHECK21=check::_VoidCheck,typename CHECK22=check::_VoidCheck,
475239462Sdim          typename CHECK23=check::_VoidCheck,typename CHECK24=check::_VoidCheck>
476221339Sdimclass Checker;
477221339Sdim
478221339Sdimtemplate <>
479239462Sdimclass Checker<check::_VoidCheck>
480226633Sdim  : public CheckerBase
481226633Sdim{
482234353Sdim  virtual void anchor();
483221339Sdimpublic:
484221339Sdim  static void _register(void *checker, CheckerManager &mgr) { }
485221339Sdim};
486221339Sdim
487221339Sdimtemplate <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
488221339Sdim          typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
489226633Sdim          typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12,
490234353Sdim          typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16,
491239462Sdim          typename CHECK17,typename CHECK18,typename CHECK19,typename CHECK20,
492239462Sdim          typename CHECK21,typename CHECK22,typename CHECK23,typename CHECK24>
493221339Sdimclass Checker
494221339Sdim    : public CHECK1,
495239462Sdim      public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
496239462Sdim                     CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
497239462Sdim                     CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
498239462Sdim                     CHECK20,CHECK21,CHECK22,CHECK23,CHECK24> {
499221339Sdimpublic:
500221339Sdim  template <typename CHECKER>
501221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
502221339Sdim    CHECK1::_register(checker, mgr);
503239462Sdim    Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
504239462Sdim            CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
505239462Sdim            CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
506239462Sdim            CHECK20,CHECK21,CHECK22,CHECK23,CHECK24>::_register(checker, mgr);
507221339Sdim  }
508221339Sdim};
509221339Sdim
510221339Sdimtemplate <typename EVENT>
511221339Sdimclass EventDispatcher {
512221339Sdim  CheckerManager *Mgr;
513221339Sdimpublic:
514221339Sdim  EventDispatcher() : Mgr(0) { }
515221339Sdim
516221339Sdim  template <typename CHECKER>
517221339Sdim  static void _register(CHECKER *checker, CheckerManager &mgr) {
518221339Sdim    mgr._registerDispatcherForEvent<EVENT>();
519221339Sdim    static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
520221339Sdim  }
521221339Sdim
522221339Sdim  void dispatchEvent(const EVENT &event) const {
523221339Sdim    Mgr->_dispatchEvent(event);
524221339Sdim  }
525221339Sdim};
526221339Sdim
527221339Sdim/// \brief We dereferenced a location that may be null.
528221339Sdimstruct ImplicitNullDerefEvent {
529221339Sdim  SVal Location;
530221339Sdim  bool IsLoad;
531221339Sdim  ExplodedNode *SinkNode;
532221339Sdim  BugReporter *BR;
533221339Sdim};
534221339Sdim
535249423Sdim/// \brief A helper class which wraps a boolean value set to false by default.
536263508Sdim///
537263508Sdim/// This class should behave exactly like 'bool' except that it doesn't need to
538263508Sdim/// be explicitly initialized.
539249423Sdimstruct DefaultBool {
540249423Sdim  bool val;
541249423Sdim  DefaultBool() : val(false) {}
542263508Sdim  /*implicit*/ operator bool&() { return val; }
543263508Sdim  /*implicit*/ operator const bool&() const { return val; }
544249423Sdim  DefaultBool &operator=(bool b) { val = b; return *this; }
545249423Sdim};
546249423Sdim
547221339Sdim} // end ento namespace
548221339Sdim
549221339Sdim} // end clang namespace
550221339Sdim
551221339Sdim#endif
552