@@ -77,6 +77,9 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
7777 /// All `VarDebuginfo` from the MIR body, partitioned by `Local`.
7878 /// This is `None` if no variable debuginfo/names are needed.
7979 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 > > ,
8083}
8184
8285impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
@@ -172,13 +175,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
172175 locals : IndexVec :: new ( ) ,
173176 debug_context,
174177 per_local_var_debug_info : debuginfo:: per_local_var_debug_info ( cx. tcx ( ) , mir_body) ,
178+ caller_location : None ,
175179 } ;
176180
177181 let memory_locals = analyze:: non_ssa_locals ( & fx) ;
178182
179183 // Allocate variable and temp allocas
180184 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) ;
182186
183187 let mut allocate_local = |local| {
184188 let decl = & mir_body. local_decls [ local] ;
@@ -320,14 +324,14 @@ fn create_funclets<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
320324/// indirect.
321325fn arg_local_refs < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > (
322326 bx : & mut Bx ,
323- fx : & FunctionCx < ' a , ' tcx , Bx > ,
327+ fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
324328 memory_locals : & BitSet < mir:: Local > ,
325329) -> Vec < LocalRef < ' tcx , Bx :: Value > > {
326330 let mir = fx. mir ;
327331 let mut idx = 0 ;
328332 let mut llarg_idx = fx. fn_abi . ret . is_indirect ( ) as usize ;
329333
330- mir. args_iter ( ) . enumerate ( ) . map ( |( arg_index, local) | {
334+ let args = mir. args_iter ( ) . enumerate ( ) . map ( |( arg_index, local) | {
331335 let arg_decl = & mir. local_decls [ local] ;
332336
333337 if Some ( local) == mir. spread_arg {
@@ -423,7 +427,27 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
423427 bx. store_fn_arg ( arg, & mut llarg_idx, tmp) ;
424428 LocalRef :: Place ( tmp)
425429 }
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
427451}
428452
429453mod analyze;
0 commit comments