xref: /minix3/external/bsd/llvm/dist/clang/include/clang/Sema/Ownership.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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