]>
Commit | Line | Data |
---|---|---|
a1dfa0c6 XL |
1 | use super::misc::MiscMethods; |
2 | use super::Backend; | |
3 | use super::HasCodegen; | |
532ac7d7 | 4 | use crate::common::TypeKind; |
9fa01778 | 5 | use crate::mir::place::PlaceRef; |
ba9703b0 XL |
6 | use rustc_middle::ty::layout::TyAndLayout; |
7 | use rustc_middle::ty::{self, Ty}; | |
60c5eb7d | 8 | use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg}; |
3dfed10e | 9 | use rustc_target::abi::{AddressSpace, Integer}; |
a1dfa0c6 XL |
10 | |
11 | // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use | |
12 | // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves. | |
13 | pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { | |
a1dfa0c6 XL |
14 | fn type_i1(&self) -> Self::Type; |
15 | fn type_i8(&self) -> Self::Type; | |
16 | fn type_i16(&self) -> Self::Type; | |
17 | fn type_i32(&self) -> Self::Type; | |
18 | fn type_i64(&self) -> Self::Type; | |
19 | fn type_i128(&self) -> Self::Type; | |
a1dfa0c6 XL |
20 | fn type_isize(&self) -> Self::Type; |
21 | ||
22 | fn type_f32(&self) -> Self::Type; | |
23 | fn type_f64(&self) -> Self::Type; | |
a1dfa0c6 XL |
24 | |
25 | fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; | |
a1dfa0c6 | 26 | fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type; |
a1dfa0c6 XL |
27 | fn type_kind(&self, ty: Self::Type) -> TypeKind; |
28 | fn type_ptr_to(&self, ty: Self::Type) -> Self::Type; | |
3dfed10e | 29 | fn type_ptr_to_ext(&self, ty: Self::Type, address_space: AddressSpace) -> Self::Type; |
a1dfa0c6 XL |
30 | fn element_type(&self, ty: Self::Type) -> Self::Type; |
31 | ||
9fa01778 | 32 | /// Returns the number of elements in `self` if it is a LLVM vector type. |
a1dfa0c6 XL |
33 | fn vector_length(&self, ty: Self::Type) -> usize; |
34 | ||
a1dfa0c6 XL |
35 | fn float_width(&self, ty: Self::Type) -> usize; |
36 | ||
9fa01778 | 37 | /// Retrieves the bit width of the integer type `self`. |
a1dfa0c6 XL |
38 | fn int_width(&self, ty: Self::Type) -> u64; |
39 | ||
40 | fn val_ty(&self, v: Self::Value) -> Self::Type; | |
a1dfa0c6 XL |
41 | } |
42 | ||
43 | pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { | |
a1dfa0c6 | 44 | fn type_i8p(&self) -> Self::Type { |
3dfed10e XL |
45 | self.type_i8p_ext(AddressSpace::DATA) |
46 | } | |
47 | ||
48 | fn type_i8p_ext(&self, address_space: AddressSpace) -> Self::Type { | |
49 | self.type_ptr_to_ext(self.type_i8(), address_space) | |
a1dfa0c6 XL |
50 | } |
51 | ||
52 | fn type_int(&self) -> Self::Type { | |
29967ef6 | 53 | match &self.sess().target.c_int_width[..] { |
a1dfa0c6 XL |
54 | "16" => self.type_i16(), |
55 | "32" => self.type_i32(), | |
56 | "64" => self.type_i64(), | |
29967ef6 | 57 | width => bug!("Unsupported c_int_width: {}", width), |
a1dfa0c6 XL |
58 | } |
59 | } | |
60 | ||
ba9703b0 XL |
61 | fn type_from_integer(&self, i: Integer) -> Self::Type { |
62 | use Integer::*; | |
a1dfa0c6 XL |
63 | match i { |
64 | I8 => self.type_i8(), | |
65 | I16 => self.type_i16(), | |
66 | I32 => self.type_i32(), | |
67 | I64 => self.type_i64(), | |
68 | I128 => self.type_i128(), | |
69 | } | |
70 | } | |
71 | ||
a1dfa0c6 | 72 | fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { |
532ac7d7 | 73 | ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all()) |
a1dfa0c6 XL |
74 | } |
75 | ||
76 | fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { | |
2b03887a | 77 | ty.is_sized(self.tcx(), ty::ParamEnv::reveal_all()) |
a1dfa0c6 XL |
78 | } |
79 | ||
80 | fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { | |
2b03887a | 81 | ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all()) |
a1dfa0c6 XL |
82 | } |
83 | ||
84 | fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { | |
416331ca | 85 | let param_env = ty::ParamEnv::reveal_all(); |
2b03887a | 86 | if ty.is_sized(self.tcx(), param_env) { |
a1dfa0c6 XL |
87 | return false; |
88 | } | |
89 | ||
416331ca | 90 | let tail = self.tcx().struct_tail_erasing_lifetimes(ty, param_env); |
1b1a35ee | 91 | match tail.kind() { |
a1dfa0c6 XL |
92 | ty::Foreign(..) => false, |
93 | ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, | |
532ac7d7 | 94 | _ => bug!("unexpected unsized tail: {:?}", tail), |
a1dfa0c6 XL |
95 | } |
96 | } | |
97 | } | |
98 | ||
a2a8927a | 99 | impl<'tcx, T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {} |
a1dfa0c6 XL |
100 | |
101 | pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { | |
ba9703b0 | 102 | fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type; |
a1dfa0c6 | 103 | fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type; |
94222f64 | 104 | fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type; |
60c5eb7d | 105 | fn fn_ptr_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type; |
a1dfa0c6 | 106 | fn reg_backend_type(&self, ty: &Reg) -> Self::Type; |
ba9703b0 XL |
107 | fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type; |
108 | fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool; | |
109 | fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool; | |
110 | fn backend_field_index(&self, layout: TyAndLayout<'tcx>, index: usize) -> u64; | |
dc9dc135 | 111 | fn scalar_pair_element_backend_type( |
a1dfa0c6 | 112 | &self, |
ba9703b0 | 113 | layout: TyAndLayout<'tcx>, |
a1dfa0c6 XL |
114 | index: usize, |
115 | immediate: bool, | |
116 | ) -> Self::Type; | |
117 | } | |
118 | ||
064997fb FG |
119 | // For backends that support CFI using type membership (i.e., testing whether a given pointer is |
120 | // associated with a type identifier). | |
121 | pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> { | |
122 | fn set_type_metadata(&self, function: Self::Function, typeid: String); | |
123 | fn typeid_metadata(&self, typeid: String) -> Self::Value; | |
124 | } | |
125 | ||
60c5eb7d | 126 | pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> { |
a1dfa0c6 XL |
127 | fn store_fn_arg( |
128 | &mut self, | |
60c5eb7d | 129 | arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, |
a1dfa0c6 XL |
130 | idx: &mut usize, |
131 | dst: PlaceRef<'tcx, Self::Value>, | |
132 | ); | |
60c5eb7d | 133 | fn store_arg( |
a1dfa0c6 | 134 | &mut self, |
60c5eb7d | 135 | arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, |
a1dfa0c6 XL |
136 | val: Self::Value, |
137 | dst: PlaceRef<'tcx, Self::Value>, | |
138 | ); | |
60c5eb7d | 139 | fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type; |
a1dfa0c6 XL |
140 | } |
141 | ||
064997fb FG |
142 | pub trait TypeMethods<'tcx>: |
143 | DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx> | |
144 | { | |
145 | } | |
a1dfa0c6 | 146 | |
064997fb FG |
147 | impl<'tcx, T> TypeMethods<'tcx> for T where |
148 | Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx> | |
149 | { | |
150 | } |