@@ -260,7 +260,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
260260
261261 // Indicates that local is set to a new value. The `layout` and `projection` are used to
262262 // calculate the offset.
263- pub ( crate ) fn debug_new_val_to_local (
263+ fn debug_new_val_to_local (
264264 & self ,
265265 bx : & mut Bx ,
266266 local : mir:: Local ,
@@ -297,7 +297,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
297297 }
298298 }
299299
300- pub ( crate ) fn debug_poison_to_local ( & self , bx : & mut Bx , local : mir:: Local ) {
300+ fn debug_poison_to_local ( & self , bx : & mut Bx , local : mir:: Local ) {
301301 let ty = self . monomorphize ( self . mir . local_decls [ local] . ty ) ;
302302 let layout = bx. cx ( ) . layout_of ( ty) ;
303303 let to_backend_ty = bx. cx ( ) . immediate_backend_type ( layout) ;
@@ -692,6 +692,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
692692 Some ( ( per_local, constants) )
693693 }
694694
695+ pub ( crate ) fn codegen_stmt_debuginfo (
696+ & mut self ,
697+ bx : & mut Bx ,
698+ debuginfo : & mir:: StmtDebugInfo < ' tcx > ,
699+ ) {
700+ match debuginfo {
701+ mir:: StmtDebugInfo :: AssignRef ( dest, place) => {
702+ let local_ref = match self . locals [ place. local ] {
703+ // For an rvalue like `&(_1.1)`, when `BackendRepr` is `BackendRepr::Memory`, we allocate a block of memory to this place.
704+ // The place is an indirect pointer, we can refer to it directly.
705+ LocalRef :: Place ( place_ref) => Some ( ( place_ref, place. projection . as_slice ( ) ) ) ,
706+ // For an rvalue like `&((*_1).1)`, we are calculating the address of `_1.1`.
707+ // The deref projection is no-op here.
708+ LocalRef :: Operand ( operand_ref) if place. is_indirect_first_projection ( ) => {
709+ Some ( ( operand_ref. deref ( bx. cx ( ) ) , & place. projection [ 1 ..] ) )
710+ }
711+ // For an rvalue like `&1`, when `BackendRepr` is `BackendRepr::Scalar`,
712+ // we cannot get the address.
713+ // N.B. `non_ssa_locals` returns that this is an SSA local.
714+ LocalRef :: Operand ( _) => None ,
715+ LocalRef :: UnsizedPlace ( _) | LocalRef :: PendingOperand => None ,
716+ }
717+ . filter ( |( _, projection) | {
718+ // Drop unsupported projections.
719+ projection. iter ( ) . all ( |p| p. can_use_in_debuginfo ( ) )
720+ } ) ;
721+ if let Some ( ( base, projection) ) = local_ref {
722+ self . debug_new_val_to_local ( bx, * dest, base, projection) ;
723+ } else {
724+ // If the address cannot be calculated, use poison to indicate that the value has been optimized out.
725+ self . debug_poison_to_local ( bx, * dest) ;
726+ }
727+ }
728+ mir:: StmtDebugInfo :: InvalidAssign ( local) => {
729+ self . debug_poison_to_local ( bx, * local) ;
730+ }
731+ }
732+ }
733+
734+ pub ( crate ) fn codegen_stmt_debuginfos (
735+ & mut self ,
736+ bx : & mut Bx ,
737+ debuginfos : & [ mir:: StmtDebugInfo < ' tcx > ] ,
738+ ) {
739+ for debuginfo in debuginfos {
740+ self . codegen_stmt_debuginfo ( bx, debuginfo) ;
741+ }
742+ }
743+
695744 /// Creates the function-specific debug context.
696745 ///
697746 /// Returns the FunctionDebugContext for the function which holds state needed
0 commit comments