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/SmallVector.h" 00019 #include "llvm/ADT/PointerIntPair.h" 00020 00021 //===----------------------------------------------------------------------===// 00022 // OpaquePtr 00023 //===----------------------------------------------------------------------===// 00024 00025 namespace clang { 00026 class Attr; 00027 class CXXCtorInitializer; 00028 class CXXBaseSpecifier; 00029 class Decl; 00030 class DeclGroupRef; 00031 class Expr; 00032 class NestedNameSpecifier; 00033 class QualType; 00034 class Sema; 00035 class Stmt; 00036 class TemplateName; 00037 class TemplateParameterList; 00038 00039 /// OpaquePtr - This is a very simple POD type that wraps a pointer that the 00040 /// Parser doesn't know about but that Sema or another client does. The UID 00041 /// template argument is used to make sure that "Decl" pointers are not 00042 /// compatible with "Type" pointers for example. 00043 template <class PtrTy> 00044 class OpaquePtr { 00045 void *Ptr; 00046 explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} 00047 00048 typedef llvm::PointerLikeTypeTraits<PtrTy> Traits; 00049 00050 public: 00051 OpaquePtr() : Ptr(0) {} 00052 00053 static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } 00054 00055 template <typename T> T* getAs() const { 00056 return get(); 00057 } 00058 00059 template <typename T> T getAsVal() const { 00060 return get(); 00061 } 00062 00063 PtrTy get() const { 00064 return Traits::getFromVoidPointer(Ptr); 00065 } 00066 00067 void set(PtrTy P) { 00068 Ptr = Traits::getAsVoidPointer(P); 00069 } 00070 00071 operator bool() const { return Ptr != 0; } 00072 00073 void *getAsOpaquePtr() const { return Ptr; } 00074 static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } 00075 }; 00076 00077 /// UnionOpaquePtr - A version of OpaquePtr suitable for membership 00078 /// in a union. 00079 template <class T> struct UnionOpaquePtr { 00080 void *Ptr; 00081 00082 static UnionOpaquePtr make(OpaquePtr<T> P) { 00083 UnionOpaquePtr OP = { P.getAsOpaquePtr() }; 00084 return OP; 00085 } 00086 00087 OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } 00088 operator OpaquePtr<T>() const { return get(); } 00089 00090 UnionOpaquePtr &operator=(OpaquePtr<T> P) { 00091 Ptr = P.getAsOpaquePtr(); 00092 return *this; 00093 } 00094 }; 00095 } 00096 00097 namespace llvm { 00098 template <class T> 00099 class PointerLikeTypeTraits<clang::OpaquePtr<T> > { 00100 public: 00101 static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) { 00102 // FIXME: Doesn't work? return P.getAs< void >(); 00103 return P.getAsOpaquePtr(); 00104 } 00105 static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) { 00106 return clang::OpaquePtr<T>::getFromOpaquePtr(P); 00107 } 00108 enum { NumLowBitsAvailable = 0 }; 00109 }; 00110 00111 template <class T> 00112 struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; }; 00113 } 00114 00115 00116 00117 // -------------------------- About Move Emulation -------------------------- // 00118 // The smart pointer classes in this file attempt to emulate move semantics 00119 // as they appear in C++0x with rvalue references. Since C++03 doesn't have 00120 // rvalue references, some tricks are needed to get similar results. 00121 // Move semantics in C++0x have the following properties: 00122 // 1) "Moving" means transferring the value of an object to another object, 00123 // similar to copying, but without caring what happens to the old object. 00124 // In particular, this means that the new object can steal the old object's 00125 // resources instead of creating a copy. 00126 // 2) Since moving can modify the source object, it must either be explicitly 00127 // requested by the user, or the modifications must be unnoticeable. 00128 // 3) As such, C++0x moving is only allowed in three contexts: 00129 // * By explicitly using std::move() to request it. 00130 // * From a temporary object, since that object cannot be accessed 00131 // afterwards anyway, thus making the state unobservable. 00132 // * On function return, since the object is not observable afterwards. 00133 // 00134 // To sum up: moving from a named object should only be possible with an 00135 // explicit std::move(), or on function return. Moving from a temporary should 00136 // be implicitly done. Moving from a const object is forbidden. 00137 // 00138 // The emulation is not perfect, and has the following shortcomings: 00139 // * move() is not in namespace std. 00140 // * move() is required on function return. 00141 // * There are difficulties with implicit conversions. 00142 // * Microsoft's compiler must be given the /Za switch to successfully compile. 00143 // 00144 // -------------------------- Implementation -------------------------------- // 00145 // The move emulation relies on the peculiar reference binding semantics of 00146 // C++03: as a rule, a non-const reference may not bind to a temporary object, 00147 // except for the implicit object parameter in a member function call, which 00148 // can refer to a temporary even when not being const. 00149 // The moveable object has five important functions to facilitate moving: 00150 // * A private, unimplemented constructor taking a non-const reference to its 00151 // own class. This constructor serves a two-fold purpose. 00152 // - It prevents the creation of a copy constructor that takes a const 00153 // reference. Temporaries would be able to bind to the argument of such a 00154 // constructor, and that would be bad. 00155 // - Named objects will bind to the non-const reference, but since it's 00156 // private, this will fail to compile. This prevents implicit moving from 00157 // named objects. 00158 // There's also a copy assignment operator for the same purpose. 00159 // * An implicit, non-const conversion operator to a special mover type. This 00160 // type represents the rvalue reference of C++0x. Being a non-const member, 00161 // its implicit this parameter can bind to temporaries. 00162 // * A constructor that takes an object of this mover type. This constructor 00163 // performs the actual move operation. There is an equivalent assignment 00164 // operator. 00165 // There is also a free move() function that takes a non-const reference to 00166 // an object and returns a temporary. Internally, this function uses explicit 00167 // constructor calls to move the value from the referenced object to the return 00168 // value. 00169 // 00170 // There are now three possible scenarios of use. 00171 // * Copying from a const object. Constructor overload resolution will find the 00172 // non-const copy constructor, and the move constructor. The first is not 00173 // viable because the const object cannot be bound to the non-const reference. 00174 // The second fails because the conversion to the mover object is non-const. 00175 // Moving from a const object fails as intended. 00176 // * Copying from a named object. Constructor overload resolution will select 00177 // the non-const copy constructor, but fail as intended, because this 00178 // constructor is private. 00179 // * Copying from a temporary. Constructor overload resolution cannot select 00180 // the non-const copy constructor, because the temporary cannot be bound to 00181 // the non-const reference. It thus selects the move constructor. The 00182 // temporary can be bound to the implicit this parameter of the conversion 00183 // operator, because of the special binding rule. Construction succeeds. 00184 // Note that the Microsoft compiler, as an extension, allows binding 00185 // temporaries against non-const references. The compiler thus selects the 00186 // non-const copy constructor and fails, because the constructor is private. 00187 // Passing /Za (disable extensions) disables this behaviour. 00188 // The free move() function is used to move from a named object. 00189 // 00190 // Note that when passing an object of a different type (the classes below 00191 // have OwningResult and OwningPtr, which should be mixable), you get a problem. 00192 // Argument passing and function return use copy initialization rules. The 00193 // effect of this is that, when the source object is not already of the target 00194 // type, the compiler will first seek a way to convert the source object to the 00195 // target type, and only then attempt to copy the resulting object. This means 00196 // that when passing an OwningResult where an OwningPtr is expected, the 00197 // compiler will first seek a conversion from OwningResult to OwningPtr, then 00198 // copy the OwningPtr. The resulting conversion sequence is: 00199 // OwningResult object -> ResultMover -> OwningResult argument to 00200 // OwningPtr(OwningResult) -> OwningPtr -> PtrMover -> final OwningPtr 00201 // This conversion sequence is too complex to be allowed. Thus the special 00202 // move_* functions, which help the compiler out with some explicit 00203 // conversions. 00204 00205 namespace clang { 00206 // Basic 00207 class DiagnosticBuilder; 00208 00209 // Determines whether the low bit of the result pointer for the 00210 // given UID is always zero. If so, ActionResult will use that bit 00211 // for it's "invalid" flag. 00212 template<class Ptr> 00213 struct IsResultPtrLowBitFree { 00214 static const bool value = false; 00215 }; 00216 00217 /// ActionResult - This structure is used while parsing/acting on 00218 /// expressions, stmts, etc. It encapsulates both the object returned by 00219 /// the action, plus a sense of whether or not it is valid. 00220 /// When CompressInvalid is true, the "invalid" flag will be 00221 /// stored in the low bit of the Val pointer. 00222 template<class PtrTy, 00223 bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value> 00224 class ActionResult { 00225 PtrTy Val; 00226 bool Invalid; 00227 00228 public: 00229 ActionResult(bool Invalid = false) 00230 : Val(PtrTy()), Invalid(Invalid) {} 00231 ActionResult(PtrTy val) : Val(val), Invalid(false) {} 00232 ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {} 00233 00234 // These two overloads prevent void* -> bool conversions. 00235 ActionResult(const void *); 00236 ActionResult(volatile void *); 00237 00238 bool isInvalid() const { return Invalid; } 00239 bool isUsable() const { return !Invalid && Val; } 00240 00241 PtrTy get() const { return Val; } 00242 PtrTy release() const { return Val; } 00243 PtrTy take() const { return Val; } 00244 template <typename T> T *takeAs() { return static_cast<T*>(get()); } 00245 00246 void set(PtrTy V) { Val = V; } 00247 00248 const ActionResult &operator=(PtrTy RHS) { 00249 Val = RHS; 00250 Invalid = false; 00251 return *this; 00252 } 00253 }; 00254 00255 // This ActionResult partial specialization places the "invalid" 00256 // flag into the low bit of the pointer. 00257 template<typename PtrTy> 00258 class ActionResult<PtrTy, true> { 00259 // A pointer whose low bit is 1 if this result is invalid, 0 00260 // otherwise. 00261 uintptr_t PtrWithInvalid; 00262 typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits; 00263 public: 00264 ActionResult(bool Invalid = false) 00265 : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { } 00266 00267 ActionResult(PtrTy V) { 00268 void *VP = PtrTraits::getAsVoidPointer(V); 00269 PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 00270 assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 00271 } 00272 ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { } 00273 00274 // These two overloads prevent void* -> bool conversions. 00275 ActionResult(const void *); 00276 ActionResult(volatile void *); 00277 00278 bool isInvalid() const { return PtrWithInvalid & 0x01; } 00279 bool isUsable() const { return PtrWithInvalid > 0x01; } 00280 00281 PtrTy get() const { 00282 void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); 00283 return PtrTraits::getFromVoidPointer(VP); 00284 } 00285 PtrTy take() const { return get(); } 00286 PtrTy release() const { return get(); } 00287 template <typename T> T *takeAs() { return static_cast<T*>(get()); } 00288 00289 void set(PtrTy V) { 00290 void *VP = PtrTraits::getAsVoidPointer(V); 00291 PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 00292 assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 00293 } 00294 00295 const ActionResult &operator=(PtrTy RHS) { 00296 void *VP = PtrTraits::getAsVoidPointer(RHS); 00297 PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); 00298 assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); 00299 return *this; 00300 } 00301 }; 00302 00303 /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns 00304 /// the individual pointers, not the array holding them. 00305 template <typename PtrTy> class ASTMultiPtr; 00306 00307 template <class PtrTy> 00308 class ASTMultiPtr { 00309 PtrTy *Nodes; 00310 unsigned Count; 00311 00312 public: 00313 // Normal copying implicitly defined 00314 ASTMultiPtr() : Nodes(0), Count(0) {} 00315 explicit ASTMultiPtr(Sema &) : Nodes(0), Count(0) {} 00316 ASTMultiPtr(Sema &, PtrTy *nodes, unsigned count) 00317 : Nodes(nodes), Count(count) {} 00318 // Fake mover in Parse/AstGuard.h needs this: 00319 ASTMultiPtr(PtrTy *nodes, unsigned count) : Nodes(nodes), Count(count) {} 00320 00321 /// Access to the raw pointers. 00322 PtrTy *get() const { return Nodes; } 00323 00324 /// Access to the count. 00325 unsigned size() const { return Count; } 00326 00327 PtrTy *release() { 00328 return Nodes; 00329 } 00330 }; 00331 00332 class ParsedTemplateArgument; 00333 00334 class ASTTemplateArgsPtr { 00335 ParsedTemplateArgument *Args; 00336 mutable unsigned Count; 00337 00338 public: 00339 ASTTemplateArgsPtr(Sema &actions, ParsedTemplateArgument *args, 00340 unsigned count) : 00341 Args(args), Count(count) { } 00342 00343 // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'. 00344 ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) : 00345 Args(Other.Args), Count(Other.Count) { 00346 } 00347 00348 // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'. 00349 ASTTemplateArgsPtr& operator=(ASTTemplateArgsPtr &Other) { 00350 Args = Other.Args; 00351 Count = Other.Count; 00352 return *this; 00353 } 00354 00355 ParsedTemplateArgument *getArgs() const { return Args; } 00356 unsigned size() const { return Count; } 00357 00358 void reset(ParsedTemplateArgument *args, unsigned count) { 00359 Args = args; 00360 Count = count; 00361 } 00362 00363 const ParsedTemplateArgument &operator[](unsigned Arg) const; 00364 00365 ParsedTemplateArgument *release() const { 00366 return Args; 00367 } 00368 }; 00369 00370 /// \brief A small vector that owns a set of AST nodes. 00371 template <class PtrTy, unsigned N = 8> 00372 class ASTOwningVector : public SmallVector<PtrTy, N> { 00373 ASTOwningVector(ASTOwningVector &); // do not implement 00374 ASTOwningVector &operator=(ASTOwningVector &); // do not implement 00375 00376 public: 00377 explicit ASTOwningVector(Sema &Actions) 00378 { } 00379 00380 PtrTy *take() { 00381 return &this->front(); 00382 } 00383 00384 template<typename T> T **takeAs() { return reinterpret_cast<T**>(take()); } 00385 }; 00386 00387 /// An opaque type for threading parsed type information through the 00388 /// parser. 00389 typedef OpaquePtr<QualType> ParsedType; 00390 typedef UnionOpaquePtr<QualType> UnionParsedType; 00391 00392 /// A SmallVector of statements, with stack size 32 (as that is the only one 00393 /// used.) 00394 typedef ASTOwningVector<Stmt*, 32> StmtVector; 00395 /// A SmallVector of expressions, with stack size 12 (the maximum used.) 00396 typedef ASTOwningVector<Expr*, 12> ExprVector; 00397 /// A SmallVector of types. 00398 typedef ASTOwningVector<ParsedType, 12> TypeVector; 00399 00400 template <class T, unsigned N> inline 00401 ASTMultiPtr<T> move_arg(ASTOwningVector<T, N> &vec) { 00402 return ASTMultiPtr<T>(vec.take(), vec.size()); 00403 } 00404 00405 // These versions are hopefully no-ops. 00406 template <class T, bool C> 00407 inline ActionResult<T,C> move(ActionResult<T,C> &ptr) { 00408 return ptr; 00409 } 00410 00411 template <class T> inline 00412 ASTMultiPtr<T>& move(ASTMultiPtr<T> &ptr) { 00413 return ptr; 00414 } 00415 00416 // We can re-use the low bit of expression, statement, base, and 00417 // member-initializer pointers for the "invalid" flag of 00418 // ActionResult. 00419 template<> struct IsResultPtrLowBitFree<Expr*> { 00420 static const bool value = true; 00421 }; 00422 template<> struct IsResultPtrLowBitFree<Stmt*> { 00423 static const bool value = true; 00424 }; 00425 template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> { 00426 static const bool value = true; 00427 }; 00428 template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> { 00429 static const bool value = true; 00430 }; 00431 00432 typedef ActionResult<Expr*> ExprResult; 00433 typedef ActionResult<Stmt*> StmtResult; 00434 typedef ActionResult<ParsedType> TypeResult; 00435 typedef ActionResult<CXXBaseSpecifier*> BaseResult; 00436 typedef ActionResult<CXXCtorInitializer*> MemInitResult; 00437 00438 typedef ActionResult<Decl*> DeclResult; 00439 typedef OpaquePtr<TemplateName> ParsedTemplateTy; 00440 00441 inline Expr *move(Expr *E) { return E; } 00442 inline Stmt *move(Stmt *S) { return S; } 00443 00444 typedef ASTMultiPtr<Expr*> MultiExprArg; 00445 typedef ASTMultiPtr<Stmt*> MultiStmtArg; 00446 typedef ASTMultiPtr<ParsedType> MultiTypeArg; 00447 typedef ASTMultiPtr<TemplateParameterList*> MultiTemplateParamsArg; 00448 00449 inline ExprResult ExprError() { return ExprResult(true); } 00450 inline StmtResult StmtError() { return StmtResult(true); } 00451 00452 inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); } 00453 inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); } 00454 00455 inline ExprResult ExprEmpty() { return ExprResult(false); } 00456 inline StmtResult StmtEmpty() { return StmtResult(false); } 00457 00458 inline Expr *AssertSuccess(ExprResult R) { 00459 assert(!R.isInvalid() && "operation was asserted to never fail!"); 00460 return R.get(); 00461 } 00462 00463 inline Stmt *AssertSuccess(StmtResult R) { 00464 assert(!R.isInvalid() && "operation was asserted to never fail!"); 00465 return R.get(); 00466 } 00467 } 00468 00469 #endif