@@ -434,31 +434,49 @@ pub struct ArgAbi<'a, Ty> {
434434}
435435
436436impl < ' 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 }
439453 }
440454
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 {
448456 let mut attrs = ArgAttributes :: new ( ) ;
449457
450458 // For non-immediate arguments the callee gets its own copy of
451459 // the value on the stack, so there are no aliases. It's also
452460 // program-invisible so can't possibly capture
453461 attrs. set ( ArgAttribute :: NoAlias ) . set ( ArgAttribute :: NoCapture ) . set ( ArgAttribute :: NonNull ) ;
454- attrs. pointee_size = self . layout . size ;
462+ attrs. pointee_size = layout. size ;
455463 // FIXME(eddyb) We should be doing this, but at least on
456464 // 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);
458466
459- let extra_attrs = self . layout . is_unsized ( ) . then_some ( ArgAttributes :: new ( ) ) ;
467+ let extra_attrs = layout. is_unsized ( ) . then_some ( ArgAttributes :: new ( ) ) ;
460468
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 ) ;
462480 }
463481
464482 pub fn make_indirect_byval ( & mut self ) {
@@ -489,10 +507,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
489507 }
490508
491509 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- }
496510 self . mode = PassMode :: Cast ( target. into ( ) ) ;
497511 }
498512
0 commit comments