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