1 use super::misc
::MiscMethods
;
4 use crate::common
::TypeKind
;
5 use crate::mir
::place
::PlaceRef
;
6 use rustc_middle
::ty
::layout
::TyAndLayout
;
7 use rustc_middle
::ty
::{self, Ty}
;
8 use rustc_span
::DUMMY_SP
;
9 use rustc_target
::abi
::call
::{ArgAbi, CastTarget, FnAbi, Reg}
;
10 use rustc_target
::abi
::{AddressSpace, Integer}
;
12 // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
13 // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
14 pub trait BaseTypeMethods
<'tcx
>: Backend
<'tcx
> {
15 fn type_i1(&self) -> Self::Type
;
16 fn type_i8(&self) -> Self::Type
;
17 fn type_i16(&self) -> Self::Type
;
18 fn type_i32(&self) -> Self::Type
;
19 fn type_i64(&self) -> Self::Type
;
20 fn type_i128(&self) -> Self::Type
;
21 fn type_isize(&self) -> Self::Type
;
23 fn type_f32(&self) -> Self::Type
;
24 fn type_f64(&self) -> Self::Type
;
26 fn type_func(&self, args
: &[Self::Type
], ret
: Self::Type
) -> Self::Type
;
27 fn type_struct(&self, els
: &[Self::Type
], packed
: bool
) -> Self::Type
;
28 fn type_kind(&self, ty
: Self::Type
) -> TypeKind
;
29 fn type_ptr_to(&self, ty
: Self::Type
) -> Self::Type
;
30 fn type_ptr_to_ext(&self, ty
: Self::Type
, address_space
: AddressSpace
) -> Self::Type
;
31 fn element_type(&self, ty
: Self::Type
) -> Self::Type
;
33 /// Returns the number of elements in `self` if it is a LLVM vector type.
34 fn vector_length(&self, ty
: Self::Type
) -> usize;
36 fn float_width(&self, ty
: Self::Type
) -> usize;
38 /// Retrieves the bit width of the integer type `self`.
39 fn int_width(&self, ty
: Self::Type
) -> u64;
41 fn val_ty(&self, v
: Self::Value
) -> Self::Type
;
44 pub trait DerivedTypeMethods
<'tcx
>: BaseTypeMethods
<'tcx
> + MiscMethods
<'tcx
> {
45 fn type_i8p(&self) -> Self::Type
{
46 self.type_i8p_ext(AddressSpace
::DATA
)
49 fn type_i8p_ext(&self, address_space
: AddressSpace
) -> Self::Type
{
50 self.type_ptr_to_ext(self.type_i8(), address_space
)
53 fn type_int(&self) -> Self::Type
{
54 match &self.sess().target
.c_int_width
[..] {
55 "16" => self.type_i16(),
56 "32" => self.type_i32(),
57 "64" => self.type_i64(),
58 width
=> bug
!("Unsupported c_int_width: {}", width
),
62 fn type_from_integer(&self, i
: Integer
) -> Self::Type
{
66 I16
=> self.type_i16(),
67 I32
=> self.type_i32(),
68 I64
=> self.type_i64(),
69 I128
=> self.type_i128(),
73 fn type_needs_drop(&self, ty
: Ty
<'tcx
>) -> bool
{
74 ty
.needs_drop(self.tcx(), ty
::ParamEnv
::reveal_all())
77 fn type_is_sized(&self, ty
: Ty
<'tcx
>) -> bool
{
78 ty
.is_sized(self.tcx().at(DUMMY_SP
), ty
::ParamEnv
::reveal_all())
81 fn type_is_freeze(&self, ty
: Ty
<'tcx
>) -> bool
{
82 ty
.is_freeze(self.tcx().at(DUMMY_SP
), ty
::ParamEnv
::reveal_all())
85 fn type_has_metadata(&self, ty
: Ty
<'tcx
>) -> bool
{
86 let param_env
= ty
::ParamEnv
::reveal_all();
87 if ty
.is_sized(self.tcx().at(DUMMY_SP
), param_env
) {
91 let tail
= self.tcx().struct_tail_erasing_lifetimes(ty
, param_env
);
93 ty
::Foreign(..) => false,
94 ty
::Str
| ty
::Slice(..) | ty
::Dynamic(..) => true,
95 _
=> bug
!("unexpected unsized tail: {:?}", tail
),
100 impl<'tcx
, T
> DerivedTypeMethods
<'tcx
> for T
where Self: BaseTypeMethods
<'tcx
> + MiscMethods
<'tcx
> {}
102 pub trait LayoutTypeMethods
<'tcx
>: Backend
<'tcx
> {
103 fn backend_type(&self, layout
: TyAndLayout
<'tcx
>) -> Self::Type
;
104 fn cast_backend_type(&self, ty
: &CastTarget
) -> Self::Type
;
105 fn fn_decl_backend_type(&self, fn_abi
: &FnAbi
<'tcx
, Ty
<'tcx
>>) -> Self::Type
;
106 fn fn_ptr_backend_type(&self, fn_abi
: &FnAbi
<'tcx
, Ty
<'tcx
>>) -> Self::Type
;
107 fn reg_backend_type(&self, ty
: &Reg
) -> Self::Type
;
108 fn immediate_backend_type(&self, layout
: TyAndLayout
<'tcx
>) -> Self::Type
;
109 fn is_backend_immediate(&self, layout
: TyAndLayout
<'tcx
>) -> bool
;
110 fn is_backend_scalar_pair(&self, layout
: TyAndLayout
<'tcx
>) -> bool
;
111 fn backend_field_index(&self, layout
: TyAndLayout
<'tcx
>, index
: usize) -> u64;
112 fn scalar_pair_element_backend_type(
114 layout
: TyAndLayout
<'tcx
>,
120 // For backends that support CFI using type membership (i.e., testing whether a given pointer is
121 // associated with a type identifier).
122 pub trait TypeMembershipMethods
<'tcx
>: Backend
<'tcx
> {
123 fn set_type_metadata(&self, function
: Self::Function
, typeid
: String
);
124 fn typeid_metadata(&self, typeid
: String
) -> Self::Value
;
127 pub trait ArgAbiMethods
<'tcx
>: HasCodegen
<'tcx
> {
130 arg_abi
: &ArgAbi
<'tcx
, Ty
<'tcx
>>,
132 dst
: PlaceRef
<'tcx
, Self::Value
>,
136 arg_abi
: &ArgAbi
<'tcx
, Ty
<'tcx
>>,
138 dst
: PlaceRef
<'tcx
, Self::Value
>,
140 fn arg_memory_ty(&self, arg_abi
: &ArgAbi
<'tcx
, Ty
<'tcx
>>) -> Self::Type
;
143 pub trait TypeMethods
<'tcx
>:
144 DerivedTypeMethods
<'tcx
> + LayoutTypeMethods
<'tcx
> + TypeMembershipMethods
<'tcx
>
148 impl<'tcx
, T
> TypeMethods
<'tcx
> for T
where
149 Self: DerivedTypeMethods
<'tcx
> + LayoutTypeMethods
<'tcx
> + TypeMembershipMethods
<'tcx
>