@@ -41,6 +41,9 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
4141
4242 /// `.place.projection` from `mir::VarDebugInfo`.
4343 pub projection : & ' tcx ty:: List < mir:: PlaceElem < ' tcx > > ,
44+
45+ /// `references` from `mir::VarDebugInfo`.
46+ pub references : u8 ,
4447}
4548
4649#[ derive( Clone , Copy , Debug ) ]
@@ -293,6 +296,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
293296 dbg_var,
294297 fragment : None ,
295298 projection : ty:: List :: empty ( ) ,
299+ references : 0 ,
296300 } )
297301 }
298302 } else {
@@ -366,14 +370,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
366370 & self ,
367371 bx : & mut Bx ,
368372 local : mir:: Local ,
369- base : PlaceRef < ' tcx , Bx :: Value > ,
373+ mut base : PlaceRef < ' tcx , Bx :: Value > ,
370374 var : PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > ,
371375 ) {
372376 let Some ( dbg_var) = var. dbg_var else { return } ;
373377 let Some ( dbg_loc) = self . dbg_loc ( var. source_info ) else { return } ;
374378
375- let DebugInfoOffset { direct_offset, indirect_offsets, result : _ } =
379+ let DebugInfoOffset { mut direct_offset, indirect_offsets, result : _ } =
376380 calculate_debuginfo_offset ( bx, local, & var, base. layout ) ;
381+ let mut indirect_offsets = & indirect_offsets[ ..] ;
377382
378383 // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
379384 // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
@@ -387,28 +392,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
387392 // LLVM can handle simple things but anything more complex than just a direct
388393 // offset or one indirect offset of 0 is too complex for it to generate CV records
389394 // correctly.
390- && ( direct_offset != Size :: ZERO || !matches ! ( & indirect_offsets[ ..] , [ Size :: ZERO ] | [ ] ) ) ;
391-
392- if should_create_individual_allocas {
393- let DebugInfoOffset { direct_offset : _, indirect_offsets : _, result : place } =
394- calculate_debuginfo_offset ( bx, local, & var, base) ;
395+ && ( direct_offset != Size :: ZERO || !matches ! ( indirect_offsets, [ Size :: ZERO ] | [ ] ) ) ;
395396
397+ let create_alloca = |bx : & mut Bx , place : PlaceRef < ' tcx , Bx :: Value > , refcount| {
396398 // Create a variable which will be a pointer to the actual value
397399 let ptr_ty = bx
398400 . tcx ( )
399401 . mk_ptr ( ty:: TypeAndMut { mutbl : mir:: Mutability :: Mut , ty : place. layout . ty } ) ;
400402 let ptr_layout = bx. layout_of ( ptr_ty) ;
401403 let alloca = PlaceRef :: alloca ( bx, ptr_layout) ;
402- bx. set_var_name ( alloca. llval , & ( var . name . to_string ( ) + ". dbg.spill") ) ;
404+ bx. set_var_name ( alloca. llval , & format ! ( "{}.ref{}. dbg.spill", var . name , refcount ) ) ;
403405
404406 // Write the pointer to the variable
405407 bx. store ( place. llval , alloca. llval , alloca. align ) ;
406408
407409 // Point the debug info to `*alloca` for the current variable
408- bx. dbg_var_addr ( dbg_var, dbg_loc, alloca. llval , Size :: ZERO , & [ Size :: ZERO ] , None ) ;
409- } else {
410- bx. dbg_var_addr ( dbg_var, dbg_loc, base. llval , direct_offset, & indirect_offsets, None ) ;
410+ alloca
411+ } ;
412+
413+ if var. references > 0 {
414+ base = calculate_debuginfo_offset ( bx, local, & var, base) . result ;
415+
416+ // Point the debug info to `&...&base == alloca` for the current variable
417+ for refcount in 0 ..var. references {
418+ base = create_alloca ( bx, base, refcount) ;
419+ }
420+
421+ direct_offset = Size :: ZERO ;
422+ indirect_offsets = & [ ] ;
423+ } else if should_create_individual_allocas {
424+ let place = calculate_debuginfo_offset ( bx, local, & var, base) . result ;
425+
426+ // Point the debug info to `*alloca` for the current variable
427+ base = create_alloca ( bx, place, 0 ) ;
428+ direct_offset = Size :: ZERO ;
429+ indirect_offsets = & [ Size :: ZERO ] ;
411430 }
431+
432+ bx. dbg_var_addr ( dbg_var, dbg_loc, base. llval , direct_offset, indirect_offsets, None ) ;
412433 }
413434
414435 pub fn debug_introduce_locals ( & self , bx : & mut Bx ) {
@@ -441,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
441462 } ;
442463
443464 let dbg_var = dbg_scope_and_span. map ( |( dbg_scope, _, span) | {
444- let ( var_ty, var_kind) = match var. value {
465+ let ( mut var_ty, var_kind) = match var. value {
445466 mir:: VarDebugInfoContents :: Place ( place) => {
446467 let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
447468 let var_kind = if let Some ( arg_index) = var. argument_index
@@ -478,6 +499,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
478499 }
479500 } ;
480501
502+ for _ in 0 ..var. references {
503+ var_ty =
504+ bx. tcx ( ) . mk_ptr ( ty:: TypeAndMut { mutbl : mir:: Mutability :: Mut , ty : var_ty } ) ;
505+ }
506+
481507 self . cx . create_dbg_var ( var. name , var_ty, dbg_scope, var_kind, span)
482508 } ) ;
483509
@@ -489,6 +515,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
489515 dbg_var,
490516 fragment : None ,
491517 projection : place. projection ,
518+ references : var. references ,
492519 } ) ;
493520 }
494521 mir:: VarDebugInfoContents :: Const ( c) => {
@@ -542,6 +569,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
542569 Some ( fragment_start..fragment_start + fragment_layout. size )
543570 } ,
544571 projection : place. projection ,
572+ references : var. references ,
545573 } ) ;
546574 }
547575 }
0 commit comments