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