clang 23.0.0git
CheckerContext.h
Go to the documentation of this file.
1//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines CheckerContext that provides contextual info for
10// path-sensitive checkers.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
15#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
16
19#include <optional>
20
21namespace clang {
22namespace ento {
23
25 ExprEngine &Eng;
26 /// The current exploded(symbolic execution) graph node.
27 ExplodedNode *Pred;
28 /// The flag is true if the (state of the execution) has been modified
29 /// by the checker using this context. For example, a new transition has been
30 /// added or a bug report issued.
31 bool Changed;
32 /// The tagged location, which is used to generate all new nodes.
33 const ProgramPoint Location;
34 NodeBuilder &NB;
35
36public:
37 /// If we are post visiting a call, this flag will be set if the
38 /// call was inlined. In all other cases it will be false.
39 const bool wasInlined;
40
42 ExprEngine &eng,
43 ExplodedNode *pred,
44 const ProgramPoint &loc,
45 bool wasInlined = false)
46 : Eng(eng),
47 Pred(pred),
48 Changed(false),
49 Location(loc),
50 NB(builder),
52 assert(Pred->getState() &&
53 "We should not call the checkers on an empty state.");
54 assert(loc.getTag() && "The ProgramPoint associated with CheckerContext "
55 "must be tagged with the active checker.");
56 }
57
59 return Eng.getAnalysisManager();
60 }
62 return Eng.getAnalysisManager();
63 }
64
66 return Eng.getConstraintManager();
67 }
69 return Eng.getConstraintManager();
70 }
71
73 return Eng.getStoreManager();
74 }
75 const StoreManager &getStoreManager() const { return Eng.getStoreManager(); }
76
77 /// Returns the previous node in the exploded graph, which includes
78 /// the state of the program before the checker ran. Note, checkers should
79 /// not retain the node in their state since the nodes might get invalidated.
80 ExplodedNode *getPredecessor() { return Pred; }
81 const ExplodedNode *getPredecessor() const { return Pred; }
82 const ProgramPoint getLocation() const { return Location; }
83 const ProgramStateRef &getState() const { return Pred->getState(); }
84
85 /// Check if the checker changed the state of the execution; ex: added
86 /// a new transition or a bug report.
87 bool isDifferent() { return Changed; }
88 bool isDifferent() const { return Changed; }
89
90 /// Returns the number of times the current block has been visited
91 /// along the analyzed path.
92 unsigned blockCount() const { return Eng.getNumVisitedCurrent(); }
93
95 return Eng.getContext();
96 }
97
98 const ASTContext &getASTContext() const { return Eng.getContext(); }
99
100 const LangOptions &getLangOpts() const {
101 return Eng.getContext().getLangOpts();
102 }
103
104 const StackFrame *getStackFrame() const { return Pred->getStackFrame(); }
105
106 /// Return true if the current StackFrame has no caller context.
107 bool inTopFrame() const { return getStackFrame()->inTopFrame(); }
108
110 return Eng.getBugReporter();
111 }
112 const BugReporter &getBugReporter() const { return Eng.getBugReporter(); }
113
119 }
120
124 }
125
127 return Eng.getSValBuilder();
128 }
129 const SValBuilder &getSValBuilder() const { return Eng.getSValBuilder(); }
130
136 }
137
139 return Eng.getStateManager();
140 }
142 return Eng.getStateManager();
143 }
144
148
149 /// Get the blockID.
150 unsigned getBlockID() const { return Eng.getCurrBlock()->getBlockID(); }
151
152 /// If the given node corresponds to a PostStore program point,
153 /// retrieve the location region as it was uttered in the code.
154 ///
155 /// This utility can be useful for generating extensive diagnostics, for
156 /// example, for finding variables that the given symbol was assigned to.
158 ProgramPoint L = N->getLocation();
159 if (std::optional<PostStore> PSL = L.getAs<PostStore>())
160 return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
161 return nullptr;
162 }
163
164 /// Get the value of arbitrary expressions at this point in the path.
165 SVal getSVal(const Expr *E) const { return Pred->getSVal(E); }
166
167 ConstCFGElementRef getCFGElementRef() const { return Eng.getCFGElementRef(); }
168
169 /// Returns true if the value of \p E is greater than or equal to \p
170 /// Val under unsigned comparison.
171 bool isGreaterOrEqual(const Expr *E, unsigned long long Val);
172
173 /// Returns true if the value of \p E is negative.
174 bool isNegative(const Expr *E);
175
176 /// Generates a new transition in the program state graph
177 /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
178 ///
179 /// @param State The state of the generated node. If not specified, the state
180 /// will not be changed, but the new node will have the checker's tag.
181 /// @param Tag The tag is used to uniquely identify the creation site. If no
182 /// tag is specified, a default tag, unique to the given checker,
183 /// will be used. Tags are used to prevent states generated at
184 /// different sites from caching out.
185 /// NOTE: If the State is unchanged and the Tag is nullptr, this may return a
186 /// node which is not tagged (instead of using the default tag corresponding
187 /// to the active checker). This is arguably a bug and should be fixed.
189 const ProgramPointTag *Tag = nullptr) {
190 return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
191 }
192
193 /// Generates a new transition with the given predecessor.
194 /// Allows checkers to generate a chain of nodes.
195 ///
196 /// @param State The state of the generated node.
197 /// @param Pred The transition will be generated from the specified Pred node
198 /// to the newly generated node.
199 /// @param Tag The tag to uniquely identify the creation site.
200 /// NOTE: If the State is unchanged and the Tag is nullptr, this may return a
201 /// node which is not tagged (instead of using the default tag corresponding
202 /// to the active checker). This is arguably a bug and should be fixed.
204 const ProgramPointTag *Tag = nullptr) {
205 return addTransitionImpl(State, false, Pred, Tag);
206 }
207
208 /// Generate a sink node. Generating a sink stops exploration of the
209 /// given path. To create a sink node for the purpose of reporting an error,
210 /// checkers should use generateErrorNode() instead.
212 const ProgramPointTag *Tag = nullptr) {
213 return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
214 }
215
216 /// Add a sink node to the current path of execution, halting analysis.
217 void addSink(ProgramStateRef State = nullptr,
218 const ProgramPointTag *Tag = nullptr) {
219 if (!State)
220 State = getState();
221 addTransition(State, generateSink(State, getPredecessor()));
222 }
223
224 /// Generate a transition to a node that will be used to report
225 /// an error. This node will be a sink. That is, it will stop exploration of
226 /// the given path.
227 ///
228 /// @param State The state of the generated node.
229 /// @param Tag The tag to uniquely identify the creation site. If null,
230 /// the default tag for the checker will be used.
232 const ProgramPointTag *Tag = nullptr) {
233 return generateSink(State, Pred,
234 (Tag ? Tag : Location.getTag()));
235 }
236
237 /// Generate a transition to a node that will be used to report
238 /// an error. This node will be a sink. That is, it will stop exploration of
239 /// the given path.
240 ///
241 /// @param State The state of the generated node.
242 /// @param Pred The transition will be generated from the specified Pred node
243 /// to the newly generated node.
244 /// @param Tag The tag to uniquely identify the creation site. If null,
245 /// the default tag for the checker will be used.
247 ExplodedNode *Pred,
248 const ProgramPointTag *Tag = nullptr) {
249 return generateSink(State, Pred,
250 (Tag ? Tag : Location.getTag()));
251 }
252
253 /// Generate a transition to a node that will be used to report
254 /// an error. This node will not be a sink. That is, exploration will
255 /// continue along this path.
256 ///
257 /// @param State The state of the generated node.
258 /// @param Tag The tag to uniquely identify the creation site. If null,
259 /// the default tag for the checker will be used.
262 const ProgramPointTag *Tag = nullptr) {
263 return addTransition(State, (Tag ? Tag : Location.getTag()));
264 }
265
266 /// Generate a transition to a node that will be used to report
267 /// an error. This node will not be a sink. That is, exploration will
268 /// continue along this path.
269 ///
270 /// @param State The state of the generated node.
271 /// @param Pred The transition will be generated from the specified Pred node
272 /// to the newly generated node.
273 /// @param Tag The tag to uniquely identify the creation site. If null,
274 /// the default tag for the checker will be used.
277 ExplodedNode *Pred,
278 const ProgramPointTag *Tag = nullptr) {
279 return addTransition(State, Pred, (Tag ? Tag : Location.getTag()));
280 }
281
282 /// Emit the diagnostics report.
283 void emitReport(std::unique_ptr<BugReport> R) {
284 Changed = true;
285 Eng.getBugReporter().emitReport(std::move(R));
286 }
287
288 /// Produce a program point tag that displays an additional path note
289 /// to the user. This is a lightweight alternative to the
290 /// BugReporterVisitor mechanism: instead of visiting the bug report
291 /// node-by-node to restore the sequence of events that led to discovering
292 /// a bug, you can add notes as you add your transitions.
293 ///
294 /// @param Cb Callback with 'BugReporterContext &, BugReport &' parameters.
295 /// @param IsPrunable Whether the note is prunable. It allows BugReporter
296 /// to omit the note from the report if it would make the displayed
297 /// bug path significantly shorter.
298 LLVM_ATTRIBUTE_RETURNS_NONNULL
299 const NoteTag *getNoteTag(NoteTag::Callback &&Cb, bool IsPrunable = false) {
300 return Eng.getDataTags().make<NoteTag>(std::move(Cb), IsPrunable);
301 }
302
303 /// A shorthand version of getNoteTag that doesn't require you to accept
304 /// the 'BugReporterContext' argument when you don't need it.
305 ///
306 /// @param Cb Callback only with 'BugReport &' parameter.
307 /// @param IsPrunable Whether the note is prunable. It allows BugReporter
308 /// to omit the note from the report if it would make the displayed
309 /// bug path significantly shorter.
310 const NoteTag
312 bool IsPrunable = false) {
313 return getNoteTag(
314 [Cb](BugReporterContext &,
315 PathSensitiveBugReport &BR) { return Cb(BR); },
316 IsPrunable);
317 }
318
319 /// A shorthand version of getNoteTag that doesn't require you to accept
320 /// the arguments when you don't need it.
321 ///
322 /// @param Cb Callback without parameters.
323 /// @param IsPrunable Whether the note is prunable. It allows BugReporter
324 /// to omit the note from the report if it would make the displayed
325 /// bug path significantly shorter.
326 const NoteTag *getNoteTag(std::function<std::string()> &&Cb,
327 bool IsPrunable = false) {
328 return getNoteTag([Cb](BugReporterContext &,
329 PathSensitiveBugReport &) { return Cb(); },
330 IsPrunable);
331 }
332
333 /// A shorthand version of getNoteTag that accepts a plain note.
334 ///
335 /// @param Note The note.
336 /// @param IsPrunable Whether the note is prunable. It allows BugReporter
337 /// to omit the note from the report if it would make the displayed
338 /// bug path significantly shorter.
339 const NoteTag *getNoteTag(StringRef Note, bool IsPrunable = false) {
340 return getNoteTag(
341 [Note = std::string(Note)](BugReporterContext &,
342 PathSensitiveBugReport &) { return Note; },
343 IsPrunable);
344 }
345
346 /// A shorthand version of getNoteTag that accepts a lambda with stream for
347 /// note.
348 ///
349 /// @param Cb Callback with 'BugReport &' and 'llvm::raw_ostream &'.
350 /// @param IsPrunable Whether the note is prunable. It allows BugReporter
351 /// to omit the note from the report if it would make the displayed
352 /// bug path significantly shorter.
354 std::function<void(PathSensitiveBugReport &BR, llvm::raw_ostream &OS)> &&Cb,
355 bool IsPrunable = false) {
356 return getNoteTag(
357 [Cb](PathSensitiveBugReport &BR) -> std::string {
359 llvm::raw_svector_ostream OS(Str);
360 Cb(BR, OS);
361 return std::string(OS.str());
362 },
363 IsPrunable);
364 }
365
366 /// Returns the word that should be used to refer to the declaration
367 /// in the report.
368 StringRef getDeclDescription(const Decl *D);
369
370 /// Get the declaration of the called function (path-sensitive).
371 const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
372
373 /// Get the name of the called function (path-sensitive).
374 StringRef getCalleeName(const FunctionDecl *FunDecl) const;
375
376 /// Get the identifier of the called function (path-sensitive).
378 const FunctionDecl *FunDecl = getCalleeDecl(CE);
379 if (FunDecl)
380 return FunDecl->getIdentifier();
381 else
382 return nullptr;
383 }
384
385 /// Get the name of the called function (path-sensitive).
386 StringRef getCalleeName(const CallExpr *CE) const {
387 const FunctionDecl *FunDecl = getCalleeDecl(CE);
388 return getCalleeName(FunDecl);
389 }
390
391 /// Returns true if the given function is an externally-visible function in
392 /// the top-level namespace, such as \c malloc.
393 ///
394 /// If a name is provided, the function must additionally match the given
395 /// name.
396 ///
397 /// Note that this also accepts functions from the \c std namespace (because
398 /// headers like <cstdlib> declare them there) and does not check if the
399 /// function is declared as 'extern "C"' or if it uses C++ name mangling.
400 static bool isCLibraryFunction(const FunctionDecl *FD,
401 StringRef Name = StringRef());
402
403 /// In builds that use source hardening (-D_FORTIFY_SOURCE), many standard
404 /// functions are implemented as macros that expand to calls of hardened
405 /// functions that take additional arguments compared to the "usual"
406 /// variant and perform additional input validation. For example, a `memcpy`
407 /// call may expand to `__memcpy_chk()` or `__builtin___memcpy_chk()`.
408 ///
409 /// This method returns true if `FD` declares a fortified variant of the
410 /// standard library function `Name`.
411 ///
412 /// NOTE: This method relies on heuristics; extend it if you need to handle a
413 /// hardened variant that's not yet covered by it.
414 static bool isHardenedVariantOf(const FunctionDecl *FD, StringRef Name);
415
416 /// Depending on whether the location corresponds to a macro, return
417 /// either the macro name or the token spelling.
418 ///
419 /// This could be useful when checkers' logic depends on whether a function
420 /// is called with a given macro argument. For example:
421 /// s = socket(AF_INET,..)
422 /// If AF_INET is a macro, the result should be treated as a source of taint.
423 ///
424 /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
426
427private:
428 ExplodedNode *addTransitionImpl(ProgramStateRef State,
429 bool MarkAsSink,
430 ExplodedNode *P = nullptr,
431 const ProgramPointTag *Tag = nullptr) {
432 // The analyzer may stop exploring if it sees a state it has previously
433 // visited ("cache out"). The early return here is a defensive check to
434 // prevent accidental caching out by checker API clients. Unless there is a
435 // tag or the client checker has requested that the generated node be
436 // marked as a sink, we assume that a client requesting a transition to a
437 // state that is the same as the predecessor state has made a mistake. We
438 // return the predecessor rather than cache out.
439 //
440 // TODO: We could potentially change the return to an assertion to alert
441 // clients to their mistake, but several checkers (including
442 // DereferenceChecker, CallAndMessageChecker, and DynamicTypePropagation)
443 // rely upon the defensive behavior and would need to be updated.
444 if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
445 return Pred;
446
447 Changed = true;
448 const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
449 if (!P)
450 P = Pred;
451
452 ExplodedNode *node;
453 if (MarkAsSink)
454 node = NB.generateSink(LocalLoc, State, P);
455 else
456 node = NB.generateNode(LocalLoc, State, P);
457 return node;
458 }
459};
460
461} // end GR namespace
462
463} // end clang namespace
464
465#endif
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:229
AnalysisDeclContext contains the context data for the function, method or block under analysis.
const StackFrame * getStackFrame(const StackFrame *ParentSF, const void *Data, const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
This represents one expression.
Definition Expr.h:112
Represents a function declaration or definition.
Definition Decl.h:2018
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
Represents a program point after a store evaluation.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
Encodes a location in the source.
This class handles loading and caching of source files into memory.
It represents a stack frame of the call stack.
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
BugReporter is a utility class for generating PathDiagnostics for analysis.
Preprocessor & getPreprocessor()
const SourceManager & getSourceManager()
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
ExplodedNode * generateErrorNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
const IdentifierInfo * getCalleeIdentifier(const CallExpr *CE) const
Get the identifier of the called function (path-sensitive).
static const MemRegion * getLocationRegionIfPostStore(const ExplodedNode *N)
If the given node corresponds to a PostStore program point, retrieve the location region as it was ut...
SymbolManager & getSymbolManager()
StringRef getDeclDescription(const Decl *D)
Returns the word that should be used to refer to the declaration in the report.
Preprocessor & getPreprocessor()
SVal getSVal(const Expr *E) const
Get the value of arbitrary expressions at this point in the path.
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a sink node.
const SourceManager & getSourceManager()
CheckerContext(NodeBuilder &builder, ExprEngine &eng, ExplodedNode *pred, const ProgramPoint &loc, bool wasInlined=false)
const NoteTag * getNoteTag(std::function< std::string()> &&Cb, bool IsPrunable=false)
A shorthand version of getNoteTag that doesn't require you to accept the arguments when you don't nee...
StringRef getCalleeName(const FunctionDecl *FunDecl) const
Get the name of the called function (path-sensitive).
const NoteTag * getNoteTag(StringRef Note, bool IsPrunable=false)
A shorthand version of getNoteTag that accepts a plain note.
const ExplodedNode * getPredecessor() const
const SourceManager & getSourceManager() const
std::string getMacroNameOrSpelling(SourceLocation &Loc)
Depending on whether the location corresponds to a macro, return either the macro name or the token s...
StringRef getCalleeName(const CallExpr *CE) const
Get the name of the called function (path-sensitive).
const ProgramStateRef & getState() const
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
ConstraintManager & getConstraintManager()
bool isDifferent()
Check if the checker changed the state of the execution; ex: added a new transition or a bug report.
ExplodedNode * addTransition(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generates a new transition with the given predecessor.
bool isNegative(const Expr *E)
Returns true if the value of E is negative.
const Preprocessor & getPreprocessor() const
const SValBuilder & getSValBuilder() const
AnalysisDeclContext * getCurrentAnalysisDeclContext() const
bool isGreaterOrEqual(const Expr *E, unsigned long long Val)
Returns true if the value of E is greater than or equal to Val under unsigned comparison.
const ProgramPoint getLocation() const
static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name=StringRef())
Returns true if the given function is an externally-visible function in the top-level namespace,...
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
LLVM_ATTRIBUTE_RETURNS_NONNULL const NoteTag * getNoteTag(NoteTag::Callback &&Cb, bool IsPrunable=false)
Produce a program point tag that displays an additional path note to the user.
const ASTContext & getASTContext() const
ConstCFGElementRef getCFGElementRef() const
AnalysisManager & getAnalysisManager()
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
const FunctionDecl * getCalleeDecl(const CallExpr *CE) const
Get the declaration of the called function (path-sensitive).
void addSink(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Add a sink node to the current path of execution, halting analysis.
const SymbolManager & getSymbolManager() const
const NoteTag * getNoteTag(std::function< void(PathSensitiveBugReport &BR, llvm::raw_ostream &OS)> &&Cb, bool IsPrunable=false)
A shorthand version of getNoteTag that accepts a lambda with stream for note.
ProgramStateManager & getStateManager()
const ProgramStateManager & getStateManager() const
const StoreManager & getStoreManager() const
const LangOptions & getLangOpts() const
const BugReporter & getBugReporter() const
bool inTopFrame() const
Return true if the current StackFrame has no caller context.
const ConstraintManager & getConstraintManager() const
const bool wasInlined
If we are post visiting a call, this flag will be set if the call was inlined.
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
StoreManager & getStoreManager()
const NoteTag * getNoteTag(std::function< std::string(PathSensitiveBugReport &)> &&Cb, bool IsPrunable=false)
A shorthand version of getNoteTag that doesn't require you to accept the 'BugReporterContext' argumen...
const AnalysisManager & getAnalysisManager() const
static bool isHardenedVariantOf(const FunctionDecl *FD, StringRef Name)
In builds that use source hardening (-D_FORTIFY_SOURCE), many standard functions are implemented as m...
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
const StackFrame * getStackFrame() const
unsigned getBlockID() const
Get the blockID.
const ProgramStateRef & getState() const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:97
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:265
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition CoreEngine.h:300
The tag upon which the TagVisitor reacts.
std::function< std::string(BugReporterContext &, PathSensitiveBugReport &)> Callback
SymbolManager & getSymbolManager()
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:56
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
CFGBlock::ConstCFGElementRef ConstCFGElementRef
Definition CFG.h:1227
int const char * function
Definition c++config.h:31
#define false
Definition stdbool.h:26