@@ -41,6 +41,9 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
41
41
42
42
/// `.place.projection` from `mir::VarDebugInfo`.
43
43
pub projection : & ' tcx ty:: List < mir:: PlaceElem < ' tcx > > ,
44
+
45
+ /// `references` from `mir::VarDebugInfo`.
46
+ pub references : u8 ,
44
47
}
45
48
46
49
#[ derive( Clone , Copy , Debug ) ]
@@ -293,6 +296,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
293
296
dbg_var,
294
297
fragment : None ,
295
298
projection : ty:: List :: empty ( ) ,
299
+ references : 0 ,
296
300
} )
297
301
}
298
302
} else {
@@ -366,14 +370,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
366
370
& self ,
367
371
bx : & mut Bx ,
368
372
local : mir:: Local ,
369
- base : PlaceRef < ' tcx , Bx :: Value > ,
373
+ mut base : PlaceRef < ' tcx , Bx :: Value > ,
370
374
var : PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > ,
371
375
) {
372
376
let Some ( dbg_var) = var. dbg_var else { return } ;
373
377
let Some ( dbg_loc) = self . dbg_loc ( var. source_info ) else { return } ;
374
378
375
- let DebugInfoOffset { direct_offset, indirect_offsets, result : _ } =
379
+ let DebugInfoOffset { mut direct_offset, indirect_offsets, result : _ } =
376
380
calculate_debuginfo_offset ( bx, local, & var, base. layout ) ;
381
+ let mut indirect_offsets = & indirect_offsets[ ..] ;
377
382
378
383
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
379
384
// 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> {
387
392
// LLVM can handle simple things but anything more complex than just a direct
388
393
// offset or one indirect offset of 0 is too complex for it to generate CV records
389
394
// 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 ] | [ ] ) ) ;
395
396
397
+ let create_alloca = |bx : & mut Bx , place : PlaceRef < ' tcx , Bx :: Value > , refcount| {
396
398
// Create a variable which will be a pointer to the actual value
397
399
let ptr_ty = bx
398
400
. tcx ( )
399
401
. mk_ptr ( ty:: TypeAndMut { mutbl : mir:: Mutability :: Mut , ty : place. layout . ty } ) ;
400
402
let ptr_layout = bx. layout_of ( ptr_ty) ;
401
403
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 ) ) ;
403
405
404
406
// Write the pointer to the variable
405
407
bx. store ( place. llval , alloca. llval , alloca. align ) ;
406
408
407
409
// 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 ] ;
411
430
}
431
+
432
+ bx. dbg_var_addr ( dbg_var, dbg_loc, base. llval , direct_offset, indirect_offsets, None ) ;
412
433
}
413
434
414
435
pub fn debug_introduce_locals ( & self , bx : & mut Bx ) {
@@ -441,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
441
462
} ;
442
463
443
464
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 {
445
466
mir:: VarDebugInfoContents :: Place ( place) => {
446
467
let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
447
468
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> {
478
499
}
479
500
} ;
480
501
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
+
481
507
self . cx . create_dbg_var ( var. name , var_ty, dbg_scope, var_kind, span)
482
508
} ) ;
483
509
@@ -489,6 +515,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
489
515
dbg_var,
490
516
fragment : None ,
491
517
projection : place. projection ,
518
+ references : var. references ,
492
519
} ) ;
493
520
}
494
521
mir:: VarDebugInfoContents :: Const ( c) => {
@@ -542,6 +569,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
542
569
Some ( fragment_start..fragment_start + fragment_layout. size )
543
570
} ,
544
571
projection : place. projection ,
572
+ references : var. references ,
545
573
} ) ;
546
574
}
547
575
}
0 commit comments