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