clang 24.0.0git
Facts.h
Go to the documentation of this file.
1//===- Facts.h - Lifetime Analysis Facts and Fact Manager ------*- 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 Facts, which are atomic lifetime-relevant events (such as
10// loan issuance, loan expiration, origin flow, and use), and the FactManager,
11// which manages the storage and retrieval of facts for each CFG block.
12//
13//===----------------------------------------------------------------------===//
14#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_FACTS_H
15#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_FACTS_H
16
17#include "clang/AST/Decl.h"
22#include "clang/Analysis/CFG.h"
23#include "llvm/ADT/BitVector.h"
24#include "llvm/ADT/DenseSet.h"
25#include "llvm/ADT/STLFunctionalExtras.h"
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Support/raw_ostream.h"
29#include <cstdint>
30#include <optional>
31
33
34class FactsGenerator;
36
38
39/// An abstract base class for a single, atomic lifetime-relevant event.
40class Fact {
41
42public:
43 enum class Kind : uint8_t {
44 /// A new loan is issued from a borrow expression (e.g., &x).
46 /// A loan expires as its underlying storage is freed (e.g., variable goes
47 /// out of scope).
49 /// An origin is propagated from a source to a destination (e.g., p = q).
50 /// This can also optionally kill the destination origin before flowing into
51 /// it. Otherwise, the source's loan set is merged into the destination's
52 /// loan set.
54 /// An origin is used (eg. appears as l-value expression like DeclRefExpr).
56 /// An origin that is moved (e.g., passed to an rvalue reference parameter).
58 /// A marker for a specific point in the code, for testing.
60 /// An origin that escapes the function scope (e.g., via return).
62 /// An origin is invalidated (e.g. vector resized, `delete` called).
64 /// All loans of an origin are cleared.
66 };
67
68private:
69 Kind K;
70 FactID ID;
71
72protected:
73 Fact(Kind K) : K(K) {}
74
75public:
76 virtual ~Fact() = default;
77 Kind getKind() const { return K; }
78
79 void setID(FactID ID) { this->ID = ID; }
80 FactID getID() const { return ID; }
81
82 template <typename T> const T *getAs() const {
83 if (T::classof(this))
84 return static_cast<const T *>(this);
85 return nullptr;
86 }
87
88 virtual void dump(llvm::raw_ostream &OS, const LoanManager &,
89 const OriginManager &,
90 const LoanPropagationAnalysis *LPA = nullptr) const;
91};
92
93/// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
94/// `Fact`. identified by a lifetime-related event (`Fact`).
95///
96/// A `ProgramPoint` has "after" semantics: it represents the location
97/// immediately after its corresponding `Fact`.
98using ProgramPoint = const Fact *;
99
100class IssueFact : public Fact {
101 LoanID LID;
102 OriginID OID;
103
104public:
105 static bool classof(const Fact *F) { return F->getKind() == Kind::Issue; }
106
107 IssueFact(LoanID LID, OriginID OID) : Fact(Kind::Issue), LID(LID), OID(OID) {}
108 LoanID getLoanID() const { return LID; }
109 OriginID getOriginID() const { return OID; }
110 void dump(llvm::raw_ostream &OS, const LoanManager &LM,
111 const OriginManager &OM,
112 const LoanPropagationAnalysis *LPA = nullptr) const override;
113};
114
115/// When an AccessPath expires (e.g., a variable goes out of scope), all loans
116/// that are associated with this path expire. For example, if `x` expires, then
117/// the loan to `x` expires.
118class ExpireFact : public Fact {
119 // The access path that expires.
120 AccessPath AP;
121
122 // Expired origin (e.g., its variable goes out of scope).
123 std::optional<OriginID> OID;
124 SourceLocation ExpiryLoc;
125
126public:
127 static bool classof(const Fact *F) { return F->getKind() == Kind::Expire; }
128
130 std::optional<OriginID> OID = std::nullopt)
131 : Fact(Kind::Expire), AP(AP), OID(OID), ExpiryLoc(ExpiryLoc) {}
132
133 const AccessPath &getAccessPath() const { return AP; }
134 std::optional<OriginID> getOriginID() const { return OID; }
135 SourceLocation getExpiryLoc() const { return ExpiryLoc; }
136
137 void dump(llvm::raw_ostream &OS, const LoanManager &LM,
138 const OriginManager &OM,
139 const LoanPropagationAnalysis *LPA = nullptr) const override;
140};
141
142class OriginFlowFact : public Fact {
143 OriginID OIDDest;
144 OriginID OIDSrc;
145 // True if the destination origin should be killed (i.e., its current loans
146 // cleared) before the source origin's loans are flowed into it.
147 bool KillDest;
148
149public:
150 static bool classof(const Fact *F) {
151 return F->getKind() == Kind::OriginFlow;
152 }
153
154 OriginFlowFact(OriginID OIDDest, OriginID OIDSrc, bool KillDest)
155 : Fact(Kind::OriginFlow), OIDDest(OIDDest), OIDSrc(OIDSrc),
156 KillDest(KillDest) {}
157
158 OriginID getDestOriginID() const { return OIDDest; }
159 OriginID getSrcOriginID() const { return OIDSrc; }
160 bool getKillDest() const { return KillDest; }
161
162 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
163 const LoanPropagationAnalysis *LPA = nullptr) const override;
164};
165
166/// Represents that an origin escapes the current scope through various means.
167/// This is the base class for different escape scenarios.
168class OriginEscapesFact : public Fact {
169 OriginID OID;
170
171public:
172 /// The way an origin can escape the current scope.
173 enum class EscapeKind : uint8_t {
174 Return, /// Escapes via return statement.
175 Field, /// Escapes via assignment to a field.
176 Global, /// Escapes via assignment to global storage.
178
179 static bool classof(const Fact *F) {
180 return F->getKind() == Kind::OriginEscapes;
181 }
182
185 OriginID getEscapedOriginID() const { return OID; }
186 EscapeKind getEscapeKind() const { return EscKind; }
187};
188
189/// Represents that an origin escapes via a return statement.
191 const Expr *ReturnExpr;
192
193public:
194 ReturnEscapeFact(OriginID OID, const Expr *ReturnExpr)
195 : OriginEscapesFact(OID, EscapeKind::Return), ReturnExpr(ReturnExpr) {}
196
197 static bool classof(const Fact *F) {
198 return F->getKind() == Kind::OriginEscapes &&
199 static_cast<const OriginEscapesFact *>(F)->getEscapeKind() ==
201 }
202 const Expr *getReturnExpr() const { return ReturnExpr; };
203 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
204 const LoanPropagationAnalysis *LPA = nullptr) const override;
205};
206
207/// Represents that an origin escapes via assignment to a field.
208/// Example: `this->view = local_var;` where local_var outlives the assignment
209/// but not the object containing the field.
211 const FieldDecl *FDecl;
212
213public:
215 : OriginEscapesFact(OID, EscapeKind::Field), FDecl(FDecl) {}
216
217 static bool classof(const Fact *F) {
218 return F->getKind() == Kind::OriginEscapes &&
219 static_cast<const OriginEscapesFact *>(F)->getEscapeKind() ==
221 }
222 const FieldDecl *getFieldDecl() const { return FDecl; };
223 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
224 const LoanPropagationAnalysis *LPA = nullptr) const override;
225};
226
227/// Represents that an origin escapes via assignment to global or static
228/// storage. Example: `global_storage = local_var;`
230 const VarDecl *Global;
231
232public:
234 : OriginEscapesFact(OID, EscapeKind::Global), Global(VDecl) {}
235
236 static bool classof(const Fact *F) {
237 return F->getKind() == Kind::OriginEscapes &&
238 static_cast<const OriginEscapesFact *>(F)->getEscapeKind() ==
240 }
241 const VarDecl *getGlobal() const { return Global; };
242 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
243 const LoanPropagationAnalysis *LPA = nullptr) const override;
244};
245
246class UseFact : public Fact {
247 const Expr *UseExpr;
248 const OriginList *OList;
249 // True if this use is a write operation (e.g., left-hand side of assignment).
250 // Write operations are exempted from use-after-free checks.
251 bool IsWritten = false;
252
253public:
254 static bool classof(const Fact *F) { return F->getKind() == Kind::Use; }
255
256 UseFact(const Expr *UseExpr, const OriginList *OList)
257 : Fact(Kind::Use), UseExpr(UseExpr), OList(OList) {}
258
259 const OriginList *getUsedOrigins() const { return OList; }
260 void setUsedOrigins(const OriginList *NewList) { OList = NewList; }
261 const Expr *getUseExpr() const { return UseExpr; }
262 void markAsWritten() { IsWritten = true; }
263 bool isWritten() const { return IsWritten; }
264
265 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
266 const LoanPropagationAnalysis *LPA = nullptr) const override;
267};
268
269/// Represents that an origin's storage has been invalidated by a container
270/// operation (e.g., vector::push_back may reallocate, invalidating iterators).
271/// Created when a container method that may invalidate references/iterators
272/// is called on the container.
274 OriginID OID;
275 const Expr *InvalidationExpr;
276
277public:
278 static bool classof(const Fact *F) {
279 return F->getKind() == Kind::InvalidateOrigin;
280 }
281
282 InvalidateOriginFact(OriginID OID, const Expr *InvalidationExpr)
283 : Fact(Kind::InvalidateOrigin), OID(OID),
284 InvalidationExpr(InvalidationExpr) {}
285
286 OriginID getInvalidatedOrigin() const { return OID; }
287 const Expr *getInvalidationExpr() const { return InvalidationExpr; }
288 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
289 const LoanPropagationAnalysis *LPA = nullptr) const override;
290};
291
292/// Top-level origin of the expression which was found to be moved, e.g, when
293/// being used as an argument to an r-value reference parameter.
294class MovedOriginFact : public Fact {
295 const OriginID MovedOrigin;
296 const Expr *MoveExpr;
297
298public:
299 static bool classof(const Fact *F) {
300 return F->getKind() == Kind::MovedOrigin;
301 }
302
303 MovedOriginFact(const Expr *MoveExpr, OriginID MovedOrigin)
304 : Fact(Kind::MovedOrigin), MovedOrigin(MovedOrigin), MoveExpr(MoveExpr) {}
305
306 OriginID getMovedOrigin() const { return MovedOrigin; }
307 const Expr *getMoveExpr() const { return MoveExpr; }
308
309 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
310 const LoanPropagationAnalysis *LPA = nullptr) const override;
311};
312
313/// A dummy-fact used to mark a specific point in the code for testing.
314/// It is generated by recognizing a `void("__lifetime_test_point_...")` cast.
315class TestPointFact : public Fact {
316 StringRef Annotation;
317
318public:
319 static bool classof(const Fact *F) { return F->getKind() == Kind::TestPoint; }
320
321 explicit TestPointFact(StringRef Annotation)
322 : Fact(Kind::TestPoint), Annotation(Annotation) {}
323
324 StringRef getAnnotation() const { return Annotation; }
325
326 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &,
327 const LoanPropagationAnalysis *LPA = nullptr) const override;
328};
329
330/// All loans are cleared from an origin (e.g., assigning a callable without
331/// tracked origins to std::function).
332class KillOriginFact : public Fact {
333 OriginID OID;
334
335public:
336 static bool classof(const Fact *F) {
337 return F->getKind() == Kind::KillOrigin;
338 }
339
341
342 OriginID getKilledOrigin() const { return OID; }
343
344 void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM,
345 const LoanPropagationAnalysis *LPA = nullptr) const override;
346};
347
349public:
350 FactManager(const AnalysisDeclContext &AC, const CFG &Cfg) : OriginMgr(AC) {
351 BlockToFacts.resize(Cfg.getNumBlockIDs());
352 }
353
355 return BlockToFacts[B->getBlockID()];
356 }
357
359 if (!NewFacts.empty())
360 BlockToFacts[B->getBlockID()].assign(NewFacts.begin(), NewFacts.end());
361 }
362
363 void appendBlockFact(const CFGBlock *B, const Fact *F) {
364 BlockToFacts[B->getBlockID()].push_back(F);
365 }
366
367 template <typename FactType, typename... Args>
368 FactType *createFact(Args &&...args) {
369 void *Mem = FactAllocator.Allocate<FactType>();
370 FactType *Res = new (Mem) FactType(std::forward<Args>(args)...);
371 Res->setID(NextFactID++);
372 return Res;
373 }
374
375 void dump(const CFG &Cfg, AnalysisDeclContext &AC,
376 const LoanPropagationAnalysis *LPA = nullptr) const;
377
378 /// Retrieves program points that were specially marked in the source code
379 /// for testing.
380 ///
381 /// The analysis recognizes special function calls of the form
382 /// `void("__lifetime_test_point_<name>")` as test points. This method returns
383 /// a map from the annotation string (<name>) to the corresponding
384 /// `ProgramPoint`. This allows test harnesses to query the analysis state at
385 /// user-defined locations in the code.
386 /// \note This is intended for testing only.
387 llvm::StringMap<ProgramPoint> getTestPoints() const;
388 /// Retrieves all the facts in the block containing Program Point P.
389 /// \note This is intended for testing only.
391 size_t getBlockID(ProgramPoint P) const;
392
393 unsigned getNumFacts() const { return NextFactID.Value; }
394
395 /// Returns the origins that are referenced from more than one basic block.
396 /// Only those need to survive block boundaries in the dataflow analyses; the
397 /// rest are block-local.
398 const llvm::BitVector &getPersistentOrigins() const {
399 assert(PersistentOrigins.size() == OriginMgr.getNumOrigins() &&
400 "persistent origins have not been computed");
401 return PersistentOrigins;
402 }
403
404 LoanManager &getLoanMgr() { return LoanMgr; }
405 const LoanManager &getLoanMgr() const { return LoanMgr; }
406 OriginManager &getOriginMgr() { return OriginMgr; }
407 const OriginManager &getOriginMgr() const { return OriginMgr; }
408
409 void addCapturedField(const FieldDecl *FD) { CapturedFields.insert(FD); }
410 bool isFieldCapturedByLambda(const FieldDecl *FD) const {
411 return IsThisCapturedByLambda || CapturedFields.contains(FD);
412 }
413 void setThisCapturedByLambda() { IsThisCapturedByLambda = true; }
414
415private:
416 /// Classifies every origin as persistent or block-local. Called by
417 /// `FactsGenerator` once all facts and origins have been created.
418 void computePersistentOrigins(const CFG &Cfg);
419
420 friend class FactsGenerator;
421
422 FactID NextFactID{0};
423 LoanManager LoanMgr;
424 OriginManager OriginMgr;
425 /// Facts for each CFG block, indexed by block ID.
427 llvm::BumpPtrAllocator FactAllocator;
428 /// Bit vector indexed by origin ID. If set, the origin is referenced from
429 /// more than one basic block and must participate in join operations. If
430 /// unset, the origin is block-local and can be discarded at block
431 /// boundaries.
432 ///
433 /// Shared by every analysis so that they all agree on which origins cross
434 /// block boundaries.
435 llvm::BitVector PersistentOrigins;
436
437 /// Set of field declarations that are explicitly or init-captured in any
438 /// lambda within the analyzed function.
439 llvm::DenseSet<const FieldDecl *> CapturedFields;
440 /// Whether the 'this' pointer is captured by any lambda within the analyzed
441 /// function. When true, any field of 'this' is considered captured.
442 bool IsThisCapturedByLambda = false;
443};
444} // namespace clang::lifetimes::internal
445
446#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_FACTS_H
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a single basic block in a source-level CFG.
Definition CFG.h:652
unsigned getBlockID() const
Definition CFG.h:1154
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition CFG.h:1271
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Definition CFG.h:1464
This represents one expression.
Definition Expr.h:112
Represents a member of a struct/union/class.
Definition Decl.h:3294
Encodes a location in the source.
Represents a variable declaration or definition.
Definition Decl.h:932
Represents the storage location being borrowed, e.g., a specific stack variable or a field within it:...
Definition Loans.h:113
const AccessPath & getAccessPath() const
Definition Facts.h:133
SourceLocation getExpiryLoc() const
Definition Facts.h:135
static bool classof(const Fact *F)
Definition Facts.h:127
ExpireFact(AccessPath AP, SourceLocation ExpiryLoc, std::optional< OriginID > OID=std::nullopt)
Definition Facts.h:129
std::optional< OriginID > getOriginID() const
Definition Facts.h:134
void dump(llvm::raw_ostream &OS, const LoanManager &LM, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:88
llvm::ArrayRef< const Fact * > getFacts(const CFGBlock *B) const
Definition Facts.h:354
FactType * createFact(Args &&...args)
Definition Facts.h:368
bool isFieldCapturedByLambda(const FieldDecl *FD) const
Definition Facts.h:410
llvm::StringMap< ProgramPoint > getTestPoints() const
Retrieves program points that were specially marked in the source code for testing.
Definition Facts.cpp:195
void dump(const CFG &Cfg, AnalysisDeclContext &AC, const LoanPropagationAnalysis *LPA=nullptr) const
Definition Facts.cpp:210
void addBlockFacts(const CFGBlock *B, llvm::ArrayRef< Fact * > NewFacts)
Definition Facts.h:358
const OriginManager & getOriginMgr() const
Definition Facts.h:407
size_t getBlockID(ProgramPoint P) const
Definition Facts.cpp:234
void appendBlockFact(const CFGBlock *B, const Fact *F)
Definition Facts.h:363
const LoanManager & getLoanMgr() const
Definition Facts.h:405
llvm::ArrayRef< const Fact * > getBlockContaining(ProgramPoint P) const
Retrieves all the facts in the block containing Program Point P.
Definition Facts.cpp:230
const llvm::BitVector & getPersistentOrigins() const
Returns the origins that are referenced from more than one basic block.
Definition Facts.h:398
void addCapturedField(const FieldDecl *FD)
Definition Facts.h:409
FactManager(const AnalysisDeclContext &AC, const CFG &Cfg)
Definition Facts.h:350
An abstract base class for a single, atomic lifetime-relevant event.
Definition Facts.h:40
virtual void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &, const LoanPropagationAnalysis *LPA=nullptr) const
Definition Facts.cpp:73
@ InvalidateOrigin
An origin is invalidated (e.g. vector resized, delete called).
Definition Facts.h:63
@ TestPoint
A marker for a specific point in the code, for testing.
Definition Facts.h:59
@ Expire
A loan expires as its underlying storage is freed (e.g., variable goes out of scope).
Definition Facts.h:48
@ Issue
A new loan is issued from a borrow expression (e.g., &x).
Definition Facts.h:45
@ OriginFlow
An origin is propagated from a source to a destination (e.g., p = q).
Definition Facts.h:53
@ MovedOrigin
An origin that is moved (e.g., passed to an rvalue reference parameter).
Definition Facts.h:57
@ Use
An origin is used (eg. appears as l-value expression like DeclRefExpr).
Definition Facts.h:55
@ OriginEscapes
An origin that escapes the function scope (e.g., via return).
Definition Facts.h:61
@ KillOrigin
All loans of an origin are cleared.
Definition Facts.h:65
const T * getAs() const
Definition Facts.h:82
FieldEscapeFact(OriginID OID, const FieldDecl *FDecl)
Definition Facts.h:214
const FieldDecl * getFieldDecl() const
Definition Facts.h:222
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:142
static bool classof(const Fact *F)
Definition Facts.h:217
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:150
GlobalEscapeFact(OriginID OID, const VarDecl *VDecl)
Definition Facts.h:233
static bool classof(const Fact *F)
Definition Facts.h:236
const VarDecl * getGlobal() const
Definition Facts.h:241
InvalidateOriginFact(OriginID OID, const Expr *InvalidationExpr)
Definition Facts.h:282
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:173
void dump(llvm::raw_ostream &OS, const LoanManager &LM, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:78
IssueFact(LoanID LID, OriginID OID)
Definition Facts.h:107
static bool classof(const Fact *F)
Definition Facts.h:105
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:187
static bool classof(const Fact *F)
Definition Facts.h:336
Manages the creation, storage and retrieval of loans.
Definition Loans.h:210
static bool classof(const Fact *F)
Definition Facts.h:299
MovedOriginFact(const Expr *MoveExpr, OriginID MovedOrigin)
Definition Facts.h:303
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:126
enum clang::lifetimes::internal::OriginEscapesFact::EscapeKind EscKind
EscapeKind
The way an origin can escape the current scope.
Definition Facts.h:173
@ Global
Escapes via assignment to a field.
Definition Facts.h:176
static bool classof(const Fact *F)
Definition Facts.h:179
OriginEscapesFact(OriginID OID, EscapeKind EscKind)
Definition Facts.h:183
static bool classof(const Fact *F)
Definition Facts.h:150
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:100
OriginFlowFact(OriginID OIDDest, OriginID OIDSrc, bool KillDest)
Definition Facts.h:154
A list of origins representing levels of indirection for pointer-like types.
Definition Origins.h:95
Manages the creation, storage, and retrieval of origins for pointer-like variables and expressions.
Definition Origins.h:125
static bool classof(const Fact *F)
Definition Facts.h:197
ReturnEscapeFact(OriginID OID, const Expr *ReturnExpr)
Definition Facts.h:194
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:134
static bool classof(const Fact *F)
Definition Facts.h:319
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:181
TestPointFact(StringRef Annotation)
Definition Facts.h:321
void setUsedOrigins(const OriginList *NewList)
Definition Facts.h:260
const Expr * getUseExpr() const
Definition Facts.h:261
void dump(llvm::raw_ostream &OS, const LoanManager &, const OriginManager &OM, const LoanPropagationAnalysis *LPA=nullptr) const override
Definition Facts.cpp:158
static bool classof(const Fact *F)
Definition Facts.h:254
UseFact(const Expr *UseExpr, const OriginList *OList)
Definition Facts.h:256
const OriginList * getUsedOrigins() const
Definition Facts.h:259
const Fact * ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
Definition Facts.h:98
utils::ID< struct LoanTag > LoanID
Definition Loans.h:27
utils::ID< struct OriginTag > OriginID
Definition Origins.h:28
utils::ID< struct FactTag > FactID
Definition Facts.h:37
const FunctionProtoType * T
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
A generic, type-safe wrapper for an ID, distinguished by its Tag type.
Definition Utils.h:21