8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use super :: misc:: MiscMethods ;
11
12
use super :: Backend ;
12
13
use super :: HasCodegen ;
13
- use common:: TypeKind ;
14
+ use common:: { self , TypeKind } ;
14
15
use mir:: place:: PlaceRef ;
15
- use rustc:: ty:: layout:: TyLayout ;
16
- use rustc:: ty:: layout:: { self , Align , Size } ;
17
- use rustc:: ty:: Ty ;
16
+ use rustc:: ty:: layout:: { self , Align , Size , TyLayout } ;
17
+ use rustc:: ty:: { self , Ty } ;
18
18
use rustc:: util:: nodemap:: FxHashMap ;
19
19
use rustc_target:: abi:: call:: { ArgType , CastTarget , FnType , Reg } ;
20
20
use std:: cell:: RefCell ;
@@ -32,6 +32,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
32
32
33
33
// Creates an integer type with the given number of bits, e.g. i24
34
34
fn type_ix ( & self , num_bits : u64 ) -> Self :: Type ;
35
+ fn type_isize ( & self ) -> Self :: Type ;
35
36
36
37
fn type_f32 ( & self ) -> Self :: Type ;
37
38
fn type_f64 ( & self ) -> Self :: Type ;
@@ -61,30 +62,109 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
61
62
fn scalar_lltypes ( & self ) -> & RefCell < FxHashMap < Ty < ' tcx > , Self :: Type > > ;
62
63
}
63
64
64
- pub trait DerivedTypeMethods < ' tcx > : Backend < ' tcx > {
65
- fn type_bool ( & self ) -> Self :: Type ;
66
- fn type_i8p ( & self ) -> Self :: Type ;
67
- fn type_isize ( & self ) -> Self :: Type ;
68
- fn type_int ( & self ) -> Self :: Type ;
69
- fn type_int_from_ty ( & self , t : ast:: IntTy ) -> Self :: Type ;
70
- fn type_uint_from_ty ( & self , t : ast:: UintTy ) -> Self :: Type ;
71
- fn type_float_from_ty ( & self , t : ast:: FloatTy ) -> Self :: Type ;
72
- fn type_from_integer ( & self , i : layout:: Integer ) -> Self :: Type ;
73
-
74
- /// Return a LLVM type that has at most the required alignment,
75
- /// as a conservative approximation for unknown pointee types.
76
- fn type_pointee_for_abi_align ( & self , align : Align ) -> Self :: Type ;
65
+ pub trait DerivedTypeMethods < ' tcx > : BaseTypeMethods < ' tcx > + MiscMethods < ' tcx > {
66
+ fn type_bool ( & self ) -> Self :: Type {
67
+ self . type_i8 ( )
68
+ }
69
+
70
+ fn type_i8p ( & self ) -> Self :: Type {
71
+ self . type_ptr_to ( self . type_i8 ( ) )
72
+ }
73
+
74
+ fn type_int ( & self ) -> Self :: Type {
75
+ match & self . sess ( ) . target . target . target_c_int_width [ ..] {
76
+ "16" => self . type_i16 ( ) ,
77
+ "32" => self . type_i32 ( ) ,
78
+ "64" => self . type_i64 ( ) ,
79
+ width => bug ! ( "Unsupported target_c_int_width: {}" , width) ,
80
+ }
81
+ }
82
+
83
+ fn type_int_from_ty ( & self , t : ast:: IntTy ) -> Self :: Type {
84
+ match t {
85
+ ast:: IntTy :: Isize => self . type_isize ( ) ,
86
+ ast:: IntTy :: I8 => self . type_i8 ( ) ,
87
+ ast:: IntTy :: I16 => self . type_i16 ( ) ,
88
+ ast:: IntTy :: I32 => self . type_i32 ( ) ,
89
+ ast:: IntTy :: I64 => self . type_i64 ( ) ,
90
+ ast:: IntTy :: I128 => self . type_i128 ( ) ,
91
+ }
92
+ }
93
+
94
+ fn type_uint_from_ty ( & self , t : ast:: UintTy ) -> Self :: Type {
95
+ match t {
96
+ ast:: UintTy :: Usize => self . type_isize ( ) ,
97
+ ast:: UintTy :: U8 => self . type_i8 ( ) ,
98
+ ast:: UintTy :: U16 => self . type_i16 ( ) ,
99
+ ast:: UintTy :: U32 => self . type_i32 ( ) ,
100
+ ast:: UintTy :: U64 => self . type_i64 ( ) ,
101
+ ast:: UintTy :: U128 => self . type_i128 ( ) ,
102
+ }
103
+ }
104
+
105
+ fn type_float_from_ty ( & self , t : ast:: FloatTy ) -> Self :: Type {
106
+ match t {
107
+ ast:: FloatTy :: F32 => self . type_f32 ( ) ,
108
+ ast:: FloatTy :: F64 => self . type_f64 ( ) ,
109
+ }
110
+ }
111
+
112
+ fn type_from_integer ( & self , i : layout:: Integer ) -> Self :: Type {
113
+ use rustc:: ty:: layout:: Integer :: * ;
114
+ match i {
115
+ I8 => self . type_i8 ( ) ,
116
+ I16 => self . type_i16 ( ) ,
117
+ I32 => self . type_i32 ( ) ,
118
+ I64 => self . type_i64 ( ) ,
119
+ I128 => self . type_i128 ( ) ,
120
+ }
121
+ }
122
+
123
+ fn type_pointee_for_abi_align ( & self , align : Align ) -> Self :: Type {
124
+ // FIXME(eddyb) We could find a better approximation if ity.align < align.
125
+ let ity = layout:: Integer :: approximate_abi_align ( self , align) ;
126
+ self . type_from_integer ( ity)
127
+ }
77
128
78
129
/// Return a LLVM type that has at most the required alignment,
79
130
/// and exactly the required size, as a best-effort padding array.
80
- fn type_padding_filler ( & self , size : Size , align : Align ) -> Self :: Type ;
81
-
82
- fn type_needs_drop ( & self , ty : Ty < ' tcx > ) -> bool ;
83
- fn type_is_sized ( & self , ty : Ty < ' tcx > ) -> bool ;
84
- fn type_is_freeze ( & self , ty : Ty < ' tcx > ) -> bool ;
85
- fn type_has_metadata ( & self , ty : Ty < ' tcx > ) -> bool ;
131
+ fn type_padding_filler ( & self , size : Size , align : Align ) -> Self :: Type {
132
+ let unit = layout:: Integer :: approximate_abi_align ( self , align) ;
133
+ let size = size. bytes ( ) ;
134
+ let unit_size = unit. size ( ) . bytes ( ) ;
135
+ assert_eq ! ( size % unit_size, 0 ) ;
136
+ self . type_array ( self . type_from_integer ( unit) , size / unit_size)
137
+ }
138
+
139
+ fn type_needs_drop ( & self , ty : Ty < ' tcx > ) -> bool {
140
+ common:: type_needs_drop ( self . tcx ( ) , ty)
141
+ }
142
+
143
+ fn type_is_sized ( & self , ty : Ty < ' tcx > ) -> bool {
144
+ common:: type_is_sized ( self . tcx ( ) , ty)
145
+ }
146
+
147
+ fn type_is_freeze ( & self , ty : Ty < ' tcx > ) -> bool {
148
+ common:: type_is_freeze ( self . tcx ( ) , ty)
149
+ }
150
+
151
+ fn type_has_metadata ( & self , ty : Ty < ' tcx > ) -> bool {
152
+ use syntax_pos:: DUMMY_SP ;
153
+ if ty. is_sized ( self . tcx ( ) . at ( DUMMY_SP ) , ty:: ParamEnv :: reveal_all ( ) ) {
154
+ return false ;
155
+ }
156
+
157
+ let tail = self . tcx ( ) . struct_tail ( ty) ;
158
+ match tail. sty {
159
+ ty:: Foreign ( ..) => false ,
160
+ ty:: Str | ty:: Slice ( ..) | ty:: Dynamic ( ..) => true ,
161
+ _ => bug ! ( "unexpected unsized tail: {:?}" , tail. sty) ,
162
+ }
163
+ }
86
164
}
87
165
166
+ impl < T > DerivedTypeMethods < ' tcx > for T where Self : BaseTypeMethods < ' tcx > + MiscMethods < ' tcx > { }
167
+
88
168
pub trait LayoutTypeMethods < ' tcx > : Backend < ' tcx > {
89
169
fn backend_type ( & self , layout : TyLayout < ' tcx > ) -> Self :: Type ;
90
170
fn cast_backend_type ( & self , ty : & CastTarget ) -> Self :: Type ;
@@ -119,11 +199,6 @@ pub trait ArgTypeMethods<'tcx>: HasCodegen<'tcx> {
119
199
fn memory_ty ( & self , ty : & ArgType < ' tcx , Ty < ' tcx > > ) -> Self :: Type ;
120
200
}
121
201
122
- pub trait TypeMethods < ' tcx > :
123
- BaseTypeMethods < ' tcx > + DerivedTypeMethods < ' tcx > + LayoutTypeMethods < ' tcx >
124
- {
125
- }
202
+ pub trait TypeMethods < ' tcx > : DerivedTypeMethods < ' tcx > + LayoutTypeMethods < ' tcx > { }
126
203
127
- impl < T > TypeMethods < ' tcx > for T where
128
- Self : BaseTypeMethods < ' tcx > + DerivedTypeMethods < ' tcx > + LayoutTypeMethods < ' tcx >
129
- { }
204
+ impl < T > TypeMethods < ' tcx > for T where Self : DerivedTypeMethods < ' tcx > + LayoutTypeMethods < ' tcx > { }
0 commit comments