clang 22.0.0git
Loans.h
Go to the documentation of this file.
1//===- Loans.h - Loan and Access Path Definitions --------------*- 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 the Loan and AccessPath structures, which represent
10// borrows of storage locations, and the LoanManager, which manages the
11// creation and retrieval of loans during lifetime analysis.
12//
13//===----------------------------------------------------------------------===//
14#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
15#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
16
17#include "clang/AST/Decl.h"
19#include "llvm/Support/raw_ostream.h"
20
22
24inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, LoanID ID) {
25 return OS << ID.Value;
26}
27
28/// Represents the storage location being borrowed, e.g., a specific stack
29/// variable.
30/// TODO: Model access paths of other types, e.g., s.field, heap and globals.
31struct AccessPath {
33
35};
36
37/// An abstract base class for a single "Loan" which represents lending a
38/// storage in memory.
39class Loan {
40 /// TODO: Represent opaque loans.
41 /// TODO: Represent nullptr: loans to no path. Accessing it UB! Currently it
42 /// is represented as empty LoanSet
43public:
44 enum class Kind : uint8_t {
45 /// A loan with an access path to a storage location.
47 /// A non-expiring placeholder loan for a parameter, representing a borrow
48 /// from the function's caller.
50 };
51
52 Loan(Kind K, LoanID ID) : K(K), ID(ID) {}
53 virtual ~Loan() = default;
54
55 Kind getKind() const { return K; }
56 LoanID getID() const { return ID; }
57
58 virtual void dump(llvm::raw_ostream &OS) const = 0;
59
60private:
61 const Kind K;
62 const LoanID ID;
63};
64
65/// PathLoan represents lending a storage location that is visible within the
66/// function's scope (e.g., a local variable on stack).
67class PathLoan : public Loan {
68 AccessPath Path;
69 /// The expression that creates the loan, e.g., &x.
70 const Expr *IssueExpr;
71
72public:
73 PathLoan(LoanID ID, AccessPath Path, const Expr *IssueExpr)
74 : Loan(Kind::Path, ID), Path(Path), IssueExpr(IssueExpr) {}
75
76 const AccessPath &getAccessPath() const { return Path; }
77 const Expr *getIssueExpr() const { return IssueExpr; }
78
79 void dump(llvm::raw_ostream &OS) const override;
80
81 static bool classof(const Loan *L) { return L->getKind() == Kind::Path; }
82};
83
84/// A placeholder loan held by a function parameter, representing a borrow from
85/// the caller's scope.
86///
87/// Created at function entry for each pointer or reference parameter with an
88/// origin. Unlike PathLoan, placeholder loans:
89/// - Have no IssueExpr (created at function entry, not at a borrow site)
90/// - Have no AccessPath (the borrowed object is not visible to the function)
91/// - Do not currently expire, but may in the future when modeling function
92/// invalidations (e.g., vector::push_back)
93///
94/// When a placeholder loan escapes the function (e.g., via return), it
95/// indicates the parameter should be marked [[clang::lifetimebound]], enabling
96/// lifetime annotation suggestions.
97class PlaceholderLoan : public Loan {
98 /// The function parameter that holds this placeholder loan.
99 const ParmVarDecl *PVD;
100
101public:
103 : Loan(Kind::Placeholder, ID), PVD(PVD) {}
104
105 const ParmVarDecl *getParmVarDecl() const { return PVD; }
106
107 void dump(llvm::raw_ostream &OS) const override;
108
109 static bool classof(const Loan *L) {
110 return L->getKind() == Kind::Placeholder;
111 }
112};
113
114/// Manages the creation, storage and retrieval of loans.
116public:
117 LoanManager() = default;
118
119 template <typename LoanType, typename... Args>
120 LoanType *createLoan(Args &&...args) {
121 static_assert(
122 std::is_same_v<LoanType, PathLoan> ||
123 std::is_same_v<LoanType, PlaceholderLoan>,
124 "createLoan can only be used with PathLoan or PlaceholderLoan");
125 void *Mem = LoanAllocator.Allocate<LoanType>();
126 auto *NewLoan =
127 new (Mem) LoanType(getNextLoanID(), std::forward<Args>(args)...);
128 AllLoans.push_back(NewLoan);
129 return NewLoan;
130 }
131
132 const Loan *getLoan(LoanID ID) const {
133 assert(ID.Value < AllLoans.size());
134 return AllLoans[ID.Value];
135 }
136 llvm::ArrayRef<const Loan *> getLoans() const { return AllLoans; }
137
138private:
139 LoanID getNextLoanID() { return NextLoanID++; }
140
141 LoanID NextLoanID{0};
142 /// TODO(opt): Profile and evaluate the usefullness of small buffer
143 /// optimisation.
145 llvm::BumpPtrAllocator LoanAllocator;
146};
147} // namespace clang::lifetimes::internal
148
149#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
This represents one expression.
Definition Expr.h:112
Represents a parameter to a function.
Definition Decl.h:1790
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
llvm::ArrayRef< const Loan * > getLoans() const
Definition Loans.h:136
const Loan * getLoan(LoanID ID) const
Definition Loans.h:132
LoanType * createLoan(Args &&...args)
Definition Loans.h:120
An abstract base class for a single "Loan" which represents lending a storage in memory.
Definition Loans.h:39
Loan(Kind K, LoanID ID)
Definition Loans.h:52
Kind
TODO: Represent opaque loans.
Definition Loans.h:44
@ Placeholder
A non-expiring placeholder loan for a parameter, representing a borrow from the function's caller.
Definition Loans.h:49
@ Path
A loan with an access path to a storage location.
Definition Loans.h:46
virtual void dump(llvm::raw_ostream &OS) const =0
const Expr * getIssueExpr() const
Definition Loans.h:77
PathLoan(LoanID ID, AccessPath Path, const Expr *IssueExpr)
Definition Loans.h:73
const AccessPath & getAccessPath() const
Definition Loans.h:76
static bool classof(const Loan *L)
Definition Loans.h:81
void dump(llvm::raw_ostream &OS) const override
Definition Loans.cpp:13
void dump(llvm::raw_ostream &OS) const override
Definition Loans.cpp:18
static bool classof(const Loan *L)
Definition Loans.h:109
PlaceholderLoan(LoanID ID, const ParmVarDecl *PVD)
Definition Loans.h:102
const ParmVarDecl * getParmVarDecl() const
Definition Loans.h:105
utils::ID< struct LoanTag > LoanID
Definition Loans.h:23
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, LoanID ID)
Definition Loans.h:24
Represents the storage location being borrowed, e.g., a specific stack variable.
Definition Loans.h:31
AccessPath(const clang::ValueDecl *D)
Definition Loans.h:34
const clang::ValueDecl * D
Definition Loans.h:32
A generic, type-safe wrapper for an ID, distinguished by its Tag type.
Definition Utils.h:21