clang 22.0.0git
Origins.h
Go to the documentation of this file.
1//===- Origins.h - Origin and Origin Management ----------------*- 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 Origins, which represent the set of possible loans a
10// pointer-like object could hold, and the OriginManager, which manages the
11// creation, storage, and retrieval of origins for variables and expressions.
12//
13//===----------------------------------------------------------------------===//
14#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_ORIGINS_H
15#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_ORIGINS_H
16
17#include "clang/AST/Decl.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/TypeBase.h"
22#include "llvm/Support/raw_ostream.h"
23
25
27
28inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, OriginID ID) {
29 return OS << ID.Value;
30}
31
32/// An Origin is a symbolic identifier that represents the set of possible
33/// loans a pointer-like object could hold at any given time.
34///
35/// Each Origin corresponds to a single level of indirection. For complex types
36/// with multiple levels of indirection (e.g., `int**`), multiple Origins are
37/// organized into an OriginList structure (see below).
38struct Origin {
40 /// A pointer to the AST node that this origin represents. This union
41 /// distinguishes between origins from declarations (variables or parameters)
42 /// and origins from expressions.
43 llvm::PointerUnion<const clang::ValueDecl *, const clang::Expr *> Ptr;
44
45 /// The type at this indirection level.
46 ///
47 /// For `int** pp`:
48 /// Root origin: QT = `int**` (what pp points to)
49 /// Pointee origin: QT = `int*` (what *pp points to)
50 ///
51 /// Null for synthetic lvalue origins (e.g., outer origin of DeclRefExpr).
52 const Type *Ty;
53
54 Origin(OriginID ID, const clang::ValueDecl *D, const Type *QT)
55 : ID(ID), Ptr(D), Ty(QT) {}
56 Origin(OriginID ID, const clang::Expr *E, const Type *QT)
57 : ID(ID), Ptr(E), Ty(QT) {}
58
59 const clang::ValueDecl *getDecl() const {
60 return Ptr.dyn_cast<const clang::ValueDecl *>();
61 }
62 const clang::Expr *getExpr() const {
63 return Ptr.dyn_cast<const clang::Expr *>();
64 }
65};
66
67/// A list of origins representing levels of indirection for pointer-like types.
68///
69/// Each node in the list contains an OriginID representing a level of
70/// indirection. The list structure captures the multi-level nature of
71/// pointer and reference types in the lifetime analysis.
72///
73/// Examples:
74/// - For `int& x`, the list has size 2:
75/// * Outer: origin for the reference storage itself (the lvalue `x`)
76/// * Inner: origin for what `x` refers to
77///
78/// - For `int* p`, the list has size 2:
79/// * Outer: origin for the pointer variable `p`
80/// * Inner: origin for what `p` points to
81///
82/// - For `View v` (where View is gsl::Pointer), the list has size 2:
83/// * Outer: origin for the view object itself
84/// * Inner: origin for what the view refers to
85///
86/// - For `int** pp`, the list has size 3:
87/// * Outer: origin for `pp` itself
88/// * Inner: origin for `*pp` (what `pp` points to)
89/// * Inner->Inner: origin for `**pp` (what `*pp` points to)
90///
91/// The list structure enables the analysis to track how loans flow through
92/// different levels of indirection when assignments and dereferences occur.
94public:
95 OriginList(OriginID OID) : OuterOID(OID) {}
96
97 OriginList *peelOuterOrigin() const { return InnerList; }
98 OriginID getOuterOriginID() const { return OuterOID; }
99
100 void setInnerOriginList(OriginList *Inner) { InnerList = Inner; }
101
102 // Used for assertion checks only (to ensure origin lists have matching
103 // lengths).
104 size_t getLength() const {
105 size_t Length = 1;
106 const OriginList *T = this;
107 while (T->InnerList) {
108 T = T->InnerList;
109 Length++;
110 }
111 return Length;
112 }
113
114private:
115 OriginID OuterOID;
116 OriginList *InnerList = nullptr;
117};
118
119bool hasOrigins(QualType QT);
120bool hasOrigins(const Expr *E);
121bool doesDeclHaveStorage(const ValueDecl *D);
122
123/// Manages the creation, storage, and retrieval of origins for pointer-like
124/// variables and expressions.
126public:
127 explicit OriginManager(ASTContext &AST) : AST(AST) {}
128
129 /// Gets or creates the OriginList for a given ValueDecl.
130 ///
131 /// Creates a list structure mirroring the levels of indirection in the
132 /// declaration's type (e.g., `int** p` creates list of size 2).
133 ///
134 /// \returns The OriginList, or nullptr if the type is not pointer-like.
136
137 /// Gets or creates the OriginList for a given Expr.
138 ///
139 /// Creates a list based on the expression's type and value category:
140 /// - Lvalues get an implicit reference level (modeling addressability)
141 /// - Rvalues of non-pointer type return nullptr (no trackable origin)
142 /// - DeclRefExpr may reuse the underlying declaration's list
143 ///
144 /// \returns The OriginList, or nullptr for non-pointer rvalues.
146
147 const Origin &getOrigin(OriginID ID) const;
148
149 llvm::ArrayRef<Origin> getOrigins() const { return AllOrigins; }
150
151 unsigned getNumOrigins() const { return NextOriginID.Value; }
152
153 void dump(OriginID OID, llvm::raw_ostream &OS) const;
154
155 /// Collects statistics about expressions that lack associated origins.
156 void collectMissingOrigins(Stmt &FunctionBody, LifetimeSafetyStats &LSStats);
157
158private:
159 OriginID getNextOriginID() { return NextOriginID++; }
160
161 OriginList *createNode(const ValueDecl *D, QualType QT);
162 OriginList *createNode(const Expr *E, QualType QT);
163
164 template <typename T>
165 OriginList *buildListForType(QualType QT, const T *Node);
166
167 ASTContext &AST;
168 OriginID NextOriginID{0};
169 /// TODO(opt): Profile and evaluate the usefulness of small buffer
170 /// optimisation.
171 llvm::SmallVector<Origin> AllOrigins;
172 llvm::BumpPtrAllocator ListAllocator;
173 llvm::DenseMap<const clang::ValueDecl *, OriginList *> DeclToList;
174 llvm::DenseMap<const clang::Expr *, OriginList *> ExprToList;
175};
176} // namespace clang::lifetimes::internal
177
178#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_ORIGINS_H
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
This represents one expression.
Definition Expr.h:112
A (possibly-)qualified type.
Definition TypeBase.h:937
Stmt - This represents one statement.
Definition Stmt.h:85
The base class of the type hierarchy.
Definition TypeBase.h:1833
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
A list of origins representing levels of indirection for pointer-like types.
Definition Origins.h:93
OriginList * peelOuterOrigin() const
Definition Origins.h:97
void setInnerOriginList(OriginList *Inner)
Definition Origins.h:100
OriginList * getOrCreateList(const ValueDecl *D)
Gets or creates the OriginList for a given ValueDecl.
Definition Origins.cpp:115
const Origin & getOrigin(OriginID ID) const
Definition Origins.cpp:187
llvm::ArrayRef< Origin > getOrigins() const
Definition Origins.h:149
void collectMissingOrigins(Stmt &FunctionBody, LifetimeSafetyStats &LSStats)
Collects statistics about expressions that lack associated origins.
Definition Origins.cpp:192
void dump(OriginID OID, llvm::raw_ostream &OS) const
Definition Origins.cpp:168
utils::ID< struct OriginTag > OriginID
Definition Origins.h:26
bool doesDeclHaveStorage(const ValueDecl *D)
Returns true if the declaration has its own storage that can be borrowed.
Definition Origins.cpp:84
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, LoanID ID)
Definition Loans.h:24
bool hasOrigins(QualType QT)
Definition Origins.cpp:51
const FunctionProtoType * T
A structure to hold the statistics related to LifetimeAnalysis.
An Origin is a symbolic identifier that represents the set of possible loans a pointer-like object co...
Definition Origins.h:38
const clang::Expr * getExpr() const
Definition Origins.h:62
const clang::ValueDecl * getDecl() const
Definition Origins.h:59
llvm::PointerUnion< const clang::ValueDecl *, const clang::Expr * > Ptr
A pointer to the AST node that this origin represents.
Definition Origins.h:43
const Type * Ty
The type at this indirection level.
Definition Origins.h:52
Origin(OriginID ID, const clang::ValueDecl *D, const Type *QT)
Definition Origins.h:54
Origin(OriginID ID, const clang::Expr *E, const Type *QT)
Definition Origins.h:56
A generic, type-safe wrapper for an ID, distinguished by its Tag type.
Definition Utils.h:21