1
- use rustc_middle:: mir:: { self , NonDivergingIntrinsic } ;
1
+ use rustc_middle:: mir:: { self , NonDivergingIntrinsic , StmtDebugInfo } ;
2
2
use rustc_middle:: span_bug;
3
3
use tracing:: instrument;
4
4
@@ -8,6 +8,7 @@ use crate::traits::*;
8
8
impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
9
9
#[ instrument( level = "debug" , skip( self , bx) ) ]
10
10
pub ( crate ) fn codegen_statement ( & mut self , bx : & mut Bx , statement : & mir:: Statement < ' tcx > ) {
11
+ self . codegen_stmt_debuginfos ( bx, & statement. debuginfos ) ;
11
12
self . set_debug_loc ( bx, statement. source_info ) ;
12
13
match statement. kind {
13
14
mir:: StatementKind :: Assign ( box ( ref place, ref rvalue) ) => {
@@ -101,4 +102,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
101
102
| mir:: StatementKind :: Nop => { }
102
103
}
103
104
}
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
+ }
104
150
}
0 commit comments