PointerUnion.h revision 37c286c18128cce7f52654876a5a104150be4b79
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. 57f54229192c22559389b0ef47e731fd628db963c5Chris Lattner /// Z = P.get<double*>(); // runtime assertion failure (regardless of tag) 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) { 7241222823db11107834414a378525bb21493d3a1fDouglas Gregor Val.setPointer( 7341222823db11107834414a378525bb21493d3a1fDouglas Gregor const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))); 742491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(0); 752491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 762491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnion(PT2 V) { 7741222823db11107834414a378525bb21493d3a1fDouglas Gregor Val.setPointer( 7841222823db11107834414a378525bb21493d3a1fDouglas Gregor const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V))); 792491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(1); 802491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 812491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 823a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// isNull - Return true if the pointer help in the union is null, 833a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// regardless of which type it is. 84ba315c1ee7bef78c6824441fe6c1761596ec9880Chris Lattner bool isNull() const { return Val.getPointer() == 0; } 85e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner operator bool() const { return !isNull(); } 86e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 873a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// is<T>() return true if the Union currently holds the type matching T. 882491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template<typename T> 892491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner int is() const { 90e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0); 91e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner assert(TyNo != -1 && "Type query could never succeed on PointerUnion!"); 9237c286c18128cce7f52654876a5a104150be4b79Sebastian Redl return static_cast<int>(Val.getInt()) == TyNo; 932491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 943a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner 953a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// get<T>() - Return the value of the specified pointer type. If the 963a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// specified pointer type is incorrect, assert. 972491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template<typename T> 982491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner T get() const { 992491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner assert(is<T>() && "Invalid accessor called"); 100e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer()); 1012491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1022491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 1033a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// dyn_cast<T>() - If the current value is of the specified pointer type, 1043a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// return it, otherwise return null. 1053a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner template<typename T> 1063a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner T dyn_cast() const { 107e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (is<T>()) return get<T>(); 1083a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner return T(); 1093a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner } 1103a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner 1113a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// Assignment operators - Allow assigning into this union from either 1123a9fe06bfe30da6fb1e0a540f05877c3640c7335Chris Lattner /// pointer type, setting the discriminator to remember what it came from. 1132491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner const PointerUnion &operator=(const PT1 &RHS) { 11441222823db11107834414a378525bb21493d3a1fDouglas Gregor Val.setPointer( 11541222823db11107834414a378525bb21493d3a1fDouglas Gregor const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS))); 1162491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(0); 1172491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return *this; 1182491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1192491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner const PointerUnion &operator=(const PT2 &RHS) { 12041222823db11107834414a378525bb21493d3a1fDouglas Gregor Val.setPointer( 12141222823db11107834414a378525bb21493d3a1fDouglas Gregor const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS))); 1222491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner Val.setInt(1); 1232491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return *this; 1242491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1252491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 1262491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner void *getOpaqueValue() const { return Val.getOpaqueValue(); } 1272491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static PointerUnion getFromOpaqueValue(void *VP) { 1282491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner PointerUnion V; 1292491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner V.Val = ValTy::getFromOpaqueValue(VP); 1302491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return V; 1312491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1322491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 1332491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 134e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has 1352491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner // # low bits available = min(PT1bits,PT2bits)-1. 1362491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner template<typename PT1, typename PT2> 1372491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > { 1382491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner public: 1392491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static inline void * 1402491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner getAsVoidPointer(const PointerUnion<PT1, PT2> &P) { 1412491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return P.getOpaqueValue(); 1422491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1432491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner static inline PointerUnion<PT1, PT2> 1442491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner getFromVoidPointer(void *P) { 1452491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner return PointerUnion<PT1, PT2>::getFromOpaqueValue(P); 1462491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner } 1472491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 1482491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner // The number of bits available are the min of the two pointer types. 1492491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner enum { 1502491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner NumLowBitsAvailable = 151e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy> 152e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner ::NumLowBitsAvailable 153e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner }; 154e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner }; 155e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 156e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 157e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// PointerUnion3 - This is a pointer union of three pointer types. See 158e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// documentation for PointerUnion for usage. 159e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template <typename PT1, typename PT2, typename PT3> 160e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner class PointerUnion3 { 161e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner public: 162e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner typedef PointerUnion<PT1, PT2> InnerUnion; 163e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner typedef PointerUnion<InnerUnion, PT3> ValTy; 164e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner private: 165e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner ValTy Val; 166e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner public: 167e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3() {} 168e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 169e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3(PT1 V) { 170e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(V); 171e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 172e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3(PT2 V) { 173e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(V); 174e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 175e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3(PT3 V) { 176e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = V; 177e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 178e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 179e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// isNull - Return true if the pointer help in the union is null, 180e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// regardless of which type it is. 181e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner bool isNull() const { return Val.isNull(); } 182e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner operator bool() const { return !isNull(); } 183e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 184e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// is<T>() return true if the Union currently holds the type matching T. 185e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename T> 186e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner int is() const { 187e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Is it PT1/PT2? 188e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) 189a7425d7fde61c2207a4467464df90b5e3e58a769Douglas Gregor return Val.is<InnerUnion>() && Val.get<InnerUnion>().is<T>(); 190da84b25b13f05b94c6c9478b1bc552054756759eDouglas Gregor return Val.is<T>(); 191e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 192e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 193e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// get<T>() - Return the value of the specified pointer type. If the 194e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// specified pointer type is incorrect, assert. 195e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename T> 196e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner T get() const { 197e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner assert(is<T>() && "Invalid accessor called"); 1982048cdb08ef6ad04bd1baf52886605d455236eb7Douglas Gregor // Is it PT1/PT2? 1992048cdb08ef6ad04bd1baf52886605d455236eb7Douglas Gregor if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) 2002048cdb08ef6ad04bd1baf52886605d455236eb7Douglas Gregor return Val.get<InnerUnion>().get<T>(); 2012048cdb08ef6ad04bd1baf52886605d455236eb7Douglas Gregor 2022048cdb08ef6ad04bd1baf52886605d455236eb7Douglas Gregor return Val.get<T>(); 203e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 204e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 205e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// dyn_cast<T>() - If the current value is of the specified pointer type, 206e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// return it, otherwise return null. 207e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename T> 208e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner T dyn_cast() const { 209e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner if (is<T>()) return get<T>(); 210e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return T(); 211e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 212e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 213e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// Assignment operators - Allow assigning into this union from either 214e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner /// pointer type, setting the discriminator to remember what it came from. 215e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner const PointerUnion3 &operator=(const PT1 &RHS) { 216e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(RHS); 217e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return *this; 218e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 219e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner const PointerUnion3 &operator=(const PT2 &RHS) { 220e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = InnerUnion(RHS); 221e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return *this; 222e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 223e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner const PointerUnion3 &operator=(const PT3 &RHS) { 224e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner Val = RHS; 225e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return *this; 226e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 227e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 228e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner void *getOpaqueValue() const { return Val.getOpaqueValue(); } 229e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static PointerUnion3 getFromOpaqueValue(void *VP) { 230e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerUnion3 V; 231e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner V.Val = ValTy::getFromOpaqueValue(VP); 232e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return V; 233e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 234e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner }; 235e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 236e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has 237e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // # low bits available = min(PT1bits,PT2bits,PT2bits)-2. 238e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner template<typename PT1, typename PT2, typename PT3> 239e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > { 240e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner public: 241e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline void * 242e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) { 243e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return P.getOpaqueValue(); 244e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 245e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner static inline PointerUnion3<PT1, PT2, PT3> 246e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner getFromVoidPointer(void *P) { 247e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P); 248e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner } 249e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner 250e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner // The number of bits available are the min of the two pointer types. 251e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner enum { 252e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner NumLowBitsAvailable = 253e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy> 254e8bc475668ddd2f31f44dd00b042d15b255e1b9eChris Lattner ::NumLowBitsAvailable 2552491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 2562491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner }; 2572491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner} 2582491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner 2592491e4657d95f7ff61fb2a741ba9996e492df515Chris Lattner#endif 260