@@ -2,7 +2,7 @@ use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts, Instance};
2
2
use rustc:: ty:: layout:: { TyLayout , HasTyCtxt , FnTypeExt } ;
3
3
use rustc:: mir:: { self , Body } ;
4
4
use rustc:: session:: config:: DebugInfo ;
5
- use rustc_target:: abi:: call:: { FnType , PassMode , IgnoreMode } ;
5
+ use rustc_target:: abi:: call:: { FnType , PassMode } ;
6
6
use rustc_target:: abi:: { Variants , VariantIdx } ;
7
7
use crate :: base;
8
8
use crate :: debuginfo:: { self , VariableAccess , VariableKind , FunctionDebugContext } ;
@@ -441,15 +441,6 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
441
441
None
442
442
} ;
443
443
444
- // Store the index of the last argument. This is used to
445
- // call va_start on the va_list instead of attempting
446
- // to store_fn_arg.
447
- let last_arg_idx = if fx. fn_ty . args . is_empty ( ) {
448
- None
449
- } else {
450
- Some ( fx. fn_ty . args . len ( ) - 1 )
451
- } ;
452
-
453
444
mir. args_iter ( ) . enumerate ( ) . map ( |( arg_index, local) | {
454
445
let arg_decl = & mir. local_decls [ local] ;
455
446
@@ -503,6 +494,33 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
503
494
return LocalRef :: Place ( place) ;
504
495
}
505
496
497
+ if fx. fn_ty . c_variadic && arg_index == fx. fn_ty . args . len ( ) {
498
+ let arg_ty = fx. monomorphize ( & arg_decl. ty ) ;
499
+
500
+ let va_list = PlaceRef :: alloca ( bx, bx. layout_of ( arg_ty) ) ;
501
+ bx. set_var_name ( va_list. llval , name) ;
502
+ bx. va_start ( va_list. llval ) ;
503
+ // FIXME(eddyb) remove `va_list_ref`.
504
+ * va_list_ref = Some ( va_list) ;
505
+
506
+ arg_scope. map ( |scope| {
507
+ let variable_access = VariableAccess :: DirectVariable {
508
+ alloca : va_list. llval
509
+ } ;
510
+ bx. declare_local (
511
+ & fx. debug_context ,
512
+ arg_decl. name . unwrap_or ( kw:: Invalid ) ,
513
+ va_list. layout . ty ,
514
+ scope,
515
+ variable_access,
516
+ VariableKind :: ArgumentVariable ( arg_index + 1 ) ,
517
+ DUMMY_SP
518
+ ) ;
519
+ } ) ;
520
+
521
+ return LocalRef :: Place ( va_list) ;
522
+ }
523
+
506
524
let arg = & fx. fn_ty . args [ idx] ;
507
525
idx += 1 ;
508
526
if arg. pad . is_some ( ) {
@@ -515,10 +533,9 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
515
533
// of putting everything in allocas just so we can use llvm.dbg.declare.
516
534
let local = |op| LocalRef :: Operand ( Some ( op) ) ;
517
535
match arg. mode {
518
- PassMode :: Ignore ( IgnoreMode :: Zst ) => {
536
+ PassMode :: Ignore => {
519
537
return local ( OperandRef :: new_zst ( bx, arg. layout ) ) ;
520
538
}
521
- PassMode :: Ignore ( IgnoreMode :: CVarArgs ) => { }
522
539
PassMode :: Direct ( _) => {
523
540
let llarg = bx. get_param ( llarg_idx) ;
524
541
bx. set_var_name ( llarg, & name) ;
@@ -568,22 +585,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
568
585
} else {
569
586
let tmp = PlaceRef :: alloca ( bx, arg. layout ) ;
570
587
bx. set_var_name ( tmp. llval , name) ;
571
- if fx. fn_ty . c_variadic && last_arg_idx. map ( |idx| arg_index == idx) . unwrap_or ( false ) {
572
- let va_list_did = match tcx. lang_items ( ) . va_list ( ) {
573
- Some ( did) => did,
574
- None => bug ! ( "`va_list` lang item required for C-variadic functions" ) ,
575
- } ;
576
- match arg_decl. ty . kind {
577
- ty:: Adt ( def, _) if def. did == va_list_did => {
578
- // Call `va_start` on the spoofed `VaListImpl`.
579
- bx. va_start ( tmp. llval ) ;
580
- * va_list_ref = Some ( tmp) ;
581
- } ,
582
- _ => bug ! ( "last argument of variadic function is not a `va_list`" )
583
- }
584
- } else {
585
- bx. store_fn_arg ( arg, & mut llarg_idx, tmp) ;
586
- }
588
+ bx. store_fn_arg ( arg, & mut llarg_idx, tmp) ;
587
589
tmp
588
590
} ;
589
591
let upvar_debuginfo = & mir. __upvar_debuginfo_codegen_only_do_not_use ;
0 commit comments