1 use super::misc
::MiscMethods
;
4 use crate::common
::{self, TypeKind}
;
5 use crate::mir
::place
::PlaceRef
;
6 use rustc
::ty
::layout
::{self, Align, Size, TyLayout}
;
7 use rustc
::ty
::{self, Ty}
;
8 use rustc
::util
::nodemap
::FxHashMap
;
9 use rustc_target
::abi
::call
::{ArgType, CastTarget, FnType, Reg}
;
10 use std
::cell
::RefCell
;
13 // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
14 // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
15 pub trait BaseTypeMethods
<'tcx
>: Backend
<'tcx
> {
16 fn type_void(&self) -> Self::Type
;
17 fn type_metadata(&self) -> Self::Type
;
18 fn type_i1(&self) -> Self::Type
;
19 fn type_i8(&self) -> Self::Type
;
20 fn type_i16(&self) -> Self::Type
;
21 fn type_i32(&self) -> Self::Type
;
22 fn type_i64(&self) -> Self::Type
;
23 fn type_i128(&self) -> Self::Type
;
25 // Creates an integer type with the given number of bits, e.g., i24
26 fn type_ix(&self, num_bits
: u64) -> Self::Type
;
27 fn type_isize(&self) -> Self::Type
;
29 fn type_f32(&self) -> Self::Type
;
30 fn type_f64(&self) -> Self::Type
;
31 fn type_x86_mmx(&self) -> Self::Type
;
33 fn type_func(&self, args
: &[Self::Type
], ret
: Self::Type
) -> Self::Type
;
34 fn type_variadic_func(&self, args
: &[Self::Type
], ret
: Self::Type
) -> Self::Type
;
35 fn type_struct(&self, els
: &[Self::Type
], packed
: bool
) -> Self::Type
;
36 fn type_array(&self, ty
: Self::Type
, len
: u64) -> Self::Type
;
37 fn type_vector(&self, ty
: Self::Type
, len
: u64) -> Self::Type
;
38 fn type_kind(&self, ty
: Self::Type
) -> TypeKind
;
39 fn type_ptr_to(&self, ty
: Self::Type
) -> Self::Type
;
40 fn element_type(&self, ty
: Self::Type
) -> Self::Type
;
42 /// Returns the number of elements in `self` if it is a LLVM vector type.
43 fn vector_length(&self, ty
: Self::Type
) -> usize;
45 fn func_params_types(&self, ty
: Self::Type
) -> Vec
<Self::Type
>;
46 fn float_width(&self, ty
: Self::Type
) -> usize;
48 /// Retrieves the bit width of the integer type `self`.
49 fn int_width(&self, ty
: Self::Type
) -> u64;
51 fn val_ty(&self, v
: Self::Value
) -> Self::Type
;
52 fn scalar_lltypes(&self) -> &RefCell
<FxHashMap
<Ty
<'tcx
>, Self::Type
>>;
55 pub trait DerivedTypeMethods
<'tcx
>: BaseTypeMethods
<'tcx
> + MiscMethods
<'tcx
> {
56 fn type_bool(&self) -> Self::Type
{
60 fn type_i8p(&self) -> Self::Type
{
61 self.type_ptr_to(self.type_i8())
64 fn type_int(&self) -> Self::Type
{
65 match &self.sess().target
.target
.target_c_int_width
[..] {
66 "16" => self.type_i16(),
67 "32" => self.type_i32(),
68 "64" => self.type_i64(),
69 width
=> bug
!("Unsupported target_c_int_width: {}", width
),
73 fn type_int_from_ty(&self, t
: ast
::IntTy
) -> Self::Type
{
75 ast
::IntTy
::Isize
=> self.type_isize(),
76 ast
::IntTy
::I8
=> self.type_i8(),
77 ast
::IntTy
::I16
=> self.type_i16(),
78 ast
::IntTy
::I32
=> self.type_i32(),
79 ast
::IntTy
::I64
=> self.type_i64(),
80 ast
::IntTy
::I128
=> self.type_i128(),
84 fn type_uint_from_ty(&self, t
: ast
::UintTy
) -> Self::Type
{
86 ast
::UintTy
::Usize
=> self.type_isize(),
87 ast
::UintTy
::U8
=> self.type_i8(),
88 ast
::UintTy
::U16
=> self.type_i16(),
89 ast
::UintTy
::U32
=> self.type_i32(),
90 ast
::UintTy
::U64
=> self.type_i64(),
91 ast
::UintTy
::U128
=> self.type_i128(),
95 fn type_float_from_ty(&self, t
: ast
::FloatTy
) -> Self::Type
{
97 ast
::FloatTy
::F32
=> self.type_f32(),
98 ast
::FloatTy
::F64
=> self.type_f64(),
102 fn type_from_integer(&self, i
: layout
::Integer
) -> Self::Type
{
103 use rustc
::ty
::layout
::Integer
::*;
105 I8
=> self.type_i8(),
106 I16
=> self.type_i16(),
107 I32
=> self.type_i32(),
108 I64
=> self.type_i64(),
109 I128
=> self.type_i128(),
113 fn type_pointee_for_align(&self, align
: Align
) -> Self::Type
{
114 // FIXME(eddyb) We could find a better approximation if ity.align < align.
115 let ity
= layout
::Integer
::approximate_align(self, align
);
116 self.type_from_integer(ity
)
119 /// Return a LLVM type that has at most the required alignment,
120 /// and exactly the required size, as a best-effort padding array.
121 fn type_padding_filler(&self, size
: Size
, align
: Align
) -> Self::Type
{
122 let unit
= layout
::Integer
::approximate_align(self, align
);
123 let size
= size
.bytes();
124 let unit_size
= unit
.size().bytes();
125 assert_eq
!(size
% unit_size
, 0);
126 self.type_array(self.type_from_integer(unit
), size
/ unit_size
)
129 fn type_needs_drop(&self, ty
: Ty
<'tcx
>) -> bool
{
130 common
::type_needs_drop(self.tcx(), ty
)
133 fn type_is_sized(&self, ty
: Ty
<'tcx
>) -> bool
{
134 common
::type_is_sized(self.tcx(), ty
)
137 fn type_is_freeze(&self, ty
: Ty
<'tcx
>) -> bool
{
138 common
::type_is_freeze(self.tcx(), ty
)
141 fn type_has_metadata(&self, ty
: Ty
<'tcx
>) -> bool
{
142 use syntax_pos
::DUMMY_SP
;
143 if ty
.is_sized(self.tcx().at(DUMMY_SP
), ty
::ParamEnv
::reveal_all()) {
147 let tail
= self.tcx().struct_tail(ty
);
149 ty
::Foreign(..) => false,
150 ty
::Str
| ty
::Slice(..) | ty
::Dynamic(..) => true,
151 _
=> bug
!("unexpected unsized tail: {:?}", tail
.sty
),
156 impl<T
> DerivedTypeMethods
<'tcx
> for T
where Self: BaseTypeMethods
<'tcx
> + MiscMethods
<'tcx
> {}
158 pub trait LayoutTypeMethods
<'tcx
>: Backend
<'tcx
> {
159 fn backend_type(&self, layout
: TyLayout
<'tcx
>) -> Self::Type
;
160 fn cast_backend_type(&self, ty
: &CastTarget
) -> Self::Type
;
161 fn fn_backend_type(&self, ty
: &FnType
<'tcx
, Ty
<'tcx
>>) -> Self::Type
;
162 fn fn_ptr_backend_type(&self, ty
: &FnType
<'tcx
, Ty
<'tcx
>>) -> Self::Type
;
163 fn reg_backend_type(&self, ty
: &Reg
) -> Self::Type
;
164 fn immediate_backend_type(&self, layout
: TyLayout
<'tcx
>) -> Self::Type
;
165 fn is_backend_immediate(&self, layout
: TyLayout
<'tcx
>) -> bool
;
166 fn is_backend_scalar_pair(&self, layout
: TyLayout
<'tcx
>) -> bool
;
167 fn backend_field_index(&self, layout
: TyLayout
<'tcx
>, index
: usize) -> u64;
168 fn scalar_pair_element_backend_type
<'a
>(
170 layout
: TyLayout
<'tcx
>,
176 pub trait ArgTypeMethods
<'tcx
>: HasCodegen
<'tcx
> {
179 ty
: &ArgType
<'tcx
, Ty
<'tcx
>>,
181 dst
: PlaceRef
<'tcx
, Self::Value
>,
185 ty
: &ArgType
<'tcx
, Ty
<'tcx
>>,
187 dst
: PlaceRef
<'tcx
, Self::Value
>,
189 fn memory_ty(&self, ty
: &ArgType
<'tcx
, Ty
<'tcx
>>) -> Self::Type
;
192 pub trait TypeMethods
<'tcx
>: DerivedTypeMethods
<'tcx
> + LayoutTypeMethods
<'tcx
> {}
194 impl<T
> TypeMethods
<'tcx
> for T
where Self: DerivedTypeMethods
<'tcx
> + LayoutTypeMethods
<'tcx
> {}