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