@@ -34,17 +34,17 @@ trait ArgAttributeExt {
3434impl ArgAttributeExt for ArgAttribute {
3535 fn for_each_kind < F > ( & self , mut f : F ) where F : FnMut ( llvm:: Attribute ) {
3636 for_each_kind ! ( self , f,
37- ByVal , NoAlias , NoCapture , NonNull , ReadOnly , SExt , StructRet , ZExt , InReg )
37+ NoAlias , NoCapture , NonNull , ReadOnly , SExt , StructRet , ZExt , InReg )
3838 }
3939}
4040
4141pub trait ArgAttributesExt {
42- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value ) ;
43- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value ) ;
42+ fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) ;
43+ fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) ;
4444}
4545
4646impl ArgAttributesExt for ArgAttributes {
47- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value ) {
47+ fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) {
4848 let mut regular = self . regular ;
4949 unsafe {
5050 let deref = self . pointee_size . bytes ( ) ;
@@ -65,11 +65,14 @@ impl ArgAttributesExt for ArgAttributes {
6565 idx. as_uint ( ) ,
6666 align. bytes ( ) as u32 ) ;
6767 }
68+ if regular. contains ( ArgAttribute :: ByVal ) {
69+ llvm:: LLVMRustAddByValAttr ( llfn, idx. as_uint ( ) , ty. unwrap ( ) ) ;
70+ }
6871 regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
6972 }
7073 }
7174
72- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
75+ fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) {
7376 let mut regular = self . regular ;
7477 unsafe {
7578 let deref = self . pointee_size . bytes ( ) ;
@@ -90,6 +93,9 @@ impl ArgAttributesExt for ArgAttributes {
9093 idx. as_uint ( ) ,
9194 align. bytes ( ) as u32 ) ;
9295 }
96+ if regular. contains ( ArgAttribute :: ByVal ) {
97+ llvm:: LLVMRustAddByValCallSiteAttr ( callsite, idx. as_uint ( ) , ty. unwrap ( ) ) ;
98+ }
9399 regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
94100 }
95101 }
@@ -298,7 +304,7 @@ pub trait FnTypeLlvmExt<'tcx> {
298304 fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
299305 fn ptr_to_llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
300306 fn llvm_cconv ( & self ) -> llvm:: CallConv ;
301- fn apply_attrs_llfn ( & self , llfn : & ' ll Value ) ;
307+ fn apply_attrs_llfn ( & self , cx : & CodegenCx < ' ll , ' tcx > , llfn : & ' ll Value ) ;
302308 fn apply_attrs_callsite ( & self , bx : & mut Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) ;
303309}
304310
@@ -384,51 +390,51 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
384390 }
385391 }
386392
387- fn apply_attrs_llfn ( & self , llfn : & ' ll Value ) {
393+ fn apply_attrs_llfn ( & self , cx : & CodegenCx < ' ll , ' tcx > , llfn : & ' ll Value ) {
388394 let mut i = 0 ;
389- let mut apply = |attrs : & ArgAttributes | {
390- attrs. apply_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn) ;
395+ let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
396+ attrs. apply_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn, ty ) ;
391397 i += 1 ;
392398 } ;
393399 match self . ret . mode {
394400 PassMode :: Direct ( ref attrs) => {
395- attrs. apply_llfn ( llvm:: AttributePlace :: ReturnValue , llfn) ;
401+ attrs. apply_llfn ( llvm:: AttributePlace :: ReturnValue , llfn, None ) ;
396402 }
397- PassMode :: Indirect ( ref attrs, _) => apply ( attrs) ,
403+ PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( cx ) ) ) ,
398404 _ => { }
399405 }
400406 for arg in & self . args {
401407 if arg. pad . is_some ( ) {
402- apply ( & ArgAttributes :: new ( ) ) ;
408+ apply ( & ArgAttributes :: new ( ) , None ) ;
403409 }
404410 match arg. mode {
405411 PassMode :: Ignore ( _) => { }
406412 PassMode :: Direct ( ref attrs) |
407- PassMode :: Indirect ( ref attrs, None ) => apply ( attrs) ,
413+ PassMode :: Indirect ( ref attrs, None ) => apply ( attrs, Some ( arg . layout . llvm_type ( cx ) ) ) ,
408414 PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
409- apply ( attrs) ;
410- apply ( extra_attrs) ;
415+ apply ( attrs, None ) ;
416+ apply ( extra_attrs, None ) ;
411417 }
412418 PassMode :: Pair ( ref a, ref b) => {
413- apply ( a) ;
414- apply ( b) ;
419+ apply ( a, None ) ;
420+ apply ( b, None ) ;
415421 }
416- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) ) ,
422+ PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
417423 }
418424 }
419425 }
420426
421427 fn apply_attrs_callsite ( & self , bx : & mut Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) {
422428 let mut i = 0 ;
423- let mut apply = |attrs : & ArgAttributes | {
424- attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
429+ let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
430+ attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite, ty ) ;
425431 i += 1 ;
426432 } ;
427433 match self . ret . mode {
428434 PassMode :: Direct ( ref attrs) => {
429- attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
435+ attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite, None ) ;
430436 }
431- PassMode :: Indirect ( ref attrs, _) => apply ( attrs) ,
437+ PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( bx ) ) ) ,
432438 _ => { }
433439 }
434440 if let layout:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
@@ -446,21 +452,21 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
446452 }
447453 for arg in & self . args {
448454 if arg. pad . is_some ( ) {
449- apply ( & ArgAttributes :: new ( ) ) ;
455+ apply ( & ArgAttributes :: new ( ) , None ) ;
450456 }
451457 match arg. mode {
452458 PassMode :: Ignore ( _) => { }
453459 PassMode :: Direct ( ref attrs) |
454- PassMode :: Indirect ( ref attrs, None ) => apply ( attrs) ,
460+ PassMode :: Indirect ( ref attrs, None ) => apply ( attrs, Some ( arg . layout . llvm_type ( bx ) ) ) ,
455461 PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
456- apply ( attrs) ;
457- apply ( extra_attrs) ;
462+ apply ( attrs, None ) ;
463+ apply ( extra_attrs, None ) ;
458464 }
459465 PassMode :: Pair ( ref a, ref b) => {
460- apply ( a) ;
461- apply ( b) ;
466+ apply ( a, None ) ;
467+ apply ( b, None ) ;
462468 }
463- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) ) ,
469+ PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
464470 }
465471 }
466472
0 commit comments