clang API Documentation
00001 //===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Defines the Static Analyzer Checker Manager. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H 00015 #define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H 00016 00017 #include "clang/Analysis/ProgramPoint.h" 00018 #include "clang/Basic/LangOptions.h" 00019 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" 00020 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 00021 #include "llvm/ADT/DenseMap.h" 00022 #include "llvm/ADT/SmallVector.h" 00023 #include <vector> 00024 00025 namespace clang { 00026 class Decl; 00027 class Stmt; 00028 class CallExpr; 00029 00030 namespace ento { 00031 class CheckerBase; 00032 class CheckerRegistry; 00033 class ExprEngine; 00034 class AnalysisManager; 00035 class BugReporter; 00036 class CheckerContext; 00037 class ObjCMethodCall; 00038 class SVal; 00039 class ExplodedNode; 00040 class ExplodedNodeSet; 00041 class ExplodedGraph; 00042 class ProgramState; 00043 class NodeBuilder; 00044 struct NodeBuilderContext; 00045 class MemRegion; 00046 class SymbolReaper; 00047 00048 template <typename T> class CheckerFn; 00049 00050 template <typename RET, typename P1, typename P2, typename P3, typename P4, 00051 typename P5> 00052 class CheckerFn<RET(P1, P2, P3, P4, P5)> { 00053 typedef RET (*Func)(void *, P1, P2, P3, P4, P5); 00054 Func Fn; 00055 public: 00056 CheckerBase *Checker; 00057 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 00058 RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { 00059 return Fn(Checker, p1, p2, p3, p4, p5); 00060 } 00061 }; 00062 00063 template <typename RET, typename P1, typename P2, typename P3, typename P4> 00064 class CheckerFn<RET(P1, P2, P3, P4)> { 00065 typedef RET (*Func)(void *, P1, P2, P3, P4); 00066 Func Fn; 00067 public: 00068 CheckerBase *Checker; 00069 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 00070 RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 00071 return Fn(Checker, p1, p2, p3, p4); 00072 } 00073 }; 00074 00075 template <typename RET, typename P1, typename P2, typename P3> 00076 class CheckerFn<RET(P1, P2, P3)> { 00077 typedef RET (*Func)(void *, P1, P2, P3); 00078 Func Fn; 00079 public: 00080 CheckerBase *Checker; 00081 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 00082 RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 00083 }; 00084 00085 template <typename RET, typename P1, typename P2> 00086 class CheckerFn<RET(P1, P2)> { 00087 typedef RET (*Func)(void *, P1, P2); 00088 Func Fn; 00089 public: 00090 CheckerBase *Checker; 00091 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 00092 RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 00093 }; 00094 00095 template <typename RET, typename P1> 00096 class CheckerFn<RET(P1)> { 00097 typedef RET (*Func)(void *, P1); 00098 Func Fn; 00099 public: 00100 CheckerBase *Checker; 00101 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 00102 RET operator()(P1 p1) const { return Fn(Checker, p1); } 00103 }; 00104 00105 template <typename RET> 00106 class CheckerFn<RET()> { 00107 typedef RET (*Func)(void *); 00108 Func Fn; 00109 public: 00110 CheckerBase *Checker; 00111 CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } 00112 RET operator()() const { return Fn(Checker); } 00113 }; 00114 00115 /// \brief Describes the different reasons a pointer escapes 00116 /// during analysis. 00117 enum PointerEscapeKind { 00118 /// A pointer escapes due to binding its value to a location 00119 /// that the analyzer cannot track. 00120 PSK_EscapeOnBind, 00121 00122 /// The pointer has been passed to a function call directly. 00123 PSK_DirectEscapeOnCall, 00124 00125 /// The pointer has been passed to a function indirectly. 00126 /// For example, the pointer is accessible through an 00127 /// argument to a function. 00128 PSK_IndirectEscapeOnCall, 00129 00130 /// The reason for pointer escape is unknown. For example, 00131 /// a region containing this pointer is invalidated. 00132 PSK_EscapeOther 00133 }; 00134 00135 // This wrapper is used to ensure that only StringRefs originating from the 00136 // CheckerRegistry are used as check names. We want to make sure all check 00137 // name strings have a lifetime that keeps them alive at least until the path 00138 // diagnostics have been processed. 00139 class CheckName { 00140 StringRef Name; 00141 friend class ::clang::ento::CheckerRegistry; 00142 explicit CheckName(StringRef Name) : Name(Name) {} 00143 00144 public: 00145 CheckName() {} 00146 CheckName(const CheckName &Other) : Name(Other.Name) {} 00147 StringRef getName() const { return Name; } 00148 }; 00149 00150 class CheckerManager { 00151 const LangOptions LangOpts; 00152 AnalyzerOptionsRef AOptions; 00153 CheckName CurrentCheckName; 00154 00155 public: 00156 CheckerManager(const LangOptions &langOpts, 00157 AnalyzerOptionsRef AOptions) 00158 : LangOpts(langOpts), 00159 AOptions(AOptions) {} 00160 00161 ~CheckerManager(); 00162 00163 void setCurrentCheckName(CheckName name) { CurrentCheckName = name; } 00164 CheckName getCurrentCheckName() const { return CurrentCheckName; } 00165 00166 bool hasPathSensitiveCheckers() const; 00167 00168 void finishedCheckerRegistration(); 00169 00170 const LangOptions &getLangOpts() const { return LangOpts; } 00171 AnalyzerOptions &getAnalyzerOptions() { return *AOptions; } 00172 00173 typedef CheckerBase *CheckerRef; 00174 typedef const void *CheckerTag; 00175 typedef CheckerFn<void ()> CheckerDtor; 00176 00177 //===----------------------------------------------------------------------===// 00178 // registerChecker 00179 //===----------------------------------------------------------------------===// 00180 00181 /// \brief Used to register checkers. 00182 /// 00183 /// \returns a pointer to the checker object. 00184 template <typename CHECKER> 00185 CHECKER *registerChecker() { 00186 CheckerTag tag = getTag<CHECKER>(); 00187 CheckerRef &ref = CheckerTags[tag]; 00188 if (ref) 00189 return static_cast<CHECKER *>(ref); // already registered. 00190 00191 CHECKER *checker = new CHECKER(); 00192 checker->Name = CurrentCheckName; 00193 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 00194 CHECKER::_register(checker, *this); 00195 ref = checker; 00196 return checker; 00197 } 00198 00199 template <typename CHECKER> 00200 CHECKER *registerChecker(AnalyzerOptions &AOpts) { 00201 CheckerTag tag = getTag<CHECKER>(); 00202 CheckerRef &ref = CheckerTags[tag]; 00203 if (ref) 00204 return static_cast<CHECKER *>(ref); // already registered. 00205 00206 CHECKER *checker = new CHECKER(AOpts); 00207 checker->Name = CurrentCheckName; 00208 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 00209 CHECKER::_register(checker, *this); 00210 ref = checker; 00211 return checker; 00212 } 00213 00214 //===----------------------------------------------------------------------===// 00215 // Functions for running checkers for AST traversing.. 00216 //===----------------------------------------------------------------------===// 00217 00218 /// \brief Run checkers handling Decls. 00219 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 00220 BugReporter &BR); 00221 00222 /// \brief Run checkers handling Decls containing a Stmt body. 00223 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 00224 BugReporter &BR); 00225 00226 //===----------------------------------------------------------------------===// 00227 // Functions for running checkers for path-sensitive checking. 00228 //===----------------------------------------------------------------------===// 00229 00230 /// \brief Run checkers for pre-visiting Stmts. 00231 /// 00232 /// The notification is performed for every explored CFGElement, which does 00233 /// not include the control flow statements such as IfStmt. 00234 /// 00235 /// \sa runCheckersForBranchCondition, runCheckersForPostStmt 00236 void runCheckersForPreStmt(ExplodedNodeSet &Dst, 00237 const ExplodedNodeSet &Src, 00238 const Stmt *S, 00239 ExprEngine &Eng) { 00240 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 00241 } 00242 00243 /// \brief Run checkers for post-visiting Stmts. 00244 /// 00245 /// The notification is performed for every explored CFGElement, which does 00246 /// not include the control flow statements such as IfStmt. 00247 /// 00248 /// \sa runCheckersForBranchCondition, runCheckersForPreStmt 00249 void runCheckersForPostStmt(ExplodedNodeSet &Dst, 00250 const ExplodedNodeSet &Src, 00251 const Stmt *S, 00252 ExprEngine &Eng, 00253 bool wasInlined = false) { 00254 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined); 00255 } 00256 00257 /// \brief Run checkers for visiting Stmts. 00258 void runCheckersForStmt(bool isPreVisit, 00259 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 00260 const Stmt *S, ExprEngine &Eng, 00261 bool wasInlined = false); 00262 00263 /// \brief Run checkers for pre-visiting obj-c messages. 00264 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 00265 const ExplodedNodeSet &Src, 00266 const ObjCMethodCall &msg, 00267 ExprEngine &Eng) { 00268 runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 00269 } 00270 00271 /// \brief Run checkers for post-visiting obj-c messages. 00272 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 00273 const ExplodedNodeSet &Src, 00274 const ObjCMethodCall &msg, 00275 ExprEngine &Eng, 00276 bool wasInlined = false) { 00277 runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng, 00278 wasInlined); 00279 } 00280 00281 /// \brief Run checkers for visiting obj-c messages. 00282 void runCheckersForObjCMessage(bool isPreVisit, 00283 ExplodedNodeSet &Dst, 00284 const ExplodedNodeSet &Src, 00285 const ObjCMethodCall &msg, ExprEngine &Eng, 00286 bool wasInlined = false); 00287 00288 /// \brief Run checkers for pre-visiting obj-c messages. 00289 void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 00290 const CallEvent &Call, ExprEngine &Eng) { 00291 runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng); 00292 } 00293 00294 /// \brief Run checkers for post-visiting obj-c messages. 00295 void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 00296 const CallEvent &Call, ExprEngine &Eng, 00297 bool wasInlined = false) { 00298 runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng, 00299 wasInlined); 00300 } 00301 00302 /// \brief Run checkers for visiting obj-c messages. 00303 void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst, 00304 const ExplodedNodeSet &Src, 00305 const CallEvent &Call, ExprEngine &Eng, 00306 bool wasInlined = false); 00307 00308 /// \brief Run checkers for load/store of a location. 00309 void runCheckersForLocation(ExplodedNodeSet &Dst, 00310 const ExplodedNodeSet &Src, 00311 SVal location, 00312 bool isLoad, 00313 const Stmt *NodeEx, 00314 const Stmt *BoundEx, 00315 ExprEngine &Eng); 00316 00317 /// \brief Run checkers for binding of a value to a location. 00318 void runCheckersForBind(ExplodedNodeSet &Dst, 00319 const ExplodedNodeSet &Src, 00320 SVal location, SVal val, 00321 const Stmt *S, ExprEngine &Eng, 00322 const ProgramPoint &PP); 00323 00324 /// \brief Run checkers for end of analysis. 00325 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 00326 ExprEngine &Eng); 00327 00328 /// \brief Run checkers on end of function. 00329 void runCheckersForEndFunction(NodeBuilderContext &BC, 00330 ExplodedNodeSet &Dst, 00331 ExplodedNode *Pred, 00332 ExprEngine &Eng); 00333 00334 /// \brief Run checkers for branch condition. 00335 void runCheckersForBranchCondition(const Stmt *condition, 00336 ExplodedNodeSet &Dst, ExplodedNode *Pred, 00337 ExprEngine &Eng); 00338 00339 /// \brief Run checkers for live symbols. 00340 /// 00341 /// Allows modifying SymbolReaper object. For example, checkers can explicitly 00342 /// register symbols of interest as live. These symbols will not be marked 00343 /// dead and removed. 00344 void runCheckersForLiveSymbols(ProgramStateRef state, 00345 SymbolReaper &SymReaper); 00346 00347 /// \brief Run checkers for dead symbols. 00348 /// 00349 /// Notifies checkers when symbols become dead. For example, this allows 00350 /// checkers to aggressively clean up/reduce the checker state and produce 00351 /// precise diagnostics. 00352 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 00353 const ExplodedNodeSet &Src, 00354 SymbolReaper &SymReaper, const Stmt *S, 00355 ExprEngine &Eng, 00356 ProgramPoint::Kind K); 00357 00358 /// \brief True if at least one checker wants to check region changes. 00359 bool wantsRegionChangeUpdate(ProgramStateRef state); 00360 00361 /// \brief Run checkers for region changes. 00362 /// 00363 /// This corresponds to the check::RegionChanges callback. 00364 /// \param state The current program state. 00365 /// \param invalidated A set of all symbols potentially touched by the change. 00366 /// \param ExplicitRegions The regions explicitly requested for invalidation. 00367 /// For example, in the case of a function call, these would be arguments. 00368 /// \param Regions The transitive closure of accessible regions, 00369 /// i.e. all regions that may have been touched by this change. 00370 /// \param Call The call expression wrapper if the regions are invalidated 00371 /// by a call. 00372 ProgramStateRef 00373 runCheckersForRegionChanges(ProgramStateRef state, 00374 const InvalidatedSymbols *invalidated, 00375 ArrayRef<const MemRegion *> ExplicitRegions, 00376 ArrayRef<const MemRegion *> Regions, 00377 const CallEvent *Call); 00378 00379 /// \brief Run checkers when pointers escape. 00380 /// 00381 /// This notifies the checkers about pointer escape, which occurs whenever 00382 /// the analyzer cannot track the symbol any more. For example, as a 00383 /// result of assigning a pointer into a global or when it's passed to a 00384 /// function call the analyzer cannot model. 00385 /// 00386 /// \param State The state at the point of escape. 00387 /// \param Escaped The list of escaped symbols. 00388 /// \param Call The corresponding CallEvent, if the symbols escape as 00389 /// parameters to the given call. 00390 /// \param Kind The reason of pointer escape. 00391 /// \param ITraits Information about invalidation for a particular 00392 /// region/symbol. 00393 /// \returns Checkers can modify the state by returning a new one. 00394 ProgramStateRef 00395 runCheckersForPointerEscape(ProgramStateRef State, 00396 const InvalidatedSymbols &Escaped, 00397 const CallEvent *Call, 00398 PointerEscapeKind Kind, 00399 RegionAndSymbolInvalidationTraits *ITraits); 00400 00401 /// \brief Run checkers for handling assumptions on symbolic values. 00402 ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, 00403 SVal Cond, bool Assumption); 00404 00405 /// \brief Run checkers for evaluating a call. 00406 /// 00407 /// Warning: Currently, the CallEvent MUST come from a CallExpr! 00408 void runCheckersForEvalCall(ExplodedNodeSet &Dst, 00409 const ExplodedNodeSet &Src, 00410 const CallEvent &CE, ExprEngine &Eng); 00411 00412 /// \brief Run checkers for the entire Translation Unit. 00413 void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, 00414 AnalysisManager &mgr, 00415 BugReporter &BR); 00416 00417 /// \brief Run checkers for debug-printing a ProgramState. 00418 /// 00419 /// Unlike most other callbacks, any checker can simply implement the virtual 00420 /// method CheckerBase::printState if it has custom data to print. 00421 /// \param Out The output stream 00422 /// \param State The state being printed 00423 /// \param NL The preferred representation of a newline. 00424 /// \param Sep The preferred separator between different kinds of data. 00425 void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, 00426 const char *NL, const char *Sep); 00427 00428 //===----------------------------------------------------------------------===// 00429 // Internal registration functions for AST traversing. 00430 //===----------------------------------------------------------------------===// 00431 00432 // Functions used by the registration mechanism, checkers should not touch 00433 // these directly. 00434 00435 typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)> 00436 CheckDeclFunc; 00437 00438 typedef bool (*HandlesDeclFunc)(const Decl *D); 00439 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 00440 00441 void _registerForBody(CheckDeclFunc checkfn); 00442 00443 //===----------------------------------------------------------------------===// 00444 // Internal registration functions for path-sensitive checking. 00445 //===----------------------------------------------------------------------===// 00446 00447 typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc; 00448 00449 typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)> 00450 CheckObjCMessageFunc; 00451 00452 typedef CheckerFn<void (const CallEvent &, CheckerContext &)> 00453 CheckCallFunc; 00454 00455 typedef CheckerFn<void (const SVal &location, bool isLoad, 00456 const Stmt *S, 00457 CheckerContext &)> 00458 CheckLocationFunc; 00459 00460 typedef CheckerFn<void (const SVal &location, const SVal &val, 00461 const Stmt *S, CheckerContext &)> 00462 CheckBindFunc; 00463 00464 typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> 00465 CheckEndAnalysisFunc; 00466 00467 typedef CheckerFn<void (CheckerContext &)> 00468 CheckEndFunctionFunc; 00469 00470 typedef CheckerFn<void (const Stmt *, CheckerContext &)> 00471 CheckBranchConditionFunc; 00472 00473 typedef CheckerFn<void (SymbolReaper &, CheckerContext &)> 00474 CheckDeadSymbolsFunc; 00475 00476 typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc; 00477 00478 typedef CheckerFn<ProgramStateRef (ProgramStateRef, 00479 const InvalidatedSymbols *symbols, 00480 ArrayRef<const MemRegion *> ExplicitRegions, 00481 ArrayRef<const MemRegion *> Regions, 00482 const CallEvent *Call)> 00483 CheckRegionChangesFunc; 00484 00485 typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc; 00486 00487 typedef CheckerFn<ProgramStateRef (ProgramStateRef, 00488 const InvalidatedSymbols &Escaped, 00489 const CallEvent *Call, 00490 PointerEscapeKind Kind, 00491 RegionAndSymbolInvalidationTraits *ITraits)> 00492 CheckPointerEscapeFunc; 00493 00494 typedef CheckerFn<ProgramStateRef (ProgramStateRef, 00495 const SVal &cond, bool assumption)> 00496 EvalAssumeFunc; 00497 00498 typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> 00499 EvalCallFunc; 00500 00501 typedef CheckerFn<void (const TranslationUnitDecl *, 00502 AnalysisManager&, BugReporter &)> 00503 CheckEndOfTranslationUnit; 00504 00505 typedef bool (*HandlesStmtFunc)(const Stmt *D); 00506 void _registerForPreStmt(CheckStmtFunc checkfn, 00507 HandlesStmtFunc isForStmtFn); 00508 void _registerForPostStmt(CheckStmtFunc checkfn, 00509 HandlesStmtFunc isForStmtFn); 00510 00511 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 00512 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 00513 00514 void _registerForPreCall(CheckCallFunc checkfn); 00515 void _registerForPostCall(CheckCallFunc checkfn); 00516 00517 void _registerForLocation(CheckLocationFunc checkfn); 00518 00519 void _registerForBind(CheckBindFunc checkfn); 00520 00521 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 00522 00523 void _registerForEndFunction(CheckEndFunctionFunc checkfn); 00524 00525 void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 00526 00527 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 00528 00529 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 00530 00531 void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 00532 WantsRegionChangeUpdateFunc wantUpdateFn); 00533 00534 void _registerForPointerEscape(CheckPointerEscapeFunc checkfn); 00535 00536 void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn); 00537 00538 void _registerForEvalAssume(EvalAssumeFunc checkfn); 00539 00540 void _registerForEvalCall(EvalCallFunc checkfn); 00541 00542 void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); 00543 00544 //===----------------------------------------------------------------------===// 00545 // Internal registration functions for events. 00546 //===----------------------------------------------------------------------===// 00547 00548 typedef void *EventTag; 00549 typedef CheckerFn<void (const void *event)> CheckEventFunc; 00550 00551 template <typename EVENT> 00552 void _registerListenerForEvent(CheckEventFunc checkfn) { 00553 EventInfo &info = Events[getTag<EVENT>()]; 00554 info.Checkers.push_back(checkfn); 00555 } 00556 00557 template <typename EVENT> 00558 void _registerDispatcherForEvent() { 00559 EventInfo &info = Events[getTag<EVENT>()]; 00560 info.HasDispatcher = true; 00561 } 00562 00563 template <typename EVENT> 00564 void _dispatchEvent(const EVENT &event) const { 00565 EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 00566 if (I == Events.end()) 00567 return; 00568 const EventInfo &info = I->second; 00569 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 00570 info.Checkers[i](&event); 00571 } 00572 00573 //===----------------------------------------------------------------------===// 00574 // Implementation details. 00575 //===----------------------------------------------------------------------===// 00576 00577 private: 00578 template <typename CHECKER> 00579 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 00580 00581 template <typename T> 00582 static void *getTag() { static int tag; return &tag; } 00583 00584 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 00585 00586 std::vector<CheckerDtor> CheckerDtors; 00587 00588 struct DeclCheckerInfo { 00589 CheckDeclFunc CheckFn; 00590 HandlesDeclFunc IsForDeclFn; 00591 }; 00592 std::vector<DeclCheckerInfo> DeclCheckers; 00593 00594 std::vector<CheckDeclFunc> BodyCheckers; 00595 00596 typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 00597 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 00598 CachedDeclCheckersMapTy CachedDeclCheckersMap; 00599 00600 struct StmtCheckerInfo { 00601 CheckStmtFunc CheckFn; 00602 HandlesStmtFunc IsForStmtFn; 00603 bool IsPreVisit; 00604 }; 00605 std::vector<StmtCheckerInfo> StmtCheckers; 00606 00607 typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 00608 typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy; 00609 CachedStmtCheckersMapTy CachedStmtCheckersMap; 00610 00611 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S, 00612 bool isPreVisit); 00613 00614 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 00615 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 00616 00617 std::vector<CheckCallFunc> PreCallCheckers; 00618 std::vector<CheckCallFunc> PostCallCheckers; 00619 00620 std::vector<CheckLocationFunc> LocationCheckers; 00621 00622 std::vector<CheckBindFunc> BindCheckers; 00623 00624 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 00625 00626 std::vector<CheckEndFunctionFunc> EndFunctionCheckers; 00627 00628 std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 00629 00630 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 00631 00632 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 00633 00634 struct RegionChangesCheckerInfo { 00635 CheckRegionChangesFunc CheckFn; 00636 WantsRegionChangeUpdateFunc WantUpdateFn; 00637 }; 00638 std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 00639 00640 std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers; 00641 00642 std::vector<EvalAssumeFunc> EvalAssumeCheckers; 00643 00644 std::vector<EvalCallFunc> EvalCallCheckers; 00645 00646 std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; 00647 00648 struct EventInfo { 00649 SmallVector<CheckEventFunc, 4> Checkers; 00650 bool HasDispatcher; 00651 EventInfo() : HasDispatcher(false) { } 00652 }; 00653 00654 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 00655 EventsTy Events; 00656 }; 00657 00658 } // end ento namespace 00659 00660 } // end clang namespace 00661 00662 #endif