File indexing completed on 2026-05-10 08:37:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H
0014 #define LLVM_CLANG_SEMA_OWNERSHIP_H
0015
0016 #include "clang/AST/Expr.h"
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/ADT/ArrayRef.h"
0019 #include "llvm/Support/PointerLikeTypeTraits.h"
0020 #include "llvm/Support/type_traits.h"
0021 #include <cassert>
0022 #include <cstddef>
0023 #include <cstdint>
0024
0025
0026
0027
0028
0029 namespace clang {
0030
0031 class CXXBaseSpecifier;
0032 class CXXCtorInitializer;
0033 class Decl;
0034 class Expr;
0035 class ParsedTemplateArgument;
0036 class QualType;
0037 class Stmt;
0038 class TemplateName;
0039 class TemplateParameterList;
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 template <class PtrTy>
0050 class OpaquePtr {
0051 void *Ptr = nullptr;
0052
0053 explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
0054
0055 using Traits = llvm::PointerLikeTypeTraits<PtrTy>;
0056
0057 public:
0058 OpaquePtr(std::nullptr_t = nullptr) {}
0059
0060 static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
0061
0062
0063
0064
0065
0066 template <typename PointeeT> PointeeT* getPtrTo() const {
0067 return get();
0068 }
0069
0070
0071
0072
0073
0074
0075
0076 template <typename PtrT> PtrT getPtrAs() const {
0077 return get();
0078 }
0079
0080 PtrTy get() const {
0081 return Traits::getFromVoidPointer(Ptr);
0082 }
0083
0084 void set(PtrTy P) {
0085 Ptr = Traits::getAsVoidPointer(P);
0086 }
0087
0088 explicit operator bool() const { return Ptr != nullptr; }
0089
0090 void *getAsOpaquePtr() const { return Ptr; }
0091 static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
0092 };
0093
0094
0095
0096 template <class T> struct UnionOpaquePtr {
0097 void *Ptr;
0098
0099 static UnionOpaquePtr make(OpaquePtr<T> P) {
0100 UnionOpaquePtr OP = { P.getAsOpaquePtr() };
0101 return OP;
0102 }
0103
0104 OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); }
0105 operator OpaquePtr<T>() const { return get(); }
0106
0107 UnionOpaquePtr &operator=(OpaquePtr<T> P) {
0108 Ptr = P.getAsOpaquePtr();
0109 return *this;
0110 }
0111 };
0112
0113 }
0114
0115 namespace llvm {
0116
0117 template <class T>
0118 struct PointerLikeTypeTraits<clang::OpaquePtr<T>> {
0119 static constexpr int NumLowBitsAvailable = 0;
0120
0121 static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
0122
0123 return P.getAsOpaquePtr();
0124 }
0125
0126 static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
0127 return clang::OpaquePtr<T>::getFromOpaquePtr(P);
0128 }
0129 };
0130
0131 }
0132
0133 namespace clang {
0134
0135 class StreamingDiagnostic;
0136
0137
0138
0139
0140 template <class Ptr> struct IsResultPtrLowBitFree {
0141 static const bool value = false;
0142 };
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 template <class PtrTy, bool Compress = IsResultPtrLowBitFree<PtrTy>::value>
0153 class ActionResult {
0154 PtrTy Val = {};
0155 bool Invalid = false;
0156
0157 public:
0158 ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
0159 ActionResult(PtrTy Val) { *this = Val; }
0160 ActionResult(const DiagnosticBuilder &) : ActionResult(true) {}
0161
0162
0163 ActionResult(const void *) = delete;
0164 ActionResult(volatile void *) = delete;
0165
0166 bool isInvalid() const { return Invalid; }
0167 bool isUnset() const { return !Invalid && !Val; }
0168 bool isUsable() const { return !isInvalid() && !isUnset(); }
0169
0170 PtrTy get() const { return Val; }
0171 template <typename T> T *getAs() { return static_cast<T *>(get()); }
0172
0173 ActionResult &operator=(PtrTy RHS) {
0174 Val = RHS;
0175 Invalid = false;
0176 return *this;
0177 }
0178 };
0179
0180
0181 template <typename PtrTy> class ActionResult<PtrTy, true> {
0182 static constexpr uintptr_t UnsetValue = 0x0;
0183 static constexpr uintptr_t InvalidValue = 0x1;
0184
0185 uintptr_t Value = UnsetValue;
0186
0187 using PtrTraits = llvm::PointerLikeTypeTraits<PtrTy>;
0188
0189 public:
0190 ActionResult(bool Invalid = false)
0191 : Value(Invalid ? InvalidValue : UnsetValue) {}
0192 ActionResult(PtrTy V) { *this = V; }
0193 ActionResult(const DiagnosticBuilder &) : ActionResult(true) {}
0194
0195
0196 ActionResult(const void *) = delete;
0197 ActionResult(volatile void *) = delete;
0198
0199 bool isInvalid() const { return Value == InvalidValue; }
0200 bool isUnset() const { return Value == UnsetValue; }
0201 bool isUsable() const { return !isInvalid() && !isUnset(); }
0202
0203 PtrTy get() const {
0204 void *VP = reinterpret_cast<void *>(Value & ~0x01);
0205 return PtrTraits::getFromVoidPointer(VP);
0206 }
0207 template <typename T> T *getAs() { return static_cast<T *>(get()); }
0208
0209 ActionResult &operator=(PtrTy RHS) {
0210 void *VP = PtrTraits::getAsVoidPointer(RHS);
0211 Value = reinterpret_cast<uintptr_t>(VP);
0212 assert((Value & 0x01) == 0 && "Badly aligned pointer");
0213 return *this;
0214 }
0215
0216
0217
0218 static ActionResult getFromOpaquePointer(void *P) {
0219 ActionResult Result;
0220 Result.Value = (uintptr_t)P;
0221 assert(Result.isInvalid() ||
0222 PtrTraits::getAsVoidPointer(Result.get()) == P);
0223 return Result;
0224 }
0225 void *getAsOpaquePointer() const { return (void *)Value; }
0226 };
0227
0228
0229 using ParsedType = OpaquePtr<QualType>;
0230 using UnionParsedType = UnionOpaquePtr<QualType>;
0231
0232
0233
0234
0235 template <> struct IsResultPtrLowBitFree<Expr *> {
0236 static const bool value = true;
0237 };
0238 template <> struct IsResultPtrLowBitFree<Stmt *> {
0239 static const bool value = true;
0240 };
0241 template <> struct IsResultPtrLowBitFree<CXXBaseSpecifier *> {
0242 static const bool value = true;
0243 };
0244 template <> struct IsResultPtrLowBitFree<CXXCtorInitializer *> {
0245 static const bool value = true;
0246 };
0247
0248 using ExprResult = ActionResult<Expr *>;
0249 using StmtResult = ActionResult<Stmt *>;
0250 using TypeResult = ActionResult<ParsedType>;
0251 using BaseResult = ActionResult<CXXBaseSpecifier *>;
0252 using MemInitResult = ActionResult<CXXCtorInitializer *>;
0253
0254 using DeclResult = ActionResult<Decl *>;
0255 using ParsedTemplateTy = OpaquePtr<TemplateName>;
0256 using UnionParsedTemplateTy = UnionOpaquePtr<TemplateName>;
0257
0258 using MultiExprArg = MutableArrayRef<Expr *>;
0259 using MultiStmtArg = MutableArrayRef<Stmt *>;
0260 using ASTTemplateArgsPtr = MutableArrayRef<ParsedTemplateArgument>;
0261 using MultiTypeArg = MutableArrayRef<ParsedType>;
0262 using MultiTemplateParamsArg = MutableArrayRef<TemplateParameterList *>;
0263
0264 inline ExprResult ExprError() { return ExprResult(true); }
0265 inline StmtResult StmtError() { return StmtResult(true); }
0266 inline TypeResult TypeError() { return TypeResult(true); }
0267
0268 inline ExprResult ExprError(const StreamingDiagnostic &) { return ExprError(); }
0269 inline StmtResult StmtError(const StreamingDiagnostic &) { return StmtError(); }
0270
0271 inline ExprResult ExprEmpty() { return ExprResult(false); }
0272 inline StmtResult StmtEmpty() { return StmtResult(false); }
0273
0274 inline Expr *AssertSuccess(ExprResult R) {
0275 assert(!R.isInvalid() && "operation was asserted to never fail!");
0276 return R.get();
0277 }
0278
0279 inline Stmt *AssertSuccess(StmtResult R) {
0280 assert(!R.isInvalid() && "operation was asserted to never fail!");
0281 return R.get();
0282 }
0283
0284 }
0285
0286 #endif