@@ -76,6 +76,53 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
76
76
}
77
77
}
78
78
79
+ struct DebugInfoOffset < T > {
80
+ /// Offset from the `base` used to calculate the debuginfo offset.
81
+ direct_offset : Size ,
82
+ /// Each offset in this vector indicates one level of indirection from the base or previous
83
+ /// indirect offset plus a dereference.
84
+ indirect_offsets : Vec < Size > ,
85
+ /// The final location debuginfo should point to.
86
+ result : T ,
87
+ }
88
+
89
+ fn calculate_debuginfo_offset < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > (
90
+ bx : & mut Bx ,
91
+ local : mir:: Local ,
92
+ var : & PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > ,
93
+ base : PlaceRef < ' tcx , Bx :: Value > ,
94
+ ) -> DebugInfoOffset < PlaceRef < ' tcx , Bx :: Value > > {
95
+ let mut direct_offset = Size :: ZERO ;
96
+ // FIXME(eddyb) use smallvec here.
97
+ let mut indirect_offsets = vec ! [ ] ;
98
+ let mut place = base;
99
+
100
+ for elem in & var. projection [ ..] {
101
+ match * elem {
102
+ mir:: ProjectionElem :: Deref => {
103
+ indirect_offsets. push ( Size :: ZERO ) ;
104
+ place = bx. load_operand ( place) . deref ( bx. cx ( ) ) ;
105
+ }
106
+ mir:: ProjectionElem :: Field ( field, _) => {
107
+ let i = field. index ( ) ;
108
+ let offset = indirect_offsets. last_mut ( ) . unwrap_or ( & mut direct_offset) ;
109
+ * offset += place. layout . fields . offset ( i) ;
110
+ place = place. project_field ( bx, i) ;
111
+ }
112
+ mir:: ProjectionElem :: Downcast ( _, variant) => {
113
+ place = place. project_downcast ( bx, variant) ;
114
+ }
115
+ _ => span_bug ! (
116
+ var. source_info. span,
117
+ "unsupported var debuginfo place `{:?}`" ,
118
+ mir:: Place { local, projection: var. projection } ,
119
+ ) ,
120
+ }
121
+ }
122
+
123
+ DebugInfoOffset { direct_offset, indirect_offsets, result : place }
124
+ }
125
+
79
126
impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
80
127
pub fn set_debug_loc ( & self , bx : & mut Bx , source_info : mir:: SourceInfo ) {
81
128
bx. set_span ( source_info. span ) ;
@@ -262,33 +309,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
262
309
let Some ( dbg_var) = var. dbg_var else { continue } ;
263
310
let Some ( dbg_loc) = self . dbg_loc ( var. source_info ) else { continue } ;
264
311
265
- let mut direct_offset = Size :: ZERO ;
266
- // FIXME(eddyb) use smallvec here.
267
- let mut indirect_offsets = vec ! [ ] ;
268
- let mut place = base;
269
-
270
- for elem in & var. projection [ ..] {
271
- match * elem {
272
- mir:: ProjectionElem :: Deref => {
273
- indirect_offsets. push ( Size :: ZERO ) ;
274
- place = bx. load_operand ( place) . deref ( bx. cx ( ) ) ;
275
- }
276
- mir:: ProjectionElem :: Field ( field, _) => {
277
- let i = field. index ( ) ;
278
- let offset = indirect_offsets. last_mut ( ) . unwrap_or ( & mut direct_offset) ;
279
- * offset += place. layout . fields . offset ( i) ;
280
- place = place. project_field ( bx, i) ;
281
- }
282
- mir:: ProjectionElem :: Downcast ( _, variant) => {
283
- place = place. project_downcast ( bx, variant) ;
284
- }
285
- _ => span_bug ! (
286
- var. source_info. span,
287
- "unsupported var debuginfo place `{:?}`" ,
288
- mir:: Place { local, projection: var. projection } ,
289
- ) ,
290
- }
291
- }
312
+ let DebugInfoOffset { direct_offset, indirect_offsets, result : place } =
313
+ calculate_debuginfo_offset ( bx, local, & var, base) ;
292
314
293
315
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
294
316
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
0 commit comments