clang API Documentation
00001 //===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains classes for managing ownership of Stmt and Expr nodes. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H 00015 #define LLVM_CLANG_SEMA_OWNERSHIP_H 00016 00017 #include "clang/Basic/LLVM.h" 00018 #include "llvm/ADT/ArrayRef.h" 00019 #include "llvm/ADT/PointerIntPair.h" 00020 00021 //===----------------------------------------------------------------------===// 00022 // OpaquePtr 00023 //===----------------------------------------------------------------------===// 00024 00025 namespace clang { 00026 class CXXCtorInitializer; 00027 class CXXBaseSpecifier; 00028 class Decl; 00029 class Expr; 00030 class ParsedTemplateArgument; 00031 class QualType; 00032 class Stmt; 00033 class TemplateName; 00034 class TemplateParameterList; 00035 00036 /// \brief Wrapper for void* pointer. 00037 /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like 00038 /// a pointer. 00039 /// 00040 /// This is a very simple POD type that wraps a pointer that the Parser 00041 /// doesn't know about but that Sema or another client does. The PtrTy 00042 /// template argument is used to make sure that "Decl" pointers are not 00043 /// compatible with "Type" pointers for example. 00044 template <class PtrTy> 00045 class OpaquePtr { 00046 void *Ptr; 00047 explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} 00048 00049 typedef llvm::PointerLikeTypeTraits<PtrTy> Traits; 00050 00051 public: 00052 OpaquePtr() : Ptr(nullptr) {} 00053 00054 static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } 00055 00056 /// \brief Returns plain pointer to the entity pointed by this wrapper. 00057 /// \tparam PointeeT Type of pointed entity. 00058 /// 00059 /// It is identical to getPtrAs<PointeeT*>. 00060 template <typename PointeeT> PointeeT* getPtrTo() const { 00061 return get(); 00062 } 00063 00064 /// \brief Returns pointer converted to the specified type. 00065 /// \tparam PtrT Result pointer type. There must be implicit conversion 00066 /// from PtrTy to PtrT. 00067 /// 00068 /// In contrast to getPtrTo, this method allows the return type to be 00069 /// a smart pointer. 00070 template <typename PtrT> PtrT getPtrAs() const { 00071 return get(); 00072 } 00073 00074 PtrTy get() const { 00075 return Traits::getFromVoidPointer(Ptr); 00076 } 00077 00078 void set(PtrTy P) { 00079 Ptr = Traits::getAsVoidPointer(P); 00080 } 00081 00082 LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; } 00083 00084 void *getAsOpaquePtr() const { return Ptr; } 00085 static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } 00086 }; 00087 00088 /// UnionOpaquePtr - A version of OpaquePtr suitable for membership 00089 /// in a union. 00090 template <class T> struct UnionOpaquePtr { 00091 void *Ptr; 00092 00093 static UnionOpaquePtr make(OpaquePtr<T> P) { 00094 UnionOpaquePtr OP = { P.getAsOpaquePtr() }; 00095 return OP; 00096 } 00097 00098 OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } 00099 operator OpaquePtr<T>() const { return get(); } 00100 00101 UnionOpaquePtr &operator=(OpaquePtr<T> P) { 00102 Ptr = P.getAsOpaquePtr(); 00103 return *this; 00104 } 00105 }; 00106 } 00107 00108 namespace llvm { 00109 template <class T> 00110 class PointerLikeTypeTraits<clang::OpaquePtr<T> > { 00111 public: 00112 static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) { 00113 // FIXME: Doesn't work? return P.getAs< void >(); 00114 return P.getAsOpaquePtr(); 00115 } 00116 static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) { 00117 return clang::OpaquePtr<T>::getFromOpaquePtr(P); 00118 } 00119 enum { NumLowBitsAvailable = 0 }; 00120 }; 00121 00122 template <class T> 00123 struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; }; 00124 } 00125 00126 namespace clang { 00127 // Basic 00128 class DiagnosticBuilder; 00129 00130 // Determines whether the low bit of the result pointer for the 00131 // given UID is always zero. If so, ActionResult will use that bit 00132 // for it's "invalid" flag. 00133 template<class Ptr> 00134 struct IsResultPtrLowBitFree { 00135 static const bool value = false; 00136 }; 00137 00138 /// ActionResult - This structure is used while parsing/acting on 00139 /// expressions, stmts, etc. It encapsulates both the object returned by 00140 /// the action, plus a sense of whether or not it is valid. 00141 /// When CompressInvalid is true, the "invalid" flag will be 00142 /// stored in the low bit of the Val pointer. 00143 template<class PtrTy, 00144 bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value> 00145 class ActionResult { 00146 PtrTy Val; 00147 bool Invalid; 00148 00149 public: 00150 ActionResult(bool Invalid = false) 00151 : Val(PtrTy()), Invalid(Invalid) {} 00152 ActionResult(PtrTy val) : Val(val), Invalid(false) {} 00153 ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {} 00154 00155 // These two overloads prevent void* -> bool conversions. 00156 ActionResult(const void *); 00157 ActionResult(volatile void *); 00158 00159 bool isInvalid() const { return Invalid; } 00160 bool isUsable() const { return !Invalid && Val; } 00161 bool isUnset() const { return !Invalid && !Val; } 00162 00163 PtrTy get() const { return Val; } 00164 template <typename T> T *getAs() { return static_cast<T*>(get()); } 00165 00166 void set(PtrTy V) { Val = V; } 00167 00168 const ActionResult &operator=(PtrTy RHS) { 00169 Val = RHS; 00170 Invalid = false; 00171 return *this; 00172 } 00173 }; 00174 00175 // This ActionResult partial specialization places the "invalid" 00176 // flag into the low bit of the pointer. 00177 template<typename PtrTy> 00178 class ActionResult<PtrTy, true> { 00179 // A pointer whose low bit is 1 if this result is invalid, 0 00180 // otherwise. 00181 uintptr_t PtrWithInvalid; 00182 typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits; 00183 public: 00184 ActionResult(bool Invalid = false) 00185 : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { } 00186 00187 ActionResult(PtrTy V) { 00188 void *VP = PtrTraits::getAsVoidPointer(V); 00189 PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 00190 assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 00191 } 00192 ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { } 00193 00194 // These two overloads prevent void* -> bool conversions. 00195 ActionResult(const void *); 00196 ActionResult(volatile void *); 00197 00198 bool isInvalid() const { return PtrWithInvalid & 0x01; } 00199 bool isUsable() const { return PtrWithInvalid > 0x01; } 00200 bool isUnset() const { return PtrWithInvalid == 0; } 00201 00202 PtrTy get() const { 00203 void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); 00204 return PtrTraits::getFromVoidPointer(VP); 00205 } 00206 template <typename T> T *getAs() { return static_cast<T*>(get()); } 00207 00208 void set(PtrTy V) { 00209 void *VP = PtrTraits::getAsVoidPointer(V); 00210 PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 00211 assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 00212 } 00213 00214 const ActionResult &operator=(PtrTy RHS) { 00215 void *VP = PtrTraits::getAsVoidPointer(RHS); 00216 PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 00217 assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 00218 return *this; 00219 } 00220 00221 // For types where we can fit a flag in with the pointer, provide 00222 // conversions to/from pointer type. 00223 static ActionResult getFromOpaquePointer(void *P) { 00224 ActionResult Result; 00225 Result.PtrWithInvalid = (uintptr_t)P; 00226 return Result; 00227 } 00228 void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; } 00229 }; 00230 00231 /// An opaque type for threading parsed type information through the 00232 /// parser. 00233 typedef OpaquePtr<QualType> ParsedType; 00234 typedef UnionOpaquePtr<QualType> UnionParsedType; 00235 00236 // We can re-use the low bit of expression, statement, base, and 00237 // member-initializer pointers for the "invalid" flag of 00238 // ActionResult. 00239 template<> struct IsResultPtrLowBitFree<Expr*> { 00240 static const bool value = true; 00241 }; 00242 template<> struct IsResultPtrLowBitFree<Stmt*> { 00243 static const bool value = true; 00244 }; 00245 template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> { 00246 static const bool value = true; 00247 }; 00248 template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> { 00249 static const bool value = true; 00250 }; 00251 00252 typedef ActionResult<Expr*> ExprResult; 00253 typedef ActionResult<Stmt*> StmtResult; 00254 typedef ActionResult<ParsedType> TypeResult; 00255 typedef ActionResult<CXXBaseSpecifier*> BaseResult; 00256 typedef ActionResult<CXXCtorInitializer*> MemInitResult; 00257 00258 typedef ActionResult<Decl*> DeclResult; 00259 typedef OpaquePtr<TemplateName> ParsedTemplateTy; 00260 00261 typedef MutableArrayRef<Expr*> MultiExprArg; 00262 typedef MutableArrayRef<Stmt*> MultiStmtArg; 00263 typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr; 00264 typedef MutableArrayRef<ParsedType> MultiTypeArg; 00265 typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg; 00266 00267 inline ExprResult ExprError() { return ExprResult(true); } 00268 inline StmtResult StmtError() { return StmtResult(true); } 00269 00270 inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); } 00271 inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); } 00272 00273 inline ExprResult ExprEmpty() { return ExprResult(false); } 00274 inline StmtResult StmtEmpty() { return StmtResult(false); } 00275 00276 inline Expr *AssertSuccess(ExprResult R) { 00277 assert(!R.isInvalid() && "operation was asserted to never fail!"); 00278 return R.get(); 00279 } 00280 00281 inline Stmt *AssertSuccess(StmtResult R) { 00282 assert(!R.isInvalid() && "operation was asserted to never fail!"); 00283 return R.get(); 00284 } 00285 } 00286 00287 #endif