clang API Documentation

Ownership.h
Go to the documentation of this file.
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