PointerUnion.h revision e8bc475668ddd2f31f44dd00b042d15b255e1b9e
12491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- C++ -*-===// 22491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// 32491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// The LLVM Compiler Infrastructure 42491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// 52491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// This file is distributed under the University of Illinois Open Source 62491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// License. See LICENSE.TXT for details. 72491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// 82491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner//===----------------------------------------------------------------------===// 92491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// 102491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// This file defines the PointerUnion class, which is a discriminated union of 112491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// pointer types. 122491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner// 132491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner//===----------------------------------------------------------------------===// 142491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 152491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner#ifndef LLVM_ADT_POINTERUNION_H 162491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner#define LLVM_ADT_POINTERUNION_H 172491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 182491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner#include "llvm/ADT/PointerIntPair.h" 192491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 202491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattnernamespace llvm { 212491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 222491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// getPointerUnionTypeNum - If the argument has type PT1* or PT2* return 232491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// false or true respectively. 242491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template <typename PT1, typename PT2> 25e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline int getPointerUnionTypeNum(PT1 *P) { return 0; } 262491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template <typename PT1, typename PT2> 27e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline int getPointerUnionTypeNum(PT2 *P) { return 1; } 28e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template <typename PT1, typename PT2> 29e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline int getPointerUnionTypeNum(...) { return -1; } 302491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 312491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 322491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion 332491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// for the two template arguments. 342491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template <typename PT1, typename PT2> 352491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner class PointerUnionUIntTraits { 362491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner public: 372491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static inline void *getAsVoidPointer(void *P) { return P; } 382491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static inline void *getFromVoidPointer(void *P) { return P; } 392491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner enum { 402491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PT1BitsAv = PointerLikeTypeTraits<PT1>::NumLowBitsAvailable, 412491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PT2BitsAv = PointerLikeTypeTraits<PT2>::NumLowBitsAvailable, 422491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv 432491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 442491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 452491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 462491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// PointerUnion - This implements a discriminated union of two pointer types, 472491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// and keeps the discriminator bit-mangled into the low bits of the pointer. 482491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// This allows the implementation to be extremely efficient in space, but 492491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// permits a very natural and type-safe API. 502491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// 512491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// Common use patterns would be something like this: 522491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// PointerUnion<int*, float*> P; 532491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// P = (int*)0; 542491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0" 552491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// X = P.get<int*>(); // ok. 562491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// Y = P.get<float*>(); // runtime assertion failure. 572491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// Z = P.get<double*>(); // does not compile. 582491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// P = (float*)0; 592491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// Y = P.get<float*>(); // ok. 602491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner /// X = P.get<int*>(); // runtime assertion failure. 612491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template <typename PT1, typename PT2> 622491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner class PointerUnion { 632491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner public: 642491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner typedef PointerIntPair<void*, 1, bool, 652491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnionUIntTraits<PT1,PT2> > ValTy; 662491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner private: 672491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner ValTy Val; 682491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner public: 692491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnion() {} 702491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 712491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnion(PT1 V) { 72e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val.setPointer(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)); 732491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(0); 742491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 752491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnion(PT2 V) { 76e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val.setPointer(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)); 772491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(1); 782491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 792491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 803a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// isNull - Return true if the pointer help in the union is null, 813a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// regardless of which type it is. 82ba315c1ee7bef78c6824441fe6c1761596ec9880Chris Lattner bool isNull() const { return Val.getPointer() == 0; } 83e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner operator bool() const { return !isNull(); } 84e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 853a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// is<T>() return true if the Union currently holds the type matching T. 862491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template<typename T> 872491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner int is() const { 88e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0); 89e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner assert(TyNo != -1 && "Type query could never succeed on PointerUnion!"); 90e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return Val.getInt() == TyNo; 912491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 923a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner 933a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// get<T>() - Return the value of the specified pointer type. If the 943a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// specified pointer type is incorrect, assert. 952491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template<typename T> 962491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner T get() const { 972491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner assert(is<T>() && "Invalid accessor called"); 98e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer()); 992491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1002491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 1013a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// dyn_cast<T>() - If the current value is of the specified pointer type, 1023a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// return it, otherwise return null. 1033a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner template<typename T> 1043a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner T dyn_cast() const { 105e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (is<T>()) return get<T>(); 1063a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner return T(); 1073a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner } 1083a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner 1093a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// Assignment operators - Allow assigning into this union from either 1103a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// pointer type, setting the discriminator to remember what it came from. 1112491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner const PointerUnion &operator=(const PT1 &RHS) { 112e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val.setPointer(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)); 1132491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(0); 1142491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return *this; 1152491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1162491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner const PointerUnion &operator=(const PT2 &RHS) { 117e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val.setPointer(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)); 1182491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(1); 1192491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return *this; 1202491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1212491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 1222491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner void *getOpaqueValue() const { return Val.getOpaqueValue(); } 1232491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static PointerUnion getFromOpaqueValue(void *VP) { 1242491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnion V; 1252491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner V.Val = ValTy::getFromOpaqueValue(VP); 1262491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return V; 1272491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1282491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 1292491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 130e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has 1312491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner // # low bits available = min(PT1bits,PT2bits)-1. 1322491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template<typename PT1, typename PT2> 1332491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > { 1342491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner public: 1352491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static inline void * 1362491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner getAsVoidPointer(const PointerUnion<PT1, PT2> &P) { 1372491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return P.getOpaqueValue(); 1382491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1392491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static inline PointerUnion<PT1, PT2> 1402491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner getFromVoidPointer(void *P) { 1412491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return PointerUnion<PT1, PT2>::getFromOpaqueValue(P); 1422491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1432491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 1442491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner // The number of bits available are the min of the two pointer types. 1452491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner enum { 1462491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner NumLowBitsAvailable = 147e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy> 148e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner ::NumLowBitsAvailable 149e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner }; 150e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner }; 151e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 152e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 153e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// PointerUnion3 - This is a pointer union of three pointer types. See 154e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// documentation for PointerUnion for usage. 155e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template <typename PT1, typename PT2, typename PT3> 156e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner class PointerUnion3 { 157e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner public: 158e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner typedef PointerUnion<PT1, PT2> InnerUnion; 159e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner typedef PointerUnion<InnerUnion, PT3> ValTy; 160e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner private: 161e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner ValTy Val; 162e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner public: 163e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3() {} 164e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 165e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3(PT1 V) { 166e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(V); 167e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 168e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3(PT2 V) { 169e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(V); 170e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 171e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3(PT3 V) { 172e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = V; 173e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 174e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 175e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// isNull - Return true if the pointer help in the union is null, 176e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// regardless of which type it is. 177e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner bool isNull() const { return Val.isNull(); } 178e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner operator bool() const { return !isNull(); } 179e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 180e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// is<T>() return true if the Union currently holds the type matching T. 181e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename T> 182e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner int is() const { 183e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Is it PT1/PT2? 184e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) 185e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return Val.get<InnerUnion>().is<T>(); 186e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Must be PT3 or statically invalid. 187e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner assert(Val.is<T>()); 188e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return true; 189e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 190e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 191e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// get<T>() - Return the value of the specified pointer type. If the 192e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// specified pointer type is incorrect, assert. 193e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename T> 194e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner T get() const { 195e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner assert(is<T>() && "Invalid accessor called"); 196e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (Val.is<T>()) 197e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return Val.get<T>(); 198e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return Val.get<InnerUnion>().get<T>(); 199e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 200e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 201e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// dyn_cast<T>() - If the current value is of the specified pointer type, 202e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// return it, otherwise return null. 203e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename T> 204e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner T dyn_cast() const { 205e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (is<T>()) return get<T>(); 206e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return T(); 207e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 208e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 209e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// Assignment operators - Allow assigning into this union from either 210e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// pointer type, setting the discriminator to remember what it came from. 211e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner const PointerUnion3 &operator=(const PT1 &RHS) { 212e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(RHS); 213e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return *this; 214e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 215e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner const PointerUnion3 &operator=(const PT2 &RHS) { 216e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(RHS); 217e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return *this; 218e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 219e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner const PointerUnion3 &operator=(const PT3 &RHS) { 220e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = RHS; 221e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return *this; 222e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 223e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 224e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner void *getOpaqueValue() const { return Val.getOpaqueValue(); } 225e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static PointerUnion3 getFromOpaqueValue(void *VP) { 226e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3 V; 227e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner V.Val = ValTy::getFromOpaqueValue(VP); 228e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return V; 229e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 230e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner }; 231e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 232e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has 233e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // # low bits available = min(PT1bits,PT2bits,PT2bits)-2. 234e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename PT1, typename PT2, typename PT3> 235e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > { 236e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner public: 237e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline void * 238e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) { 239e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return P.getOpaqueValue(); 240e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 241e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline PointerUnion3<PT1, PT2, PT3> 242e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner getFromVoidPointer(void *P) { 243e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P); 244e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 245e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 246e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // The number of bits available are the min of the two pointer types. 247e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner enum { 248e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner NumLowBitsAvailable = 249e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy> 250e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner ::NumLowBitsAvailable 2512491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 2522491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 2532491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner} 2542491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 2552491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner#endif 256