14#ifndef LLVM_SUPPORT_CASTING_H
15#define LLVM_SUPPORT_CASTING_H
63template <
typename To,
typename From,
typename Enabler =
void>
struct isa_impl {
64 static inline bool doit(
const From &Val) {
return To::classof(&Val); }
68template <
typename To,
typename From>
70 static inline bool doit(
const From &) {
return true; }
85template <
typename To,
typename From>
87 static inline bool doit(
const std::unique_ptr<From> &Val) {
88 assert(Val &&
"isa<> used on a null pointer");
95 assert(Val &&
"isa<> used on a null pointer");
102 assert(Val &&
"isa<> used on a null pointer");
109 assert(Val &&
"isa<> used on a null pointer");
114template <
typename To,
typename From>
117 assert(Val &&
"isa<> used on a null pointer");
122template <
typename To,
typename From,
typename SimpleFrom>
133template <
typename To,
typename FromTy>
136 static bool doit(
const FromTy &Val) {
145template <
class To,
class From>
struct cast_retty;
168template <
class To,
class From>
172 using ResultType = std::remove_pointer_t<PointerType>;
214 return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
215 *)&
const_cast<FromTy &
>(Val);
219template <
class To,
class FromTy>
234 std::is_same<X, typename simplify_type<X>::SimpleType>
::value;
252template <
typename To,
typename From,
typename Enable =
void>
265template <
typename To,
typename From>
267 static inline bool isPossible(
const std::optional<From> &f) {
268 assert(f &&
"CastIsPossible::isPossible called on a nullopt!");
277template <
typename To,
typename From>
279 std::enable_if_t<std::is_base_of<To, From>::value>> {
309template <
typename To,
typename From,
typename Derived>
312 if (!Derived::isPossible(f))
313 return Derived::castFailed();
314 return Derived::doCast(f);
321template <
typename OptionalDerived,
typename Default>
322using SelfType = std::conditional_t<std::is_same<OptionalDerived, void>::value,
329template <
typename To,
typename From,
typename Derived =
void>
335 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
343template <
typename To,
typename From,
typename Derived =
void>
347 std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
350 return CastResultType((
typename CastResultType::element_type *)f.release());
356 if (!Self::isPossible(f))
365template <
typename To,
typename From,
typename Derived =
void>
369 std::optional<To>, From,
370 detail::SelfType<Derived, OptionalValueCast<To, From>>> {
371 static inline std::optional<To>
castFailed() {
return std::optional<To>{}; }
373 static inline std::optional<To>
doCast(
const From &f) {
return To(f); }
388template <
typename To,
typename From,
typename ForwardTo>
391 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>;
397 return ForwardTo::isPossible(
const_cast<NonConstFrom>(f));
400 static inline decltype(
auto)
castFailed() {
return ForwardTo::castFailed(); }
407 return ForwardTo::doCastIfPossible(
const_cast<NonConstFrom>(f));
423template <
typename To,
typename From,
typename ForwardTo>
426 return ForwardTo::isPossible(&f);
430 return *ForwardTo::doCast(&f);
476template <
typename To,
typename From,
typename Enable =
void>
503template <
typename To,
typename From>
510 return SimplifiedSelf::isPossible(
519 return SimplifiedSelf::castFailed();
523 return SimplifiedSelf::doCastIfPossible(
533template <
typename To,
typename From>
539template <
typename To,
typename From>
548template <
typename To,
typename From>
549[[nodiscard]]
inline bool isa(
const From &Val) {
553template <
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);
565template <
typename To,
typename From>
566[[nodiscard]]
inline decltype(
auto)
cast(
const From &Val) {
567 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
571template <
typename To,
typename From>
572[[nodiscard]]
inline decltype(
auto)
cast(
From &Val) {
573 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
577template <
typename To,
typename From>
578[[nodiscard]]
inline decltype(
auto)
cast(
From *Val) {
579 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
583template <
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!");
595 std::is_pointer_v<T> || std::is_constructible_v<T, std::nullptr_t>;
612 static inline bool isPresent(
const std::optional<T> &t) {
613 return t.has_value();
615 static inline decltype(
auto)
unwrapValue(std::optional<T> &t) {
return *t; }
623 static inline bool isPresent(
const T &t) {
return t !=
T(
nullptr); }
649template <
typename To,
typename From>
655template <
typename To,
typename From>
661template <
typename To,
typename From>
667template <
typename To,
typename From>
668[[nodiscard]]
inline decltype(
auto)
dyn_cast(std::unique_ptr<From> &&Val) {
671 std::forward<std::unique_ptr<From> &&>(Val));
676template <
typename...
X,
class Y>
680 return isa<
X...>(Val);
683template <
typename...
X,
class Y>
690template <
class X,
class Y>
694 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
701 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
708 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
712template <
class X,
class Y>
723 return cast_if_present<X>(Val);
727 return cast_if_present<X>(Val);
731 return cast_if_present<X>(Val);
734template <
class X,
class Y>
auto cast_or_null(std::unique_ptr<Y> &&Val) {
735 return cast_if_present<X>(std::move(Val));
762 return dyn_cast_if_present<X>(Val);
766 return dyn_cast_if_present<X>(Val);
770 return dyn_cast_if_present<X>(Val);
778template <
class X,
class Y>
779[[nodiscard]]
inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
783 return cast<X>(std::move(Val));
786template <
class X,
class Y>
788 return unique_dyn_cast<X, Y>(Val);
793template <
class X,
class Y>
794[[nodiscard]]
inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
798 return unique_dyn_cast<X, Y>(Val);
801template <
class X,
class Y>
803 return unique_dyn_cast_or_null<X, Y>(Val);
BlockVerifier::State From
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::conditional_t< std::is_same< OptionalDerived, void >::value, Default, OptionalDerived > SelfType
A helper to derive the type to use with Self for cast traits, when the provided CRTP derived type is ...
bool isPresent(const T &t)
decltype(auto) unwrapValue(T &t)
This is an optimization pass for GlobalISel generic memory operations.
auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast(std::unique_ptr< Y > &Val)
unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, taking ownership of the in...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
auto cast_or_null(const Y &Val)
bool isa_and_nonnull(const Y &Val)
auto dyn_cast_or_null(const Y &Val)
bool isa_and_present(const Y &Val)
isa_and_present<X> - Functionally identical to isa, except that a null value is accepted.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr bool IsNullable
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast_or_null(std::unique_ptr< Y > &Val)
@ Default
The result values are uniform if and only if all operands are uniform.
typename simplify_type< From >::SimpleType SimpleFrom
static decltype(auto) castFailed()
static bool isPossible(From &f)
static decltype(auto) doCast(From &f)
static decltype(auto) doCastIfPossible(From &f)
This struct provides a method for customizing the way a cast is performed.
static CastReturnType castFailed()
static CastReturnType doCast(const From &f)
static CastReturnType doCastIfPossible(const From &f)
typename cast_retty< To, From >::ret_type CastReturnType
static bool isPossible(const From &f)
static bool isPossible(const std::optional< From > &f)
This struct provides a way to check if a given cast is possible.
static bool isPossible(const From &f)
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
std::conditional_t< std::is_pointer< From >::value, DecayedFrom *, DecayedFrom & > NonConstFrom
static decltype(auto) castFailed()
static decltype(auto) doCastIfPossible(const From &f)
static decltype(auto) doCast(const From &f)
static bool isPossible(const From &f)
std::remove_cv_t< std::remove_pointer_t< From > > DecayedFrom
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
static To doCastIfPossible(From f)
Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...
static bool isPossible(const From &f)
static decltype(auto) doCast(const From &f)
All of these cast traits are meant to be implementations for useful casts that users may want to use ...
This cast trait provides std::optional<T> casting.
static std::optional< To > doCast(const From &f)
static std::optional< To > castFailed()
This cast trait provides std::unique_ptr casting.
std::unique_ptr< std::remove_reference_t< typename cast_retty< To, From >::ret_type > > CastResultType
detail::SelfType< Derived, UniquePtrCast< To, From > > Self
static CastResultType doCastIfPossible(std::unique_ptr< From > &&f)
static CastResultType doCast(std::unique_ptr< From > &&f)
static CastResultType castFailed()
This cast trait provides casting for the specific case of casting to a value-typed object from a poin...
static To doCast(From *f)
static decltype(auto) unwrapValue(T &t)
static bool isPresent(const T &t)
static decltype(auto) unwrapValue(std::optional< T > &t)
static bool isPresent(const std::optional< T > &t)
ValueIsPresent provides a way to check if a value is, well, present.
static bool isPresent(const T &t)
static decltype(auto) unwrapValue(T &t)
static cast_retty< To, FromTy >::ret_type doit(const FromTy &Val)
static cast_retty< To, FromTy * >::ret_type doit(const FromTy *Val)
static cast_retty< To, From >::ret_type doit(const From &Val)
std::unique_ptr< ResultType > ret_type
typename cast_retty_impl< To, FromTy >::ret_type ret_type
typename cast_retty< To, SimpleFrom >::ret_type ret_type
typename cast_retty_wrap< To, From, typename simplify_type< From >::SimpleType >::ret_type ret_type
static bool doit(const From &)
static bool doit(const From *Val)
static bool doit(const From *Val)
static bool doit(const From &Val)
static bool doit(const From *Val)
static bool doit(const From *Val)
static bool doit(const std::unique_ptr< From > &Val)
static bool doit(const From &Val)
static bool doit(const FromTy &Val)
static bool doit(const From &Val)
static bool doit(const From &Val)
typename add_const_past_pointer< NonConstSimpleType >::type SimpleType
typename add_lvalue_reference_if_not_pointer< SimpleType >::type RetType
typename simplify_type< From >::SimpleType NonConstSimpleType
static RetType getSimplifiedValue(const From &Val)
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
static SimpleType & getSimplifiedValue(From &Val)