1 //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
10 // and dyn_cast_or_null<X>() templates.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_SUPPORT_CASTING_H
15 #define LLVM_SUPPORT_CASTING_H
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/type_traits.h"
21 #include <type_traits>
25 //===----------------------------------------------------------------------===//
26 // isa<x> Support Templates
27 //===----------------------------------------------------------------------===//
29 // Define a template that can be specialized by smart pointers to reflect the
30 // fact that they are automatically dereferenced, and are not involved with the
31 // template selection process... the default implementation is a noop.
33 template<typename From
> struct simplify_type
{
34 using SimpleType
= From
; // The real type this represents...
36 // An accessor to get the real value...
37 static SimpleType
&getSimplifiedValue(From
&Val
) { return Val
; }
40 template<typename From
> struct simplify_type
<const From
> {
41 using NonConstSimpleType
= typename simplify_type
<From
>::SimpleType
;
43 typename add_const_past_pointer
<NonConstSimpleType
>::type
;
45 typename add_lvalue_reference_if_not_pointer
<SimpleType
>::type
;
47 static RetType
getSimplifiedValue(const From
& Val
) {
48 return simplify_type
<From
>::getSimplifiedValue(const_cast<From
&>(Val
));
52 // The core of the implementation of isa<X> is here; To and From should be
53 // the names of classes. This template can be specialized to customize the
54 // implementation of isa<> without rewriting it from scratch.
55 template <typename To
, typename From
, typename Enabler
= void>
57 static inline bool doit(const From
&Val
) {
58 return To::classof(&Val
);
62 /// Always allow upcasts, and perform no dynamic check for them.
63 template <typename To
, typename From
>
65 To
, From
, typename
std::enable_if
<std::is_base_of
<To
, From
>::value
>::type
> {
66 static inline bool doit(const From
&) { return true; }
69 template <typename To
, typename From
> struct isa_impl_cl
{
70 static inline bool doit(const From
&Val
) {
71 return isa_impl
<To
, From
>::doit(Val
);
75 template <typename To
, typename From
> struct isa_impl_cl
<To
, const From
> {
76 static inline bool doit(const From
&Val
) {
77 return isa_impl
<To
, From
>::doit(Val
);
81 template <typename To
, typename From
>
82 struct isa_impl_cl
<To
, const std::unique_ptr
<From
>> {
83 static inline bool doit(const std::unique_ptr
<From
> &Val
) {
84 assert(Val
&& "isa<> used on a null pointer");
85 return isa_impl_cl
<To
, From
>::doit(*Val
);
89 template <typename To
, typename From
> struct isa_impl_cl
<To
, From
*> {
90 static inline bool doit(const From
*Val
) {
91 assert(Val
&& "isa<> used on a null pointer");
92 return isa_impl
<To
, From
>::doit(*Val
);
96 template <typename To
, typename From
> struct isa_impl_cl
<To
, From
*const> {
97 static inline bool doit(const From
*Val
) {
98 assert(Val
&& "isa<> used on a null pointer");
99 return isa_impl
<To
, From
>::doit(*Val
);
103 template <typename To
, typename From
> struct isa_impl_cl
<To
, const From
*> {
104 static inline bool doit(const From
*Val
) {
105 assert(Val
&& "isa<> used on a null pointer");
106 return isa_impl
<To
, From
>::doit(*Val
);
110 template <typename To
, typename From
> struct isa_impl_cl
<To
, const From
*const> {
111 static inline bool doit(const From
*Val
) {
112 assert(Val
&& "isa<> used on a null pointer");
113 return isa_impl
<To
, From
>::doit(*Val
);
117 template<typename To
, typename From
, typename SimpleFrom
>
118 struct isa_impl_wrap
{
119 // When From != SimplifiedType, we can simplify the type some more by using
120 // the simplify_type template.
121 static bool doit(const From
&Val
) {
122 return isa_impl_wrap
<To
, SimpleFrom
,
123 typename simplify_type
<SimpleFrom
>::SimpleType
>::doit(
124 simplify_type
<const From
>::getSimplifiedValue(Val
));
128 template<typename To
, typename FromTy
>
129 struct isa_impl_wrap
<To
, FromTy
, FromTy
> {
130 // When From == SimpleType, we are as simple as we are going to get.
131 static bool doit(const FromTy
&Val
) {
132 return isa_impl_cl
<To
,FromTy
>::doit(Val
);
136 // isa<X> - Return true if the parameter to the template is an instance of the
137 // template type argument. Used like this:
139 // if (isa<Type>(myVal)) { ... }
141 template <class X
, class Y
> LLVM_NODISCARD
inline bool isa(const Y
&Val
) {
142 return isa_impl_wrap
<X
, const Y
,
143 typename simplify_type
<const Y
>::SimpleType
>::doit(Val
);
146 // isa_and_nonnull<X> - Functionally identical to isa, except that a null value
149 template <class X
, class Y
>
150 LLVM_NODISCARD
inline bool isa_and_nonnull(const Y
&Val
) {
156 //===----------------------------------------------------------------------===//
157 // cast<x> Support Templates
158 //===----------------------------------------------------------------------===//
160 template<class To
, class From
> struct cast_retty
;
162 // Calculate what type the 'cast' function should return, based on a requested
163 // type of To and a source type of From.
164 template<class To
, class From
> struct cast_retty_impl
{
165 using ret_type
= To
&; // Normal case, return Ty&
167 template<class To
, class From
> struct cast_retty_impl
<To
, const From
> {
168 using ret_type
= const To
&; // Normal case, return Ty&
171 template<class To
, class From
> struct cast_retty_impl
<To
, From
*> {
172 using ret_type
= To
*; // Pointer arg case, return Ty*
175 template<class To
, class From
> struct cast_retty_impl
<To
, const From
*> {
176 using ret_type
= const To
*; // Constant pointer arg case, return const Ty*
179 template<class To
, class From
> struct cast_retty_impl
<To
, const From
*const> {
180 using ret_type
= const To
*; // Constant pointer arg case, return const Ty*
183 template <class To
, class From
>
184 struct cast_retty_impl
<To
, std::unique_ptr
<From
>> {
186 using PointerType
= typename cast_retty_impl
<To
, From
*>::ret_type
;
187 using ResultType
= typename
std::remove_pointer
<PointerType
>::type
;
190 using ret_type
= std::unique_ptr
<ResultType
>;
193 template<class To
, class From
, class SimpleFrom
>
194 struct cast_retty_wrap
{
195 // When the simplified type and the from type are not the same, use the type
196 // simplifier to reduce the type, then reuse cast_retty_impl to get the
198 using ret_type
= typename cast_retty
<To
, SimpleFrom
>::ret_type
;
201 template<class To
, class FromTy
>
202 struct cast_retty_wrap
<To
, FromTy
, FromTy
> {
203 // When the simplified type is equal to the from type, use it directly.
204 using ret_type
= typename cast_retty_impl
<To
,FromTy
>::ret_type
;
207 template<class To
, class From
>
209 using ret_type
= typename cast_retty_wrap
<
210 To
, From
, typename simplify_type
<From
>::SimpleType
>::ret_type
;
213 // Ensure the non-simple values are converted using the simplify_type template
214 // that may be specialized by smart pointers...
216 template<class To
, class From
, class SimpleFrom
> struct cast_convert_val
{
217 // This is not a simple type, use the template to simplify it...
218 static typename cast_retty
<To
, From
>::ret_type
doit(From
&Val
) {
219 return cast_convert_val
<To
, SimpleFrom
,
220 typename simplify_type
<SimpleFrom
>::SimpleType
>::doit(
221 simplify_type
<From
>::getSimplifiedValue(Val
));
225 template<class To
, class FromTy
> struct cast_convert_val
<To
,FromTy
,FromTy
> {
226 // This _is_ a simple type, just cast it.
227 static typename cast_retty
<To
, FromTy
>::ret_type
doit(const FromTy
&Val
) {
228 typename cast_retty
<To
, FromTy
>::ret_type Res2
229 = (typename cast_retty
<To
, FromTy
>::ret_type
)const_cast<FromTy
&>(Val
);
234 template <class X
> struct is_simple_type
{
235 static const bool value
=
236 std::is_same
<X
, typename simplify_type
<X
>::SimpleType
>::value
;
239 // cast<X> - Return the argument parameter cast to the specified type. This
240 // casting operator asserts that the type is correct, so it does not return null
241 // on failure. It does not allow a null argument (use cast_or_null for that).
242 // It is typically used like this:
244 // cast<Instruction>(myVal)->getParent()
246 template <class X
, class Y
>
247 inline typename
std::enable_if
<!is_simple_type
<Y
>::value
,
248 typename cast_retty
<X
, const Y
>::ret_type
>::type
250 assert(isa
<X
>(Val
) && "cast<Ty>() argument of incompatible type!");
251 return cast_convert_val
<
252 X
, const Y
, typename simplify_type
<const Y
>::SimpleType
>::doit(Val
);
255 template <class X
, class Y
>
256 inline typename cast_retty
<X
, Y
>::ret_type
cast(Y
&Val
) {
257 assert(isa
<X
>(Val
) && "cast<Ty>() argument of incompatible type!");
258 return cast_convert_val
<X
, Y
,
259 typename simplify_type
<Y
>::SimpleType
>::doit(Val
);
262 template <class X
, class Y
>
263 inline typename cast_retty
<X
, Y
*>::ret_type
cast(Y
*Val
) {
264 assert(isa
<X
>(Val
) && "cast<Ty>() argument of incompatible type!");
265 return cast_convert_val
<X
, Y
*,
266 typename simplify_type
<Y
*>::SimpleType
>::doit(Val
);
269 template <class X
, class Y
>
270 inline typename cast_retty
<X
, std::unique_ptr
<Y
>>::ret_type
271 cast(std::unique_ptr
<Y
> &&Val
) {
272 assert(isa
<X
>(Val
.get()) && "cast<Ty>() argument of incompatible type!");
273 using ret_type
= typename cast_retty
<X
, std::unique_ptr
<Y
>>::ret_type
;
275 cast_convert_val
<X
, Y
*, typename simplify_type
<Y
*>::SimpleType
>::doit(
279 // cast_or_null<X> - Functionally identical to cast, except that a null value is
282 template <class X
, class Y
>
283 LLVM_NODISCARD
inline
284 typename
std::enable_if
<!is_simple_type
<Y
>::value
,
285 typename cast_retty
<X
, const Y
>::ret_type
>::type
286 cast_or_null(const Y
&Val
) {
289 assert(isa
<X
>(Val
) && "cast_or_null<Ty>() argument of incompatible type!");
293 template <class X
, class Y
>
294 LLVM_NODISCARD
inline
295 typename
std::enable_if
<!is_simple_type
<Y
>::value
,
296 typename cast_retty
<X
, Y
>::ret_type
>::type
297 cast_or_null(Y
&Val
) {
300 assert(isa
<X
>(Val
) && "cast_or_null<Ty>() argument of incompatible type!");
304 template <class X
, class Y
>
305 LLVM_NODISCARD
inline typename cast_retty
<X
, Y
*>::ret_type
306 cast_or_null(Y
*Val
) {
307 if (!Val
) return nullptr;
308 assert(isa
<X
>(Val
) && "cast_or_null<Ty>() argument of incompatible type!");
312 template <class X
, class Y
>
313 inline typename cast_retty
<X
, std::unique_ptr
<Y
>>::ret_type
314 cast_or_null(std::unique_ptr
<Y
> &&Val
) {
317 return cast
<X
>(std::move(Val
));
320 // dyn_cast<X> - Return the argument parameter cast to the specified type. This
321 // casting operator returns null if the argument is of the wrong type, so it can
322 // be used to test for a type as well as cast if successful. This should be
323 // used in the context of an if statement like this:
325 // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
328 template <class X
, class Y
>
329 LLVM_NODISCARD
inline
330 typename
std::enable_if
<!is_simple_type
<Y
>::value
,
331 typename cast_retty
<X
, const Y
>::ret_type
>::type
332 dyn_cast(const Y
&Val
) {
333 return isa
<X
>(Val
) ? cast
<X
>(Val
) : nullptr;
336 template <class X
, class Y
>
337 LLVM_NODISCARD
inline typename cast_retty
<X
, Y
>::ret_type
dyn_cast(Y
&Val
) {
338 return isa
<X
>(Val
) ? cast
<X
>(Val
) : nullptr;
341 template <class X
, class Y
>
342 LLVM_NODISCARD
inline typename cast_retty
<X
, Y
*>::ret_type
dyn_cast(Y
*Val
) {
343 return isa
<X
>(Val
) ? cast
<X
>(Val
) : nullptr;
346 // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
347 // value is accepted.
349 template <class X
, class Y
>
350 LLVM_NODISCARD
inline
351 typename
std::enable_if
<!is_simple_type
<Y
>::value
,
352 typename cast_retty
<X
, const Y
>::ret_type
>::type
353 dyn_cast_or_null(const Y
&Val
) {
354 return (Val
&& isa
<X
>(Val
)) ? cast
<X
>(Val
) : nullptr;
357 template <class X
, class Y
>
358 LLVM_NODISCARD
inline
359 typename
std::enable_if
<!is_simple_type
<Y
>::value
,
360 typename cast_retty
<X
, Y
>::ret_type
>::type
361 dyn_cast_or_null(Y
&Val
) {
362 return (Val
&& isa
<X
>(Val
)) ? cast
<X
>(Val
) : nullptr;
365 template <class X
, class Y
>
366 LLVM_NODISCARD
inline typename cast_retty
<X
, Y
*>::ret_type
367 dyn_cast_or_null(Y
*Val
) {
368 return (Val
&& isa
<X
>(Val
)) ? cast
<X
>(Val
) : nullptr;
371 // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
372 // taking ownership of the input pointer iff isa<X>(Val) is true. If the
373 // cast is successful, From refers to nullptr on exit and the casted value
374 // is returned. If the cast is unsuccessful, the function returns nullptr
375 // and From is unchanged.
376 template <class X
, class Y
>
377 LLVM_NODISCARD
inline auto unique_dyn_cast(std::unique_ptr
<Y
> &Val
)
378 -> decltype(cast
<X
>(Val
)) {
381 return cast
<X
>(std::move(Val
));
384 template <class X
, class Y
>
385 LLVM_NODISCARD
inline auto unique_dyn_cast(std::unique_ptr
<Y
> &&Val
)
386 -> decltype(cast
<X
>(Val
)) {
387 return unique_dyn_cast
<X
, Y
>(Val
);
390 // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that
391 // a null value is accepted.
392 template <class X
, class Y
>
393 LLVM_NODISCARD
inline auto unique_dyn_cast_or_null(std::unique_ptr
<Y
> &Val
)
394 -> decltype(cast
<X
>(Val
)) {
397 return unique_dyn_cast
<X
, Y
>(Val
);
400 template <class X
, class Y
>
401 LLVM_NODISCARD
inline auto unique_dyn_cast_or_null(std::unique_ptr
<Y
> &&Val
)
402 -> decltype(cast
<X
>(Val
)) {
403 return unique_dyn_cast_or_null
<X
, Y
>(Val
);
406 } // end namespace llvm
408 #endif // LLVM_SUPPORT_CASTING_H