1- use rustc_middle:: mir:: { self , NonDivergingIntrinsic } ;
1+ use rustc_middle:: mir:: { self , NonDivergingIntrinsic , StmtDebugInfo } ;
22use rustc_middle:: span_bug;
33use tracing:: instrument;
44
@@ -8,6 +8,7 @@ use crate::traits::*;
88impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
99 #[ instrument( level = "debug" , skip( self , bx) ) ]
1010 pub ( crate ) fn codegen_statement ( & mut self , bx : & mut Bx , statement : & mir:: Statement < ' tcx > ) {
11+ self . codegen_stmt_debuginfos ( bx, & statement. debuginfos ) ;
1112 self . set_debug_loc ( bx, statement. source_info ) ;
1213 match statement. kind {
1314 mir:: StatementKind :: Assign ( box ( ref place, ref rvalue) ) => {
@@ -101,4 +102,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
101102 | mir:: StatementKind :: Nop => { }
102103 }
103104 }
105+
106+ pub ( crate ) fn codegen_stmt_debuginfo ( & mut self , bx : & mut Bx , debuginfo : & StmtDebugInfo < ' tcx > ) {
107+ match debuginfo {
108+ StmtDebugInfo :: AssignRef ( dest, place) => {
109+ let local_ref = match self . locals [ place. local ] {
110+ // For an rvalue like `&(_1.1)`, when `BackendRepr` is `BackendRepr::Memory`, we allocate a block of memory to this place.
111+ // The place is an indirect pointer, we can refer to it directly.
112+ LocalRef :: Place ( place_ref) => Some ( ( place_ref, place. projection . as_slice ( ) ) ) ,
113+ // For an rvalue like `&((*_1).1)`, we are calculating the address of `_1.1`.
114+ // The deref projection is no-op here.
115+ LocalRef :: Operand ( operand_ref) if place. is_indirect_first_projection ( ) => {
116+ Some ( ( operand_ref. deref ( bx. cx ( ) ) , & place. projection [ 1 ..] ) )
117+ }
118+ // For an rvalue like `&1`, when `BackendRepr` is `BackendRepr::Scalar`,
119+ // we cannot get the address.
120+ // N.B. `non_ssa_locals` returns that this is an SSA local.
121+ LocalRef :: Operand ( _) => None ,
122+ LocalRef :: UnsizedPlace ( _) | LocalRef :: PendingOperand => None ,
123+ }
124+ . filter ( |( _, projection) | {
125+ // Drop unsupported projections.
126+ projection. iter ( ) . all ( |p| p. can_use_in_debuginfo ( ) )
127+ } ) ;
128+ if let Some ( ( base, projection) ) = local_ref {
129+ self . debug_new_val_to_local ( bx, * dest, base, projection) ;
130+ } else {
131+ // If the address cannot be calculated, use poison to indicate that the value has been optimized out.
132+ self . debug_poison_to_local ( bx, * dest) ;
133+ }
134+ }
135+ StmtDebugInfo :: InvalidAssign ( local) => {
136+ self . debug_poison_to_local ( bx, * local) ;
137+ }
138+ }
139+ }
140+
141+ pub ( crate ) fn codegen_stmt_debuginfos (
142+ & mut self ,
143+ bx : & mut Bx ,
144+ debuginfos : & [ StmtDebugInfo < ' tcx > ] ,
145+ ) {
146+ for debuginfo in debuginfos {
147+ self . codegen_stmt_debuginfo ( bx, debuginfo) ;
148+ }
149+ }
104150}
0 commit comments