X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FPointerUnion.h;h=a9e86d22002de7f1b5c57b3a039ad2c809d6439e;hb=2430973fb657eb84dfbacb1e8886d3a29190e0b5;hp=975ba8a5f5277c11ea7eb71f00f145daaaadc203;hpb=128ccbb8e5e142d4ec6c9afb4160b74f76cb3064;p=oota-llvm.git diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 975ba8a5f52..a9e86d22002 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -19,29 +19,6 @@ namespace llvm { - /// \brief Statically get an integer for a type. For: - /// @code - /// PointerUnionTypeNum::template NumFor::Result - /// @endcode - /// Result will be 0 if T is PT1, 1 if it is PT2, and -1 otherwise. - template - struct PointerUnionTypeNum { - private: - struct IsNeither { char x; }; - struct IsPT1 { char x[2]; }; - struct IsPT2 { char x[3]; }; - - static IsPT1 determine(PT1 *P); - static IsPT2 determine(PT2 *P); - static IsNeither determine(...); - - public: - template - struct NumFor { - static const int Result = (int)sizeof(determine((T*)0)) - 2; - }; - }; - template struct PointerUnionTypeSelectorReturn { typedef T Return; @@ -77,8 +54,8 @@ namespace llvm { static inline void *getAsVoidPointer(void *P) { return P; } static inline void *getFromVoidPointer(void *P) { return P; } enum { - PT1BitsAv = PointerLikeTypeTraits::NumLowBitsAvailable, - PT2BitsAv = PointerLikeTypeTraits::NumLowBitsAvailable, + PT1BitsAv = (int)(PointerLikeTypeTraits::NumLowBitsAvailable), + PT2BitsAv = (int)(PointerLikeTypeTraits::NumLowBitsAvailable), NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv }; }; @@ -105,6 +82,16 @@ namespace llvm { PointerUnionUIntTraits > ValTy; private: ValTy Val; + + struct IsPT1 { + static const int Num = 0; + }; + struct IsPT2 { + static const int Num = 1; + }; + template + struct UNION_DOESNT_CONTAIN_TYPE { }; + public: PointerUnion() {} @@ -121,16 +108,21 @@ namespace llvm { /// isNull - Return true if the pointer held in the union is null, /// regardless of which type it is. - bool isNull() const { return Val.getPointer() == 0; } + bool isNull() const { + // Convert from the void* to one of the pointer types, to make sure that + // we recursively strip off low bits if we have a nested PointerUnion. + return !PointerLikeTypeTraits::getFromVoidPointer(Val.getPointer()); + } operator bool() const { return !isNull(); } /// is() return true if the Union currently holds the type matching T. template int is() const { - static const int TyNo = - ::llvm::PointerUnionTypeNum::template NumFor::Result; - char TYPE_IS_NOT_IN_UNION[TyNo*2+1]; // statically check the type. - (void)TYPE_IS_NOT_IN_UNION; + typedef typename + ::llvm::PointerUnionTypeSelector > >::Return Ty; + int TyNo = Ty::Num; return static_cast(Val.getInt()) == TyNo; } @@ -150,16 +142,19 @@ namespace llvm { return T(); } - /// \brief If the union is set to the first pointer type we can get an - /// address pointing to it. - template - PT1 const *getAddrOf() const { + /// \brief If the union is set to the first pointer type get an address + /// pointing to it. + PT1 const *getAddrOfPtr1() const { + return const_cast(this)->getAddrOfPtr1(); + } + + /// \brief If the union is set to the first pointer type get an address + /// pointing to it. + PT1 *getAddrOfPtr1() { assert(is() && "Val is not the first pointer"); assert(get() == Val.getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"); - T const *can_only_get_address_of_first_pointer_type - = reinterpret_cast(Val.getAddrOfPointer()); - return can_only_get_address_of_first_pointer_type; + return (PT1 *)Val.getAddrOfPointer(); } /// Assignment operators - Allow assigning into this union from either @@ -271,7 +266,7 @@ namespace llvm { ::llvm::PointerUnionTypeSelector >::Return Ty; - return Ty(Val).is(); + return Ty(Val).template is(); } /// get() - Return the value of the specified pointer type. If the @@ -284,7 +279,7 @@ namespace llvm { ::llvm::PointerUnionTypeSelector >::Return Ty; - return Ty(Val).get(); + return Ty(Val).template get(); } /// dyn_cast() - If the current value is of the specified pointer type,