Casting.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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/Compiler.h"
  17. #include "llvm/Support/ErrorHandling.h"
  18. #include "llvm/Support/type_traits.h"
  19. #include <cassert>
  20. namespace llvm {
  21. //===----------------------------------------------------------------------===//
  22. // isa<x> Support Templates
  23. //===----------------------------------------------------------------------===//
  24. // Define a template that can be specialized by smart pointers to reflect the
  25. // fact that they are automatically dereferenced, and are not involved with the
  26. // template selection process... the default implementation is a noop.
  27. //
  28. template<typename From> struct simplify_type {
  29. typedef From SimpleType; // The real type this represents...
  30. // An accessor to get the real value...
  31. static SimpleType &getSimplifiedValue(From &Val) { return Val; }
  32. };
  33. template<typename From> struct simplify_type<const From> {
  34. typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
  35. typedef typename add_const_past_pointer<NonConstSimpleType>::type
  36. SimpleType;
  37. typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
  38. RetType;
  39. static RetType getSimplifiedValue(const From& Val) {
  40. return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
  41. }
  42. };
  43. // The core of the implementation of isa<X> is here; To and From should be
  44. // the names of classes. This template can be specialized to customize the
  45. // implementation of isa<> without rewriting it from scratch.
  46. template <typename To, typename From, typename Enabler = void>
  47. struct isa_impl {
  48. static inline bool doit(const From &Val) {
  49. return To::classof(&Val);
  50. }
  51. };
  52. /// \brief Always allow upcasts, and perform no dynamic check for them.
  53. template <typename To, typename From>
  54. struct isa_impl<
  55. To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
  56. static inline bool doit(const From &) { return true; }
  57. };
  58. template <typename To, typename From> struct isa_impl_cl {
  59. static inline bool doit(const From &Val) {
  60. return isa_impl<To, From>::doit(Val);
  61. }
  62. };
  63. template <typename To, typename From> struct isa_impl_cl<To, const From> {
  64. static inline bool doit(const From &Val) {
  65. return isa_impl<To, From>::doit(Val);
  66. }
  67. };
  68. template <typename To, typename From> struct isa_impl_cl<To, From*> {
  69. static inline bool doit(const From *Val) {
  70. assert(Val && "isa<> used on a null pointer");
  71. return isa_impl<To, From>::doit(*Val);
  72. }
  73. };
  74. template <typename To, typename From> struct isa_impl_cl<To, From*const> {
  75. static inline bool doit(const From *Val) {
  76. assert(Val && "isa<> used on a null pointer");
  77. return isa_impl<To, From>::doit(*Val);
  78. }
  79. };
  80. template <typename To, typename From> struct isa_impl_cl<To, const From*> {
  81. static inline bool doit(const From *Val) {
  82. assert(Val && "isa<> used on a null pointer");
  83. return isa_impl<To, From>::doit(*Val);
  84. }
  85. };
  86. template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
  87. static inline bool doit(const From *Val) {
  88. assert(Val && "isa<> used on a null pointer");
  89. return isa_impl<To, From>::doit(*Val);
  90. }
  91. };
  92. template<typename To, typename From, typename SimpleFrom>
  93. struct isa_impl_wrap {
  94. // When From != SimplifiedType, we can simplify the type some more by using
  95. // the simplify_type template.
  96. static bool doit(const From &Val) {
  97. return isa_impl_wrap<To, SimpleFrom,
  98. typename simplify_type<SimpleFrom>::SimpleType>::doit(
  99. simplify_type<const From>::getSimplifiedValue(Val));
  100. }
  101. };
  102. template<typename To, typename FromTy>
  103. struct isa_impl_wrap<To, FromTy, FromTy> {
  104. // When From == SimpleType, we are as simple as we are going to get.
  105. static bool doit(const FromTy &Val) {
  106. return isa_impl_cl<To,FromTy>::doit(Val);
  107. }
  108. };
  109. // isa<X> - Return true if the parameter to the template is an instance of the
  110. // template type argument. Used like this:
  111. //
  112. // if (isa<Type>(myVal)) { ... }
  113. //
  114. template <class X, class Y>
  115. LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) {
  116. return isa_impl_wrap<X, const Y,
  117. typename simplify_type<const Y>::SimpleType>::doit(Val);
  118. }
  119. //===----------------------------------------------------------------------===//
  120. // cast<x> Support Templates
  121. // //
  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. template <class X> struct is_simple_type {
  178. static const bool value =
  179. std::is_same<X, typename simplify_type<X>::SimpleType>::value;
  180. };
  181. // cast<X> - Return the argument parameter cast to the specified type. This
  182. // casting operator asserts that the type is correct, so it does not return null
  183. // on failure. It does not allow a null argument (use cast_or_null for that).
  184. // It is typically used like this:
  185. //
  186. // cast<Instruction>(myVal)->getParent()
  187. //
  188. template <class X, class Y>
  189. inline typename std::enable_if<!is_simple_type<Y>::value,
  190. typename cast_retty<X, const Y>::ret_type>::type
  191. cast(const Y &Val) {
  192. llvm_cast_assert(X, Val); // HLSL change
  193. return cast_convert_val<
  194. X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
  195. }
  196. template <class X, class Y>
  197. inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
  198. llvm_cast_assert(X, Val); // HLSL change
  199. return cast_convert_val<X, Y,
  200. typename simplify_type<Y>::SimpleType>::doit(Val);
  201. }
  202. template <class X, class Y>
  203. inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
  204. llvm_cast_assert(X, Val); // HLSL change
  205. return cast_convert_val<X, Y*,
  206. typename simplify_type<Y*>::SimpleType>::doit(Val);
  207. }
  208. // cast_or_null<X> - Functionally identical to cast, except that a null value is
  209. // accepted.
  210. //
  211. template <class X, class Y>
  212. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
  213. !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type
  214. cast_or_null(const Y &Val) {
  215. if (!Val)
  216. return nullptr;
  217. llvm_cast_assert(X, Val); // HLSL change
  218. return cast<X>(Val);
  219. }
  220. template <class X, class Y>
  221. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
  222. !is_simple_type<Y>::value, typename cast_retty<X, Y>::ret_type>::type
  223. cast_or_null(Y &Val) {
  224. if (!Val)
  225. return nullptr;
  226. llvm_cast_assert(X, Val); // HLSL change
  227. return cast<X>(Val);
  228. }
  229. template <class X, class Y>
  230. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
  231. cast_or_null(Y *Val) {
  232. if (!Val) return nullptr;
  233. llvm_cast_assert(X, Val); // HLSL change
  234. return cast<X>(Val);
  235. }
  236. // dyn_cast<X> - Return the argument parameter cast to the specified type. This
  237. // casting operator returns null if the argument is of the wrong type, so it can
  238. // be used to test for a type as well as cast if successful. This should be
  239. // used in the context of an if statement like this:
  240. //
  241. // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
  242. //
  243. template <class X, class Y>
  244. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
  245. !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type
  246. dyn_cast(const Y &Val) {
  247. return isa<X>(Val) ? cast<X>(Val) : nullptr;
  248. }
  249. template <class X, class Y>
  250. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type
  251. dyn_cast(Y &Val) {
  252. return isa<X>(Val) ? cast<X>(Val) : nullptr;
  253. }
  254. template <class X, class Y>
  255. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
  256. dyn_cast(Y *Val) {
  257. return isa<X>(Val) ? cast<X>(Val) : nullptr;
  258. }
  259. // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
  260. // value is accepted.
  261. //
  262. template <class X, class Y>
  263. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
  264. !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type
  265. dyn_cast_or_null(const Y &Val) {
  266. return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
  267. }
  268. template <class X, class Y>
  269. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
  270. !is_simple_type<Y>::value, typename cast_retty<X, Y>::ret_type>::type
  271. dyn_cast_or_null(Y &Val) {
  272. return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
  273. }
  274. template <class X, class Y>
  275. LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
  276. dyn_cast_or_null(Y *Val) {
  277. return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
  278. }
  279. } // End llvm namespace
  280. #endif