Counter Strike : Global Offensive Source Code

289 lines
9.9 KiB

  1. //===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- 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 isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
  11. // and dyn_cast_or_null<X>() templates.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_SUPPORT_CASTING_H
  15. #define LLVM_SUPPORT_CASTING_H
  16. #include "llvm/Support/type_traits.h"
  17. #include <cassert>
  18. namespace llvm {
  19. //===----------------------------------------------------------------------===//
  20. // isa<x> Support Templates
  21. //===----------------------------------------------------------------------===//
  22. // Define a template that can be specialized by smart pointers to reflect the
  23. // fact that they are automatically dereferenced, and are not involved with the
  24. // template selection process... the default implementation is a noop.
  25. //
  26. template<typename From> struct simplify_type {
  27. typedef From SimpleType; // The real type this represents...
  28. // An accessor to get the real value...
  29. static SimpleType &getSimplifiedValue(From &Val) { return Val; }
  30. };
  31. template<typename From> struct simplify_type<const From> {
  32. typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
  33. typedef typename add_const_past_pointer<NonConstSimpleType>::type
  34. SimpleType;
  35. typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
  36. RetType;
  37. static RetType getSimplifiedValue(const From& Val) {
  38. return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
  39. }
  40. };
  41. // The core of the implementation of isa<X> is here; To and From should be
  42. // the names of classes. This template can be specialized to customize the
  43. // implementation of isa<> without rewriting it from scratch.
  44. template <typename To, typename From, typename Enabler = void>
  45. struct isa_impl {
  46. static inline bool doit(const From &Val) {
  47. return To::classof(&Val);
  48. }
  49. };
  50. /// \brief Always allow upcasts, and perform no dynamic check for them.
  51. template <typename To, typename From>
  52. struct isa_impl<To, From,
  53. typename enable_if<
  54. llvm::is_base_of<To, From>
  55. >::type
  56. > {
  57. static inline bool doit(const From &) { return true; }
  58. };
  59. template <typename To, typename From> struct isa_impl_cl {
  60. static inline bool doit(const From &Val) {
  61. return isa_impl<To, From>::doit(Val);
  62. }
  63. };
  64. template <typename To, typename From> struct isa_impl_cl<To, const From> {
  65. static inline bool doit(const From &Val) {
  66. return isa_impl<To, From>::doit(Val);
  67. }
  68. };
  69. template <typename To, typename From> struct isa_impl_cl<To, From*> {
  70. static inline bool doit(const From *Val) {
  71. assert(Val && "isa<> used on a null pointer");
  72. return isa_impl<To, From>::doit(*Val);
  73. }
  74. };
  75. template <typename To, typename From> struct isa_impl_cl<To, From*const> {
  76. static inline bool doit(const From *Val) {
  77. assert(Val && "isa<> used on a null pointer");
  78. return isa_impl<To, From>::doit(*Val);
  79. }
  80. };
  81. template <typename To, typename From> struct isa_impl_cl<To, const From*> {
  82. static inline bool doit(const From *Val) {
  83. assert(Val && "isa<> used on a null pointer");
  84. return isa_impl<To, From>::doit(*Val);
  85. }
  86. };
  87. template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
  88. static inline bool doit(const From *Val) {
  89. assert(Val && "isa<> used on a null pointer");
  90. return isa_impl<To, From>::doit(*Val);
  91. }
  92. };
  93. template<typename To, typename From, typename SimpleFrom>
  94. struct isa_impl_wrap {
  95. // When From != SimplifiedType, we can simplify the type some more by using
  96. // the simplify_type template.
  97. static bool doit(const From &Val) {
  98. return isa_impl_wrap<To, SimpleFrom,
  99. typename simplify_type<SimpleFrom>::SimpleType>::doit(
  100. simplify_type<const From>::getSimplifiedValue(Val));
  101. }
  102. };
  103. template<typename To, typename FromTy>
  104. struct isa_impl_wrap<To, FromTy, FromTy> {
  105. // When From == SimpleType, we are as simple as we are going to get.
  106. static bool doit(const FromTy &Val) {
  107. return isa_impl_cl<To,FromTy>::doit(Val);
  108. }
  109. };
  110. // isa<X> - Return true if the parameter to the template is an instance of the
  111. // template type argument. Used like this:
  112. //
  113. // if (isa<Type>(myVal)) { ... }
  114. //
  115. template <class X, class Y>
  116. inline bool isa(const Y &Val) {
  117. return isa_impl_wrap<X, const Y,
  118. typename simplify_type<const Y>::SimpleType>::doit(Val);
  119. }
  120. //===----------------------------------------------------------------------===//
  121. // cast<x> Support Templates
  122. //===----------------------------------------------------------------------===//
  123. template<class To, class From> struct cast_retty;
  124. // Calculate what type the 'cast' function should return, based on a requested
  125. // type of To and a source type of From.
  126. template<class To, class From> struct cast_retty_impl {
  127. typedef To& ret_type; // Normal case, return Ty&
  128. };
  129. template<class To, class From> struct cast_retty_impl<To, const From> {
  130. typedef const To &ret_type; // Normal case, return Ty&
  131. };
  132. template<class To, class From> struct cast_retty_impl<To, From*> {
  133. typedef To* ret_type; // Pointer arg case, return Ty*
  134. };
  135. template<class To, class From> struct cast_retty_impl<To, const From*> {
  136. typedef const To* ret_type; // Constant pointer arg case, return const Ty*
  137. };
  138. template<class To, class From> struct cast_retty_impl<To, const From*const> {
  139. typedef const To* ret_type; // Constant pointer arg case, return const Ty*
  140. };
  141. template<class To, class From, class SimpleFrom>
  142. struct cast_retty_wrap {
  143. // When the simplified type and the from type are not the same, use the type
  144. // simplifier to reduce the type, then reuse cast_retty_impl to get the
  145. // resultant type.
  146. typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
  147. };
  148. template<class To, class FromTy>
  149. struct cast_retty_wrap<To, FromTy, FromTy> {
  150. // When the simplified type is equal to the from type, use it directly.
  151. typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
  152. };
  153. template<class To, class From>
  154. struct cast_retty {
  155. typedef typename cast_retty_wrap<To, From,
  156. typename simplify_type<From>::SimpleType>::ret_type ret_type;
  157. };
  158. // Ensure the non-simple values are converted using the simplify_type template
  159. // that may be specialized by smart pointers...
  160. //
  161. template<class To, class From, class SimpleFrom> struct cast_convert_val {
  162. // This is not a simple type, use the template to simplify it...
  163. static typename cast_retty<To, From>::ret_type doit(From &Val) {
  164. return cast_convert_val<To, SimpleFrom,
  165. typename simplify_type<SimpleFrom>::SimpleType>::doit(
  166. simplify_type<From>::getSimplifiedValue(Val));
  167. }
  168. };
  169. template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
  170. // This _is_ a simple type, just cast it.
  171. static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
  172. typename cast_retty<To, FromTy>::ret_type Res2
  173. = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
  174. return Res2;
  175. }
  176. };
  177. // cast<X> - Return the argument parameter cast to the specified type. This
  178. // casting operator asserts that the type is correct, so it does not return null
  179. // on failure. It does not allow a null argument (use cast_or_null for that).
  180. // It is typically used like this:
  181. //
  182. // cast<Instruction>(myVal)->getParent()
  183. //
  184. template <class X, class Y>
  185. inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) {
  186. assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
  187. return cast_convert_val<X, const Y,
  188. typename simplify_type<const Y>::SimpleType>::doit(Val);
  189. }
  190. template <class X, class Y>
  191. inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
  192. assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
  193. return cast_convert_val<X, Y,
  194. typename simplify_type<Y>::SimpleType>::doit(Val);
  195. }
  196. template <class X, class Y>
  197. inline typename enable_if<
  198. is_same<Y, typename simplify_type<Y>::SimpleType>,
  199. typename cast_retty<X, Y*>::ret_type
  200. >::type cast(Y *Val) {
  201. assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
  202. return cast_convert_val<X, Y*,
  203. typename simplify_type<Y*>::SimpleType>::doit(Val);
  204. }
  205. // cast_or_null<X> - Functionally identical to cast, except that a null value is
  206. // accepted.
  207. //
  208. template <class X, class Y>
  209. inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
  210. if (Val == 0) return 0;
  211. assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
  212. return cast<X>(Val);
  213. }
  214. // dyn_cast<X> - Return the argument parameter cast to the specified type. This
  215. // casting operator returns null if the argument is of the wrong type, so it can
  216. // be used to test for a type as well as cast if successful. This should be
  217. // used in the context of an if statement like this:
  218. //
  219. // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
  220. //
  221. template <class X, class Y>
  222. inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) {
  223. return isa<X>(Val) ? cast<X>(Val) : 0;
  224. }
  225. template <class X, class Y>
  226. inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
  227. return isa<X>(Val) ? cast<X>(Val) : 0;
  228. }
  229. template <class X, class Y>
  230. inline typename enable_if<
  231. is_same<Y, typename simplify_type<Y>::SimpleType>,
  232. typename cast_retty<X, Y*>::ret_type
  233. >::type dyn_cast(Y *Val) {
  234. return isa<X>(Val) ? cast<X>(Val) : 0;
  235. }
  236. // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
  237. // value is accepted.
  238. //
  239. template <class X, class Y>
  240. inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
  241. return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
  242. }
  243. } // End llvm namespace
  244. #endif