@@ -76,6 +76,53 @@ impl<'tcx, S: Copy, L: Copy> DebugScope<S, L> {
7676 }
7777}
7878
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+
79126impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
80127 pub fn set_debug_loc ( & self , bx : & mut Bx , source_info : mir:: SourceInfo ) {
81128 bx. set_span ( source_info. span ) ;
@@ -262,33 +309,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
262309 let Some ( dbg_var) = var. dbg_var else { continue } ;
263310 let Some ( dbg_loc) = self . dbg_loc ( var. source_info ) else { continue } ;
264311
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) ;
292314
293315 // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
294316 // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
0 commit comments