@@ -34,17 +34,17 @@ trait ArgAttributeExt {
34
34
impl ArgAttributeExt for ArgAttribute {
35
35
fn for_each_kind < F > ( & self , mut f : F ) where F : FnMut ( llvm:: Attribute ) {
36
36
for_each_kind ! ( self , f,
37
- ByVal , NoAlias , NoCapture , NonNull , ReadOnly , SExt , StructRet , ZExt , InReg )
37
+ NoAlias , NoCapture , NonNull , ReadOnly , SExt , StructRet , ZExt , InReg )
38
38
}
39
39
}
40
40
41
41
pub 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 > ) ;
44
44
}
45
45
46
46
impl ArgAttributesExt for ArgAttributes {
47
- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value ) {
47
+ fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) {
48
48
let mut regular = self . regular ;
49
49
unsafe {
50
50
let deref = self . pointee_size . bytes ( ) ;
@@ -65,11 +65,14 @@ impl ArgAttributesExt for ArgAttributes {
65
65
idx. as_uint ( ) ,
66
66
align. bytes ( ) as u32 ) ;
67
67
}
68
+ if regular. contains ( ArgAttribute :: ByVal ) {
69
+ llvm:: LLVMRustAddByValAttr ( llfn, idx. as_uint ( ) , ty. unwrap ( ) ) ;
70
+ }
68
71
regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
69
72
}
70
73
}
71
74
72
- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
75
+ fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) {
73
76
let mut regular = self . regular ;
74
77
unsafe {
75
78
let deref = self . pointee_size . bytes ( ) ;
@@ -90,6 +93,9 @@ impl ArgAttributesExt for ArgAttributes {
90
93
idx. as_uint ( ) ,
91
94
align. bytes ( ) as u32 ) ;
92
95
}
96
+ if regular. contains ( ArgAttribute :: ByVal ) {
97
+ llvm:: LLVMRustAddByValCallSiteAttr ( callsite, idx. as_uint ( ) , ty. unwrap ( ) ) ;
98
+ }
93
99
regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
94
100
}
95
101
}
@@ -298,7 +304,7 @@ pub trait FnTypeLlvmExt<'tcx> {
298
304
fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
299
305
fn ptr_to_llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
300
306
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 ) ;
302
308
fn apply_attrs_callsite ( & self , bx : & mut Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) ;
303
309
}
304
310
@@ -384,51 +390,51 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
384
390
}
385
391
}
386
392
387
- fn apply_attrs_llfn ( & self , llfn : & ' ll Value ) {
393
+ fn apply_attrs_llfn ( & self , cx : & CodegenCx < ' ll , ' tcx > , llfn : & ' ll Value ) {
388
394
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 ) ;
391
397
i += 1 ;
392
398
} ;
393
399
match self . ret . mode {
394
400
PassMode :: Direct ( ref attrs) => {
395
- attrs. apply_llfn ( llvm:: AttributePlace :: ReturnValue , llfn) ;
401
+ attrs. apply_llfn ( llvm:: AttributePlace :: ReturnValue , llfn, None ) ;
396
402
}
397
- PassMode :: Indirect ( ref attrs, _) => apply ( attrs) ,
403
+ PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( cx ) ) ) ,
398
404
_ => { }
399
405
}
400
406
for arg in & self . args {
401
407
if arg. pad . is_some ( ) {
402
- apply ( & ArgAttributes :: new ( ) ) ;
408
+ apply ( & ArgAttributes :: new ( ) , None ) ;
403
409
}
404
410
match arg. mode {
405
411
PassMode :: Ignore ( _) => { }
406
412
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 ) ) ) ,
408
414
PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
409
- apply ( attrs) ;
410
- apply ( extra_attrs) ;
415
+ apply ( attrs, None ) ;
416
+ apply ( extra_attrs, None ) ;
411
417
}
412
418
PassMode :: Pair ( ref a, ref b) => {
413
- apply ( a) ;
414
- apply ( b) ;
419
+ apply ( a, None ) ;
420
+ apply ( b, None ) ;
415
421
}
416
- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) ) ,
422
+ PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
417
423
}
418
424
}
419
425
}
420
426
421
427
fn apply_attrs_callsite ( & self , bx : & mut Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) {
422
428
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 ) ;
425
431
i += 1 ;
426
432
} ;
427
433
match self . ret . mode {
428
434
PassMode :: Direct ( ref attrs) => {
429
- attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
435
+ attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite, None ) ;
430
436
}
431
- PassMode :: Indirect ( ref attrs, _) => apply ( attrs) ,
437
+ PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( bx ) ) ) ,
432
438
_ => { }
433
439
}
434
440
if let layout:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
@@ -446,21 +452,21 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
446
452
}
447
453
for arg in & self . args {
448
454
if arg. pad . is_some ( ) {
449
- apply ( & ArgAttributes :: new ( ) ) ;
455
+ apply ( & ArgAttributes :: new ( ) , None ) ;
450
456
}
451
457
match arg. mode {
452
458
PassMode :: Ignore ( _) => { }
453
459
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 ) ) ) ,
455
461
PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
456
- apply ( attrs) ;
457
- apply ( extra_attrs) ;
462
+ apply ( attrs, None ) ;
463
+ apply ( extra_attrs, None ) ;
458
464
}
459
465
PassMode :: Pair ( ref a, ref b) => {
460
- apply ( a) ;
461
- apply ( b) ;
466
+ apply ( a, None ) ;
467
+ apply ( b, None ) ;
462
468
}
463
- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) ) ,
469
+ PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
464
470
}
465
471
}
466
472
0 commit comments