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