1f4a2713aSLionel Sambuc //===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===// 2f4a2713aSLionel Sambuc // 3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4f4a2713aSLionel Sambuc // 5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7f4a2713aSLionel Sambuc // 8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9f4a2713aSLionel Sambuc // 10f4a2713aSLionel Sambuc // This file contains classes for managing ownership of Stmt and Expr nodes. 11f4a2713aSLionel Sambuc // 12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 13f4a2713aSLionel Sambuc 14f4a2713aSLionel Sambuc #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H 15f4a2713aSLionel Sambuc #define LLVM_CLANG_SEMA_OWNERSHIP_H 16f4a2713aSLionel Sambuc 17f4a2713aSLionel Sambuc #include "clang/Basic/LLVM.h" 18f4a2713aSLionel Sambuc #include "llvm/ADT/ArrayRef.h" 19f4a2713aSLionel Sambuc #include "llvm/ADT/PointerIntPair.h" 20f4a2713aSLionel Sambuc 21f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 22f4a2713aSLionel Sambuc // OpaquePtr 23f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 24f4a2713aSLionel Sambuc 25f4a2713aSLionel Sambuc namespace clang { 26f4a2713aSLionel Sambuc class CXXCtorInitializer; 27f4a2713aSLionel Sambuc class CXXBaseSpecifier; 28f4a2713aSLionel Sambuc class Decl; 29f4a2713aSLionel Sambuc class Expr; 30f4a2713aSLionel Sambuc class ParsedTemplateArgument; 31f4a2713aSLionel Sambuc class QualType; 32f4a2713aSLionel Sambuc class Stmt; 33f4a2713aSLionel Sambuc class TemplateName; 34f4a2713aSLionel Sambuc class TemplateParameterList; 35f4a2713aSLionel Sambuc 36f4a2713aSLionel Sambuc /// \brief Wrapper for void* pointer. 37f4a2713aSLionel Sambuc /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like 38f4a2713aSLionel Sambuc /// a pointer. 39f4a2713aSLionel Sambuc /// 40f4a2713aSLionel Sambuc /// This is a very simple POD type that wraps a pointer that the Parser 41f4a2713aSLionel Sambuc /// doesn't know about but that Sema or another client does. The PtrTy 42f4a2713aSLionel Sambuc /// template argument is used to make sure that "Decl" pointers are not 43f4a2713aSLionel Sambuc /// compatible with "Type" pointers for example. 44f4a2713aSLionel Sambuc template <class PtrTy> 45f4a2713aSLionel Sambuc class OpaquePtr { 46f4a2713aSLionel Sambuc void *Ptr; OpaquePtr(void * Ptr)47f4a2713aSLionel Sambuc explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} 48f4a2713aSLionel Sambuc 49f4a2713aSLionel Sambuc typedef llvm::PointerLikeTypeTraits<PtrTy> Traits; 50f4a2713aSLionel Sambuc 51f4a2713aSLionel Sambuc public: OpaquePtr()52*0a6a1f1dSLionel Sambuc OpaquePtr() : Ptr(nullptr) {} 53f4a2713aSLionel Sambuc make(PtrTy P)54f4a2713aSLionel Sambuc static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } 55f4a2713aSLionel Sambuc 56f4a2713aSLionel Sambuc /// \brief Returns plain pointer to the entity pointed by this wrapper. 57f4a2713aSLionel Sambuc /// \tparam PointeeT Type of pointed entity. 58f4a2713aSLionel Sambuc /// 59f4a2713aSLionel Sambuc /// It is identical to getPtrAs<PointeeT*>. getPtrTo()60f4a2713aSLionel Sambuc template <typename PointeeT> PointeeT* getPtrTo() const { 61f4a2713aSLionel Sambuc return get(); 62f4a2713aSLionel Sambuc } 63f4a2713aSLionel Sambuc 64f4a2713aSLionel Sambuc /// \brief Returns pointer converted to the specified type. 65f4a2713aSLionel Sambuc /// \tparam PtrT Result pointer type. There must be implicit conversion 66f4a2713aSLionel Sambuc /// from PtrTy to PtrT. 67f4a2713aSLionel Sambuc /// 68f4a2713aSLionel Sambuc /// In contrast to getPtrTo, this method allows the return type to be 69f4a2713aSLionel Sambuc /// a smart pointer. getPtrAs()70f4a2713aSLionel Sambuc template <typename PtrT> PtrT getPtrAs() const { 71f4a2713aSLionel Sambuc return get(); 72f4a2713aSLionel Sambuc } 73f4a2713aSLionel Sambuc get()74f4a2713aSLionel Sambuc PtrTy get() const { 75f4a2713aSLionel Sambuc return Traits::getFromVoidPointer(Ptr); 76f4a2713aSLionel Sambuc } 77f4a2713aSLionel Sambuc set(PtrTy P)78f4a2713aSLionel Sambuc void set(PtrTy P) { 79f4a2713aSLionel Sambuc Ptr = Traits::getAsVoidPointer(P); 80f4a2713aSLionel Sambuc } 81f4a2713aSLionel Sambuc 82*0a6a1f1dSLionel Sambuc LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; } 83f4a2713aSLionel Sambuc getAsOpaquePtr()84f4a2713aSLionel Sambuc void *getAsOpaquePtr() const { return Ptr; } getFromOpaquePtr(void * P)85f4a2713aSLionel Sambuc static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } 86f4a2713aSLionel Sambuc }; 87f4a2713aSLionel Sambuc 88f4a2713aSLionel Sambuc /// UnionOpaquePtr - A version of OpaquePtr suitable for membership 89f4a2713aSLionel Sambuc /// in a union. 90f4a2713aSLionel Sambuc template <class T> struct UnionOpaquePtr { 91f4a2713aSLionel Sambuc void *Ptr; 92f4a2713aSLionel Sambuc makeUnionOpaquePtr93f4a2713aSLionel Sambuc static UnionOpaquePtr make(OpaquePtr<T> P) { 94f4a2713aSLionel Sambuc UnionOpaquePtr OP = { P.getAsOpaquePtr() }; 95f4a2713aSLionel Sambuc return OP; 96f4a2713aSLionel Sambuc } 97f4a2713aSLionel Sambuc getUnionOpaquePtr98f4a2713aSLionel Sambuc OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } 99f4a2713aSLionel Sambuc operator OpaquePtr<T>() const { return get(); } 100f4a2713aSLionel Sambuc 101f4a2713aSLionel Sambuc UnionOpaquePtr &operator=(OpaquePtr<T> P) { 102f4a2713aSLionel Sambuc Ptr = P.getAsOpaquePtr(); 103f4a2713aSLionel Sambuc return *this; 104f4a2713aSLionel Sambuc } 105f4a2713aSLionel Sambuc }; 106f4a2713aSLionel Sambuc } 107f4a2713aSLionel Sambuc 108f4a2713aSLionel Sambuc namespace llvm { 109f4a2713aSLionel Sambuc template <class T> 110f4a2713aSLionel Sambuc class PointerLikeTypeTraits<clang::OpaquePtr<T> > { 111f4a2713aSLionel Sambuc public: getAsVoidPointer(clang::OpaquePtr<T> P)112f4a2713aSLionel Sambuc static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) { 113f4a2713aSLionel Sambuc // FIXME: Doesn't work? return P.getAs< void >(); 114f4a2713aSLionel Sambuc return P.getAsOpaquePtr(); 115f4a2713aSLionel Sambuc } getFromVoidPointer(void * P)116f4a2713aSLionel Sambuc static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) { 117f4a2713aSLionel Sambuc return clang::OpaquePtr<T>::getFromOpaquePtr(P); 118f4a2713aSLionel Sambuc } 119f4a2713aSLionel Sambuc enum { NumLowBitsAvailable = 0 }; 120f4a2713aSLionel Sambuc }; 121f4a2713aSLionel Sambuc 122f4a2713aSLionel Sambuc template <class T> 123f4a2713aSLionel Sambuc struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; }; 124f4a2713aSLionel Sambuc } 125f4a2713aSLionel Sambuc 126f4a2713aSLionel Sambuc namespace clang { 127f4a2713aSLionel Sambuc // Basic 128f4a2713aSLionel Sambuc class DiagnosticBuilder; 129f4a2713aSLionel Sambuc 130f4a2713aSLionel Sambuc // Determines whether the low bit of the result pointer for the 131f4a2713aSLionel Sambuc // given UID is always zero. If so, ActionResult will use that bit 132f4a2713aSLionel Sambuc // for it's "invalid" flag. 133f4a2713aSLionel Sambuc template<class Ptr> 134f4a2713aSLionel Sambuc struct IsResultPtrLowBitFree { 135f4a2713aSLionel Sambuc static const bool value = false; 136f4a2713aSLionel Sambuc }; 137f4a2713aSLionel Sambuc 138f4a2713aSLionel Sambuc /// ActionResult - This structure is used while parsing/acting on 139f4a2713aSLionel Sambuc /// expressions, stmts, etc. It encapsulates both the object returned by 140f4a2713aSLionel Sambuc /// the action, plus a sense of whether or not it is valid. 141f4a2713aSLionel Sambuc /// When CompressInvalid is true, the "invalid" flag will be 142f4a2713aSLionel Sambuc /// stored in the low bit of the Val pointer. 143f4a2713aSLionel Sambuc template<class PtrTy, 144f4a2713aSLionel Sambuc bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value> 145f4a2713aSLionel Sambuc class ActionResult { 146f4a2713aSLionel Sambuc PtrTy Val; 147f4a2713aSLionel Sambuc bool Invalid; 148f4a2713aSLionel Sambuc 149f4a2713aSLionel Sambuc public: 150f4a2713aSLionel Sambuc ActionResult(bool Invalid = false) 151f4a2713aSLionel Sambuc : Val(PtrTy()), Invalid(Invalid) {} 152f4a2713aSLionel Sambuc ActionResult(PtrTy val) : Val(val), Invalid(false) {} 153f4a2713aSLionel Sambuc ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {} 154f4a2713aSLionel Sambuc 155f4a2713aSLionel Sambuc // These two overloads prevent void* -> bool conversions. 156f4a2713aSLionel Sambuc ActionResult(const void *); 157f4a2713aSLionel Sambuc ActionResult(volatile void *); 158f4a2713aSLionel Sambuc 159f4a2713aSLionel Sambuc bool isInvalid() const { return Invalid; } 160f4a2713aSLionel Sambuc bool isUsable() const { return !Invalid && Val; } 161*0a6a1f1dSLionel Sambuc bool isUnset() const { return !Invalid && !Val; } 162f4a2713aSLionel Sambuc 163f4a2713aSLionel Sambuc PtrTy get() const { return Val; } 164*0a6a1f1dSLionel Sambuc template <typename T> T *getAs() { return static_cast<T*>(get()); } 165f4a2713aSLionel Sambuc 166f4a2713aSLionel Sambuc void set(PtrTy V) { Val = V; } 167f4a2713aSLionel Sambuc 168f4a2713aSLionel Sambuc const ActionResult &operator=(PtrTy RHS) { 169f4a2713aSLionel Sambuc Val = RHS; 170f4a2713aSLionel Sambuc Invalid = false; 171f4a2713aSLionel Sambuc return *this; 172f4a2713aSLionel Sambuc } 173f4a2713aSLionel Sambuc }; 174f4a2713aSLionel Sambuc 175f4a2713aSLionel Sambuc // This ActionResult partial specialization places the "invalid" 176f4a2713aSLionel Sambuc // flag into the low bit of the pointer. 177f4a2713aSLionel Sambuc template<typename PtrTy> 178f4a2713aSLionel Sambuc class ActionResult<PtrTy, true> { 179f4a2713aSLionel Sambuc // A pointer whose low bit is 1 if this result is invalid, 0 180f4a2713aSLionel Sambuc // otherwise. 181f4a2713aSLionel Sambuc uintptr_t PtrWithInvalid; 182f4a2713aSLionel Sambuc typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits; 183f4a2713aSLionel Sambuc public: 184f4a2713aSLionel Sambuc ActionResult(bool Invalid = false) 185f4a2713aSLionel Sambuc : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { } 186f4a2713aSLionel Sambuc 187f4a2713aSLionel Sambuc ActionResult(PtrTy V) { 188f4a2713aSLionel Sambuc void *VP = PtrTraits::getAsVoidPointer(V); 189f4a2713aSLionel Sambuc PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 190f4a2713aSLionel Sambuc assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 191f4a2713aSLionel Sambuc } 192f4a2713aSLionel Sambuc ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { } 193f4a2713aSLionel Sambuc 194f4a2713aSLionel Sambuc // These two overloads prevent void* -> bool conversions. 195f4a2713aSLionel Sambuc ActionResult(const void *); 196f4a2713aSLionel Sambuc ActionResult(volatile void *); 197f4a2713aSLionel Sambuc 198f4a2713aSLionel Sambuc bool isInvalid() const { return PtrWithInvalid & 0x01; } 199f4a2713aSLionel Sambuc bool isUsable() const { return PtrWithInvalid > 0x01; } 200*0a6a1f1dSLionel Sambuc bool isUnset() const { return PtrWithInvalid == 0; } 201f4a2713aSLionel Sambuc 202f4a2713aSLionel Sambuc PtrTy get() const { 203f4a2713aSLionel Sambuc void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); 204f4a2713aSLionel Sambuc return PtrTraits::getFromVoidPointer(VP); 205f4a2713aSLionel Sambuc } 206*0a6a1f1dSLionel Sambuc template <typename T> T *getAs() { return static_cast<T*>(get()); } 207f4a2713aSLionel Sambuc 208f4a2713aSLionel Sambuc void set(PtrTy V) { 209f4a2713aSLionel Sambuc void *VP = PtrTraits::getAsVoidPointer(V); 210f4a2713aSLionel Sambuc PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 211f4a2713aSLionel Sambuc assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 212f4a2713aSLionel Sambuc } 213f4a2713aSLionel Sambuc 214f4a2713aSLionel Sambuc const ActionResult &operator=(PtrTy RHS) { 215f4a2713aSLionel Sambuc void *VP = PtrTraits::getAsVoidPointer(RHS); 216f4a2713aSLionel Sambuc PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 217f4a2713aSLionel Sambuc assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 218f4a2713aSLionel Sambuc return *this; 219f4a2713aSLionel Sambuc } 220f4a2713aSLionel Sambuc 221f4a2713aSLionel Sambuc // For types where we can fit a flag in with the pointer, provide 222f4a2713aSLionel Sambuc // conversions to/from pointer type. 223f4a2713aSLionel Sambuc static ActionResult getFromOpaquePointer(void *P) { 224f4a2713aSLionel Sambuc ActionResult Result; 225f4a2713aSLionel Sambuc Result.PtrWithInvalid = (uintptr_t)P; 226f4a2713aSLionel Sambuc return Result; 227f4a2713aSLionel Sambuc } 228f4a2713aSLionel Sambuc void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; } 229f4a2713aSLionel Sambuc }; 230f4a2713aSLionel Sambuc 231f4a2713aSLionel Sambuc /// An opaque type for threading parsed type information through the 232f4a2713aSLionel Sambuc /// parser. 233f4a2713aSLionel Sambuc typedef OpaquePtr<QualType> ParsedType; 234f4a2713aSLionel Sambuc typedef UnionOpaquePtr<QualType> UnionParsedType; 235f4a2713aSLionel Sambuc 236f4a2713aSLionel Sambuc // We can re-use the low bit of expression, statement, base, and 237f4a2713aSLionel Sambuc // member-initializer pointers for the "invalid" flag of 238f4a2713aSLionel Sambuc // ActionResult. 239f4a2713aSLionel Sambuc template<> struct IsResultPtrLowBitFree<Expr*> { 240f4a2713aSLionel Sambuc static const bool value = true; 241f4a2713aSLionel Sambuc }; 242f4a2713aSLionel Sambuc template<> struct IsResultPtrLowBitFree<Stmt*> { 243f4a2713aSLionel Sambuc static const bool value = true; 244f4a2713aSLionel Sambuc }; 245f4a2713aSLionel Sambuc template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> { 246f4a2713aSLionel Sambuc static const bool value = true; 247f4a2713aSLionel Sambuc }; 248f4a2713aSLionel Sambuc template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> { 249f4a2713aSLionel Sambuc static const bool value = true; 250f4a2713aSLionel Sambuc }; 251f4a2713aSLionel Sambuc 252f4a2713aSLionel Sambuc typedef ActionResult<Expr*> ExprResult; 253f4a2713aSLionel Sambuc typedef ActionResult<Stmt*> StmtResult; 254f4a2713aSLionel Sambuc typedef ActionResult<ParsedType> TypeResult; 255f4a2713aSLionel Sambuc typedef ActionResult<CXXBaseSpecifier*> BaseResult; 256f4a2713aSLionel Sambuc typedef ActionResult<CXXCtorInitializer*> MemInitResult; 257f4a2713aSLionel Sambuc 258f4a2713aSLionel Sambuc typedef ActionResult<Decl*> DeclResult; 259f4a2713aSLionel Sambuc typedef OpaquePtr<TemplateName> ParsedTemplateTy; 260f4a2713aSLionel Sambuc 261*0a6a1f1dSLionel Sambuc typedef MutableArrayRef<Expr*> MultiExprArg; 262*0a6a1f1dSLionel Sambuc typedef MutableArrayRef<Stmt*> MultiStmtArg; 263*0a6a1f1dSLionel Sambuc typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr; 264*0a6a1f1dSLionel Sambuc typedef MutableArrayRef<ParsedType> MultiTypeArg; 265*0a6a1f1dSLionel Sambuc typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg; 266f4a2713aSLionel Sambuc 267f4a2713aSLionel Sambuc inline ExprResult ExprError() { return ExprResult(true); } 268f4a2713aSLionel Sambuc inline StmtResult StmtError() { return StmtResult(true); } 269f4a2713aSLionel Sambuc 270f4a2713aSLionel Sambuc inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); } 271f4a2713aSLionel Sambuc inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); } 272f4a2713aSLionel Sambuc 273f4a2713aSLionel Sambuc inline ExprResult ExprEmpty() { return ExprResult(false); } 274f4a2713aSLionel Sambuc inline StmtResult StmtEmpty() { return StmtResult(false); } 275f4a2713aSLionel Sambuc 276f4a2713aSLionel Sambuc inline Expr *AssertSuccess(ExprResult R) { 277f4a2713aSLionel Sambuc assert(!R.isInvalid() && "operation was asserted to never fail!"); 278f4a2713aSLionel Sambuc return R.get(); 279f4a2713aSLionel Sambuc } 280f4a2713aSLionel Sambuc 281f4a2713aSLionel Sambuc inline Stmt *AssertSuccess(StmtResult R) { 282f4a2713aSLionel Sambuc assert(!R.isInvalid() && "operation was asserted to never fail!"); 283f4a2713aSLionel Sambuc return R.get(); 284f4a2713aSLionel Sambuc } 285f4a2713aSLionel Sambuc } 286f4a2713aSLionel Sambuc 287f4a2713aSLionel Sambuc #endif 288