@@ -36,8 +36,10 @@ use mir::operand::OperandValue;
36
36
use type_:: Type ;
37
37
use type_of:: { LayoutLlvmExt , PointerKind } ;
38
38
39
+ use rustc_target:: abi:: { HasDataLayout , LayoutOf , Size , TyLayout , TyLayoutMethods } ;
40
+ use rustc_target:: spec:: HasTargetSpec ;
39
41
use rustc:: ty:: { self , Ty } ;
40
- use rustc:: ty:: layout:: { self , LayoutOf , Size , TyLayout } ;
42
+ use rustc:: ty:: layout;
41
43
42
44
use libc:: c_uint;
43
45
use std:: cmp;
@@ -142,12 +144,13 @@ impl LlvmType for Reg {
142
144
}
143
145
}
144
146
145
- pub trait LayoutExt < ' tcx > {
147
+ pub trait LayoutExt < ' a , Ty > : Sized {
146
148
fn is_aggregate ( & self ) -> bool ;
147
- fn homogeneous_aggregate < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Option < Reg > ;
149
+ fn homogeneous_aggregate < C > ( & self , cx : C ) -> Option < Reg >
150
+ where Ty : TyLayoutMethods < ' a , C > + Copy , C : LayoutOf < Ty = Ty , TyLayout = Self > + Copy ;
148
151
}
149
152
150
- impl < ' tcx > LayoutExt < ' tcx > for TyLayout < ' tcx > {
153
+ impl < ' a , Ty > LayoutExt < ' a , Ty > for TyLayout < ' a , Ty > {
151
154
fn is_aggregate ( & self ) -> bool {
152
155
match self . abi {
153
156
layout:: Abi :: Uninhabited |
@@ -158,7 +161,9 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> {
158
161
}
159
162
}
160
163
161
- fn homogeneous_aggregate < ' a > ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Option < Reg > {
164
+ fn homogeneous_aggregate < C > ( & self , cx : C ) -> Option < Reg >
165
+ where Ty : TyLayoutMethods < ' a , C > + Copy , C : LayoutOf < Ty = Ty , TyLayout = Self > + Copy
166
+ {
162
167
match self . abi {
163
168
layout:: Abi :: Uninhabited => None ,
164
169
@@ -280,17 +285,17 @@ impl LlvmType for CastTarget {
280
285
/// Information about how to pass an argument to,
281
286
/// or return a value from, a function, under some ABI.
282
287
#[ derive( Debug ) ]
283
- pub struct ArgType < ' tcx > {
284
- pub layout : TyLayout < ' tcx > ,
288
+ pub struct ArgType < ' tcx , Ty = ty :: Ty < ' tcx > > {
289
+ pub layout : TyLayout < ' tcx , Ty > ,
285
290
286
291
/// Dummy argument, which is emitted before the real argument.
287
292
pub pad : Option < Reg > ,
288
293
289
294
pub mode : PassMode ,
290
295
}
291
296
292
- impl < ' a , ' tcx > ArgType < ' tcx > {
293
- fn new ( layout : TyLayout < ' tcx > ) -> ArgType < ' tcx > {
297
+ impl < ' a , ' tcx , Ty > ArgType < ' tcx , Ty > {
298
+ fn new ( layout : TyLayout < ' tcx , Ty > ) -> Self {
294
299
ArgType {
295
300
layout,
296
301
pad : None ,
@@ -364,7 +369,9 @@ impl<'a, 'tcx> ArgType<'tcx> {
364
369
pub fn is_ignore ( & self ) -> bool {
365
370
self . mode == PassMode :: Ignore
366
371
}
372
+ }
367
373
374
+ impl < ' a , ' tcx > ArgType < ' tcx > {
368
375
/// Get the LLVM type for a place of the original Rust type of
369
376
/// this argument/return, i.e. the result of `type_of::type_of`.
370
377
pub fn memory_ty ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Type {
@@ -451,12 +458,12 @@ impl<'a, 'tcx> ArgType<'tcx> {
451
458
/// I will do my best to describe this structure, but these
452
459
/// comments are reverse-engineered and may be inaccurate. -NDM
453
460
#[ derive( Debug ) ]
454
- pub struct FnType < ' tcx > {
461
+ pub struct FnType < ' tcx , Ty = ty :: Ty < ' tcx > > {
455
462
/// The LLVM types of each argument.
456
- pub args : Vec < ArgType < ' tcx > > ,
463
+ pub args : Vec < ArgType < ' tcx , Ty > > ,
457
464
458
465
/// LLVM return type.
459
- pub ret : ArgType < ' tcx > ,
466
+ pub ret : ArgType < ' tcx , Ty > ,
460
467
461
468
pub variadic : bool ,
462
469
@@ -474,15 +481,15 @@ impl<'a, 'tcx> FnType<'tcx> {
474
481
475
482
pub fn new ( cx : & CodegenCx < ' a , ' tcx > ,
476
483
sig : ty:: FnSig < ' tcx > ,
477
- extra_args : & [ Ty < ' tcx > ] ) -> FnType < ' tcx > {
484
+ extra_args : & [ Ty < ' tcx > ] ) -> Self {
478
485
let mut fn_ty = FnType :: unadjusted ( cx, sig, extra_args) ;
479
486
fn_ty. adjust_for_abi ( cx, sig. abi ) ;
480
487
fn_ty
481
488
}
482
489
483
490
pub fn new_vtable ( cx : & CodegenCx < ' a , ' tcx > ,
484
491
sig : ty:: FnSig < ' tcx > ,
485
- extra_args : & [ Ty < ' tcx > ] ) -> FnType < ' tcx > {
492
+ extra_args : & [ Ty < ' tcx > ] ) -> Self {
486
493
let mut fn_ty = FnType :: unadjusted ( cx, sig, extra_args) ;
487
494
// Don't pass the vtable, it's not an argument of the virtual fn.
488
495
{
@@ -507,7 +514,7 @@ impl<'a, 'tcx> FnType<'tcx> {
507
514
508
515
pub fn unadjusted ( cx : & CodegenCx < ' a , ' tcx > ,
509
516
sig : ty:: FnSig < ' tcx > ,
510
- extra_args : & [ Ty < ' tcx > ] ) -> FnType < ' tcx > {
517
+ extra_args : & [ Ty < ' tcx > ] ) -> Self {
511
518
debug ! ( "FnType::unadjusted({:?}, {:?})" , sig, extra_args) ;
512
519
513
520
use self :: Abi :: * ;
@@ -569,7 +576,7 @@ impl<'a, 'tcx> FnType<'tcx> {
569
576
// Handle safe Rust thin and fat pointers.
570
577
let adjust_for_rust_scalar = |attrs : & mut ArgAttributes ,
571
578
scalar : & layout:: Scalar ,
572
- layout : TyLayout < ' tcx > ,
579
+ layout : TyLayout < ' tcx , Ty < ' tcx > > ,
573
580
offset : Size ,
574
581
is_return : bool | {
575
582
// Booleans are always an i1 that needs to be zero-extended.
@@ -742,7 +749,18 @@ impl<'a, 'tcx> FnType<'tcx> {
742
749
return ;
743
750
}
744
751
745
- match & cx. sess ( ) . target . target . arch [ ..] {
752
+ if let Err ( msg) = self . adjust_for_cabi ( cx, abi) {
753
+ cx. sess ( ) . fatal ( & msg) ;
754
+ }
755
+ }
756
+ }
757
+
758
+ impl < ' a , Ty > FnType < ' a , Ty > {
759
+ fn adjust_for_cabi < C > ( & mut self , cx : C , abi : Abi ) -> Result < ( ) , String >
760
+ where Ty : TyLayoutMethods < ' a , C > + Copy ,
761
+ C : LayoutOf < Ty = Ty , TyLayout = TyLayout < ' a , Ty > > + HasDataLayout + HasTargetSpec
762
+ {
763
+ match & cx. target_spec ( ) . arch [ ..] {
746
764
"x86" => {
747
765
let flavor = if abi == Abi :: Fastcall {
748
766
cabi_x86:: Flavor :: Fastcall
@@ -753,7 +771,7 @@ impl<'a, 'tcx> FnType<'tcx> {
753
771
} ,
754
772
"x86_64" => if abi == Abi :: SysV64 {
755
773
cabi_x86_64:: compute_abi_info ( cx, self ) ;
756
- } else if abi == Abi :: Win64 || cx. sess ( ) . target . target . options . is_like_windows {
774
+ } else if abi == Abi :: Win64 || cx. target_spec ( ) . options . is_like_windows {
757
775
cabi_x86_win64:: compute_abi_info ( self ) ;
758
776
} else {
759
777
cabi_x86_64:: compute_abi_info ( cx, self ) ;
@@ -767,10 +785,10 @@ impl<'a, 'tcx> FnType<'tcx> {
767
785
"s390x" => cabi_s390x:: compute_abi_info ( cx, self ) ,
768
786
"asmjs" => cabi_asmjs:: compute_abi_info ( cx, self ) ,
769
787
"wasm32" => {
770
- if cx. sess ( ) . opts . target_triple . triple ( ) . contains ( "emscripten" ) {
788
+ if cx. target_spec ( ) . llvm_target . contains ( "emscripten" ) {
771
789
cabi_asmjs:: compute_abi_info ( cx, self )
772
790
} else {
773
- cabi_wasm32:: compute_abi_info ( cx , self )
791
+ cabi_wasm32:: compute_abi_info ( self )
774
792
}
775
793
}
776
794
"msp430" => cabi_msp430:: compute_abi_info ( self ) ,
@@ -779,14 +797,18 @@ impl<'a, 'tcx> FnType<'tcx> {
779
797
"nvptx" => cabi_nvptx:: compute_abi_info ( self ) ,
780
798
"nvptx64" => cabi_nvptx64:: compute_abi_info ( self ) ,
781
799
"hexagon" => cabi_hexagon:: compute_abi_info ( self ) ,
782
- a => cx . sess ( ) . fatal ( & format ! ( "unrecognized arch \" {}\" in target specification" , a) )
800
+ a => return Err ( format ! ( "unrecognized arch \" {}\" in target specification" , a) )
783
801
}
784
802
785
803
if let PassMode :: Indirect ( ref mut attrs) = self . ret . mode {
786
804
attrs. set ( ArgAttribute :: StructRet ) ;
787
805
}
806
+
807
+ Ok ( ( ) )
788
808
}
809
+ }
789
810
811
+ impl < ' a , ' tcx > FnType < ' tcx > {
790
812
pub fn llvm_type ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Type {
791
813
let mut llargument_tys = Vec :: new ( ) ;
792
814
0 commit comments