88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ use super :: misc:: MiscMethods ;
1112use super :: Backend ;
1213use super :: HasCodegen ;
13- use common:: TypeKind ;
14+ use common:: { self , TypeKind } ;
1415use 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 } ;
1818use rustc:: util:: nodemap:: FxHashMap ;
1919use rustc_target:: abi:: call:: { ArgType , CastTarget , FnType , Reg } ;
2020use std:: cell:: RefCell ;
@@ -32,6 +32,7 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
3232
3333 // Creates an integer type with the given number of bits, e.g. i24
3434 fn type_ix ( & self , num_bits : u64 ) -> Self :: Type ;
35+ fn type_isize ( & self ) -> Self :: Type ;
3536
3637 fn type_f32 ( & self ) -> Self :: Type ;
3738 fn type_f64 ( & self ) -> Self :: Type ;
@@ -61,30 +62,109 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
6162 fn scalar_lltypes ( & self ) -> & RefCell < FxHashMap < Ty < ' tcx > , Self :: Type > > ;
6263}
6364
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+ }
77128
78129 /// Return a LLVM type that has at most the required alignment,
79130 /// 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+ }
86164}
87165
166+ impl < T > DerivedTypeMethods < ' tcx > for T where Self : BaseTypeMethods < ' tcx > + MiscMethods < ' tcx > { }
167+
88168pub trait LayoutTypeMethods < ' tcx > : Backend < ' tcx > {
89169 fn backend_type ( & self , layout : TyLayout < ' tcx > ) -> Self :: Type ;
90170 fn cast_backend_type ( & self , ty : & CastTarget ) -> Self :: Type ;
@@ -119,11 +199,6 @@ pub trait ArgTypeMethods<'tcx>: HasCodegen<'tcx> {
119199 fn memory_ty ( & self , ty : & ArgType < ' tcx , Ty < ' tcx > > ) -> Self :: Type ;
120200}
121201
122- pub trait TypeMethods < ' tcx > :
123- BaseTypeMethods < ' tcx > + DerivedTypeMethods < ' tcx > + LayoutTypeMethods < ' tcx >
124- {
125- }
202+ pub trait TypeMethods < ' tcx > : DerivedTypeMethods < ' tcx > + LayoutTypeMethods < ' tcx > { }
126203
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