]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_ssa/src/traits/type_.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / compiler / rustc_codegen_ssa / src / traits / type_.rs
CommitLineData
a1dfa0c6
XL
1use super::misc::MiscMethods;
2use super::Backend;
3use super::HasCodegen;
532ac7d7 4use crate::common::TypeKind;
9fa01778 5use crate::mir::place::PlaceRef;
ba9703b0
XL
6use rustc_middle::ty::layout::TyAndLayout;
7use rustc_middle::ty::{self, Ty};
60c5eb7d 8use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
3dfed10e 9use 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.
13pub 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
43pub 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 99impl<'tcx, T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}
a1dfa0c6
XL
100
101pub 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).
121pub 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 126pub 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
142pub trait TypeMethods<'tcx>:
143 DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx>
144{
145}
a1dfa0c6 146
064997fb
FG
147impl<'tcx, T> TypeMethods<'tcx> for T where
148 Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx>
149{
150}