Go to the documentation of this file.
14 #ifndef LLVM_SUPPORT_CASTING_H
15 #define LLVM_SUPPORT_CASTING_H
22 #include <type_traits>
34 template <
typename From>
struct simplify_type {
63 template <
typename To,
typename From,
typename Enabler =
void>
struct isa_impl {
64 static inline bool doit(
const From &Val) {
return To::classof(&Val); }
68 template <
typename To,
typename From>
70 static inline bool doit(
const From &) {
return true; }
85 template <
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");
114 template <
typename To,
typename From>
117 assert(Val &&
"isa<> used on a null pointer");
122 template <
typename To,
typename From,
typename SimpleFrom>
133 template <
typename To,
typename FromTy>
136 static bool doit(
const FromTy &Val) {
168 template <
class To,
class From>
172 using ResultType = std::remove_pointer_t<PointerType>;
190 template <
class To,
class From>
struct cast_retty {
214 return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
215 *)&
const_cast<FromTy &
>(Val);
219 template <
class To,
class FromTy>
234 std::is_same<X, typename simplify_type<X>::SimpleType>
::value;
252 template <
typename To,
typename From,
typename Enable =
void>
265 template <
typename To,
typename From>
268 assert(
f.hasValue() &&
"CastIsPossible::isPossible called on a nullopt!");
277 template <
typename To,
typename From>
279 std::enable_if_t<std::is_base_of<To, From>::value>> {
309 template <
typename To,
typename From,
typename Derived>
312 if (!Derived::isPossible(
f))
313 return Derived::castFailed();
314 return Derived::doCast(
f);
321 template <
typename OptionalDerived,
typename Default>
322 using SelfType = std::conditional_t<std::is_same<OptionalDerived, void>::value,
323 Default, OptionalDerived>;
329 template <
typename To,
typename From,
typename Derived =
void>
335 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
343 template <
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))
365 template <
typename To,
typename From,
typename Derived =
void>
370 detail::SelfType<Derived, OptionalValueCast<To, From>>> {
388 template <
typename To,
typename From,
typename ForwardTo>
391 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>;
393 using NonConstFrom = std::conditional_t<std::is_pointer<From>::value,
400 static inline decltype(
auto)
castFailed() {
return ForwardTo::castFailed(); }
407 return ForwardTo::doCastIfPossible(
const_cast<NonConstFrom>(
f));
423 template <
typename To,
typename From,
typename ForwardTo>
426 return ForwardTo::isPossible(&
f);
430 return *ForwardTo::doCast(&
f);
476 template <
typename To,
typename From,
typename Enable =
void>
503 template <
typename To,
typename From>
510 return SimplifiedSelf::isPossible(
519 return SimplifiedSelf::castFailed();
523 return SimplifiedSelf::doCastIfPossible(
533 template <
typename To,
typename From>
539 template <
typename To,
typename From>
547 template <
typename To,
typename From>
552 template <
typename First,
typename Second,
typename... Rest,
typename From>
554 return isa<First>(Val) ||
isa<Second, Rest...>(Val);
564 template <
typename To,
typename From>
566 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
570 template <
typename To,
typename From>
572 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
576 template <
typename To,
typename From>
578 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
582 template <
typename To,
typename From>
584 assert(isa<To>(Val) &&
"cast<Ty>() argument of incompatible type!");
596 template <
typename To,
typename From>
601 template <
typename To,
typename From>
606 template <
typename To,
typename From>
611 template <
typename To,
typename From>
620 template <
typename T>
622 std::is_constructible<T, std::nullptr_t>::value;
648 template <
typename T>
671 template <
typename...
X,
class Y>
675 return isa<
X...>(Val);
678 template <
typename...
X,
class Y>
685 template <
class X,
class Y>
689 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
696 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
703 assert(isa<X>(Val) &&
"cast_if_present<Ty>() argument of incompatible type!");
707 template <
class X,
class Y>
718 return cast_if_present<X>(Val);
722 return cast_if_present<X>(Val);
726 return cast_if_present<X>(Val);
729 template <
class X,
class Y>
auto cast_or_null(std::unique_ptr<Y> &&Val) {
730 return cast_if_present<X>(
std::move(Val));
757 return dyn_cast_if_present<X>(Val);
761 return dyn_cast_if_present<X>(Val);
765 return dyn_cast_if_present<X>(Val);
773 template <
class X,
class Y>
774 LLVM_NODISCARD inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
781 template <
class X,
class Y>
783 return unique_dyn_cast<X, Y>(Val);
788 template <
class X,
class Y>
789 LLVM_NODISCARD inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
793 return unique_dyn_cast<X, Y>(Val);
796 template <
class X,
class Y>
798 return unique_dyn_cast_or_null<X, Y>(Val);
803 #endif // LLVM_SUPPORT_CASTING_H
static bool isPossible(const Optional< From > &f)
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
static decltype(auto) unwrapValue(T &t)
static bool doit(const FromTy &Val)
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< ResultType > ret_type
This struct provides a method for customizing the way a cast is performed.
static bool isPossible(const From &f)
decltype(auto) LLVM_NODISCARD cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_NODISCARD auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
static cast_retty< To, FromTy >::ret_type doit(const FromTy &Val)
static Optional< To > castFailed()
LLVM_NODISCARD bool isa_and_present(const Y &Val)
isa_and_present<X> - Functionally identical to isa, except that a null value is accepted.
LLVM_NODISCARD 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...
typename add_lvalue_reference_if_not_pointer< SimpleType >::type RetType
LLVM_NODISCARD 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...
static bool isPossible(const From &f)
static cast_retty< To, FromTy * >::ret_type doit(const FromTy *Val)
This cast trait provides Optional<T> casting.
std::unique_ptr< std::remove_reference_t< typename cast_retty< To, From >::ret_type > > CastResultType
This cast trait provides std::unique_ptr casting.
static bool doit(const From *Val)
auto cast_or_null(const Y &Val)
This struct provides a way to check if a given cast is possible.
typename cast_retty_wrap< To, From, typename simplify_type< From >::SimpleType >::ret_type ret_type
static bool doit(const From &Val)
static bool isPossible(const From &f)
static bool doit(const From *Val)
Itanium Name Demangler i e convert the string _Z1fv into f()". You can also use the CRTP base ManglingParser to perform some simple analysis on the mangled name
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static To doCast(From *f)
static CastResultType castFailed()
static bool doit(const From &Val)
bitcast float %x to i32 %s=and i32 %t, 2147483647 %d=bitcast i32 %s to float ret float %d } declare float @fabsf(float %n) define float @bar(float %x) nounwind { %d=call float @fabsf(float %x) ret float %d } This IR(from PR6194):target datalayout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple="x86_64-apple-darwin10.0.0" %0=type { double, double } %struct.float3=type { float, float, float } define void @test(%0, %struct.float3 *nocapture %res) nounwind noinline ssp { entry:%tmp18=extractvalue %0 %0, 0 t
static bool doit(const From *Val)
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
typename cast_retty< To, From >::ret_type CastReturnType
into llvm powi allowing the code generator to produce balanced multiplication trees First
typename simplify_type< From >::SimpleType NonConstSimpleType
ValueIsPresent provides a way to check if a value is, well, present.
All of these cast traits are meant to be implementations for useful casts that users may want to use ...
static CastReturnType doCast(const From &f)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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 ...
detail::SelfType< void, UniquePtrCast< To, From > > Self
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 ...
std::remove_cv_t< std::remove_pointer_t< const PointerUnion< PTs... > > > DecayedFrom
static Optional< To > doCast(const From &f)
typename cast_retty< To, SimpleFrom >::ret_type ret_type
static bool isPresent(const T &t)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static decltype(auto) doCast(const From &f)
static decltype(auto) castFailed()
Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...
static CastResultType doCast(std::unique_ptr< From > &&f)
static bool doit(const From *Val)
static cast_retty< To, From >::ret_type doit(const From &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static CastReturnType castFailed()
typename cast_retty_impl< To, FromTy >::ret_type ret_type
This cast trait provides casting for the specific case of casting to a value-typed object from a poin...
static RetType getSimplifiedValue(const From &Val)
static bool doit(const From &Val)
static bool isPresent(const T &t)
typename simplify_type< From >::SimpleType SimpleFrom
static bool isPossible(From &f)
constexpr bool IsNullable
LLVM_NODISCARD bool isa_and_nonnull(const Y &Val)
static bool isPresent(const Optional< T > &t)
static bool doit(const From &)
static bool isPossible(const From &f)
std::conditional_t< std::is_pointer< const PointerUnion< PTs... > >::value, DecayedFrom *, DecayedFrom & > NonConstFrom
static To doCastIfPossible(From f)
static SimpleType & getSimplifiedValue(From &Val)
static CastReturnType doCastIfPossible(const From &f)
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
static decltype(auto) doCast(const From &f)
static CastResultType doCastIfPossible(std::unique_ptr< From > &&f)
static bool doit(const From &Val)
static decltype(auto) doCastIfPossible(const From &f)
LLVM_NODISCARD CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast_or_null(std::unique_ptr< Y > &Val)
bool isPresent(const T &t)
BlockVerifier::State From
static bool doit(const std::unique_ptr< From > &Val)
decltype(auto) unwrapValue(T &t)
decltype(auto) LLVM_NODISCARD dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
typename add_const_past_pointer< NonConstSimpleType >::type SimpleType
auto dyn_cast_or_null(const Y &Val)