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