LLVM: include/llvm/Support/Casting.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef LLVM_SUPPORT_CASTING_H
15#define LLVM_SUPPORT_CASTING_H
16
19#include
20#include
21#include
22#include <type_traits>
23
24namespace llvm {
25
26
27
28
29
30
31
32
33
36
37
39};
40
46
49 }
50};
51
52
53
54
55
56
57
58
59
60
61
62
63template <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
68template <typename To, typename From>
69struct isa_impl<To, From, std::enable_if_t<std::is_base_of_v<To, From>>> {
70 static inline bool doit(const From &) { return true; }
71};
72
73template <typename To, typename From> struct isa_impl_cl {
74 static inline bool doit(const From &Val) {
76 }
77};
78
80 static inline bool doit(const From &Val) {
82 }
83};
84
85template <typename To, typename From>
87 static inline bool doit(const std::unique_ptr &Val) {
88 assert(Val && "isa<> used on a null pointer");
90 }
91};
92
93template <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");
97 }
98};
99
100template <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");
104 }
105};
106
108 static inline bool doit(const From *Val) {
109 assert(Val && "isa<> used on a null pointer");
111 }
112};
113
114template <typename To, typename From>
116 static inline bool doit(const From *Val) {
117 assert(Val && "isa<> used on a null pointer");
119 }
120};
121
122template <typename To, typename From, typename SimpleFrom>
124
125
130 }
131};
132
133template <typename To, typename FromTy>
135
136 static bool doit(const FromTy &Val) {
138 }
139};
140
141
142
143
144
145template <class To, class From> struct cast_retty;
146
147
148
151};
153 using ret_type = const To &;
154};
155
158};
159
161 using ret_type = const To *;
162};
163
165 using ret_type = const To *;
166};
167
168template <class To, class From>
170private:
172 using ResultType = std::remove_pointer_t;
173
174public:
175 using ret_type = std::unique_ptr;
176};
177
178template <class To, class From, class SimpleFrom> struct cast_retty_wrap {
179
180
181
183};
184
185template <class To, class FromTy> struct cast_retty_wrap<To, FromTy, FromTy> {
186
188};
189
190template <class To, class From> struct cast_retty {
193};
194
195
196
197
198
199
200
201
202template <class To, class From, class SimpleFrom> struct cast_convert_val {
203
208 }
209};
210
211template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> {
212
214 return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
215 *)&const_cast<FromTy &>(Val);
216 }
217};
218
219template <class To, class FromTy>
221
224 Val);
225 }
226};
227
228
229
230
231
234 std::is_same_v<X, typename simplify_type::SimpleType>;
235};
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252template <typename To, typename From, typename Enable = void>
256 To, const From,
258 }
259};
260
261
262
263
264
265template <typename To, typename From>
267 static inline bool isPossible(const std::optional &f) {
268 assert(f && "CastIsPossible::isPossible called on a nullopt!");
270 To, const From,
272 }
273};
274
275
276
277template <typename To, typename From>
280};
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
303};
304
305
306
307
308template <typename To, typename From, typename Derived>
311 if (!Derived::isPossible(f))
312 return Derived::castFailed();
313 return Derived::doCast(f);
314 }
315};
316
318
319
320template <typename OptionalDerived, typename Default>
321using SelfType = std::conditional_t<std::is_same_v<OptionalDerived, void>,
322 Default, OptionalDerived>;
323}
324
325
326
327
328template <typename To, typename From, typename Derived = void>
333 To, From *,
334 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
335 static inline To doCast(From *f) { return To(f); }
336};
337
338
339
340
341
342template <typename To, typename From, typename Derived = void>
346 std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
347
349 return CastResultType((typename CastResultType::element_type *)f.release());
350 }
351
353
355 if (!Self::isPossible(f.get()))
357 return doCast(std::move(f));
358 }
359};
360
361
362
363
364template <typename To, typename From, typename Derived = void>
368 std::optional, From,
369 detail::SelfType<Derived, OptionalValueCast<To, From>>> {
370 static inline std::optional castFailed() { return std::optional{}; }
371
372 static inline std::optional doCast(const From &f) { return To(f); }
373};
374
375
376
377
378
379
380
381
382
383
384
385
386
387template <typename To, typename From, typename ForwardTo>
389
390 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t>;
391
394
396 return ForwardTo::isPossible(const_cast<NonConstFrom>(f));
397 }
398
399 static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); }
400
401 static inline decltype(auto) doCast(const From &f) {
402 return ForwardTo::doCast(const_cast<NonConstFrom>(f));
403 }
404
406 return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f));
407 }
408};
409
410
411
412
413
414
415
416
417
418
419
420
421
422template <typename To, typename From, typename ForwardTo>
425 return ForwardTo::isPossible(&f);
426 }
427
428 static inline decltype(auto) doCast(const From &f) {
429 return *ForwardTo::doCast(&f);
430 }
431};
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475template <typename To, typename From, typename Enable = void>
478
480
485 }
486
487
488
489
491
496 }
497};
498
499
500
501
502template <typename To, typename From>
503struct CastInfo<To, From, std::enable_if_t<!is_simple_type::value>> {
507
509 return SimplifiedSelf::isPossible(
511 }
512
515 }
516
518 return SimplifiedSelf::castFailed();
519 }
520
522 return SimplifiedSelf::doCastIfPossible(
524 }
525};
526
527
528
529
530
531
532template <typename To, typename From>
534
535
536
537
538template <typename To, typename From>
540};
541
542
543
544
545
546
547template <typename To, typename From>
548[[nodiscard]] inline bool isa(const From &Val) {
550}
551
552template <typename First, typename Second, typename... Rest, typename From>
553[[nodiscard]] inline bool isa(const From &Val) {
554 return isa(Val) || isa<Second, Rest...>(Val);
555}
556
557
558
559
560
561
562
563
564template <typename To, typename From>
565[[nodiscard]] inline decltype(auto) cast(const From &Val) {
566 assert(isa(Val) && "cast() argument of incompatible type!");
568}
569
570template <typename To, typename From>
571[[nodiscard]] inline decltype(auto) cast(From &Val) {
572 assert(isa(Val) && "cast() argument of incompatible type!");
574}
575
576template <typename To, typename From>
577[[nodiscard]] inline decltype(auto) cast(From *Val) {
578 assert(isa(Val) && "cast() argument of incompatible type!");
580}
581
582template <typename To, typename From>
583[[nodiscard]] inline decltype(auto) cast(std::unique_ptr &&Val) {
584 assert(isa(Val) && "cast() argument of incompatible type!");
586}
587
588
589
590
591
592template
594 std::is_pointer_v || std::is_constructible_v<T, std::nullptr_t>;
595
596
597
598
599
600
601
602template <typename T, typename Enable = void> struct ValueIsPresent {
604 static inline bool isPresent(const T &t) { return true; }
605 static inline decltype(auto) unwrapValue(T &t) { return t; }
606};
607
608
611 static inline bool isPresent(const std::optional &t) {
612 return t.has_value();
613 }
614 static inline decltype(auto) unwrapValue(std::optional &t) { return *t; }
615};
616
617
618
619template
622 static inline bool isPresent(const T &t) { return t != T(nullptr); }
623 static inline decltype(auto) unwrapValue(T &t) { return t; }
624};
625
627
628
629template inline bool isPresent(const T &t) {
632}
633
634
635template inline decltype(auto) unwrapValue(T &t) {
637}
638}
639
640
641
642
643
644
645
646
647
648template <typename To, typename From>
649[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) {
652}
653
654template <typename To, typename From>
658}
659
660template <typename To, typename From>
664}
665
666template <typename To, typename From>
667[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr &Val) {
670}
671
672
673
674template <typename... X, class Y>
677 return false;
679}
680
681template <typename... X, class Y>
684}
685
686
687
688template <class X, class Y>
692 assert(isa(Val) && "cast_if_present() argument of incompatible type!");
694}
695
696template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) {
699 assert(isa(Val) && "cast_if_present() argument of incompatible type!");
701}
702
703template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) {
706 assert(isa(Val) && "cast_if_present() argument of incompatible type!");
708}
709
710template <class X, class Y>
715}
716
717
718
719
721 return cast_if_present(Val);
722}
723
725 return cast_if_present(Val);
726}
727
729 return cast_if_present(Val);
730}
731
732template <class X, class Y> auto cast_or_null(std::unique_ptr &&Val) {
733 return cast_if_present(std::move(Val));
734}
735
736
737
742}
743
748}
749
754}
755
756
757
758
760 return dyn_cast_if_present(Val);
761}
762
764 return dyn_cast_if_present(Val);
765}
766
768 return dyn_cast_if_present(Val);
769}
770
771
772
773
774
775
776template <class X, class Y>
777[[nodiscard]] inline typename CastInfo<X, std::unique_ptr>::CastResultType
779 if (!isa(Val))
780 return nullptr;
781 return cast(std::move(Val));
782}
783
784template <class X, class Y>
786 return unique_dyn_cast<X, Y>(Val);
787}
788
789
790
791template <class X, class Y>
792[[nodiscard]] inline typename CastInfo<X, std::unique_ptr>::CastResultType
794 if (!Val)
795 return nullptr;
796 return unique_dyn_cast<X, Y>(Val);
797}
798
799template <class X, class Y>
801 return unique_dyn_cast_or_null<X, Y>(Val);
802}
803
804
805
806
807
808
809
810
811
812
815 template [[nodiscard]] bool operator()(const T &Val) const {
816 return isa<Types...>(Val);
817 }
818};
819
821 template [[nodiscard]] bool operator()(const T &Val) const {
823 }
824};
825}
826
827
828
829
830
831
832
833
834
835template <typename... Types>
837
838
839
840
841
842
843
844
845
846template <typename... Types>
847inline constexpr detail::IsaAndPresentCheckPredicate<Types...>
849
850}
851
852#endif
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_v< OptionalDerived, void >, 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 - 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 - Given a unique_ptr, try to return a unique_ptr, taking ownership of the in...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...
auto cast_or_null(const Y &Val)
constexpr detail::IsaAndPresentCheckPredicate< Types... > IsaAndPresentPred
Function object wrapper for the llvm::isa_and_present type check.
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 - Functionally identical to isa, except that a null value is accepted.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
constexpr bool IsNullable
decltype(auto) cast(const From &Val)
cast - 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.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Implement std::hash so that hash_code can be used in STL containers.
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 ...
static decltype(auto) castFailed()
static decltype(auto) doCastIfPossible(const From &f)
std::conditional_t< std::is_pointer_v< From >, DecayedFrom *, DecayedFrom & > NonConstFrom
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 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 doCast(std::unique_ptr< From > &&f)
static CastResultType doCastIfPossible(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
bool operator()(const T &Val) const
bool operator()(const T &Val) const
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)