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