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 
29 namespace clang {
30 
31 class CXXBaseSpecifier;
32 class CXXCtorInitializer;
33 class Decl;
34 class Expr;
35 class ParsedTemplateArgument;
36 class QualType;
37 class Stmt;
38 class TemplateName;
39 class 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 
115 namespace llvm {
116 
117  template <class T>
118  struct PointerLikeTypeTraits<clang::OpaquePtr<T>> {
119  static constexpr int NumLowBitsAvailable = 0;
120 
121  static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
122  // FIXME: Doesn't work? return P.getAs< void >();
123  return P.getAsOpaquePtr();
124  }
125 
126  static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
128  }
129  };
130 
131 } // namespace llvm
132 
133 namespace clang {
134 
135 class 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.
140 template <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)
152 template <class PtrTy, bool Compress = IsResultPtrLowBitFree<PtrTy>::value>
154  PtrTy Val = {};
155  bool Invalid = false;
156 
157 public:
158  ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
159  ActionResult(PtrTy Val) { *this = Val; }
160  ActionResult(const DiagnosticBuilder &) : ActionResult(/*Invalid=*/true) {}
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 
173  ActionResult &operator=(PtrTy RHS) {
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.
181 template <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 
189 public:
190  ActionResult(bool Invalid = false)
191  : Value(Invalid ? InvalidValue : UnsetValue) {}
192  ActionResult(PtrTy V) { *this = V; }
193  ActionResult(const DiagnosticBuilder &) : ActionResult(/*Invalid=*/true) {}
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 
209  ActionResult &operator=(PtrTy RHS) {
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.
219  ActionResult Result;
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.
235 template <> struct IsResultPtrLowBitFree<Expr *> {
236  static const bool value = true;
237 };
238 template <> 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 
264 inline ExprResult ExprError() { return ExprResult(true); }
265 inline StmtResult StmtError() { return StmtResult(true); }
266 inline TypeResult TypeError() { return TypeResult(true); }
267 
268 inline ExprResult ExprError(const StreamingDiagnostic &) { return ExprError(); }
269 inline StmtResult StmtError(const StreamingDiagnostic &) { return StmtError(); }
270 
271 inline ExprResult ExprEmpty() { return ExprResult(false); }
272 inline 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:3299
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(volatile void *)=delete
PtrTy get() const
Definition: Ownership.h:170
ActionResult & operator=(PtrTy RHS)
Definition: Ownership.h:173
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:2300
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1277
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
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:91
void * getAsOpaquePtr() const
Definition: Ownership.h:90
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:1121
@ 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
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
const FunctionProtoType * T
StmtResult StmtEmpty()
Definition: Ownership.h:272
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
#define bool
Definition: stdbool.h:24
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