clang 23.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"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/ExprCXX.h"
21#include "llvm/Support/raw_ostream.h"
22
24
26inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, LoanID ID) {
27 return OS << ID.Value;
28}
29
30/// Represents the storage location being borrowed, e.g., a specific stack
31/// variable or a field within it: var.field.*
32///
33/// An AccessPath consists of a root which is one of:
34/// - ValueDecl: a local variable or global
35/// - MaterializeTemporaryExpr: a temporary object
36/// - ParmVarDecl: a function parameter (placeholder)
37/// - CXXMethodDecl: the implicit 'this' object (placeholder)
38/// - CXXNewExpr: a heap allocation made by `new`
39///
40/// Placeholder paths never expire within the function scope, as they represent
41/// storage from the caller's scope.
42///
43/// TODO: Model access paths of other types, e.g. field, array subscript, heap
44/// allocation not through `new`, and globals.
46public:
54
55private:
56 Kind K;
57 llvm::PointerUnion<const Expr *, const Decl *> Root;
58
59public:
60 AccessPath(const clang::ValueDecl *D) : K(Kind::ValueDecl), Root(D) {}
64 static AccessPath Placeholder(const ParmVarDecl *PVD) {
66 }
69 }
70 AccessPath(const AccessPath &Other) : K(Other.K), Root(Other.Root) {}
71 AccessPath &operator=(const AccessPath &) = delete;
72
73 Kind getKind() const { return K; }
74
76 return K == Kind::ValueDecl
78 : nullptr;
79 }
97 return K == Kind::NewAllocation
99 : nullptr;
100 }
101
102 bool operator==(const AccessPath &RHS) const {
103 return K == RHS.K && Root == RHS.Root;
104 }
105 bool operator!=(const AccessPath &RHS) const { return !(*this == RHS); }
106 void dump(llvm::raw_ostream &OS) const;
107
108private:
109 AccessPath(Kind K, const ParmVarDecl *PVD) : K(K), Root(PVD) {}
110 AccessPath(Kind K, const CXXMethodDecl *MD) : K(K), Root(MD) {}
111};
112
113/// Represents lending a storage location.
114///
115/// A loan tracks the borrowing relationship created by operations like
116/// taking a pointer/reference (&x), creating a view (std::string_view sv = s),
117/// or receiving a parameter.
118///
119/// Examples:
120/// - `int* p = &x;` creates a loan to `x`
121/// - Parameter loans have no IssueExpr (created at function entry)
122class Loan {
123 const LoanID ID;
124 const AccessPath Path;
125 /// The expression that creates the loan, e.g., &x. Null for placeholder
126 /// loans.
127 const Expr *IssuingExpr;
128
129public:
130 Loan(LoanID ID, AccessPath Path, const Expr *IssuingExpr)
131 : ID(ID), Path(Path), IssuingExpr(IssuingExpr) {}
132 LoanID getID() const { return ID; }
133 const AccessPath &getAccessPath() const { return Path; }
134 const Expr *getIssuingExpr() const { return IssuingExpr; }
135 void dump(llvm::raw_ostream &OS) const;
136};
137
138/// Manages the creation, storage and retrieval of loans.
140public:
141 LoanManager() = default;
142
143 Loan *createLoan(AccessPath Path, const Expr *IssueExpr) {
144 void *Mem = LoanAllocator.Allocate<Loan>();
145 auto *NewLoan = new (Mem) Loan(getNextLoanID(), Path, IssueExpr);
146 AllLoans.push_back(NewLoan);
147 return NewLoan;
148 }
149
150 const Loan *getLoan(LoanID ID) const {
151 assert(ID.Value < AllLoans.size());
152 return AllLoans[ID.Value];
153 }
154
155 llvm::ArrayRef<const Loan *> getLoans() const { return AllLoans; }
156
157private:
158 LoanID getNextLoanID() { return NextLoanID++; }
159
160 LoanID NextLoanID{0};
161 /// TODO(opt): Profile and evaluate the usefullness of small buffer
162 /// optimisation.
164 llvm::BumpPtrAllocator LoanAllocator;
165};
166} // namespace clang::lifetimes::internal
167
168#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_LOANS_H
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
This represents one expression.
Definition Expr.h:112
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4920
Represents a parameter to a function.
Definition Decl.h:1808
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Represents the storage location being borrowed, e.g., a specific stack variable or a field within it:...
Definition Loans.h:45
AccessPath & operator=(const AccessPath &)=delete
bool operator!=(const AccessPath &RHS) const
Definition Loans.h:105
const CXXNewExpr * getAsNewAllocation() const
Definition Loans.h:96
AccessPath(const clang::ValueDecl *D)
Definition Loans.h:60
AccessPath(const CXXNewExpr *New)
Definition Loans.h:63
const clang::ValueDecl * getAsValueDecl() const
Definition Loans.h:75
bool operator==(const AccessPath &RHS) const
Definition Loans.h:102
AccessPath(const clang::MaterializeTemporaryExpr *MTE)
Definition Loans.h:61
const clang::MaterializeTemporaryExpr * getAsMaterializeTemporaryExpr() const
Definition Loans.h:80
void dump(llvm::raw_ostream &OS) const
Definition Loans.cpp:13
const CXXMethodDecl * getAsPlaceholderThis() const
Definition Loans.h:91
const ParmVarDecl * getAsPlaceholderParam() const
Definition Loans.h:86
AccessPath(const AccessPath &Other)
Definition Loans.h:70
static AccessPath Placeholder(const ParmVarDecl *PVD)
Definition Loans.h:64
static AccessPath Placeholder(const CXXMethodDecl *MD)
Definition Loans.h:67
llvm::ArrayRef< const Loan * > getLoans() const
Definition Loans.h:155
Loan * createLoan(AccessPath Path, const Expr *IssueExpr)
Definition Loans.h:143
const Loan * getLoan(LoanID ID) const
Definition Loans.h:150
Represents lending a storage location.
Definition Loans.h:122
Loan(LoanID ID, AccessPath Path, const Expr *IssuingExpr)
Definition Loans.h:130
const Expr * getIssuingExpr() const
Definition Loans.h:134
const AccessPath & getAccessPath() const
Definition Loans.h:133
void dump(llvm::raw_ostream &OS) const
Definition Loans.cpp:38
utils::ID< struct LoanTag > LoanID
Definition Loans.h:25
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, LoanID ID)
Definition Loans.h:26
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1763
A generic, type-safe wrapper for an ID, distinguished by its Tag type.
Definition Utils.h:21