Home | History | Annotate | Download | only in Sema
      1 //===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file contains classes for managing ownership of Stmt and Expr nodes.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H
     15 #define LLVM_CLANG_SEMA_OWNERSHIP_H
     16 
     17 #include "llvm/ADT/SmallVector.h"
     18 #include "llvm/ADT/PointerIntPair.h"
     19 
     20 //===----------------------------------------------------------------------===//
     21 // OpaquePtr
     22 //===----------------------------------------------------------------------===//
     23 
     24 namespace clang {
     25   class Attr;
     26   class CXXCtorInitializer;
     27   class CXXBaseSpecifier;
     28   class Decl;
     29   class DeclGroupRef;
     30   class Expr;
     31   class NestedNameSpecifier;
     32   class QualType;
     33   class Sema;
     34   class Stmt;
     35   class TemplateName;
     36   class TemplateParameterList;
     37 
     38   /// OpaquePtr - This is a very simple POD type that wraps a pointer that the
     39   /// Parser doesn't know about but that Sema or another client does.  The UID
     40   /// template argument is used to make sure that "Decl" pointers are not
     41   /// compatible with "Type" pointers for example.
     42   template <class PtrTy>
     43   class OpaquePtr {
     44     void *Ptr;
     45     explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
     46 
     47     typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
     48 
     49   public:
     50     OpaquePtr() : Ptr(0) {}
     51 
     52     static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
     53 
     54     template <typename T> T* getAs() const {
     55       return get();
     56     }
     57 
     58     template <typename T> T getAsVal() const {
     59       return get();
     60     }
     61 
     62     PtrTy get() const {
     63       return Traits::getFromVoidPointer(Ptr);
     64     }
     65 
     66     void set(PtrTy P) {
     67       Ptr = Traits::getAsVoidPointer(P);
     68     }
     69 
     70     operator bool() const { return Ptr != 0; }
     71 
     72     void *getAsOpaquePtr() const { return Ptr; }
     73     static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
     74   };
     75 
     76   /// UnionOpaquePtr - A version of OpaquePtr suitable for membership
     77   /// in a union.
     78   template <class T> struct UnionOpaquePtr {
     79     void *Ptr;
     80 
     81     static UnionOpaquePtr make(OpaquePtr<T> P) {
     82       UnionOpaquePtr OP = { P.getAsOpaquePtr() };
     83       return OP;
     84     }
     85 
     86     OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); }
     87     operator OpaquePtr<T>() const { return get(); }
     88 
     89     UnionOpaquePtr &operator=(OpaquePtr<T> P) {
     90       Ptr = P.getAsOpaquePtr();
     91       return *this;
     92     }
     93   };
     94 }
     95 
     96 namespace llvm {
     97   template <class T>
     98   class PointerLikeTypeTraits<clang::OpaquePtr<T> > {
     99   public:
    100     static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
    101       // FIXME: Doesn't work? return P.getAs< void >();
    102       return P.getAsOpaquePtr();
    103     }
    104     static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
    105       return clang::OpaquePtr<T>::getFromOpaquePtr(P);
    106     }
    107     enum { NumLowBitsAvailable = 0 };
    108   };
    109 
    110   template <class T>
    111   struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; };
    112 }
    113 
    114 
    115 
    116 // -------------------------- About Move Emulation -------------------------- //
    117 // The smart pointer classes in this file attempt to emulate move semantics
    118 // as they appear in C++0x with rvalue references. Since C++03 doesn't have
    119 // rvalue references, some tricks are needed to get similar results.
    120 // Move semantics in C++0x have the following properties:
    121 // 1) "Moving" means transferring the value of an object to another object,
    122 //    similar to copying, but without caring what happens to the old object.
    123 //    In particular, this means that the new object can steal the old object's
    124 //    resources instead of creating a copy.
    125 // 2) Since moving can modify the source object, it must either be explicitly
    126 //    requested by the user, or the modifications must be unnoticeable.
    127 // 3) As such, C++0x moving is only allowed in three contexts:
    128 //    * By explicitly using std::move() to request it.
    129 //    * From a temporary object, since that object cannot be accessed
    130 //      afterwards anyway, thus making the state unobservable.
    131 //    * On function return, since the object is not observable afterwards.
    132 //
    133 // To sum up: moving from a named object should only be possible with an
    134 // explicit std::move(), or on function return. Moving from a temporary should
    135 // be implicitly done. Moving from a const object is forbidden.
    136 //
    137 // The emulation is not perfect, and has the following shortcomings:
    138 // * move() is not in namespace std.
    139 // * move() is required on function return.
    140 // * There are difficulties with implicit conversions.
    141 // * Microsoft's compiler must be given the /Za switch to successfully compile.
    142 //
    143 // -------------------------- Implementation -------------------------------- //
    144 // The move emulation relies on the peculiar reference binding semantics of
    145 // C++03: as a rule, a non-const reference may not bind to a temporary object,
    146 // except for the implicit object parameter in a member function call, which
    147 // can refer to a temporary even when not being const.
    148 // The moveable object has five important functions to facilitate moving:
    149 // * A private, unimplemented constructor taking a non-const reference to its
    150 //   own class. This constructor serves a two-fold purpose.
    151 //   - It prevents the creation of a copy constructor that takes a const
    152 //     reference. Temporaries would be able to bind to the argument of such a
    153 //     constructor, and that would be bad.
    154 //   - Named objects will bind to the non-const reference, but since it's
    155 //     private, this will fail to compile. This prevents implicit moving from
    156 //     named objects.
    157 //   There's also a copy assignment operator for the same purpose.
    158 // * An implicit, non-const conversion operator to a special mover type. This
    159 //   type represents the rvalue reference of C++0x. Being a non-const member,
    160 //   its implicit this parameter can bind to temporaries.
    161 // * A constructor that takes an object of this mover type. This constructor
    162 //   performs the actual move operation. There is an equivalent assignment
    163 //   operator.
    164 // There is also a free move() function that takes a non-const reference to
    165 // an object and returns a temporary. Internally, this function uses explicit
    166 // constructor calls to move the value from the referenced object to the return
    167 // value.
    168 //
    169 // There are now three possible scenarios of use.
    170 // * Copying from a const object. Constructor overload resolution will find the
    171 //   non-const copy constructor, and the move constructor. The first is not
    172 //   viable because the const object cannot be bound to the non-const reference.
    173 //   The second fails because the conversion to the mover object is non-const.
    174 //   Moving from a const object fails as intended.
    175 // * Copying from a named object. Constructor overload resolution will select
    176 //   the non-const copy constructor, but fail as intended, because this
    177 //   constructor is private.
    178 // * Copying from a temporary. Constructor overload resolution cannot select
    179 //   the non-const copy constructor, because the temporary cannot be bound to
    180 //   the non-const reference. It thus selects the move constructor. The
    181 //   temporary can be bound to the implicit this parameter of the conversion
    182 //   operator, because of the special binding rule. Construction succeeds.
    183 //   Note that the Microsoft compiler, as an extension, allows binding
    184 //   temporaries against non-const references. The compiler thus selects the
    185 //   non-const copy constructor and fails, because the constructor is private.
    186 //   Passing /Za (disable extensions) disables this behaviour.
    187 // The free move() function is used to move from a named object.
    188 //
    189 // Note that when passing an object of a different type (the classes below
    190 // have OwningResult and OwningPtr, which should be mixable), you get a problem.
    191 // Argument passing and function return use copy initialization rules. The
    192 // effect of this is that, when the source object is not already of the target
    193 // type, the compiler will first seek a way to convert the source object to the
    194 // target type, and only then attempt to copy the resulting object. This means
    195 // that when passing an OwningResult where an OwningPtr is expected, the
    196 // compiler will first seek a conversion from OwningResult to OwningPtr, then
    197 // copy the OwningPtr. The resulting conversion sequence is:
    198 // OwningResult object -> ResultMover -> OwningResult argument to
    199 // OwningPtr(OwningResult) -> OwningPtr -> PtrMover -> final OwningPtr
    200 // This conversion sequence is too complex to be allowed. Thus the special
    201 // move_* functions, which help the compiler out with some explicit
    202 // conversions.
    203 
    204 namespace clang {
    205   // Basic
    206   class DiagnosticBuilder;
    207 
    208   // Determines whether the low bit of the result pointer for the
    209   // given UID is always zero. If so, ActionResult will use that bit
    210   // for it's "invalid" flag.
    211   template<class Ptr>
    212   struct IsResultPtrLowBitFree {
    213     static const bool value = false;
    214   };
    215 
    216   /// ActionResult - This structure is used while parsing/acting on
    217   /// expressions, stmts, etc.  It encapsulates both the object returned by
    218   /// the action, plus a sense of whether or not it is valid.
    219   /// When CompressInvalid is true, the "invalid" flag will be
    220   /// stored in the low bit of the Val pointer.
    221   template<class PtrTy,
    222            bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value>
    223   class ActionResult {
    224     PtrTy Val;
    225     bool Invalid;
    226 
    227   public:
    228     ActionResult(bool Invalid = false)
    229       : Val(PtrTy()), Invalid(Invalid) {}
    230     ActionResult(PtrTy val) : Val(val), Invalid(false) {}
    231     ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
    232 
    233     // These two overloads prevent void* -> bool conversions.
    234     ActionResult(const void *);
    235     ActionResult(volatile void *);
    236 
    237     bool isInvalid() const { return Invalid; }
    238     bool isUsable() const { return !Invalid && Val; }
    239 
    240     PtrTy get() const { return Val; }
    241     PtrTy release() const { return Val; }
    242     PtrTy take() const { return Val; }
    243     template <typename T> T *takeAs() { return static_cast<T*>(get()); }
    244 
    245     void set(PtrTy V) { Val = V; }
    246 
    247     const ActionResult &operator=(PtrTy RHS) {
    248       Val = RHS;
    249       Invalid = false;
    250       return *this;
    251     }
    252   };
    253 
    254   // This ActionResult partial specialization places the "invalid"
    255   // flag into the low bit of the pointer.
    256   template<typename PtrTy>
    257   class ActionResult<PtrTy, true> {
    258     // A pointer whose low bit is 1 if this result is invalid, 0
    259     // otherwise.
    260     uintptr_t PtrWithInvalid;
    261     typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits;
    262   public:
    263     ActionResult(bool Invalid = false)
    264       : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { }
    265 
    266     ActionResult(PtrTy V) {
    267       void *VP = PtrTraits::getAsVoidPointer(V);
    268       PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
    269       assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
    270     }
    271     ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { }
    272 
    273     // These two overloads prevent void* -> bool conversions.
    274     ActionResult(const void *);
    275     ActionResult(volatile void *);
    276 
    277     bool isInvalid() const { return PtrWithInvalid & 0x01; }
    278     bool isUsable() const { return PtrWithInvalid > 0x01; }
    279 
    280     PtrTy get() const {
    281       void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
    282       return PtrTraits::getFromVoidPointer(VP);
    283     }
    284     PtrTy take() const { return get(); }
    285     PtrTy release() const { return get(); }
    286     template <typename T> T *takeAs() { return static_cast<T*>(get()); }
    287 
    288     void set(PtrTy V) {
    289       void *VP = PtrTraits::getAsVoidPointer(V);
    290       PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
    291       assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
    292     }
    293 
    294     const ActionResult &operator=(PtrTy RHS) {
    295       void *VP = PtrTraits::getAsVoidPointer(RHS);
    296       PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
    297       assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
    298       return *this;
    299     }
    300   };
    301 
    302   /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns
    303   /// the individual pointers, not the array holding them.
    304   template <typename PtrTy> class ASTMultiPtr;
    305 
    306   template <class PtrTy>
    307   class ASTMultiPtr {
    308     PtrTy *Nodes;
    309     unsigned Count;
    310 
    311   public:
    312     // Normal copying implicitly defined
    313     ASTMultiPtr() : Nodes(0), Count(0) {}
    314     explicit ASTMultiPtr(Sema &) : Nodes(0), Count(0) {}
    315     ASTMultiPtr(Sema &, PtrTy *nodes, unsigned count)
    316       : Nodes(nodes), Count(count) {}
    317     // Fake mover in Parse/AstGuard.h needs this:
    318     ASTMultiPtr(PtrTy *nodes, unsigned count) : Nodes(nodes), Count(count) {}
    319 
    320     /// Access to the raw pointers.
    321     PtrTy *get() const { return Nodes; }
    322 
    323     /// Access to the count.
    324     unsigned size() const { return Count; }
    325 
    326     PtrTy *release() {
    327       return Nodes;
    328     }
    329   };
    330 
    331   class ParsedTemplateArgument;
    332 
    333   class ASTTemplateArgsPtr {
    334     ParsedTemplateArgument *Args;
    335     mutable unsigned Count;
    336 
    337   public:
    338     ASTTemplateArgsPtr(Sema &actions, ParsedTemplateArgument *args,
    339                        unsigned count) :
    340       Args(args), Count(count) { }
    341 
    342     // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
    343     ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
    344       Args(Other.Args), Count(Other.Count) {
    345     }
    346 
    347     // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
    348     ASTTemplateArgsPtr& operator=(ASTTemplateArgsPtr &Other)  {
    349       Args = Other.Args;
    350       Count = Other.Count;
    351       return *this;
    352     }
    353 
    354     ParsedTemplateArgument *getArgs() const { return Args; }
    355     unsigned size() const { return Count; }
    356 
    357     void reset(ParsedTemplateArgument *args, unsigned count) {
    358       Args = args;
    359       Count = count;
    360     }
    361 
    362     const ParsedTemplateArgument &operator[](unsigned Arg) const;
    363 
    364     ParsedTemplateArgument *release() const {
    365       return Args;
    366     }
    367   };
    368 
    369   /// \brief A small vector that owns a set of AST nodes.
    370   template <class PtrTy, unsigned N = 8>
    371   class ASTOwningVector : public llvm::SmallVector<PtrTy, N> {
    372     ASTOwningVector(ASTOwningVector &); // do not implement
    373     ASTOwningVector &operator=(ASTOwningVector &); // do not implement
    374 
    375   public:
    376     explicit ASTOwningVector(Sema &Actions)
    377     { }
    378 
    379     PtrTy *take() {
    380       return &this->front();
    381     }
    382 
    383     template<typename T> T **takeAs() { return reinterpret_cast<T**>(take()); }
    384   };
    385 
    386   /// An opaque type for threading parsed type information through the
    387   /// parser.
    388   typedef OpaquePtr<QualType> ParsedType;
    389   typedef UnionOpaquePtr<QualType> UnionParsedType;
    390 
    391   /// A SmallVector of statements, with stack size 32 (as that is the only one
    392   /// used.)
    393   typedef ASTOwningVector<Stmt*, 32> StmtVector;
    394   /// A SmallVector of expressions, with stack size 12 (the maximum used.)
    395   typedef ASTOwningVector<Expr*, 12> ExprVector;
    396   /// A SmallVector of types.
    397   typedef ASTOwningVector<ParsedType, 12> TypeVector;
    398 
    399   template <class T, unsigned N> inline
    400   ASTMultiPtr<T> move_arg(ASTOwningVector<T, N> &vec) {
    401     return ASTMultiPtr<T>(vec.take(), vec.size());
    402   }
    403 
    404   // These versions are hopefully no-ops.
    405   template <class T, bool C>
    406   inline ActionResult<T,C> move(ActionResult<T,C> &ptr) {
    407     return ptr;
    408   }
    409 
    410   template <class T> inline
    411   ASTMultiPtr<T>& move(ASTMultiPtr<T> &ptr) {
    412     return ptr;
    413   }
    414 
    415   // We can re-use the low bit of expression, statement, base, and
    416   // member-initializer pointers for the "invalid" flag of
    417   // ActionResult.
    418   template<> struct IsResultPtrLowBitFree<Expr*> {
    419     static const bool value = true;
    420   };
    421   template<> struct IsResultPtrLowBitFree<Stmt*> {
    422     static const bool value = true;
    423   };
    424   template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> {
    425     static const bool value = true;
    426   };
    427   template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> {
    428     static const bool value = true;
    429   };
    430 
    431   typedef ActionResult<Expr*> ExprResult;
    432   typedef ActionResult<Stmt*> StmtResult;
    433   typedef ActionResult<ParsedType> TypeResult;
    434   typedef ActionResult<CXXBaseSpecifier*> BaseResult;
    435   typedef ActionResult<CXXCtorInitializer*> MemInitResult;
    436 
    437   typedef ActionResult<Decl*> DeclResult;
    438   typedef OpaquePtr<TemplateName> ParsedTemplateTy;
    439 
    440   inline Expr *move(Expr *E) { return E; }
    441   inline Stmt *move(Stmt *S) { return S; }
    442 
    443   typedef ASTMultiPtr<Expr*> MultiExprArg;
    444   typedef ASTMultiPtr<Stmt*> MultiStmtArg;
    445   typedef ASTMultiPtr<ParsedType> MultiTypeArg;
    446   typedef ASTMultiPtr<TemplateParameterList*> MultiTemplateParamsArg;
    447 
    448   inline ExprResult ExprError() { return ExprResult(true); }
    449   inline StmtResult StmtError() { return StmtResult(true); }
    450 
    451   inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
    452   inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
    453 
    454   inline ExprResult ExprEmpty() { return ExprResult(false); }
    455   inline StmtResult StmtEmpty() { return StmtResult(false); }
    456 
    457   inline Expr *AssertSuccess(ExprResult R) {
    458     assert(!R.isInvalid() && "operation was asserted to never fail!");
    459     return R.get();
    460   }
    461 
    462   inline Stmt *AssertSuccess(StmtResult R) {
    463     assert(!R.isInvalid() && "operation was asserted to never fail!");
    464     return R.get();
    465   }
    466 }
    467 
    468 #endif
    469