Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

447 lines
15 KiB

  1. //===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- 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 defines the PointerUnion class, which is a discriminated union of
  11. // pointer types.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_ADT_POINTERUNION_H
  15. #define LLVM_ADT_POINTERUNION_H
  16. #include "llvm/ADT/PointerIntPair.h"
  17. namespace llvm {
  18. template <typename T>
  19. struct PointerUnionTypeSelectorReturn {
  20. typedef T Return;
  21. };
  22. /// \brief Get a type based on whether two types are the same or not. For:
  23. /// @code
  24. /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
  25. /// @endcode
  26. /// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
  27. template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
  28. struct PointerUnionTypeSelector {
  29. typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
  30. };
  31. template <typename T, typename RET_EQ, typename RET_NE>
  32. struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
  33. typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
  34. };
  35. template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
  36. struct PointerUnionTypeSelectorReturn<
  37. PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > {
  38. typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return
  39. Return;
  40. };
  41. /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
  42. /// for the two template arguments.
  43. template <typename PT1, typename PT2>
  44. class PointerUnionUIntTraits {
  45. public:
  46. static inline void *getAsVoidPointer(void *P) { return P; }
  47. static inline void *getFromVoidPointer(void *P) { return P; }
  48. enum {
  49. PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
  50. PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
  51. NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
  52. };
  53. };
  54. /// PointerUnion - This implements a discriminated union of two pointer types,
  55. /// and keeps the discriminator bit-mangled into the low bits of the pointer.
  56. /// This allows the implementation to be extremely efficient in space, but
  57. /// permits a very natural and type-safe API.
  58. ///
  59. /// Common use patterns would be something like this:
  60. /// PointerUnion<int*, float*> P;
  61. /// P = (int*)0;
  62. /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
  63. /// X = P.get<int*>(); // ok.
  64. /// Y = P.get<float*>(); // runtime assertion failure.
  65. /// Z = P.get<double*>(); // runtime assertion failure (regardless of tag)
  66. /// P = (float*)0;
  67. /// Y = P.get<float*>(); // ok.
  68. /// X = P.get<int*>(); // runtime assertion failure.
  69. template <typename PT1, typename PT2>
  70. class PointerUnion {
  71. public:
  72. typedef PointerIntPair<void*, 1, bool,
  73. PointerUnionUIntTraits<PT1,PT2> > ValTy;
  74. private:
  75. ValTy Val;
  76. struct IsPT1 {
  77. static const int Num = 0;
  78. };
  79. struct IsPT2 {
  80. static const int Num = 1;
  81. };
  82. template <typename T>
  83. struct UNION_DOESNT_CONTAIN_TYPE { };
  84. public:
  85. PointerUnion() {}
  86. PointerUnion(PT1 V) : Val(
  87. const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
  88. }
  89. PointerUnion(PT2 V) : Val(
  90. const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
  91. }
  92. /// isNull - Return true if the pointer held in the union is null,
  93. /// regardless of which type it is.
  94. bool isNull() const {
  95. // Convert from the void* to one of the pointer types, to make sure that
  96. // we recursively strip off low bits if we have a nested PointerUnion.
  97. return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
  98. }
  99. operator bool() const { return !isNull(); }
  100. /// is<T>() return true if the Union currently holds the type matching T.
  101. template<typename T>
  102. int is() const {
  103. typedef typename
  104. ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1,
  105. ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
  106. UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty;
  107. int TyNo = Ty::Num;
  108. return static_cast<int>(Val.getInt()) == TyNo;
  109. }
  110. /// get<T>() - Return the value of the specified pointer type. If the
  111. /// specified pointer type is incorrect, assert.
  112. template<typename T>
  113. T get() const {
  114. assert(is<T>() && "Invalid accessor called");
  115. return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
  116. }
  117. /// dyn_cast<T>() - If the current value is of the specified pointer type,
  118. /// return it, otherwise return null.
  119. template<typename T>
  120. T dyn_cast() const {
  121. if (is<T>()) return get<T>();
  122. return T();
  123. }
  124. /// \brief If the union is set to the first pointer type get an address
  125. /// pointing to it.
  126. PT1 const *getAddrOfPtr1() const {
  127. return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
  128. }
  129. /// \brief If the union is set to the first pointer type get an address
  130. /// pointing to it.
  131. PT1 *getAddrOfPtr1() {
  132. assert(is<PT1>() && "Val is not the first pointer");
  133. assert(get<PT1>() == Val.getPointer() &&
  134. "Can't get the address because PointerLikeTypeTraits changes the ptr");
  135. return (PT1 *)Val.getAddrOfPointer();
  136. }
  137. /// Assignment operators - Allow assigning into this union from either
  138. /// pointer type, setting the discriminator to remember what it came from.
  139. const PointerUnion &operator=(const PT1 &RHS) {
  140. Val.initWithPointer(
  141. const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
  142. return *this;
  143. }
  144. const PointerUnion &operator=(const PT2 &RHS) {
  145. Val.setPointerAndInt(
  146. const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
  147. 1);
  148. return *this;
  149. }
  150. void *getOpaqueValue() const { return Val.getOpaqueValue(); }
  151. static inline PointerUnion getFromOpaqueValue(void *VP) {
  152. PointerUnion V;
  153. V.Val = ValTy::getFromOpaqueValue(VP);
  154. return V;
  155. }
  156. };
  157. // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
  158. // # low bits available = min(PT1bits,PT2bits)-1.
  159. template<typename PT1, typename PT2>
  160. class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > {
  161. public:
  162. static inline void *
  163. getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
  164. return P.getOpaqueValue();
  165. }
  166. static inline PointerUnion<PT1, PT2>
  167. getFromVoidPointer(void *P) {
  168. return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
  169. }
  170. // The number of bits available are the min of the two pointer types.
  171. enum {
  172. NumLowBitsAvailable =
  173. PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy>
  174. ::NumLowBitsAvailable
  175. };
  176. };
  177. /// PointerUnion3 - This is a pointer union of three pointer types. See
  178. /// documentation for PointerUnion for usage.
  179. template <typename PT1, typename PT2, typename PT3>
  180. class PointerUnion3 {
  181. public:
  182. typedef PointerUnion<PT1, PT2> InnerUnion;
  183. typedef PointerUnion<InnerUnion, PT3> ValTy;
  184. private:
  185. ValTy Val;
  186. struct IsInnerUnion {
  187. ValTy Val;
  188. IsInnerUnion(ValTy val) : Val(val) { }
  189. template<typename T>
  190. int is() const {
  191. return Val.template is<InnerUnion>() &&
  192. Val.template get<InnerUnion>().template is<T>();
  193. }
  194. template<typename T>
  195. T get() const {
  196. return Val.template get<InnerUnion>().template get<T>();
  197. }
  198. };
  199. struct IsPT3 {
  200. ValTy Val;
  201. IsPT3(ValTy val) : Val(val) { }
  202. template<typename T>
  203. int is() const {
  204. return Val.template is<T>();
  205. }
  206. template<typename T>
  207. T get() const {
  208. return Val.template get<T>();
  209. }
  210. };
  211. public:
  212. PointerUnion3() {}
  213. PointerUnion3(PT1 V) {
  214. Val = InnerUnion(V);
  215. }
  216. PointerUnion3(PT2 V) {
  217. Val = InnerUnion(V);
  218. }
  219. PointerUnion3(PT3 V) {
  220. Val = V;
  221. }
  222. /// isNull - Return true if the pointer held in the union is null,
  223. /// regardless of which type it is.
  224. bool isNull() const { return Val.isNull(); }
  225. operator bool() const { return !isNull(); }
  226. /// is<T>() return true if the Union currently holds the type matching T.
  227. template<typename T>
  228. int is() const {
  229. // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
  230. typedef typename
  231. ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
  232. ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
  233. >::Return Ty;
  234. return Ty(Val).template is<T>();
  235. }
  236. /// get<T>() - Return the value of the specified pointer type. If the
  237. /// specified pointer type is incorrect, assert.
  238. template<typename T>
  239. T get() const {
  240. assert(is<T>() && "Invalid accessor called");
  241. // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
  242. typedef typename
  243. ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
  244. ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
  245. >::Return Ty;
  246. return Ty(Val).template get<T>();
  247. }
  248. /// dyn_cast<T>() - If the current value is of the specified pointer type,
  249. /// return it, otherwise return null.
  250. template<typename T>
  251. T dyn_cast() const {
  252. if (is<T>()) return get<T>();
  253. return T();
  254. }
  255. /// Assignment operators - Allow assigning into this union from either
  256. /// pointer type, setting the discriminator to remember what it came from.
  257. const PointerUnion3 &operator=(const PT1 &RHS) {
  258. Val = InnerUnion(RHS);
  259. return *this;
  260. }
  261. const PointerUnion3 &operator=(const PT2 &RHS) {
  262. Val = InnerUnion(RHS);
  263. return *this;
  264. }
  265. const PointerUnion3 &operator=(const PT3 &RHS) {
  266. Val = RHS;
  267. return *this;
  268. }
  269. void *getOpaqueValue() const { return Val.getOpaqueValue(); }
  270. static inline PointerUnion3 getFromOpaqueValue(void *VP) {
  271. PointerUnion3 V;
  272. V.Val = ValTy::getFromOpaqueValue(VP);
  273. return V;
  274. }
  275. };
  276. // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
  277. // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
  278. template<typename PT1, typename PT2, typename PT3>
  279. class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > {
  280. public:
  281. static inline void *
  282. getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
  283. return P.getOpaqueValue();
  284. }
  285. static inline PointerUnion3<PT1, PT2, PT3>
  286. getFromVoidPointer(void *P) {
  287. return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
  288. }
  289. // The number of bits available are the min of the two pointer types.
  290. enum {
  291. NumLowBitsAvailable =
  292. PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy>
  293. ::NumLowBitsAvailable
  294. };
  295. };
  296. /// PointerUnion4 - This is a pointer union of four pointer types. See
  297. /// documentation for PointerUnion for usage.
  298. template <typename PT1, typename PT2, typename PT3, typename PT4>
  299. class PointerUnion4 {
  300. public:
  301. typedef PointerUnion<PT1, PT2> InnerUnion1;
  302. typedef PointerUnion<PT3, PT4> InnerUnion2;
  303. typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
  304. private:
  305. ValTy Val;
  306. public:
  307. PointerUnion4() {}
  308. PointerUnion4(PT1 V) {
  309. Val = InnerUnion1(V);
  310. }
  311. PointerUnion4(PT2 V) {
  312. Val = InnerUnion1(V);
  313. }
  314. PointerUnion4(PT3 V) {
  315. Val = InnerUnion2(V);
  316. }
  317. PointerUnion4(PT4 V) {
  318. Val = InnerUnion2(V);
  319. }
  320. /// isNull - Return true if the pointer held in the union is null,
  321. /// regardless of which type it is.
  322. bool isNull() const { return Val.isNull(); }
  323. operator bool() const { return !isNull(); }
  324. /// is<T>() return true if the Union currently holds the type matching T.
  325. template<typename T>
  326. int is() const {
  327. // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
  328. typedef typename
  329. ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
  330. ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
  331. >::Return Ty;
  332. return Val.template is<Ty>() &&
  333. Val.template get<Ty>().template is<T>();
  334. }
  335. /// get<T>() - Return the value of the specified pointer type. If the
  336. /// specified pointer type is incorrect, assert.
  337. template<typename T>
  338. T get() const {
  339. assert(is<T>() && "Invalid accessor called");
  340. // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
  341. typedef typename
  342. ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
  343. ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
  344. >::Return Ty;
  345. return Val.template get<Ty>().template get<T>();
  346. }
  347. /// dyn_cast<T>() - If the current value is of the specified pointer type,
  348. /// return it, otherwise return null.
  349. template<typename T>
  350. T dyn_cast() const {
  351. if (is<T>()) return get<T>();
  352. return T();
  353. }
  354. /// Assignment operators - Allow assigning into this union from either
  355. /// pointer type, setting the discriminator to remember what it came from.
  356. const PointerUnion4 &operator=(const PT1 &RHS) {
  357. Val = InnerUnion1(RHS);
  358. return *this;
  359. }
  360. const PointerUnion4 &operator=(const PT2 &RHS) {
  361. Val = InnerUnion1(RHS);
  362. return *this;
  363. }
  364. const PointerUnion4 &operator=(const PT3 &RHS) {
  365. Val = InnerUnion2(RHS);
  366. return *this;
  367. }
  368. const PointerUnion4 &operator=(const PT4 &RHS) {
  369. Val = InnerUnion2(RHS);
  370. return *this;
  371. }
  372. void *getOpaqueValue() const { return Val.getOpaqueValue(); }
  373. static inline PointerUnion4 getFromOpaqueValue(void *VP) {
  374. PointerUnion4 V;
  375. V.Val = ValTy::getFromOpaqueValue(VP);
  376. return V;
  377. }
  378. };
  379. // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
  380. // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
  381. template<typename PT1, typename PT2, typename PT3, typename PT4>
  382. class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4> > {
  383. public:
  384. static inline void *
  385. getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
  386. return P.getOpaqueValue();
  387. }
  388. static inline PointerUnion4<PT1, PT2, PT3, PT4>
  389. getFromVoidPointer(void *P) {
  390. return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
  391. }
  392. // The number of bits available are the min of the two pointer types.
  393. enum {
  394. NumLowBitsAvailable =
  395. PointerLikeTypeTraits<typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>
  396. ::NumLowBitsAvailable
  397. };
  398. };
  399. }
  400. #endif