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