@@ -434,31 +434,49 @@ pub struct ArgAbi<'a, Ty> {
434
434
}
435
435
436
436
impl < ' a , Ty > ArgAbi < ' a , Ty > {
437
- pub fn new ( layout : TyAndLayout < ' a , Ty > ) -> Self {
438
- ArgAbi { layout, pad : None , mode : PassMode :: Direct ( ArgAttributes :: new ( ) ) }
437
+ pub fn new (
438
+ cx : & impl HasDataLayout ,
439
+ layout : TyAndLayout < ' a , Ty > ,
440
+ scalar_attrs : impl Fn ( & TyAndLayout < ' a , Ty > , & abi:: Scalar , Size ) -> ArgAttributes ,
441
+ ) -> Self {
442
+ let mode = match & layout. abi {
443
+ Abi :: Uninhabited => PassMode :: Ignore ,
444
+ Abi :: Scalar ( scalar) => PassMode :: Direct ( scalar_attrs ( & layout, scalar, Size :: ZERO ) ) ,
445
+ Abi :: ScalarPair ( a, b) => PassMode :: Pair (
446
+ scalar_attrs ( & layout, a, Size :: ZERO ) ,
447
+ scalar_attrs ( & layout, b, a. value . size ( cx) . align_to ( b. value . align ( cx) . abi ) ) ,
448
+ ) ,
449
+ Abi :: Vector { .. } => PassMode :: Direct ( ArgAttributes :: new ( ) ) ,
450
+ Abi :: Aggregate { .. } => Self :: indirect_pass_mode ( & layout) ,
451
+ } ;
452
+ ArgAbi { layout, pad : None , mode }
439
453
}
440
454
441
- pub fn make_indirect ( & mut self ) {
442
- match self . mode {
443
- PassMode :: Direct ( _) | PassMode :: Pair ( _, _) => { }
444
- _ => panic ! ( "Tried to make {:?} indirect" , self . mode) ,
445
- }
446
-
447
- // Start with fresh attributes for the pointer.
455
+ fn indirect_pass_mode ( layout : & TyAndLayout < ' a , Ty > ) -> PassMode {
448
456
let mut attrs = ArgAttributes :: new ( ) ;
449
457
450
458
// For non-immediate arguments the callee gets its own copy of
451
459
// the value on the stack, so there are no aliases. It's also
452
460
// program-invisible so can't possibly capture
453
461
attrs. set ( ArgAttribute :: NoAlias ) . set ( ArgAttribute :: NoCapture ) . set ( ArgAttribute :: NonNull ) ;
454
- attrs. pointee_size = self . layout . size ;
462
+ attrs. pointee_size = layout. size ;
455
463
// FIXME(eddyb) We should be doing this, but at least on
456
464
// i686-pc-windows-msvc, it results in wrong stack offsets.
457
- // attrs.pointee_align = Some(self. layout.align.abi);
465
+ // attrs.pointee_align = Some(layout.align.abi);
458
466
459
- let extra_attrs = self . layout . is_unsized ( ) . then_some ( ArgAttributes :: new ( ) ) ;
467
+ let extra_attrs = layout. is_unsized ( ) . then_some ( ArgAttributes :: new ( ) ) ;
460
468
461
- self . mode = PassMode :: Indirect { attrs, extra_attrs, on_stack : false } ;
469
+ PassMode :: Indirect { attrs, extra_attrs, on_stack : false }
470
+ }
471
+
472
+ pub fn make_indirect ( & mut self ) {
473
+ match self . mode {
474
+ PassMode :: Direct ( _) | PassMode :: Pair ( _, _) => { }
475
+ PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : false } => return ,
476
+ _ => panic ! ( "Tried to make {:?} indirect" , self . mode) ,
477
+ }
478
+
479
+ self . mode = Self :: indirect_pass_mode ( & self . layout ) ;
462
480
}
463
481
464
482
pub fn make_indirect_byval ( & mut self ) {
@@ -489,10 +507,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
489
507
}
490
508
491
509
pub fn cast_to < T : Into < CastTarget > > ( & mut self , target : T ) {
492
- match self . mode {
493
- PassMode :: Direct ( _) | PassMode :: Pair ( _, _) => { }
494
- _ => panic ! ( "Tried to cast {:?} to {:?}" , self . mode, target. into( ) ) ,
495
- }
496
510
self . mode = PassMode :: Cast ( target. into ( ) ) ;
497
511
}
498
512
0 commit comments