Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(),
  10. // cast_if_present<X>(), and dyn_cast_if_present<X>() templates.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_SUPPORT_CASTING_H
  15. #define LLVM_SUPPORT_CASTING_H
  16.  
  17. #include "llvm/Support/Compiler.h"
  18. #include "llvm/Support/type_traits.h"
  19. #include <cassert>
  20. #include <memory>
  21. #include <optional>
  22. #include <type_traits>
  23.  
  24. namespace llvm {
  25.  
  26. //===----------------------------------------------------------------------===//
  27. // simplify_type
  28. //===----------------------------------------------------------------------===//
  29.  
  30. /// Define a template that can be specialized by smart pointers to reflect the
  31. /// fact that they are automatically dereferenced, and are not involved with the
  32. /// template selection process...  the default implementation is a noop.
  33. // TODO: rename this and/or replace it with other cast traits.
  34. template <typename From> struct simplify_type {
  35.   using SimpleType = From; // The real type this represents...
  36.  
  37.   // An accessor to get the real value...
  38.   static SimpleType &getSimplifiedValue(From &Val) { return Val; }
  39. };
  40.  
  41. template <typename From> struct simplify_type<const From> {
  42.   using NonConstSimpleType = typename simplify_type<From>::SimpleType;
  43.   using SimpleType = typename add_const_past_pointer<NonConstSimpleType>::type;
  44.   using RetType =
  45.       typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
  46.  
  47.   static RetType getSimplifiedValue(const From &Val) {
  48.     return simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val));
  49.   }
  50. };
  51.  
  52. // TODO: add this namespace once everyone is switched to using the new
  53. //       interface.
  54. // namespace detail {
  55.  
  56. //===----------------------------------------------------------------------===//
  57. // isa_impl
  58. //===----------------------------------------------------------------------===//
  59.  
  60. // The core of the implementation of isa<X> is here; To and From should be
  61. // the names of classes.  This template can be specialized to customize the
  62. // implementation of isa<> without rewriting it from scratch.
  63. template <typename To, typename From, typename Enabler = void> struct isa_impl {
  64.   static inline bool doit(const From &Val) { return To::classof(&Val); }
  65. };
  66.  
  67. // Always allow upcasts, and perform no dynamic check for them.
  68. template <typename To, typename From>
  69. struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> {
  70.   static inline bool doit(const From &) { return true; }
  71. };
  72.  
  73. template <typename To, typename From> struct isa_impl_cl {
  74.   static inline bool doit(const From &Val) {
  75.     return isa_impl<To, From>::doit(Val);
  76.   }
  77. };
  78.  
  79. template <typename To, typename From> struct isa_impl_cl<To, const From> {
  80.   static inline bool doit(const From &Val) {
  81.     return isa_impl<To, From>::doit(Val);
  82.   }
  83. };
  84.  
  85. template <typename To, typename From>
  86. struct isa_impl_cl<To, const std::unique_ptr<From>> {
  87.   static inline bool doit(const std::unique_ptr<From> &Val) {
  88.     assert(Val && "isa<> used on a null pointer");
  89.     return isa_impl_cl<To, From>::doit(*Val);
  90.   }
  91. };
  92.  
  93. template <typename To, typename From> struct isa_impl_cl<To, From *> {
  94.   static inline bool doit(const From *Val) {
  95.     assert(Val && "isa<> used on a null pointer");
  96.     return isa_impl<To, From>::doit(*Val);
  97.   }
  98. };
  99.  
  100. template <typename To, typename From> struct isa_impl_cl<To, From *const> {
  101.   static inline bool doit(const From *Val) {
  102.     assert(Val && "isa<> used on a null pointer");
  103.     return isa_impl<To, From>::doit(*Val);
  104.   }
  105. };
  106.  
  107. template <typename To, typename From> struct isa_impl_cl<To, const From *> {
  108.   static inline bool doit(const From *Val) {
  109.     assert(Val && "isa<> used on a null pointer");
  110.     return isa_impl<To, From>::doit(*Val);
  111.   }
  112. };
  113.  
  114. template <typename To, typename From>
  115. struct isa_impl_cl<To, const From *const> {
  116.   static inline bool doit(const From *Val) {
  117.     assert(Val && "isa<> used on a null pointer");
  118.     return isa_impl<To, From>::doit(*Val);
  119.   }
  120. };
  121.  
  122. template <typename To, typename From, typename SimpleFrom>
  123. struct isa_impl_wrap {
  124.   // When From != SimplifiedType, we can simplify the type some more by using
  125.   // the simplify_type template.
  126.   static bool doit(const From &Val) {
  127.     return isa_impl_wrap<To, SimpleFrom,
  128.                          typename simplify_type<SimpleFrom>::SimpleType>::
  129.         doit(simplify_type<const From>::getSimplifiedValue(Val));
  130.   }
  131. };
  132.  
  133. template <typename To, typename FromTy>
  134. struct isa_impl_wrap<To, FromTy, FromTy> {
  135.   // When From == SimpleType, we are as simple as we are going to get.
  136.   static bool doit(const FromTy &Val) {
  137.     return isa_impl_cl<To, FromTy>::doit(Val);
  138.   }
  139. };
  140.  
  141. //===----------------------------------------------------------------------===//
  142. // cast_retty + cast_retty_impl
  143. //===----------------------------------------------------------------------===//
  144.  
  145. template <class To, class From> struct cast_retty;
  146.  
  147. // Calculate what type the 'cast' function should return, based on a requested
  148. // type of To and a source type of From.
  149. template <class To, class From> struct cast_retty_impl {
  150.   using ret_type = To &; // Normal case, return Ty&
  151. };
  152. template <class To, class From> struct cast_retty_impl<To, const From> {
  153.   using ret_type = const To &; // Normal case, return Ty&
  154. };
  155.  
  156. template <class To, class From> struct cast_retty_impl<To, From *> {
  157.   using ret_type = To *; // Pointer arg case, return Ty*
  158. };
  159.  
  160. template <class To, class From> struct cast_retty_impl<To, const From *> {
  161.   using ret_type = const To *; // Constant pointer arg case, return const Ty*
  162. };
  163.  
  164. template <class To, class From> struct cast_retty_impl<To, const From *const> {
  165.   using ret_type = const To *; // Constant pointer arg case, return const Ty*
  166. };
  167.  
  168. template <class To, class From>
  169. struct cast_retty_impl<To, std::unique_ptr<From>> {
  170. private:
  171.   using PointerType = typename cast_retty_impl<To, From *>::ret_type;
  172.   using ResultType = std::remove_pointer_t<PointerType>;
  173.  
  174. public:
  175.   using ret_type = std::unique_ptr<ResultType>;
  176. };
  177.  
  178. template <class To, class From, class SimpleFrom> struct cast_retty_wrap {
  179.   // When the simplified type and the from type are not the same, use the type
  180.   // simplifier to reduce the type, then reuse cast_retty_impl to get the
  181.   // resultant type.
  182.   using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
  183. };
  184.  
  185. template <class To, class FromTy> struct cast_retty_wrap<To, FromTy, FromTy> {
  186.   // When the simplified type is equal to the from type, use it directly.
  187.   using ret_type = typename cast_retty_impl<To, FromTy>::ret_type;
  188. };
  189.  
  190. template <class To, class From> struct cast_retty {
  191.   using ret_type = typename cast_retty_wrap<
  192.       To, From, typename simplify_type<From>::SimpleType>::ret_type;
  193. };
  194.  
  195. //===----------------------------------------------------------------------===//
  196. // cast_convert_val
  197. //===----------------------------------------------------------------------===//
  198.  
  199. // Ensure the non-simple values are converted using the simplify_type template
  200. // that may be specialized by smart pointers...
  201. //
  202. template <class To, class From, class SimpleFrom> struct cast_convert_val {
  203.   // This is not a simple type, use the template to simplify it...
  204.   static typename cast_retty<To, From>::ret_type doit(const From &Val) {
  205.     return cast_convert_val<To, SimpleFrom,
  206.                             typename simplify_type<SimpleFrom>::SimpleType>::
  207.         doit(simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val)));
  208.   }
  209. };
  210.  
  211. template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> {
  212.   // If it's a reference, switch to a pointer to do the cast and then deref it.
  213.   static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
  214.     return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
  215.                  *)&const_cast<FromTy &>(Val);
  216.   }
  217. };
  218.  
  219. template <class To, class FromTy>
  220. struct cast_convert_val<To, FromTy *, FromTy *> {
  221.   // If it's a pointer, we can use c-style casting directly.
  222.   static typename cast_retty<To, FromTy *>::ret_type doit(const FromTy *Val) {
  223.     return (typename cast_retty<To, FromTy *>::ret_type) const_cast<FromTy *>(
  224.         Val);
  225.   }
  226. };
  227.  
  228. //===----------------------------------------------------------------------===//
  229. // is_simple_type
  230. //===----------------------------------------------------------------------===//
  231.  
  232. template <class X> struct is_simple_type {
  233.   static const bool value =
  234.       std::is_same<X, typename simplify_type<X>::SimpleType>::value;
  235. };
  236.  
  237. // } // namespace detail
  238.  
  239. //===----------------------------------------------------------------------===//
  240. // CastIsPossible
  241. //===----------------------------------------------------------------------===//
  242.  
  243. /// This struct provides a way to check if a given cast is possible. It provides
  244. /// a static function called isPossible that is used to check if a cast can be
  245. /// performed. It should be overridden like this:
  246. ///
  247. /// template<> struct CastIsPossible<foo, bar> {
  248. ///   static inline bool isPossible(const bar &b) {
  249. ///     return bar.isFoo();
  250. ///   }
  251. /// };
  252. template <typename To, typename From, typename Enable = void>
  253. struct CastIsPossible {
  254.   static inline bool isPossible(const From &f) {
  255.     return isa_impl_wrap<
  256.         To, const From,
  257.         typename simplify_type<const From>::SimpleType>::doit(f);
  258.   }
  259. };
  260.  
  261. // Needed for optional unwrapping. This could be implemented with isa_impl, but
  262. // we want to implement things in the new method and move old implementations
  263. // over. In fact, some of the isa_impl templates should be moved over to
  264. // CastIsPossible.
  265. template <typename To, typename From>
  266. struct CastIsPossible<To, std::optional<From>> {
  267.   static inline bool isPossible(const std::optional<From> &f) {
  268.     assert(f && "CastIsPossible::isPossible called on a nullopt!");
  269.     return isa_impl_wrap<
  270.         To, const From,
  271.         typename simplify_type<const From>::SimpleType>::doit(*f);
  272.   }
  273. };
  274.  
  275. /// Upcasting (from derived to base) and casting from a type to itself should
  276. /// always be possible.
  277. template <typename To, typename From>
  278. struct CastIsPossible<To, From,
  279.                       std::enable_if_t<std::is_base_of<To, From>::value>> {
  280.   static inline bool isPossible(const From &f) { return true; }
  281. };
  282.  
  283. //===----------------------------------------------------------------------===//
  284. // Cast traits
  285. //===----------------------------------------------------------------------===//
  286.  
  287. /// All of these cast traits are meant to be implementations for useful casts
  288. /// that users may want to use that are outside the standard behavior. An
  289. /// example of how to use a special cast called `CastTrait` is:
  290. ///
  291. /// template<> struct CastInfo<foo, bar> : public CastTrait<foo, bar> {};
  292. ///
  293. /// Essentially, if your use case falls directly into one of the use cases
  294. /// supported by a given cast trait, simply inherit your special CastInfo
  295. /// directly from one of these to avoid having to reimplement the boilerplate
  296. /// `isPossible/castFailed/doCast/doCastIfPossible`. A cast trait can also
  297. /// provide a subset of those functions.
  298.  
  299. /// This cast trait just provides castFailed for the specified `To` type to make
  300. /// CastInfo specializations more declarative. In order to use this, the target
  301. /// result type must be `To` and `To` must be constructible from `nullptr`.
  302. template <typename To> struct NullableValueCastFailed {
  303.   static To castFailed() { return To(nullptr); }
  304. };
  305.  
  306. /// This cast trait just provides the default implementation of doCastIfPossible
  307. /// to make CastInfo specializations more declarative. The `Derived` template
  308. /// parameter *must* be provided for forwarding castFailed and doCast.
  309. template <typename To, typename From, typename Derived>
  310. struct DefaultDoCastIfPossible {
  311.   static To doCastIfPossible(From f) {
  312.     if (!Derived::isPossible(f))
  313.       return Derived::castFailed();
  314.     return Derived::doCast(f);
  315.   }
  316. };
  317.  
  318. namespace detail {
  319. /// A helper to derive the type to use with `Self` for cast traits, when the
  320. /// provided CRTP derived type is allowed to be void.
  321. template <typename OptionalDerived, typename Default>
  322. using SelfType = std::conditional_t<std::is_same<OptionalDerived, void>::value,
  323.                                     Default, OptionalDerived>;
  324. } // namespace detail
  325.  
  326. /// This cast trait provides casting for the specific case of casting to a
  327. /// value-typed object from a pointer-typed object. Note that `To` must be
  328. /// nullable/constructible from a pointer to `From` to use this cast.
  329. template <typename To, typename From, typename Derived = void>
  330. struct ValueFromPointerCast
  331.     : public CastIsPossible<To, From *>,
  332.       public NullableValueCastFailed<To>,
  333.       public DefaultDoCastIfPossible<
  334.           To, From *,
  335.           detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
  336.   static inline To doCast(From *f) { return To(f); }
  337. };
  338.  
  339. /// This cast trait provides std::unique_ptr casting. It has the semantics of
  340. /// moving the contents of the input unique_ptr into the output unique_ptr
  341. /// during the cast. It's also a good example of how to implement a move-only
  342. /// cast.
  343. template <typename To, typename From, typename Derived = void>
  344. struct UniquePtrCast : public CastIsPossible<To, From *> {
  345.   using Self = detail::SelfType<Derived, UniquePtrCast<To, From>>;
  346.   using CastResultType = std::unique_ptr<
  347.       std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
  348.  
  349.   static inline CastResultType doCast(std::unique_ptr<From> &&f) {
  350.     return CastResultType((typename CastResultType::element_type *)f.release());
  351.   }
  352.  
  353.   static inline CastResultType castFailed() { return CastResultType(nullptr); }
  354.  
  355.   static inline CastResultType doCastIfPossible(std::unique_ptr<From> &&f) {
  356.     if (!Self::isPossible(f))
  357.       return castFailed();
  358.     return doCast(f);
  359.   }
  360. };
  361.  
  362. /// This cast trait provides std::optional<T> casting. This means that if you
  363. /// have a value type, you can cast it to another value type and have dyn_cast
  364. /// return an std::optional<T>.
  365. template <typename To, typename From, typename Derived = void>
  366. struct OptionalValueCast
  367.     : public CastIsPossible<To, From>,
  368.       public DefaultDoCastIfPossible<
  369.           std::optional<To>, From,
  370.           detail::SelfType<Derived, OptionalValueCast<To, From>>> {
  371.   static inline std::optional<To> castFailed() { return std::optional<To>{}; }
  372.  
  373.   static inline std::optional<To> doCast(const From &f) { return To(f); }
  374. };
  375.  
  376. /// Provides a cast trait that strips `const` from types to make it easier to
  377. /// implement a const-version of a non-const cast. It just removes boilerplate
  378. /// and reduces the amount of code you as the user need to implement. You can
  379. /// use it like this:
  380. ///
  381. /// template<> struct CastInfo<foo, bar> {
  382. ///   ...verbose implementation...
  383. /// };
  384. ///
  385. /// template<> struct CastInfo<foo, const bar> : public
  386. ///        ConstStrippingForwardingCast<foo, const bar, CastInfo<foo, bar>> {};
  387. ///
  388. template <typename To, typename From, typename ForwardTo>
  389. struct ConstStrippingForwardingCast {
  390.   // Remove the pointer if it exists, then we can get rid of consts/volatiles.
  391.   using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>;
  392.   // Now if it's a pointer, add it back. Otherwise, we want a ref.
  393.   using NonConstFrom = std::conditional_t<std::is_pointer<From>::value,
  394.                                           DecayedFrom *, DecayedFrom &>;
  395.  
  396.   static inline bool isPossible(const From &f) {
  397.     return ForwardTo::isPossible(const_cast<NonConstFrom>(f));
  398.   }
  399.  
  400.   static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); }
  401.  
  402.   static inline decltype(auto) doCast(const From &f) {
  403.     return ForwardTo::doCast(const_cast<NonConstFrom>(f));
  404.   }
  405.  
  406.   static inline decltype(auto) doCastIfPossible(const From &f) {
  407.     return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f));
  408.   }
  409. };
  410.  
  411. /// Provides a cast trait that uses a defined pointer to pointer cast as a base
  412. /// for reference-to-reference casts. Note that it does not provide castFailed
  413. /// and doCastIfPossible because a pointer-to-pointer cast would likely just
  414. /// return `nullptr` which could cause nullptr dereference. You can use it like
  415. /// this:
  416. ///
  417. ///   template <> struct CastInfo<foo, bar *> { ... verbose implementation... };
  418. ///
  419. ///   template <>
  420. ///   struct CastInfo<foo, bar>
  421. ///       : public ForwardToPointerCast<foo, bar, CastInfo<foo, bar *>> {};
  422. ///
  423. template <typename To, typename From, typename ForwardTo>
  424. struct ForwardToPointerCast {
  425.   static inline bool isPossible(const From &f) {
  426.     return ForwardTo::isPossible(&f);
  427.   }
  428.  
  429.   static inline decltype(auto) doCast(const From &f) {
  430.     return *ForwardTo::doCast(&f);
  431.   }
  432. };
  433.  
  434. //===----------------------------------------------------------------------===//
  435. // CastInfo
  436. //===----------------------------------------------------------------------===//
  437.  
  438. /// This struct provides a method for customizing the way a cast is performed.
  439. /// It inherits from CastIsPossible, to support the case of declaring many
  440. /// CastIsPossible specializations without having to specialize the full
  441. /// CastInfo.
  442. ///
  443. /// In order to specialize different behaviors, specify different functions in
  444. /// your CastInfo specialization.
  445. /// For isa<> customization, provide:
  446. ///
  447. ///   `static bool isPossible(const From &f)`
  448. ///
  449. /// For cast<> customization, provide:
  450. ///
  451. ///  `static To doCast(const From &f)`
  452. ///
  453. /// For dyn_cast<> and the *_if_present<> variants' customization, provide:
  454. ///
  455. ///  `static To castFailed()` and `static To doCastIfPossible(const From &f)`
  456. ///
  457. /// Your specialization might look something like this:
  458. ///
  459. ///  template<> struct CastInfo<foo, bar> : public CastIsPossible<foo, bar> {
  460. ///    static inline foo doCast(const bar &b) {
  461. ///      return foo(const_cast<bar &>(b));
  462. ///    }
  463. ///    static inline foo castFailed() { return foo(); }
  464. ///    static inline foo doCastIfPossible(const bar &b) {
  465. ///      if (!CastInfo<foo, bar>::isPossible(b))
  466. ///        return castFailed();
  467. ///      return doCast(b);
  468. ///    }
  469. ///  };
  470.  
  471. // The default implementations of CastInfo don't use cast traits for now because
  472. // we need to specify types all over the place due to the current expected
  473. // casting behavior and the way cast_retty works. New use cases can and should
  474. // take advantage of the cast traits whenever possible!
  475.  
  476. template <typename To, typename From, typename Enable = void>
  477. struct CastInfo : public CastIsPossible<To, From> {
  478.   using Self = CastInfo<To, From, Enable>;
  479.  
  480.   using CastReturnType = typename cast_retty<To, From>::ret_type;
  481.  
  482.   static inline CastReturnType doCast(const From &f) {
  483.     return cast_convert_val<
  484.         To, From,
  485.         typename simplify_type<From>::SimpleType>::doit(const_cast<From &>(f));
  486.   }
  487.  
  488.   // This assumes that you can construct the cast return type from `nullptr`.
  489.   // This is largely to support legacy use cases - if you don't want this
  490.   // behavior you should specialize CastInfo for your use case.
  491.   static inline CastReturnType castFailed() { return CastReturnType(nullptr); }
  492.  
  493.   static inline CastReturnType doCastIfPossible(const From &f) {
  494.     if (!Self::isPossible(f))
  495.       return castFailed();
  496.     return doCast(f);
  497.   }
  498. };
  499.  
  500. /// This struct provides an overload for CastInfo where From has simplify_type
  501. /// defined. This simply forwards to the appropriate CastInfo with the
  502. /// simplified type/value, so you don't have to implement both.
  503. template <typename To, typename From>
  504. struct CastInfo<To, From, std::enable_if_t<!is_simple_type<From>::value>> {
  505.   using Self = CastInfo<To, From>;
  506.   using SimpleFrom = typename simplify_type<From>::SimpleType;
  507.   using SimplifiedSelf = CastInfo<To, SimpleFrom>;
  508.  
  509.   static inline bool isPossible(From &f) {
  510.     return SimplifiedSelf::isPossible(
  511.         simplify_type<From>::getSimplifiedValue(f));
  512.   }
  513.  
  514.   static inline decltype(auto) doCast(From &f) {
  515.     return SimplifiedSelf::doCast(simplify_type<From>::getSimplifiedValue(f));
  516.   }
  517.  
  518.   static inline decltype(auto) castFailed() {
  519.     return SimplifiedSelf::castFailed();
  520.   }
  521.  
  522.   static inline decltype(auto) doCastIfPossible(From &f) {
  523.     return SimplifiedSelf::doCastIfPossible(
  524.         simplify_type<From>::getSimplifiedValue(f));
  525.   }
  526. };
  527.  
  528. //===----------------------------------------------------------------------===//
  529. // Pre-specialized CastInfo
  530. //===----------------------------------------------------------------------===//
  531.  
  532. /// Provide a CastInfo specialized for std::unique_ptr.
  533. template <typename To, typename From>
  534. struct CastInfo<To, std::unique_ptr<From>> : public UniquePtrCast<To, From> {};
  535.  
  536. /// Provide a CastInfo specialized for std::optional<From>. It's assumed that if
  537. /// the input is std::optional<From> that the output can be std::optional<To>.
  538. /// If that's not the case, specialize CastInfo for your use case.
  539. template <typename To, typename From>
  540. struct CastInfo<To, std::optional<From>> : public OptionalValueCast<To, From> {
  541. };
  542.  
  543. /// isa<X> - Return true if the parameter to the template is an instance of one
  544. /// of the template type arguments.  Used like this:
  545. ///
  546. ///  if (isa<Type>(myVal)) { ... }
  547. ///  if (isa<Type0, Type1, Type2>(myVal)) { ... }
  548. template <typename To, typename From>
  549. [[nodiscard]] inline bool isa(const From &Val) {
  550.   return CastInfo<To, const From>::isPossible(Val);
  551. }
  552.  
  553. template <typename First, typename Second, typename... Rest, typename From>
  554. [[nodiscard]] inline bool isa(const From &Val) {
  555.   return isa<First>(Val) || isa<Second, Rest...>(Val);
  556. }
  557.  
  558. /// cast<X> - Return the argument parameter cast to the specified type.  This
  559. /// casting operator asserts that the type is correct, so it does not return
  560. /// null on failure.  It does not allow a null argument (use cast_if_present for
  561. /// that). It is typically used like this:
  562. ///
  563. ///  cast<Instruction>(myVal)->getParent()
  564.  
  565. template <typename To, typename From>
  566. [[nodiscard]] inline decltype(auto) cast(const From &Val) {
  567.   assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
  568.   return CastInfo<To, const From>::doCast(Val);
  569. }
  570.  
  571. template <typename To, typename From>
  572. [[nodiscard]] inline decltype(auto) cast(From &Val) {
  573.   assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
  574.   return CastInfo<To, From>::doCast(Val);
  575. }
  576.  
  577. template <typename To, typename From>
  578. [[nodiscard]] inline decltype(auto) cast(From *Val) {
  579.   assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
  580.   return CastInfo<To, From *>::doCast(Val);
  581. }
  582.  
  583. template <typename To, typename From>
  584. [[nodiscard]] inline decltype(auto) cast(std::unique_ptr<From> &&Val) {
  585.   assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
  586.   return CastInfo<To, std::unique_ptr<From>>::doCast(std::move(Val));
  587. }
  588.  
  589. //===----------------------------------------------------------------------===//
  590. // ValueIsPresent
  591. //===----------------------------------------------------------------------===//
  592.  
  593. template <typename T>
  594. constexpr bool IsNullable =
  595.     std::is_pointer_v<T> || std::is_constructible_v<T, std::nullptr_t>;
  596.  
  597. /// ValueIsPresent provides a way to check if a value is, well, present. For
  598. /// pointers, this is the equivalent of checking against nullptr, for Optionals
  599. /// this is the equivalent of checking hasValue(). It also provides a method for
  600. /// unwrapping a value (think calling .value() on an optional).
  601.  
  602. // Generic values can't *not* be present.
  603. template <typename T, typename Enable = void> struct ValueIsPresent {
  604.   using UnwrappedType = T;
  605.   static inline bool isPresent(const T &t) { return true; }
  606.   static inline decltype(auto) unwrapValue(T &t) { return t; }
  607. };
  608.  
  609. // Optional provides its own way to check if something is present.
  610. template <typename T> struct ValueIsPresent<std::optional<T>> {
  611.   using UnwrappedType = T;
  612.   static inline bool isPresent(const std::optional<T> &t) {
  613.     return t.has_value();
  614.   }
  615.   static inline decltype(auto) unwrapValue(std::optional<T> &t) { return *t; }
  616. };
  617.  
  618. // If something is "nullable" then we just compare it to nullptr to see if it
  619. // exists.
  620. template <typename T>
  621. struct ValueIsPresent<T, std::enable_if_t<IsNullable<T>>> {
  622.   using UnwrappedType = T;
  623.   static inline bool isPresent(const T &t) { return t != T(nullptr); }
  624.   static inline decltype(auto) unwrapValue(T &t) { return t; }
  625. };
  626.  
  627. namespace detail {
  628. // Convenience function we can use to check if a value is present. Because of
  629. // simplify_type, we have to call it on the simplified type for now.
  630. template <typename T> inline bool isPresent(const T &t) {
  631.   return ValueIsPresent<typename simplify_type<T>::SimpleType>::isPresent(
  632.       simplify_type<T>::getSimplifiedValue(const_cast<T &>(t)));
  633. }
  634.  
  635. // Convenience function we can use to unwrap a value.
  636. template <typename T> inline decltype(auto) unwrapValue(T &t) {
  637.   return ValueIsPresent<T>::unwrapValue(t);
  638. }
  639. } // namespace detail
  640.  
  641. /// dyn_cast<X> - Return the argument parameter cast to the specified type. This
  642. /// casting operator returns null if the argument is of the wrong type, so it
  643. /// can be used to test for a type as well as cast if successful. The value
  644. /// passed in must be present, if not, use dyn_cast_if_present. This should be
  645. /// used in the context of an if statement like this:
  646. ///
  647. ///  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
  648.  
  649. template <typename To, typename From>
  650. [[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) {
  651.   assert(detail::isPresent(Val) && "dyn_cast on a non-existent value");
  652.   return CastInfo<To, const From>::doCastIfPossible(Val);
  653. }
  654.  
  655. template <typename To, typename From>
  656. [[nodiscard]] inline decltype(auto) dyn_cast(From &Val) {
  657.   assert(detail::isPresent(Val) && "dyn_cast on a non-existent value");
  658.   return CastInfo<To, From>::doCastIfPossible(Val);
  659. }
  660.  
  661. template <typename To, typename From>
  662. [[nodiscard]] inline decltype(auto) dyn_cast(From *Val) {
  663.   assert(detail::isPresent(Val) && "dyn_cast on a non-existent value");
  664.   return CastInfo<To, From *>::doCastIfPossible(Val);
  665. }
  666.  
  667. template <typename To, typename From>
  668. [[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr<From> &&Val) {
  669.   assert(detail::isPresent(Val) && "dyn_cast on a non-existent value");
  670.   return CastInfo<To, std::unique_ptr<From>>::doCastIfPossible(
  671.       std::forward<std::unique_ptr<From> &&>(Val));
  672. }
  673.  
  674. /// isa_and_present<X> - Functionally identical to isa, except that a null value
  675. /// is accepted.
  676. template <typename... X, class Y>
  677. [[nodiscard]] inline bool isa_and_present(const Y &Val) {
  678.   if (!detail::isPresent(Val))
  679.     return false;
  680.   return isa<X...>(Val);
  681. }
  682.  
  683. template <typename... X, class Y>
  684. [[nodiscard]] inline bool isa_and_nonnull(const Y &Val) {
  685.   return isa_and_present<X...>(Val);
  686. }
  687.  
  688. /// cast_if_present<X> - Functionally identical to cast, except that a null
  689. /// value is accepted.
  690. template <class X, class Y>
  691. [[nodiscard]] inline auto cast_if_present(const Y &Val) {
  692.   if (!detail::isPresent(Val))
  693.     return CastInfo<X, const Y>::castFailed();
  694.   assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!");
  695.   return cast<X>(detail::unwrapValue(Val));
  696. }
  697.  
  698. template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) {
  699.   if (!detail::isPresent(Val))
  700.     return CastInfo<X, Y>::castFailed();
  701.   assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!");
  702.   return cast<X>(detail::unwrapValue(Val));
  703. }
  704.  
  705. template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) {
  706.   if (!detail::isPresent(Val))
  707.     return CastInfo<X, Y *>::castFailed();
  708.   assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!");
  709.   return cast<X>(detail::unwrapValue(Val));
  710. }
  711.  
  712. template <class X, class Y>
  713. [[nodiscard]] inline auto cast_if_present(std::unique_ptr<Y> &&Val) {
  714.   if (!detail::isPresent(Val))
  715.     return UniquePtrCast<X, Y>::castFailed();
  716.   return UniquePtrCast<X, Y>::doCast(std::move(Val));
  717. }
  718.  
  719. // Provide a forwarding from cast_or_null to cast_if_present for current
  720. // users. This is deprecated and will be removed in a future patch, use
  721. // cast_if_present instead.
  722. template <class X, class Y> auto cast_or_null(const Y &Val) {
  723.   return cast_if_present<X>(Val);
  724. }
  725.  
  726. template <class X, class Y> auto cast_or_null(Y &Val) {
  727.   return cast_if_present<X>(Val);
  728. }
  729.  
  730. template <class X, class Y> auto cast_or_null(Y *Val) {
  731.   return cast_if_present<X>(Val);
  732. }
  733.  
  734. template <class X, class Y> auto cast_or_null(std::unique_ptr<Y> &&Val) {
  735.   return cast_if_present<X>(std::move(Val));
  736. }
  737.  
  738. /// dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a
  739. /// null (or none in the case of optionals) value is accepted.
  740. template <class X, class Y> auto dyn_cast_if_present(const Y &Val) {
  741.   if (!detail::isPresent(Val))
  742.     return CastInfo<X, const Y>::castFailed();
  743.   return CastInfo<X, const Y>::doCastIfPossible(detail::unwrapValue(Val));
  744. }
  745.  
  746. template <class X, class Y> auto dyn_cast_if_present(Y &Val) {
  747.   if (!detail::isPresent(Val))
  748.     return CastInfo<X, Y>::castFailed();
  749.   return CastInfo<X, Y>::doCastIfPossible(detail::unwrapValue(Val));
  750. }
  751.  
  752. template <class X, class Y> auto dyn_cast_if_present(Y *Val) {
  753.   if (!detail::isPresent(Val))
  754.     return CastInfo<X, Y *>::castFailed();
  755.   return CastInfo<X, Y *>::doCastIfPossible(detail::unwrapValue(Val));
  756. }
  757.  
  758. // Forwards to dyn_cast_if_present to avoid breaking current users. This is
  759. // deprecated and will be removed in a future patch, use
  760. // cast_if_present instead.
  761. template <class X, class Y> auto dyn_cast_or_null(const Y &Val) {
  762.   return dyn_cast_if_present<X>(Val);
  763. }
  764.  
  765. template <class X, class Y> auto dyn_cast_or_null(Y &Val) {
  766.   return dyn_cast_if_present<X>(Val);
  767. }
  768.  
  769. template <class X, class Y> auto dyn_cast_or_null(Y *Val) {
  770.   return dyn_cast_if_present<X>(Val);
  771. }
  772.  
  773. /// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
  774. /// taking ownership of the input pointer iff isa<X>(Val) is true.  If the
  775. /// cast is successful, From refers to nullptr on exit and the casted value
  776. /// is returned.  If the cast is unsuccessful, the function returns nullptr
  777. /// and From is unchanged.
  778. template <class X, class Y>
  779. [[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
  780. unique_dyn_cast(std::unique_ptr<Y> &Val) {
  781.   if (!isa<X>(Val))
  782.     return nullptr;
  783.   return cast<X>(std::move(Val));
  784. }
  785.  
  786. template <class X, class Y>
  787. [[nodiscard]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) {
  788.   return unique_dyn_cast<X, Y>(Val);
  789. }
  790.  
  791. // unique_dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast,
  792. // except that a null value is accepted.
  793. template <class X, class Y>
  794. [[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
  795. unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) {
  796.   if (!Val)
  797.     return nullptr;
  798.   return unique_dyn_cast<X, Y>(Val);
  799. }
  800.  
  801. template <class X, class Y>
  802. [[nodiscard]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) {
  803.   return unique_dyn_cast_or_null<X, Y>(Val);
  804. }
  805.  
  806. } // end namespace llvm
  807.  
  808. #endif // LLVM_SUPPORT_CASTING_H
  809.