@@ -41,12 +41,12 @@ impl ArgAttributeExt for ArgAttribute {
4141}
4242
4343pub trait ArgAttributesExt {
44- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) ;
45- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) ;
44+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) ;
45+ fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) ;
4646}
4747
4848impl ArgAttributesExt for ArgAttributes {
49- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) {
49+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) {
5050 let mut regular = self . regular ;
5151 unsafe {
5252 let deref = self . pointee_size . bytes ( ) ;
@@ -61,9 +61,6 @@ impl ArgAttributesExt for ArgAttributes {
6161 if let Some ( align) = self . pointee_align {
6262 llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
6363 }
64- if regular. contains ( ArgAttribute :: ByVal ) {
65- llvm:: LLVMRustAddByValAttr ( llfn, idx. as_uint ( ) , ty. unwrap ( ) ) ;
66- }
6764 regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
6865 match self . arg_ext {
6966 ArgExtension :: None => { }
@@ -77,7 +74,7 @@ impl ArgAttributesExt for ArgAttributes {
7774 }
7875 }
7976
80- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) {
77+ fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
8178 let mut regular = self . regular ;
8279 unsafe {
8380 let deref = self . pointee_size . bytes ( ) ;
@@ -100,9 +97,6 @@ impl ArgAttributesExt for ArgAttributes {
10097 align. bytes ( ) as u32 ,
10198 ) ;
10299 }
103- if regular. contains ( ArgAttribute :: ByVal ) {
104- llvm:: LLVMRustAddByValCallSiteAttr ( callsite, idx. as_uint ( ) , ty. unwrap ( ) ) ;
105- }
106100 regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
107101 match self . arg_ext {
108102 ArgExtension :: None => { }
@@ -285,10 +279,12 @@ impl ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
285279 PassMode :: Pair ( ..) => {
286280 OperandValue :: Pair ( next ( ) , next ( ) ) . store ( bx, dst) ;
287281 }
288- PassMode :: Indirect ( _, Some ( _) ) => {
282+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
289283 OperandValue :: Ref ( next ( ) , Some ( next ( ) ) , self . layout . align . abi ) . store ( bx, dst) ;
290284 }
291- PassMode :: Direct ( _) | PassMode :: Indirect ( _, None ) | PassMode :: Cast ( _) => {
285+ PassMode :: Direct ( _)
286+ | PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : _ }
287+ | PassMode :: Cast ( _) => {
292288 let next_arg = next ( ) ;
293289 self . store ( bx, next_arg, dst) ;
294290 }
@@ -333,14 +329,14 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
333329 if let PassMode :: Pair ( _, _) = arg. mode { 2 } else { 1 }
334330 ) . sum ( ) ;
335331 let mut llargument_tys = Vec :: with_capacity (
336- if let PassMode :: Indirect ( .. ) = self . ret . mode { 1 } else { 0 } + args_capacity,
332+ if let PassMode :: Indirect { .. } = self . ret . mode { 1 } else { 0 } + args_capacity,
337333 ) ;
338334
339335 let llreturn_ty = match self . ret . mode {
340336 PassMode :: Ignore => cx. type_void ( ) ,
341337 PassMode :: Direct ( _) | PassMode :: Pair ( ..) => self . ret . layout . immediate_llvm_type ( cx) ,
342338 PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
343- PassMode :: Indirect ( .. ) => {
339+ PassMode :: Indirect { .. } => {
344340 llargument_tys. push ( cx. type_ptr_to ( self . ret . memory_ty ( cx) ) ) ;
345341 cx. type_void ( )
346342 }
@@ -360,15 +356,17 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
360356 llargument_tys. push ( arg. layout . scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
361357 continue ;
362358 }
363- PassMode :: Indirect ( _, Some ( _) ) => {
359+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
364360 let ptr_ty = cx. tcx . mk_mut_ptr ( arg. layout . ty ) ;
365361 let ptr_layout = cx. layout_of ( ptr_ty) ;
366362 llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 0 , true ) ) ;
367363 llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
368364 continue ;
369365 }
370366 PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
371- PassMode :: Indirect ( _, None ) => cx. type_ptr_to ( arg. memory_ty ( cx) ) ,
367+ PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : _ } => {
368+ cx. type_ptr_to ( arg. memory_ty ( cx) )
369+ }
372370 } ;
373371 llargument_tys. push ( llarg_ty) ;
374372 }
@@ -420,35 +418,53 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
420418 }
421419
422420 let mut i = 0 ;
423- let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
424- attrs. apply_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn, ty ) ;
421+ let mut apply = |attrs : & ArgAttributes | {
422+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn) ;
425423 i += 1 ;
424+ i - 1
426425 } ;
427426 match self . ret . mode {
428427 PassMode :: Direct ( ref attrs) => {
429- attrs. apply_llfn ( llvm:: AttributePlace :: ReturnValue , llfn, None ) ;
428+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , llfn) ;
429+ }
430+ PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
431+ assert ! ( !on_stack) ;
432+ apply ( attrs) ;
430433 }
431- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( cx) ) ) ,
432434 _ => { }
433435 }
434436 for arg in & self . args {
435437 if arg. pad . is_some ( ) {
436- apply ( & ArgAttributes :: new ( ) , None ) ;
438+ apply ( & ArgAttributes :: new ( ) ) ;
437439 }
438440 match arg. mode {
439441 PassMode :: Ignore => { }
440- PassMode :: Direct ( ref attrs) | PassMode :: Indirect ( ref attrs, None ) => {
441- apply ( attrs, Some ( arg. layout . llvm_type ( cx) ) )
442+ PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
443+ let i = apply ( attrs) ;
444+ unsafe {
445+ llvm:: LLVMRustAddByValAttr (
446+ llfn,
447+ llvm:: AttributePlace :: Argument ( i) . as_uint ( ) ,
448+ arg. layout . llvm_type ( cx) ,
449+ ) ;
450+ }
451+ }
452+ PassMode :: Direct ( ref attrs)
453+ | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
454+ apply ( attrs) ;
442455 }
443- PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
444- apply ( attrs, None ) ;
445- apply ( extra_attrs, None ) ;
456+ PassMode :: Indirect { ref attrs, extra_attrs : Some ( ref extra_attrs) , on_stack } => {
457+ assert ! ( !on_stack) ;
458+ apply ( attrs) ;
459+ apply ( extra_attrs) ;
446460 }
447461 PassMode :: Pair ( ref a, ref b) => {
448- apply ( a, None ) ;
449- apply ( b, None ) ;
462+ apply ( a) ;
463+ apply ( b) ;
464+ }
465+ PassMode :: Cast ( _) => {
466+ apply ( & ArgAttributes :: new ( ) ) ;
450467 }
451- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
452468 }
453469 }
454470 }
@@ -457,15 +473,19 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
457473 // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
458474
459475 let mut i = 0 ;
460- let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
461- attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite, ty ) ;
476+ let mut apply = |attrs : & ArgAttributes | {
477+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
462478 i += 1 ;
479+ i - 1
463480 } ;
464481 match self . ret . mode {
465482 PassMode :: Direct ( ref attrs) => {
466- attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite, None ) ;
483+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
484+ }
485+ PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
486+ assert ! ( !on_stack) ;
487+ apply ( attrs) ;
467488 }
468- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( bx) ) ) ,
469489 _ => { }
470490 }
471491 if let abi:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
@@ -483,22 +503,39 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
483503 }
484504 for arg in & self . args {
485505 if arg. pad . is_some ( ) {
486- apply ( & ArgAttributes :: new ( ) , None ) ;
506+ apply ( & ArgAttributes :: new ( ) ) ;
487507 }
488508 match arg. mode {
489509 PassMode :: Ignore => { }
490- PassMode :: Direct ( ref attrs) | PassMode :: Indirect ( ref attrs, None ) => {
491- apply ( attrs, Some ( arg. layout . llvm_type ( bx) ) )
510+ PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
511+ let i = apply ( attrs) ;
512+ unsafe {
513+ llvm:: LLVMRustAddByValCallSiteAttr (
514+ callsite,
515+ llvm:: AttributePlace :: Argument ( i) . as_uint ( ) ,
516+ arg. layout . llvm_type ( bx) ,
517+ ) ;
518+ }
492519 }
493- PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
494- apply ( attrs, None ) ;
495- apply ( extra_attrs, None ) ;
520+ PassMode :: Direct ( ref attrs)
521+ | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
522+ apply ( attrs) ;
523+ }
524+ PassMode :: Indirect {
525+ ref attrs,
526+ extra_attrs : Some ( ref extra_attrs) ,
527+ on_stack : _,
528+ } => {
529+ apply ( attrs) ;
530+ apply ( extra_attrs) ;
496531 }
497532 PassMode :: Pair ( ref a, ref b) => {
498- apply ( a, None ) ;
499- apply ( b, None ) ;
533+ apply ( a) ;
534+ apply ( b) ;
535+ }
536+ PassMode :: Cast ( _) => {
537+ apply ( & ArgAttributes :: new ( ) ) ;
500538 }
501- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
502539 }
503540 }
504541
0 commit comments