]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_ssa/traits/type_.rs
Introduce FuncId backend type
[rust.git] / src / librustc_codegen_ssa / traits / type_.rs
1 use super::misc::MiscMethods;
2 use super::Backend;
3 use super::HasCodegen;
4 use crate::common::TypeKind;
5 use crate::mir::place::PlaceRef;
6 use rustc::ty::{self, Ty};
7 use rustc::ty::layout::{self, TyLayout};
8 use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg};
9 use syntax_pos::DUMMY_SP;
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> {
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;
20     fn type_isize(&self) -> Self::Type;
21
22     fn type_f32(&self) -> Self::Type;
23     fn type_f64(&self) -> Self::Type;
24
25     fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
26     fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type;
27     fn type_kind(&self, ty: Self::Type) -> TypeKind;
28     fn type_ptr_to(&self, ty: Self::Type) -> Self::Type;
29     fn element_type(&self, ty: Self::Type) -> Self::Type;
30
31     /// Returns the number of elements in `self` if it is a LLVM vector type.
32     fn vector_length(&self, ty: Self::Type) -> usize;
33
34     fn float_width(&self, ty: Self::Type) -> usize;
35
36     /// Retrieves the bit width of the integer type `self`.
37     fn int_width(&self, ty: Self::Type) -> u64;
38
39     fn val_ty(&self, v: Self::Value) -> Self::Type;
40 }
41
42 pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
43     fn type_i8p(&self) -> Self::Type {
44         self.type_ptr_to(self.type_i8())
45     }
46
47     fn type_int(&self) -> Self::Type {
48         match &self.sess().target.target.target_c_int_width[..] {
49             "16" => self.type_i16(),
50             "32" => self.type_i32(),
51             "64" => self.type_i64(),
52             width => bug!("Unsupported target_c_int_width: {}", width),
53         }
54     }
55
56     fn type_from_integer(&self, i: layout::Integer) -> Self::Type {
57         use rustc::ty::layout::Integer::*;
58         match i {
59             I8 => self.type_i8(),
60             I16 => self.type_i16(),
61             I32 => self.type_i32(),
62             I64 => self.type_i64(),
63             I128 => self.type_i128(),
64         }
65     }
66
67     fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
68         ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all())
69     }
70
71     fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
72         ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
73     }
74
75     fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
76         ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all(), DUMMY_SP)
77     }
78
79     fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
80         let param_env = ty::ParamEnv::reveal_all();
81         if ty.is_sized(self.tcx().at(DUMMY_SP), param_env) {
82             return false;
83         }
84
85         let tail = self.tcx().struct_tail_erasing_lifetimes(ty, param_env);
86         match tail.kind {
87             ty::Foreign(..) => false,
88             ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
89             _ => bug!("unexpected unsized tail: {:?}", tail),
90         }
91     }
92 }
93
94 impl<T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}
95
96 pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
97     fn backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type;
98     fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type;
99     fn fn_ptr_backend_type(&self, ty: &FnType<'tcx, Ty<'tcx>>) -> Self::Type;
100     fn reg_backend_type(&self, ty: &Reg) -> Self::Type;
101     fn immediate_backend_type(&self, layout: TyLayout<'tcx>) -> Self::Type;
102     fn is_backend_immediate(&self, layout: TyLayout<'tcx>) -> bool;
103     fn is_backend_scalar_pair(&self, layout: TyLayout<'tcx>) -> bool;
104     fn backend_field_index(&self, layout: TyLayout<'tcx>, index: usize) -> u64;
105     fn scalar_pair_element_backend_type(
106         &self,
107         layout: TyLayout<'tcx>,
108         index: usize,
109         immediate: bool,
110     ) -> Self::Type;
111 }
112
113 pub trait ArgTypeMethods<'tcx>: HasCodegen<'tcx> {
114     fn store_fn_arg(
115         &mut self,
116         ty: &ArgType<'tcx, Ty<'tcx>>,
117         idx: &mut usize,
118         dst: PlaceRef<'tcx, Self::Value>,
119     );
120     fn store_arg_ty(
121         &mut self,
122         ty: &ArgType<'tcx, Ty<'tcx>>,
123         val: Self::Value,
124         dst: PlaceRef<'tcx, Self::Value>,
125     );
126     fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> Self::Type;
127 }
128
129 pub trait TypeMethods<'tcx>: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> {}
130
131 impl<T> TypeMethods<'tcx> for T where Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> {}