@@ -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