1*f4a2713aSLionel Sambuc //= CheckerDocumentation.cpp - Documentation checker ---------------*- C++ -*-//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc // This checker lists all the checker callbacks and provides documentation for
11*f4a2713aSLionel Sambuc // checker writers.
12*f4a2713aSLionel Sambuc //
13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14*f4a2713aSLionel Sambuc
15*f4a2713aSLionel Sambuc #include "ClangSACheckers.h"
16*f4a2713aSLionel Sambuc #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
17*f4a2713aSLionel Sambuc #include "clang/StaticAnalyzer/Core/Checker.h"
18*f4a2713aSLionel Sambuc #include "clang/StaticAnalyzer/Core/CheckerManager.h"
19*f4a2713aSLionel Sambuc #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20*f4a2713aSLionel Sambuc #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
21*f4a2713aSLionel Sambuc
22*f4a2713aSLionel Sambuc using namespace clang;
23*f4a2713aSLionel Sambuc using namespace ento;
24*f4a2713aSLionel Sambuc
25*f4a2713aSLionel Sambuc // All checkers should be placed into anonymous namespace.
26*f4a2713aSLionel Sambuc // We place the CheckerDocumentation inside ento namespace to make the
27*f4a2713aSLionel Sambuc // it visible in doxygen.
28*f4a2713aSLionel Sambuc namespace clang {
29*f4a2713aSLionel Sambuc namespace ento {
30*f4a2713aSLionel Sambuc
31*f4a2713aSLionel Sambuc /// This checker documents the callback functions checkers can use to implement
32*f4a2713aSLionel Sambuc /// the custom handling of the specific events during path exploration as well
33*f4a2713aSLionel Sambuc /// as reporting bugs. Most of the callbacks are targeted at path-sensitive
34*f4a2713aSLionel Sambuc /// checking.
35*f4a2713aSLionel Sambuc ///
36*f4a2713aSLionel Sambuc /// \sa CheckerContext
37*f4a2713aSLionel Sambuc class CheckerDocumentation : public Checker< check::PreStmt<ReturnStmt>,
38*f4a2713aSLionel Sambuc check::PostStmt<DeclStmt>,
39*f4a2713aSLionel Sambuc check::PreObjCMessage,
40*f4a2713aSLionel Sambuc check::PostObjCMessage,
41*f4a2713aSLionel Sambuc check::PreCall,
42*f4a2713aSLionel Sambuc check::PostCall,
43*f4a2713aSLionel Sambuc check::BranchCondition,
44*f4a2713aSLionel Sambuc check::Location,
45*f4a2713aSLionel Sambuc check::Bind,
46*f4a2713aSLionel Sambuc check::DeadSymbols,
47*f4a2713aSLionel Sambuc check::EndFunction,
48*f4a2713aSLionel Sambuc check::EndAnalysis,
49*f4a2713aSLionel Sambuc check::EndOfTranslationUnit,
50*f4a2713aSLionel Sambuc eval::Call,
51*f4a2713aSLionel Sambuc eval::Assume,
52*f4a2713aSLionel Sambuc check::LiveSymbols,
53*f4a2713aSLionel Sambuc check::RegionChanges,
54*f4a2713aSLionel Sambuc check::PointerEscape,
55*f4a2713aSLionel Sambuc check::ConstPointerEscape,
56*f4a2713aSLionel Sambuc check::Event<ImplicitNullDerefEvent>,
57*f4a2713aSLionel Sambuc check::ASTDecl<FunctionDecl> > {
58*f4a2713aSLionel Sambuc public:
59*f4a2713aSLionel Sambuc
60*f4a2713aSLionel Sambuc /// \brief Pre-visit the Statement.
61*f4a2713aSLionel Sambuc ///
62*f4a2713aSLionel Sambuc /// The method will be called before the analyzer core processes the
63*f4a2713aSLionel Sambuc /// statement. The notification is performed for every explored CFGElement,
64*f4a2713aSLionel Sambuc /// which does not include the control flow statements such as IfStmt. The
65*f4a2713aSLionel Sambuc /// callback can be specialized to be called with any subclass of Stmt.
66*f4a2713aSLionel Sambuc ///
67*f4a2713aSLionel Sambuc /// See checkBranchCondition() callback for performing custom processing of
68*f4a2713aSLionel Sambuc /// the branching statements.
69*f4a2713aSLionel Sambuc ///
70*f4a2713aSLionel Sambuc /// check::PreStmt<ReturnStmt>
checkPreStmt(const ReturnStmt * DS,CheckerContext & C) const71*f4a2713aSLionel Sambuc void checkPreStmt(const ReturnStmt *DS, CheckerContext &C) const {}
72*f4a2713aSLionel Sambuc
73*f4a2713aSLionel Sambuc /// \brief Post-visit the Statement.
74*f4a2713aSLionel Sambuc ///
75*f4a2713aSLionel Sambuc /// The method will be called after the analyzer core processes the
76*f4a2713aSLionel Sambuc /// statement. The notification is performed for every explored CFGElement,
77*f4a2713aSLionel Sambuc /// which does not include the control flow statements such as IfStmt. The
78*f4a2713aSLionel Sambuc /// callback can be specialized to be called with any subclass of Stmt.
79*f4a2713aSLionel Sambuc ///
80*f4a2713aSLionel Sambuc /// check::PostStmt<DeclStmt>
81*f4a2713aSLionel Sambuc void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const;
82*f4a2713aSLionel Sambuc
83*f4a2713aSLionel Sambuc /// \brief Pre-visit the Objective C message.
84*f4a2713aSLionel Sambuc ///
85*f4a2713aSLionel Sambuc /// This will be called before the analyzer core processes the method call.
86*f4a2713aSLionel Sambuc /// This is called for any action which produces an Objective-C message send,
87*f4a2713aSLionel Sambuc /// including explicit message syntax and property access.
88*f4a2713aSLionel Sambuc ///
89*f4a2713aSLionel Sambuc /// check::PreObjCMessage
checkPreObjCMessage(const ObjCMethodCall & M,CheckerContext & C) const90*f4a2713aSLionel Sambuc void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}
91*f4a2713aSLionel Sambuc
92*f4a2713aSLionel Sambuc /// \brief Post-visit the Objective C message.
93*f4a2713aSLionel Sambuc /// \sa checkPreObjCMessage()
94*f4a2713aSLionel Sambuc ///
95*f4a2713aSLionel Sambuc /// check::PostObjCMessage
checkPostObjCMessage(const ObjCMethodCall & M,CheckerContext & C) const96*f4a2713aSLionel Sambuc void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}
97*f4a2713aSLionel Sambuc
98*f4a2713aSLionel Sambuc /// \brief Pre-visit an abstract "call" event.
99*f4a2713aSLionel Sambuc ///
100*f4a2713aSLionel Sambuc /// This is used for checkers that want to check arguments or attributed
101*f4a2713aSLionel Sambuc /// behavior for functions and methods no matter how they are being invoked.
102*f4a2713aSLionel Sambuc ///
103*f4a2713aSLionel Sambuc /// Note that this includes ALL cross-body invocations, so if you want to
104*f4a2713aSLionel Sambuc /// limit your checks to, say, function calls, you should test for that at the
105*f4a2713aSLionel Sambuc /// beginning of your callback function.
106*f4a2713aSLionel Sambuc ///
107*f4a2713aSLionel Sambuc /// check::PreCall
checkPreCall(const CallEvent & Call,CheckerContext & C) const108*f4a2713aSLionel Sambuc void checkPreCall(const CallEvent &Call, CheckerContext &C) const {}
109*f4a2713aSLionel Sambuc
110*f4a2713aSLionel Sambuc /// \brief Post-visit an abstract "call" event.
111*f4a2713aSLionel Sambuc /// \sa checkPreObjCMessage()
112*f4a2713aSLionel Sambuc ///
113*f4a2713aSLionel Sambuc /// check::PostCall
checkPostCall(const CallEvent & Call,CheckerContext & C) const114*f4a2713aSLionel Sambuc void checkPostCall(const CallEvent &Call, CheckerContext &C) const {}
115*f4a2713aSLionel Sambuc
116*f4a2713aSLionel Sambuc /// \brief Pre-visit of the condition statement of a branch (such as IfStmt).
checkBranchCondition(const Stmt * Condition,CheckerContext & Ctx) const117*f4a2713aSLionel Sambuc void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const {}
118*f4a2713aSLionel Sambuc
119*f4a2713aSLionel Sambuc /// \brief Called on a load from and a store to a location.
120*f4a2713aSLionel Sambuc ///
121*f4a2713aSLionel Sambuc /// The method will be called each time a location (pointer) value is
122*f4a2713aSLionel Sambuc /// accessed.
123*f4a2713aSLionel Sambuc /// \param Loc The value of the location (pointer).
124*f4a2713aSLionel Sambuc /// \param IsLoad The flag specifying if the location is a store or a load.
125*f4a2713aSLionel Sambuc /// \param S The load is performed while processing the statement.
126*f4a2713aSLionel Sambuc ///
127*f4a2713aSLionel Sambuc /// check::Location
checkLocation(SVal Loc,bool IsLoad,const Stmt * S,CheckerContext &) const128*f4a2713aSLionel Sambuc void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
129*f4a2713aSLionel Sambuc CheckerContext &) const {}
130*f4a2713aSLionel Sambuc
131*f4a2713aSLionel Sambuc /// \brief Called on binding of a value to a location.
132*f4a2713aSLionel Sambuc ///
133*f4a2713aSLionel Sambuc /// \param Loc The value of the location (pointer).
134*f4a2713aSLionel Sambuc /// \param Val The value which will be stored at the location Loc.
135*f4a2713aSLionel Sambuc /// \param S The bind is performed while processing the statement S.
136*f4a2713aSLionel Sambuc ///
137*f4a2713aSLionel Sambuc /// check::Bind
checkBind(SVal Loc,SVal Val,const Stmt * S,CheckerContext &) const138*f4a2713aSLionel Sambuc void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &) const {}
139*f4a2713aSLionel Sambuc
140*f4a2713aSLionel Sambuc
141*f4a2713aSLionel Sambuc /// \brief Called whenever a symbol becomes dead.
142*f4a2713aSLionel Sambuc ///
143*f4a2713aSLionel Sambuc /// This callback should be used by the checkers to aggressively clean
144*f4a2713aSLionel Sambuc /// up/reduce the checker state, which is important for reducing the overall
145*f4a2713aSLionel Sambuc /// memory usage. Specifically, if a checker keeps symbol specific information
146*f4a2713aSLionel Sambuc /// in the sate, it can and should be dropped after the symbol becomes dead.
147*f4a2713aSLionel Sambuc /// In addition, reporting a bug as soon as the checker becomes dead leads to
148*f4a2713aSLionel Sambuc /// more precise diagnostics. (For example, one should report that a malloced
149*f4a2713aSLionel Sambuc /// variable is not freed right after it goes out of scope.)
150*f4a2713aSLionel Sambuc ///
151*f4a2713aSLionel Sambuc /// \param SR The SymbolReaper object can be queried to determine which
152*f4a2713aSLionel Sambuc /// symbols are dead.
153*f4a2713aSLionel Sambuc ///
154*f4a2713aSLionel Sambuc /// check::DeadSymbols
checkDeadSymbols(SymbolReaper & SR,CheckerContext & C) const155*f4a2713aSLionel Sambuc void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const {}
156*f4a2713aSLionel Sambuc
157*f4a2713aSLionel Sambuc /// \brief Called when the analyzer core reaches the end of a
158*f4a2713aSLionel Sambuc /// function being analyzed.
159*f4a2713aSLionel Sambuc ///
160*f4a2713aSLionel Sambuc /// check::EndFunction
checkEndFunction(CheckerContext & Ctx) const161*f4a2713aSLionel Sambuc void checkEndFunction(CheckerContext &Ctx) const {}
162*f4a2713aSLionel Sambuc
163*f4a2713aSLionel Sambuc /// \brief Called after all the paths in the ExplodedGraph reach end of path
164*f4a2713aSLionel Sambuc /// - the symbolic execution graph is fully explored.
165*f4a2713aSLionel Sambuc ///
166*f4a2713aSLionel Sambuc /// This callback should be used in cases when a checker needs to have a
167*f4a2713aSLionel Sambuc /// global view of the information generated on all paths. For example, to
168*f4a2713aSLionel Sambuc /// compare execution summary/result several paths.
169*f4a2713aSLionel Sambuc /// See IdempotentOperationChecker for a usage example.
170*f4a2713aSLionel Sambuc ///
171*f4a2713aSLionel Sambuc /// check::EndAnalysis
checkEndAnalysis(ExplodedGraph & G,BugReporter & BR,ExprEngine & Eng) const172*f4a2713aSLionel Sambuc void checkEndAnalysis(ExplodedGraph &G,
173*f4a2713aSLionel Sambuc BugReporter &BR,
174*f4a2713aSLionel Sambuc ExprEngine &Eng) const {}
175*f4a2713aSLionel Sambuc
176*f4a2713aSLionel Sambuc /// \brief Called after analysis of a TranslationUnit is complete.
177*f4a2713aSLionel Sambuc ///
178*f4a2713aSLionel Sambuc /// check::EndOfTranslationUnit
checkEndOfTranslationUnit(const TranslationUnitDecl * TU,AnalysisManager & Mgr,BugReporter & BR) const179*f4a2713aSLionel Sambuc void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
180*f4a2713aSLionel Sambuc AnalysisManager &Mgr,
181*f4a2713aSLionel Sambuc BugReporter &BR) const {}
182*f4a2713aSLionel Sambuc
183*f4a2713aSLionel Sambuc
184*f4a2713aSLionel Sambuc /// \brief Evaluates function call.
185*f4a2713aSLionel Sambuc ///
186*f4a2713aSLionel Sambuc /// The analysis core threats all function calls in the same way. However, some
187*f4a2713aSLionel Sambuc /// functions have special meaning, which should be reflected in the program
188*f4a2713aSLionel Sambuc /// state. This callback allows a checker to provide domain specific knowledge
189*f4a2713aSLionel Sambuc /// about the particular functions it knows about.
190*f4a2713aSLionel Sambuc ///
191*f4a2713aSLionel Sambuc /// \returns true if the call has been successfully evaluated
192*f4a2713aSLionel Sambuc /// and false otherwise. Note, that only one checker can evaluate a call. If
193*f4a2713aSLionel Sambuc /// more than one checker claims that they can evaluate the same call the
194*f4a2713aSLionel Sambuc /// first one wins.
195*f4a2713aSLionel Sambuc ///
196*f4a2713aSLionel Sambuc /// eval::Call
evalCall(const CallExpr * CE,CheckerContext & C) const197*f4a2713aSLionel Sambuc bool evalCall(const CallExpr *CE, CheckerContext &C) const { return true; }
198*f4a2713aSLionel Sambuc
199*f4a2713aSLionel Sambuc /// \brief Handles assumptions on symbolic values.
200*f4a2713aSLionel Sambuc ///
201*f4a2713aSLionel Sambuc /// This method is called when a symbolic expression is assumed to be true or
202*f4a2713aSLionel Sambuc /// false. For example, the assumptions are performed when evaluating a
203*f4a2713aSLionel Sambuc /// condition at a branch. The callback allows checkers track the assumptions
204*f4a2713aSLionel Sambuc /// performed on the symbols of interest and change the state accordingly.
205*f4a2713aSLionel Sambuc ///
206*f4a2713aSLionel Sambuc /// eval::Assume
evalAssume(ProgramStateRef State,SVal Cond,bool Assumption) const207*f4a2713aSLionel Sambuc ProgramStateRef evalAssume(ProgramStateRef State,
208*f4a2713aSLionel Sambuc SVal Cond,
209*f4a2713aSLionel Sambuc bool Assumption) const { return State; }
210*f4a2713aSLionel Sambuc
211*f4a2713aSLionel Sambuc /// Allows modifying SymbolReaper object. For example, checkers can explicitly
212*f4a2713aSLionel Sambuc /// register symbols of interest as live. These symbols will not be marked
213*f4a2713aSLionel Sambuc /// dead and removed.
214*f4a2713aSLionel Sambuc ///
215*f4a2713aSLionel Sambuc /// check::LiveSymbols
checkLiveSymbols(ProgramStateRef State,SymbolReaper & SR) const216*f4a2713aSLionel Sambuc void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}
217*f4a2713aSLionel Sambuc
218*f4a2713aSLionel Sambuc /// \brief Called to determine if the checker currently needs to know if when
219*f4a2713aSLionel Sambuc /// contents of any regions change.
220*f4a2713aSLionel Sambuc ///
221*f4a2713aSLionel Sambuc /// Since it is not necessarily cheap to compute which regions are being
222*f4a2713aSLionel Sambuc /// changed, this allows the analyzer core to skip the more expensive
223*f4a2713aSLionel Sambuc /// #checkRegionChanges when no checkers are tracking any state.
wantsRegionChangeUpdate(ProgramStateRef St) const224*f4a2713aSLionel Sambuc bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
225*f4a2713aSLionel Sambuc
226*f4a2713aSLionel Sambuc /// \brief Called when the contents of one or more regions change.
227*f4a2713aSLionel Sambuc ///
228*f4a2713aSLionel Sambuc /// This can occur in many different ways: an explicit bind, a blanket
229*f4a2713aSLionel Sambuc /// invalidation of the region contents, or by passing a region to a function
230*f4a2713aSLionel Sambuc /// call whose behavior the analyzer cannot model perfectly.
231*f4a2713aSLionel Sambuc ///
232*f4a2713aSLionel Sambuc /// \param State The current program state.
233*f4a2713aSLionel Sambuc /// \param Invalidated A set of all symbols potentially touched by the change.
234*f4a2713aSLionel Sambuc /// \param ExplicitRegions The regions explicitly requested for invalidation.
235*f4a2713aSLionel Sambuc /// For a function call, this would be the arguments. For a bind, this
236*f4a2713aSLionel Sambuc /// would be the region being bound to.
237*f4a2713aSLionel Sambuc /// \param Regions The transitive closure of regions accessible from,
238*f4a2713aSLionel Sambuc /// \p ExplicitRegions, i.e. all regions that may have been touched
239*f4a2713aSLionel Sambuc /// by this change. For a simple bind, this list will be the same as
240*f4a2713aSLionel Sambuc /// \p ExplicitRegions, since a bind does not affect the contents of
241*f4a2713aSLionel Sambuc /// anything accessible through the base region.
242*f4a2713aSLionel Sambuc /// \param Call The opaque call triggering this invalidation. Will be 0 if the
243*f4a2713aSLionel Sambuc /// change was not triggered by a call.
244*f4a2713aSLionel Sambuc ///
245*f4a2713aSLionel Sambuc /// Note that this callback will not be invoked unless
246*f4a2713aSLionel Sambuc /// #wantsRegionChangeUpdate returns \c true.
247*f4a2713aSLionel Sambuc ///
248*f4a2713aSLionel Sambuc /// check::RegionChanges
249*f4a2713aSLionel Sambuc ProgramStateRef
checkRegionChanges(ProgramStateRef State,const InvalidatedSymbols * Invalidated,ArrayRef<const MemRegion * > ExplicitRegions,ArrayRef<const MemRegion * > Regions,const CallEvent * Call) const250*f4a2713aSLionel Sambuc checkRegionChanges(ProgramStateRef State,
251*f4a2713aSLionel Sambuc const InvalidatedSymbols *Invalidated,
252*f4a2713aSLionel Sambuc ArrayRef<const MemRegion *> ExplicitRegions,
253*f4a2713aSLionel Sambuc ArrayRef<const MemRegion *> Regions,
254*f4a2713aSLionel Sambuc const CallEvent *Call) const {
255*f4a2713aSLionel Sambuc return State;
256*f4a2713aSLionel Sambuc }
257*f4a2713aSLionel Sambuc
258*f4a2713aSLionel Sambuc /// \brief Called when pointers escape.
259*f4a2713aSLionel Sambuc ///
260*f4a2713aSLionel Sambuc /// This notifies the checkers about pointer escape, which occurs whenever
261*f4a2713aSLionel Sambuc /// the analyzer cannot track the symbol any more. For example, as a
262*f4a2713aSLionel Sambuc /// result of assigning a pointer into a global or when it's passed to a
263*f4a2713aSLionel Sambuc /// function call the analyzer cannot model.
264*f4a2713aSLionel Sambuc ///
265*f4a2713aSLionel Sambuc /// \param State The state at the point of escape.
266*f4a2713aSLionel Sambuc /// \param Escaped The list of escaped symbols.
267*f4a2713aSLionel Sambuc /// \param Call The corresponding CallEvent, if the symbols escape as
268*f4a2713aSLionel Sambuc /// parameters to the given call.
269*f4a2713aSLionel Sambuc /// \param Kind How the symbols have escaped.
270*f4a2713aSLionel Sambuc /// \returns Checkers can modify the state by returning a new state.
checkPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const271*f4a2713aSLionel Sambuc ProgramStateRef checkPointerEscape(ProgramStateRef State,
272*f4a2713aSLionel Sambuc const InvalidatedSymbols &Escaped,
273*f4a2713aSLionel Sambuc const CallEvent *Call,
274*f4a2713aSLionel Sambuc PointerEscapeKind Kind) const {
275*f4a2713aSLionel Sambuc return State;
276*f4a2713aSLionel Sambuc }
277*f4a2713aSLionel Sambuc
278*f4a2713aSLionel Sambuc /// \brief Called when const pointers escape.
279*f4a2713aSLionel Sambuc ///
280*f4a2713aSLionel Sambuc /// Note: in most cases checkPointerEscape callback is sufficient.
281*f4a2713aSLionel Sambuc /// \sa checkPointerEscape
checkConstPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const282*f4a2713aSLionel Sambuc ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
283*f4a2713aSLionel Sambuc const InvalidatedSymbols &Escaped,
284*f4a2713aSLionel Sambuc const CallEvent *Call,
285*f4a2713aSLionel Sambuc PointerEscapeKind Kind) const {
286*f4a2713aSLionel Sambuc return State;
287*f4a2713aSLionel Sambuc }
288*f4a2713aSLionel Sambuc
289*f4a2713aSLionel Sambuc /// check::Event<ImplicitNullDerefEvent>
checkEvent(ImplicitNullDerefEvent Event) const290*f4a2713aSLionel Sambuc void checkEvent(ImplicitNullDerefEvent Event) const {}
291*f4a2713aSLionel Sambuc
292*f4a2713aSLionel Sambuc /// \brief Check every declaration in the AST.
293*f4a2713aSLionel Sambuc ///
294*f4a2713aSLionel Sambuc /// An AST traversal callback, which should only be used when the checker is
295*f4a2713aSLionel Sambuc /// not path sensitive. It will be called for every Declaration in the AST and
296*f4a2713aSLionel Sambuc /// can be specialized to only be called on subclasses of Decl, for example,
297*f4a2713aSLionel Sambuc /// FunctionDecl.
298*f4a2713aSLionel Sambuc ///
299*f4a2713aSLionel Sambuc /// check::ASTDecl<FunctionDecl>
checkASTDecl(const FunctionDecl * D,AnalysisManager & Mgr,BugReporter & BR) const300*f4a2713aSLionel Sambuc void checkASTDecl(const FunctionDecl *D,
301*f4a2713aSLionel Sambuc AnalysisManager &Mgr,
302*f4a2713aSLionel Sambuc BugReporter &BR) const {}
303*f4a2713aSLionel Sambuc
304*f4a2713aSLionel Sambuc };
305*f4a2713aSLionel Sambuc
checkPostStmt(const DeclStmt * DS,CheckerContext & C) const306*f4a2713aSLionel Sambuc void CheckerDocumentation::checkPostStmt(const DeclStmt *DS,
307*f4a2713aSLionel Sambuc CheckerContext &C) const {
308*f4a2713aSLionel Sambuc return;
309*f4a2713aSLionel Sambuc }
310*f4a2713aSLionel Sambuc
311*f4a2713aSLionel Sambuc } // end namespace ento
312*f4a2713aSLionel Sambuc } // end namespace clang
313