rustc_codegen_ssa/traits/
type_.rs1use rustc_abi::{AddressSpace, Float, Integer, Reg};
2use rustc_middle::bug;
3use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout};
4use rustc_middle::ty::{self, Ty};
5use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi};
6
7use super::BackendTypes;
8use super::misc::MiscCodegenMethods;
9use crate::common::TypeKind;
10use crate::mir::place::PlaceRef;
11
12pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes {
13 fn type_i8(&self) -> Self::Type;
14 fn type_i16(&self) -> Self::Type;
15 fn type_i32(&self) -> Self::Type;
16 fn type_i64(&self) -> Self::Type;
17 fn type_i128(&self) -> Self::Type;
18 fn type_isize(&self) -> Self::Type;
19
20 fn type_f16(&self) -> Self::Type;
21 fn type_f32(&self) -> Self::Type;
22 fn type_f64(&self) -> Self::Type;
23 fn type_f128(&self) -> Self::Type;
24
25 fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
26 fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
27 fn type_kind(&self, ty: Self::Type) -> TypeKind;
28 fn type_ptr(&self) -> Self::Type;
29 fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type;
30 fn element_type(&self, ty: Self::Type) -> Self::Type;
31
32 fn vector_length(&self, ty: Self::Type) -> usize;
34
35 fn float_width(&self, ty: Self::Type) -> usize;
36
37 fn int_width(&self, ty: Self::Type) -> u64;
39
40 fn val_ty(&self, v: Self::Value) -> Self::Type;
41}
42
43pub trait DerivedTypeCodegenMethods<'tcx>:
44 BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx>
45{
46 fn type_int(&self) -> Self::Type {
47 match &self.sess().target.c_int_width[..] {
48 "16" => self.type_i16(),
49 "32" => self.type_i32(),
50 "64" => self.type_i64(),
51 width => bug!("Unsupported c_int_width: {}", width),
52 }
53 }
54
55 fn type_from_integer(&self, i: Integer) -> Self::Type {
56 use Integer::*;
57 match i {
58 I8 => self.type_i8(),
59 I16 => self.type_i16(),
60 I32 => self.type_i32(),
61 I64 => self.type_i64(),
62 I128 => self.type_i128(),
63 }
64 }
65
66 fn type_from_float(&self, f: Float) -> Self::Type {
67 use Float::*;
68 match f {
69 F16 => self.type_f16(),
70 F32 => self.type_f32(),
71 F64 => self.type_f64(),
72 F128 => self.type_f128(),
73 }
74 }
75
76 fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
77 ty.needs_drop(self.tcx(), self.typing_env())
78 }
79
80 fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
81 ty.is_sized(self.tcx(), self.typing_env())
82 }
83
84 fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
85 ty.is_freeze(self.tcx(), self.typing_env())
86 }
87
88 fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
89 if ty.is_sized(self.tcx(), self.typing_env()) {
90 return false;
91 }
92
93 let tail = self.tcx().struct_tail_for_codegen(ty, self.typing_env());
94 match tail.kind() {
95 ty::Foreign(..) => false,
96 ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
97 _ => bug!("unexpected unsized tail: {:?}", tail),
98 }
99 }
100}
101
102impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where
103 Self: BaseTypeCodegenMethods<'tcx>
104 + MiscCodegenMethods<'tcx>
105 + HasTyCtxt<'tcx>
106 + HasTypingEnv<'tcx>
107{
108}
109
110pub trait LayoutTypeCodegenMethods<'tcx>: BackendTypes {
111 fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
114 fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type;
115 fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type;
116 fn fn_ptr_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type;
117 fn reg_backend_type(&self, ty: &Reg) -> Self::Type;
118 fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
128 fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool;
129 fn is_backend_scalar_pair(&self, layout: TyAndLayout<'tcx>) -> bool;
130 fn scalar_pair_element_backend_type(
131 &self,
132 layout: TyAndLayout<'tcx>,
133 index: usize,
134 immediate: bool,
135 ) -> Self::Type;
136
137 fn is_backend_ref(&self, layout: TyAndLayout<'tcx>) -> bool {
146 !(layout.is_zst()
147 || self.is_backend_immediate(layout)
148 || self.is_backend_scalar_pair(layout))
149 }
150}
151
152pub trait TypeMembershipCodegenMethods<'tcx>: BackendTypes {
155 fn add_type_metadata(&self, _function: Self::Function, _typeid: String) {}
156 fn set_type_metadata(&self, _function: Self::Function, _typeid: String) {}
157 fn typeid_metadata(&self, _typeid: String) -> Option<Self::Metadata> {
158 None
159 }
160 fn add_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
161 fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
162}
163
164pub trait ArgAbiBuilderMethods<'tcx>: BackendTypes {
165 fn store_fn_arg(
166 &mut self,
167 arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
168 idx: &mut usize,
169 dst: PlaceRef<'tcx, Self::Value>,
170 );
171 fn store_arg(
172 &mut self,
173 arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
174 val: Self::Value,
175 dst: PlaceRef<'tcx, Self::Value>,
176 );
177 fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type;
178}
179
180pub trait TypeCodegenMethods<'tcx> = DerivedTypeCodegenMethods<'tcx>
181 + LayoutTypeCodegenMethods<'tcx>
182 + TypeMembershipCodegenMethods<'tcx>;