@@ -77,6 +77,9 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
77
77
/// All `VarDebuginfo` from the MIR body, partitioned by `Local`.
78
78
/// This is `None` if no variable debuginfo/names are needed.
79
79
per_local_var_debug_info : Option < IndexVec < mir:: Local , Vec < & ' tcx mir:: VarDebugInfo < ' tcx > > > > ,
80
+
81
+ /// Caller location propagated if this function has `#[track_caller]`.
82
+ caller_location : Option < OperandRef < ' tcx , Bx :: Value > > ,
80
83
}
81
84
82
85
impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
@@ -172,13 +175,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
172
175
locals : IndexVec :: new ( ) ,
173
176
debug_context,
174
177
per_local_var_debug_info : debuginfo:: per_local_var_debug_info ( cx. tcx ( ) , mir_body) ,
178
+ caller_location : None ,
175
179
} ;
176
180
177
181
let memory_locals = analyze:: non_ssa_locals ( & fx) ;
178
182
179
183
// Allocate variable and temp allocas
180
184
fx. locals = {
181
- let args = arg_local_refs ( & mut bx, & fx, & memory_locals) ;
185
+ let args = arg_local_refs ( & mut bx, & mut fx, & memory_locals) ;
182
186
183
187
let mut allocate_local = |local| {
184
188
let decl = & mir_body. local_decls [ local] ;
@@ -320,14 +324,14 @@ fn create_funclets<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
320
324
/// indirect.
321
325
fn arg_local_refs < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > (
322
326
bx : & mut Bx ,
323
- fx : & FunctionCx < ' a , ' tcx , Bx > ,
327
+ fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
324
328
memory_locals : & BitSet < mir:: Local > ,
325
329
) -> Vec < LocalRef < ' tcx , Bx :: Value > > {
326
330
let mir = fx. mir ;
327
331
let mut idx = 0 ;
328
332
let mut llarg_idx = fx. fn_abi . ret . is_indirect ( ) as usize ;
329
333
330
- mir. args_iter ( ) . enumerate ( ) . map ( |( arg_index, local) | {
334
+ let args = mir. args_iter ( ) . enumerate ( ) . map ( |( arg_index, local) | {
331
335
let arg_decl = & mir. local_decls [ local] ;
332
336
333
337
if Some ( local) == mir. spread_arg {
@@ -423,7 +427,27 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
423
427
bx. store_fn_arg ( arg, & mut llarg_idx, tmp) ;
424
428
LocalRef :: Place ( tmp)
425
429
}
426
- } ) . collect ( )
430
+ } ) . collect :: < Vec < _ > > ( ) ;
431
+
432
+ if fx. instance . def . requires_caller_location ( bx. tcx ( ) ) {
433
+ assert_eq ! (
434
+ fx. fn_abi. args. len( ) , args. len( ) + 1 ,
435
+ "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR" ,
436
+ ) ;
437
+
438
+ let arg = fx. fn_abi . args . last ( ) . unwrap ( ) ;
439
+ match arg. mode {
440
+ PassMode :: Direct ( _) => ( ) ,
441
+ _ => bug ! ( "caller location must be PassMode::Direct, found {:?}" , arg. mode) ,
442
+ }
443
+
444
+ fx. caller_location = Some ( OperandRef {
445
+ val : OperandValue :: Immediate ( bx. get_param ( llarg_idx) ) ,
446
+ layout : arg. layout ,
447
+ } ) ;
448
+ }
449
+
450
+ args
427
451
}
428
452
429
453
mod analyze;
0 commit comments