LLVM  15.0.0git
Casting.h
Go to the documentation of this file.
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/ADT/Optional.h"
18 #include "llvm/Support/Compiler.h"
20 #include <cassert>
21 #include <memory>
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> {
44  using RetType =
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>
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,
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:
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.
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.
188 };
189 
190 template <class To, class From> struct cast_retty {
191  using ret_type = typename cast_retty_wrap<
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,
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>
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>
267  static inline bool isPossible(const Optional<From> &f) {
268  assert(f.hasValue() && "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>
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>
331  : public CastIsPossible<To, From *>,
332  public NullableValueCastFailed<To>,
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 *> {
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 Optional<T> casting. This means that if you have a
363 /// value type, you can cast it to another value type and have dyn_cast return
364 /// an Optional<T>.
365 template <typename To, typename From, typename Derived = void>
367  : public CastIsPossible<To, From>,
369  Optional<To>, From,
370  detail::SelfType<Derived, OptionalValueCast<To, From>>> {
371  static inline Optional<To> castFailed() { return Optional<To>{}; }
372 
373  static inline 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>
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,
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>
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> {
479 
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>> {
508 
509  static inline bool isPossible(From &f) {
510  return SimplifiedSelf::isPossible(
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(
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 Optional<From>. It's assumed that if the
537 /// input is Optional<From> that the output can be Optional<To>. If that's not
538 /// the case, specialize CastInfo for your use case.
539 template <typename To, typename From>
540 struct CastInfo<To, Optional<From>> : public OptionalValueCast<To, From> {};
541 
542 /// isa<X> - Return true if the parameter to the template is an instance of one
543 /// of the template type arguments. Used like this:
544 ///
545 /// if (isa<Type>(myVal)) { ... }
546 /// if (isa<Type0, Type1, Type2>(myVal)) { ... }
547 template <typename To, typename From>
548 LLVM_NODISCARD inline bool isa(const From &Val) {
550 }
551 
552 template <typename First, typename Second, typename... Rest, typename From>
553 LLVM_NODISCARD inline bool isa(const From &Val) {
554  return isa<First>(Val) || isa<Second, Rest...>(Val);
555 }
556 
557 /// cast<X> - Return the argument parameter cast to the specified type. This
558 /// casting operator asserts that the type is correct, so it does not return
559 /// null on failure. It does not allow a null argument (use cast_if_present for
560 /// that). It is typically used like this:
561 ///
562 /// cast<Instruction>(myVal)->getParent()
563 
564 template <typename To, typename From>
565 LLVM_NODISCARD inline decltype(auto) cast(const From &Val) {
566  assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
568 }
569 
570 template <typename To, typename From>
571 LLVM_NODISCARD inline decltype(auto) cast(From &Val) {
572  assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
573  return CastInfo<To, From>::doCast(Val);
574 }
575 
576 template <typename To, typename From>
577 LLVM_NODISCARD inline decltype(auto) cast(From *Val) {
578  assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
579  return CastInfo<To, From *>::doCast(Val);
580 }
581 
582 template <typename To, typename From>
583 LLVM_NODISCARD inline decltype(auto) cast(std::unique_ptr<From> &&Val) {
584  assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");
585  return CastInfo<To, std::unique_ptr<From>>::doCast(std::move(Val));
586 }
587 
588 /// dyn_cast<X> - Return the argument parameter cast to the specified type. This
589 /// casting operator returns null if the argument is of the wrong type, so it
590 /// can be used to test for a type as well as cast if successful. The value
591 /// passed in must be present, if not, use dyn_cast_if_present. This should be
592 /// used in the context of an if statement like this:
593 ///
594 /// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
595 
596 template <typename To, typename From>
597 LLVM_NODISCARD inline decltype(auto) dyn_cast(const From &Val) {
599 }
600 
601 template <typename To, typename From>
602 LLVM_NODISCARD inline decltype(auto) dyn_cast(From &Val) {
604 }
605 
606 template <typename To, typename From>
607 LLVM_NODISCARD inline decltype(auto) dyn_cast(From *Val) {
609 }
610 
611 template <typename To, typename From>
612 LLVM_NODISCARD inline decltype(auto) dyn_cast(std::unique_ptr<From> &&Val) {
613  return CastInfo<To, std::unique_ptr<From>>::doCastIfPossible(std::move(Val));
614 }
615 
616 //===----------------------------------------------------------------------===//
617 // ValueIsPresent
618 //===----------------------------------------------------------------------===//
619 
620 template <typename T>
621 constexpr bool IsNullable = std::is_pointer<T>::value ||
622  std::is_constructible<T, std::nullptr_t>::value;
623 
624 /// ValueIsPresent provides a way to check if a value is, well, present. For
625 /// pointers, this is the equivalent of checking against nullptr, for
626 /// Optionals this is the equivalent of checking hasValue(). It also
627 /// provides a method for unwrapping a value (think dereferencing a
628 /// pointer).
629 
630 // Generic values can't *not* be present.
631 template <typename T, typename Enable = void> struct ValueIsPresent {
632  using UnwrappedType = T;
633  static inline bool isPresent(const T &t) { return true; }
634  static inline decltype(auto) unwrapValue(T &t) { return t; }
635 };
636 
637 // Optional provides its own way to check if something is present.
638 template <typename T> struct ValueIsPresent<Optional<T>> {
639  using UnwrappedType = T;
640  static inline bool isPresent(const Optional<T> &t) { return t.has_value(); }
641  static inline decltype(auto) unwrapValue(Optional<T> &t) {
642  return t.getValue();
643  }
644 };
645 
646 // If something is "nullable" then we just compare it to nullptr to see if it
647 // exists.
648 template <typename T>
649 struct ValueIsPresent<T, std::enable_if_t<IsNullable<T>>> {
650  using UnwrappedType = T;
651  static inline bool isPresent(const T &t) { return t != nullptr; }
652  static inline decltype(auto) unwrapValue(T &t) { return t; }
653 };
654 
655 namespace detail {
656 // Convenience function we can use to check if a value is present. Because of
657 // simplify_type, we have to call it on the simplified type for now.
658 template <typename T> inline bool isPresent(const T &t) {
660  simplify_type<T>::getSimplifiedValue(const_cast<T &>(t)));
661 }
662 
663 // Convenience function we can use to unwrap a value.
664 template <typename T> inline decltype(auto) unwrapValue(T &t) {
666 }
667 } // namespace detail
668 
669 /// isa_and_present<X> - Functionally identical to isa, except that a null value
670 /// is accepted.
671 template <typename... X, class Y>
672 LLVM_NODISCARD inline bool isa_and_present(const Y &Val) {
673  if (!detail::isPresent(Val))
674  return false;
675  return isa<X...>(Val);
676 }
677 
678 template <typename... X, class Y>
679 LLVM_NODISCARD inline bool isa_and_nonnull(const Y &Val) {
680  return isa_and_present<X...>(Val);
681 }
682 
683 /// cast_if_present<X> - Functionally identical to cast, except that a null
684 /// value is accepted.
685 template <class X, class Y>
686 LLVM_NODISCARD inline auto cast_if_present(const Y &Val) {
687  if (!detail::isPresent(Val))
689  assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!");
690  return cast<X>(detail::unwrapValue(Val));
691 }
692 
693 template <class X, class Y> LLVM_NODISCARD inline auto cast_if_present(Y &Val) {
694  if (!detail::isPresent(Val))
696  assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!");
697  return cast<X>(detail::unwrapValue(Val));
698 }
699 
700 template <class X, class Y> LLVM_NODISCARD inline auto cast_if_present(Y *Val) {
701  if (!detail::isPresent(Val))
703  assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!");
704  return cast<X>(detail::unwrapValue(Val));
705 }
706 
707 template <class X, class Y>
708 LLVM_NODISCARD inline auto cast_if_present(std::unique_ptr<Y> &&Val) {
709  if (!detail::isPresent(Val))
712 }
713 
714 // Provide a forwarding from cast_or_null to cast_if_present for current
715 // users. This is deprecated and will be removed in a future patch, use
716 // cast_if_present instead.
717 template <class X, class Y> auto cast_or_null(const Y &Val) {
718  return cast_if_present<X>(Val);
719 }
720 
721 template <class X, class Y> auto cast_or_null(Y &Val) {
722  return cast_if_present<X>(Val);
723 }
724 
725 template <class X, class Y> auto cast_or_null(Y *Val) {
726  return cast_if_present<X>(Val);
727 }
728 
729 template <class X, class Y> auto cast_or_null(std::unique_ptr<Y> &&Val) {
730  return cast_if_present<X>(std::move(Val));
731 }
732 
733 /// dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a
734 /// null (or none in the case of optionals) value is accepted.
735 template <class X, class Y> auto dyn_cast_if_present(const Y &Val) {
736  if (!detail::isPresent(Val))
739 }
740 
741 template <class X, class Y> auto dyn_cast_if_present(Y &Val) {
742  if (!detail::isPresent(Val))
745 }
746 
747 template <class X, class Y> auto dyn_cast_if_present(Y *Val) {
748  if (!detail::isPresent(Val))
751 }
752 
753 // Forwards to dyn_cast_if_present to avoid breaking current users. This is
754 // deprecated and will be removed in a future patch, use
755 // cast_if_present instead.
756 template <class X, class Y> auto dyn_cast_or_null(const Y &Val) {
757  return dyn_cast_if_present<X>(Val);
758 }
759 
760 template <class X, class Y> auto dyn_cast_or_null(Y &Val) {
761  return dyn_cast_if_present<X>(Val);
762 }
763 
764 template <class X, class Y> auto dyn_cast_or_null(Y *Val) {
765  return dyn_cast_if_present<X>(Val);
766 }
767 
768 /// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
769 /// taking ownership of the input pointer iff isa<X>(Val) is true. If the
770 /// cast is successful, From refers to nullptr on exit and the casted value
771 /// is returned. If the cast is unsuccessful, the function returns nullptr
772 /// and From is unchanged.
773 template <class X, class Y>
774 LLVM_NODISCARD inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
775 unique_dyn_cast(std::unique_ptr<Y> &Val) {
776  if (!isa<X>(Val))
777  return nullptr;
778  return cast<X>(std::move(Val));
779 }
780 
781 template <class X, class Y>
782 LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) {
783  return unique_dyn_cast<X, Y>(Val);
784 }
785 
786 // unique_dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast,
787 // except that a null value is accepted.
788 template <class X, class Y>
789 LLVM_NODISCARD inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
790 unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) {
791  if (!Val)
792  return nullptr;
793  return unique_dyn_cast<X, Y>(Val);
794 }
795 
796 template <class X, class Y>
797 LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) {
798  return unique_dyn_cast_or_null<X, Y>(Val);
799 }
800 
801 } // end namespace llvm
802 
803 #endif // LLVM_SUPPORT_CASTING_H
llvm::CastIsPossible< To, Optional< From > >::isPossible
static bool isPossible(const Optional< From > &f)
Definition: Casting.h:267
llvm::DefaultDoCastIfPossible
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
Definition: Casting.h:310
PointerType
Definition: ItaniumDemangle.h:580
llvm::ValueIsPresent::unwrapValue
static decltype(auto) unwrapValue(T &t)
Definition: Casting.h:634
llvm::isa_impl_wrap< To, FromTy, FromTy >::doit
static bool doit(const FromTy &Val)
Definition: Casting.h:136
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::cast_retty_impl< To, std::unique_ptr< From > >::ret_type
std::unique_ptr< ResultType > ret_type
Definition: Casting.h:175
Optional.h
llvm::CastInfo
This struct provides a method for customizing the way a cast is performed.
Definition: Casting.h:477
llvm::ForwardToPointerCast::isPossible
static bool isPossible(const From &f)
Definition: Casting.h:425
llvm::ValueIsPresent< Optional< T > >::UnwrappedType
T UnwrappedType
Definition: Casting.h:639
llvm::cast
decltype(auto) LLVM_NODISCARD cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:565
llvm::cast_if_present
LLVM_NODISCARD auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
Definition: Casting.h:686
llvm::cast_retty_impl< To, const From >::ret_type
const To & ret_type
Definition: Casting.h:153
llvm::cast_convert_val< To, FromTy, FromTy >::doit
static cast_retty< To, FromTy >::ret_type doit(const FromTy &Val)
Definition: Casting.h:213
llvm::OptionalValueCast::castFailed
static Optional< To > castFailed()
Definition: Casting.h:371
llvm::isa_and_present
LLVM_NODISCARD bool isa_and_present(const Y &Val)
isa_and_present<X> - Functionally identical to isa, except that a null value is accepted.
Definition: Casting.h:672
llvm::cast_retty_impl< To, From * >::ret_type
To * ret_type
Definition: Casting.h:157
llvm::isa
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...
Definition: Casting.h:548
llvm::Optional
Definition: APInt.h:33
llvm::simplify_type< const From >::RetType
typename add_lvalue_reference_if_not_pointer< SimpleType >::type RetType
Definition: Casting.h:45
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::ValueIsPresent::UnwrappedType
T UnwrappedType
Definition: Casting.h:632
llvm::unique_dyn_cast
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...
Definition: Casting.h:775
llvm::ConstStrippingForwardingCast::isPossible
static bool isPossible(const From &f)
Definition: Casting.h:396
llvm::cast_convert_val< To, FromTy *, FromTy * >::doit
static cast_retty< To, FromTy * >::ret_type doit(const FromTy *Val)
Definition: Casting.h:222
llvm::OptionalValueCast
This cast trait provides Optional<T> casting.
Definition: Casting.h:366
llvm::UniquePtrCast< To, From >::CastResultType
std::unique_ptr< std::remove_reference_t< typename cast_retty< To, From >::ret_type > > CastResultType
Definition: Casting.h:347
llvm::UniquePtrCast
This cast trait provides std::unique_ptr casting.
Definition: Casting.h:344
llvm::isa_impl_cl< To, From *const >::doit
static bool doit(const From *Val)
Definition: Casting.h:101
llvm::cast_retty
Definition: Casting.h:145
llvm::cast_or_null
auto cast_or_null(const Y &Val)
Definition: Casting.h:717
llvm::NullableValueCastFailed::castFailed
static To castFailed()
Definition: Casting.h:303
llvm::CastIsPossible
This struct provides a way to check if a given cast is possible.
Definition: Casting.h:253
llvm::cast_retty::ret_type
typename cast_retty_wrap< To, From, typename simplify_type< From >::SimpleType >::ret_type ret_type
Definition: Casting.h:192
llvm::add_lvalue_reference_if_not_pointer::type
T & type
Definition: type_traits.h:44
llvm::isa_impl::doit
static bool doit(const From &Val)
Definition: Casting.h:64
llvm::CastIsPossible::isPossible
static bool isPossible(const From &f)
Definition: Casting.h:254
llvm::isa_impl_cl< To, const From * >::doit
static bool doit(const From *Val)
Definition: Casting.h:108
f
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
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
llvm::ValueFromPointerCast::doCast
static To doCast(From *f)
Definition: Casting.h:336
llvm::UniquePtrCast::castFailed
static CastResultType castFailed()
Definition: Casting.h:353
llvm::isa_impl_wrap::doit
static bool doit(const From &Val)
Definition: Casting.h:126
t
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
Definition: README-SSE.txt:788
llvm::cast_retty_impl< To, const From * >::ret_type
const To * ret_type
Definition: Casting.h:161
llvm::isa_impl_cl< To, From * >::doit
static bool doit(const From *Val)
Definition: Casting.h:94
llvm::simplify_type
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
Definition: ilist_iterator.h:178
llvm::CastInfo::CastReturnType
typename cast_retty< To, From >::ret_type CastReturnType
Definition: Casting.h:480
llvm::isa_impl_wrap
Definition: Casting.h:123
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
llvm::simplify_type< const From >::NonConstSimpleType
typename simplify_type< From >::SimpleType NonConstSimpleType
Definition: Casting.h:42
llvm::ValueIsPresent
ValueIsPresent provides a way to check if a value is, well, present.
Definition: Casting.h:631
llvm::NullableValueCastFailed
All of these cast traits are meant to be implementations for useful casts that users may want to use ...
Definition: Casting.h:302
llvm::CastInfo::doCast
static CastReturnType doCast(const From &f)
Definition: Casting.h:482
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::dyn_cast_if_present
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 ...
Definition: Casting.h:735
llvm::is_simple_type::value
static const bool value
Definition: Casting.h:233
llvm::UniquePtrCast< To, From >::Self
detail::SelfType< void, UniquePtrCast< To, From > > Self
Definition: Casting.h:345
llvm::detail::SelfType
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 ...
Definition: Casting.h:323
llvm::ConstStrippingForwardingCast< To, const PointerUnion< PTs... >, CastInfo< To, PointerUnion< PTs... > > >::DecayedFrom
std::remove_cv_t< std::remove_pointer_t< const PointerUnion< PTs... > > > DecayedFrom
Definition: Casting.h:391
llvm::OptionalValueCast::doCast
static Optional< To > doCast(const From &f)
Definition: Casting.h:373
llvm::cast_retty_impl
Definition: Casting.h:149
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::cast_retty_wrap::ret_type
typename cast_retty< To, SimpleFrom >::ret_type ret_type
Definition: Casting.h:182
llvm::ValueIsPresent< T, std::enable_if_t< IsNullable< T > > >::isPresent
static bool isPresent(const T &t)
Definition: Casting.h:651
move
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
Definition: README.txt:546
llvm::ForwardToPointerCast::doCast
static decltype(auto) doCast(const From &f)
Definition: Casting.h:429
llvm::ConstStrippingForwardingCast::castFailed
static decltype(auto) castFailed()
Definition: Casting.h:400
llvm::ForwardToPointerCast
Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...
Definition: Casting.h:424
llvm::UniquePtrCast::doCast
static CastResultType doCast(std::unique_ptr< From > &&f)
Definition: Casting.h:349
llvm::isa_impl_cl< To, const From *const >::doit
static bool doit(const From *Val)
Definition: Casting.h:116
llvm::cast_convert_val
Definition: Casting.h:202
llvm::cast_convert_val::doit
static cast_retty< To, From >::ret_type doit(const From &Val)
Definition: Casting.h:204
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::CastInfo::castFailed
static CastReturnType castFailed()
Definition: Casting.h:491
llvm::cast_retty_wrap< To, FromTy, FromTy >::ret_type
typename cast_retty_impl< To, FromTy >::ret_type ret_type
Definition: Casting.h:187
llvm::ValueFromPointerCast
This cast trait provides casting for the specific case of casting to a value-typed object from a poin...
Definition: Casting.h:330
llvm::simplify_type< const From >::getSimplifiedValue
static RetType getSimplifiedValue(const From &Val)
Definition: Casting.h:47
llvm::isa_impl_cl< To, const From >::doit
static bool doit(const From &Val)
Definition: Casting.h:80
llvm::ValueIsPresent::isPresent
static bool isPresent(const T &t)
Definition: Casting.h:633
llvm::simplify_type::SimpleType
From SimpleType
Definition: Casting.h:35
llvm::CastInfo< To, From, std::enable_if_t<!is_simple_type< From >::value > >::SimpleFrom
typename simplify_type< From >::SimpleType SimpleFrom
Definition: Casting.h:506
Compiler.h
llvm::CastInfo< To, From, std::enable_if_t<!is_simple_type< From >::value > >::isPossible
static bool isPossible(From &f)
Definition: Casting.h:509
llvm::IsNullable
constexpr bool IsNullable
Definition: Casting.h:621
llvm::cast_retty_impl::ret_type
To & ret_type
Definition: Casting.h:150
llvm::isa_and_nonnull
LLVM_NODISCARD bool isa_and_nonnull(const Y &Val)
Definition: Casting.h:679
llvm::ValueIsPresent< Optional< T > >::isPresent
static bool isPresent(const Optional< T > &t)
Definition: Casting.h:640
llvm::add_const_past_pointer::type
const T type
Definition: type_traits.h:55
llvm::isa_impl< To, From, std::enable_if_t< std::is_base_of< To, From >::value > >::doit
static bool doit(const From &)
Definition: Casting.h:70
llvm::CastIsPossible< To, From, std::enable_if_t< std::is_base_of< To, From >::value > >::isPossible
static bool isPossible(const From &f)
Definition: Casting.h:280
llvm::ConstStrippingForwardingCast< To, const PointerUnion< PTs... >, CastInfo< To, PointerUnion< PTs... > > >::NonConstFrom
std::conditional_t< std::is_pointer< const PointerUnion< PTs... > >::value, DecayedFrom *, DecayedFrom & > NonConstFrom
Definition: Casting.h:394
llvm::cast_retty_impl< To, const From *const >::ret_type
const To * ret_type
Definition: Casting.h:165
llvm::DefaultDoCastIfPossible::doCastIfPossible
static To doCastIfPossible(From f)
Definition: Casting.h:311
std
Definition: BitVector.h:851
type_traits.h
llvm::simplify_type::getSimplifiedValue
static SimpleType & getSimplifiedValue(From &Val)
Definition: Casting.h:38
llvm::CastInfo::doCastIfPossible
static CastReturnType doCastIfPossible(const From &f)
Definition: Casting.h:493
llvm::cast_retty_wrap
Definition: Casting.h:178
LLVM_NODISCARD
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
Definition: Compiler.h:155
llvm::is_simple_type
Definition: Casting.h:232
llvm::ConstStrippingForwardingCast
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
Definition: Casting.h:389
llvm::ConstStrippingForwardingCast::doCast
static decltype(auto) doCast(const From &f)
Definition: Casting.h:402
llvm::isa_impl_cl
Definition: Casting.h:73
llvm::UniquePtrCast::doCastIfPossible
static CastResultType doCastIfPossible(std::unique_ptr< From > &&f)
Definition: Casting.h:355
llvm::isa_impl_cl::doit
static bool doit(const From &Val)
Definition: Casting.h:74
llvm::ConstStrippingForwardingCast::doCastIfPossible
static decltype(auto) doCastIfPossible(const From &f)
Definition: Casting.h:406
llvm::unique_dyn_cast_or_null
LLVM_NODISCARD CastInfo< X, std::unique_ptr< Y > >::CastResultType unique_dyn_cast_or_null(std::unique_ptr< Y > &Val)
Definition: Casting.h:790
llvm::detail::isPresent
bool isPresent(const T &t)
Definition: Casting.h:658
From
BlockVerifier::State From
Definition: BlockVerifier.cpp:55
llvm::isa_impl_cl< To, const std::unique_ptr< From > >::doit
static bool doit(const std::unique_ptr< From > &Val)
Definition: Casting.h:87
llvm::isa_impl
Definition: Casting.h:63
llvm::detail::unwrapValue
decltype(auto) unwrapValue(T &t)
Definition: Casting.h:664
llvm::ValueIsPresent< T, std::enable_if_t< IsNullable< T > > >::UnwrappedType
T UnwrappedType
Definition: Casting.h:650
llvm::dyn_cast
decltype(auto) LLVM_NODISCARD dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:597
llvm::simplify_type< const From >::SimpleType
typename add_const_past_pointer< NonConstSimpleType >::type SimpleType
Definition: Casting.h:43
llvm::dyn_cast_or_null
auto dyn_cast_or_null(const Y &Val)
Definition: Casting.h:756