clang 22.0.0git
Ownership.h
Go to the documentation of this file.
1//===- Ownership.h - Parser ownership helpers -------------------*- 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 contains classes for managing ownership of Stmt and Expr nodes.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_SEMA_OWNERSHIP_H
14#define LLVM_CLANG_SEMA_OWNERSHIP_H
15
17#include "clang/AST/Expr.h"
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/Support/PointerLikeTypeTraits.h"
21#include "llvm/Support/type_traits.h"
22#include <cassert>
23#include <cstddef>
24#include <cstdint>
25
26//===----------------------------------------------------------------------===//
27// OpaquePtr
28//===----------------------------------------------------------------------===//
29
30namespace clang {
31
32class CXXBaseSpecifier;
33class CXXCtorInitializer;
34class Decl;
35class Expr;
36class ParsedTemplateArgument;
37class QualType;
38class Stmt;
39class TemplateName;
40class TemplateParameterList;
41
42 /// Wrapper for void* pointer.
43 /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like
44 /// a pointer.
45 ///
46 /// This is a very simple POD type that wraps a pointer that the Parser
47 /// doesn't know about but that Sema or another client does. The PtrTy
48 /// template argument is used to make sure that "Decl" pointers are not
49 /// compatible with "Type" pointers for example.
50 template <class PtrTy>
51 class OpaquePtr {
52 void *Ptr = nullptr;
53
54 explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
55
57
58 public:
59 OpaquePtr(std::nullptr_t = nullptr) {}
60
61 static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
62
63 /// Returns plain pointer to the entity pointed by this wrapper.
64 /// \tparam PointeeT Type of pointed entity.
65 ///
66 /// It is identical to getPtrAs<PointeeT*>.
67 template <typename PointeeT> PointeeT* getPtrTo() const {
68 return get();
69 }
70
71 /// Returns pointer converted to the specified type.
72 /// \tparam PtrT Result pointer type. There must be implicit conversion
73 /// from PtrTy to PtrT.
74 ///
75 /// In contrast to getPtrTo, this method allows the return type to be
76 /// a smart pointer.
77 template <typename PtrT> PtrT getPtrAs() const {
78 return get();
79 }
80
81 PtrTy get() const {
82 return Traits::getFromVoidPointer(Ptr);
83 }
84
85 void set(PtrTy P) {
86 Ptr = Traits::getAsVoidPointer(P);
87 }
88
89 explicit operator bool() const { return Ptr != nullptr; }
90
91 void *getAsOpaquePtr() const { return Ptr; }
92 static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
93 };
94
95 /// UnionOpaquePtr - A version of OpaquePtr suitable for membership
96 /// in a union.
97 template <class T> struct UnionOpaquePtr {
98 void *Ptr;
99
101 UnionOpaquePtr OP = { P.getAsOpaquePtr() };
102 return OP;
103 }
104
106 operator OpaquePtr<T>() const { return get(); }
107
109 Ptr = P.getAsOpaquePtr();
110 return *this;
111 }
112 };
113
114} // namespace clang
115
116namespace llvm {
117
118 template <class T>
119 struct PointerLikeTypeTraits<clang::OpaquePtr<T>> {
120 static constexpr int NumLowBitsAvailable = 0;
121
123 // FIXME: Doesn't work? return P.getAs< void >();
124 return P.getAsOpaquePtr();
125 }
126
129 }
130 };
131
132} // namespace llvm
133
134namespace clang {
135
136class StreamingDiagnostic;
137
138// Determines whether the low bit of the result pointer for the
139// given UID is always zero. If so, ActionResult will use that bit
140// for it's "invalid" flag.
141template <class Ptr> struct IsResultPtrLowBitFree {
142 static const bool value = false;
143};
144
145/// The result of parsing/analyzing an expression, statement etc.
146///
147/// It may be:
148/// - usable: a valid pointer to the result object
149/// - unset (null but valid): for constructs that may legitimately be absent
150/// (for example, the condition of a for loop)
151/// - invalid: indicating an error
152/// (no detail is provided, usually the error has already been diagnosed)
153template <class PtrTy, bool Compress = IsResultPtrLowBitFree<PtrTy>::value>
155 PtrTy Val = {};
156 bool Invalid = false;
157
158public:
159 ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
160 ActionResult(PtrTy Val) { *this = Val; }
162
163 // These two overloads prevent void* -> bool conversions.
164 ActionResult(const void *) = delete;
165 ActionResult(volatile void *) = delete;
166
167 bool isInvalid() const { return Invalid; }
168 bool isUnset() const { return !Invalid && !Val; }
169 bool isUsable() const { return !isInvalid() && !isUnset(); }
170
171 PtrTy get() const { return Val; }
172 template <typename T> T *getAs() { return static_cast<T *>(get()); }
173
175 Val = RHS;
176 Invalid = false;
177 return *this;
178 }
179};
180
181// If we PtrTy has a free bit, we can represent "invalid" as nullptr|1.
182template <typename PtrTy> class ActionResult<PtrTy, true> {
183 static constexpr uintptr_t UnsetValue = 0x0;
184 static constexpr uintptr_t InvalidValue = 0x1;
185
186 uintptr_t Value = UnsetValue;
187
189
190public:
191 ActionResult(bool Invalid = false)
192 : Value(Invalid ? InvalidValue : UnsetValue) {}
193 ActionResult(PtrTy V) { *this = V; }
195
196 // These two overloads prevent void* -> bool conversions.
197 ActionResult(const void *) = delete;
198 ActionResult(volatile void *) = delete;
199
200 bool isInvalid() const { return Value == InvalidValue; }
201 bool isUnset() const { return Value == UnsetValue; }
202 bool isUsable() const { return !isInvalid() && !isUnset(); }
203
204 PtrTy get() const {
205 void *VP = reinterpret_cast<void *>(Value & ~0x01);
206 return PtrTraits::getFromVoidPointer(VP);
207 }
208 template <typename T> T *getAs() { return static_cast<T *>(get()); }
209
211 void *VP = PtrTraits::getAsVoidPointer(RHS);
212 Value = reinterpret_cast<uintptr_t>(VP);
213 assert((Value & 0x01) == 0 && "Badly aligned pointer");
214 return *this;
215 }
216
217 // For types where we can fit a flag in with the pointer, provide
218 // conversions to/from pointer type.
221 Result.Value = (uintptr_t)P;
222 assert(Result.isInvalid() ||
223 PtrTraits::getAsVoidPointer(Result.get()) == P);
224 return Result;
225 }
226 void *getAsOpaquePointer() const { return (void *)Value; }
227};
228
229/// An opaque type for threading parsed type information through the parser.
232
233// We can re-use the low bit of expression, statement, base, and
234// member-initializer pointers for the "invalid" flag of
235// ActionResult.
236template <> struct IsResultPtrLowBitFree<Expr *> {
237 static const bool value = true;
238};
239template <> struct IsResultPtrLowBitFree<Stmt *> {
240 static const bool value = true;
241};
243 static const bool value = true;
244};
246 static const bool value = true;
247};
248
254
258
264
265inline ExprResult ExprError() { return ExprResult(true); }
266inline StmtResult StmtError() { return StmtResult(true); }
267inline TypeResult TypeError() { return TypeResult(true); }
268
271
272inline ExprResult ExprEmpty() { return ExprResult(false); }
273inline StmtResult StmtEmpty() { return StmtResult(false); }
274
276 assert(!R.isInvalid() && "operation was asserted to never fail!");
277 return R.get();
278}
279
281 assert(!R.isInvalid() && "operation was asserted to never fail!");
282 return R.get();
283}
284
285} // namespace clang
286
287#endif // LLVM_CLANG_SEMA_OWNERSHIP_H
#define V(N, I)
Definition: ASTContext.h:3597
StringRef P
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static ActionResult getFromOpaquePointer(void *P)
Definition: Ownership.h:219
ActionResult(bool Invalid=false)
Definition: Ownership.h:191
ActionResult(const void *)=delete
ActionResult & operator=(PtrTy RHS)
Definition: Ownership.h:210
ActionResult(volatile void *)=delete
ActionResult(const DiagnosticBuilder &)
Definition: Ownership.h:194
The result of parsing/analyzing an expression, statement etc.
Definition: Ownership.h:154
bool isUnset() const
Definition: Ownership.h:168
ActionResult(const void *)=delete
ActionResult & operator=(PtrTy RHS)
Definition: Ownership.h:174
ActionResult(volatile void *)=delete
PtrTy get() const
Definition: Ownership.h:171
bool isInvalid() const
Definition: Ownership.h:167
ActionResult(bool Invalid=false)
Definition: Ownership.h:159
ActionResult(const DiagnosticBuilder &)
Definition: Ownership.h:161
bool isUsable() const
Definition: Ownership.h:169
ActionResult(PtrTy Val)
Definition: Ownership.h:160
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2369
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1233
This represents one expression.
Definition: Expr.h:112
Wrapper for void* pointer.
Definition: Ownership.h:51
PointeeT * getPtrTo() const
Returns plain pointer to the entity pointed by this wrapper.
Definition: Ownership.h:67
OpaquePtr(std::nullptr_t=nullptr)
Definition: Ownership.h:59
PtrT getPtrAs() const
Returns pointer converted to the specified type.
Definition: Ownership.h:77
void * getAsOpaquePtr() const
Definition: Ownership.h:91
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:92
PtrTy get() const
Definition: Ownership.h:81
static OpaquePtr make(PtrTy P)
Definition: Ownership.h:61
void set(PtrTy P)
Definition: Ownership.h:85
Stmt - This represents one statement.
Definition: Stmt.h:85
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1115
#define bool
Definition: gpuintrin.h:32
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Definition: ModuleMapFile.h:36
The JSON file list parser is used to communicate input to InstallAPI.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Expr * AssertSuccess(ExprResult R)
Definition: Ownership.h:275
TypeResult TypeError()
Definition: Ownership.h:267
ExprResult ExprEmpty()
Definition: Ownership.h:272
StmtResult StmtError()
Definition: Ownership.h:266
@ Result
The result type of a method or function.
ActionResult< Expr * > ExprResult
Definition: Ownership.h:249
ExprResult ExprError()
Definition: Ownership.h:265
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:250
ActionResult< ParsedType > TypeResult
Definition: Ownership.h:251
const FunctionProtoType * T
StmtResult StmtEmpty()
Definition: Ownership.h:273
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
#define true
Definition: stdbool.h:25
static const bool value
Definition: Ownership.h:142
UnionOpaquePtr - A version of OpaquePtr suitable for membership in a union.
Definition: Ownership.h:97
OpaquePtr< T > get() const
Definition: Ownership.h:105
static UnionOpaquePtr make(OpaquePtr< T > P)
Definition: Ownership.h:100
UnionOpaquePtr & operator=(OpaquePtr< T > P)
Definition: Ownership.h:108
static clang::OpaquePtr< T > getFromVoidPointer(void *P)
Definition: Ownership.h:127
static void * getAsVoidPointer(clang::OpaquePtr< T > P)
Definition: Ownership.h:122