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