@@ -321,7 +321,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
321
321
let tcx = self . tcx ;
322
322
323
323
let def_id = instance. def_id ( ) ;
324
- let containing_scope = get_containing_scope ( self , instance) ;
324
+ let ( containing_scope, is_method ) = get_containing_scope ( self , instance) ;
325
325
let span = tcx. def_span ( def_id) ;
326
326
let loc = self . lookup_debug_loc ( span. lo ( ) ) ;
327
327
let file_metadata = file_metadata ( self , & loc. file ) ;
@@ -377,8 +377,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
377
377
}
378
378
}
379
379
380
- unsafe {
381
- return llvm:: LLVMRustDIBuilderCreateFunction (
380
+ // When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because
381
+ // LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
382
+ // When we use this `decl` below, the subprogram definition gets created at the CU level
383
+ // with a DW_AT_specification pointing back to the type's declaration.
384
+ let decl = is_method. then ( || unsafe {
385
+ llvm:: LLVMRustDIBuilderCreateMethod (
386
+ DIB ( self ) ,
387
+ containing_scope,
388
+ name. as_ptr ( ) . cast ( ) ,
389
+ name. len ( ) ,
390
+ linkage_name. as_ptr ( ) . cast ( ) ,
391
+ linkage_name. len ( ) ,
392
+ file_metadata,
393
+ loc. line ,
394
+ function_type_metadata,
395
+ flags,
396
+ spflags & !DISPFlags :: SPFlagDefinition ,
397
+ template_parameters,
398
+ )
399
+ } ) ;
400
+
401
+ return unsafe {
402
+ llvm:: LLVMRustDIBuilderCreateFunction (
382
403
DIB ( self ) ,
383
404
containing_scope,
384
405
name. as_ptr ( ) . cast ( ) ,
@@ -393,9 +414,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
393
414
spflags,
394
415
maybe_definition_llfn,
395
416
template_parameters,
396
- None ,
397
- ) ;
398
- }
417
+ decl ,
418
+ )
419
+ } ;
399
420
400
421
fn get_function_signature < ' ll , ' tcx > (
401
422
cx : & CodegenCx < ' ll , ' tcx > ,
@@ -494,14 +515,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
494
515
names
495
516
}
496
517
518
+ /// Returns a scope, plus `true` if that's a type scope for "class" methods,
519
+ /// otherwise `false` for plain namespace scopes.
497
520
fn get_containing_scope < ' ll , ' tcx > (
498
521
cx : & CodegenCx < ' ll , ' tcx > ,
499
522
instance : Instance < ' tcx > ,
500
- ) -> & ' ll DIScope {
523
+ ) -> ( & ' ll DIScope , bool ) {
501
524
// First, let's see if this is a method within an inherent impl. Because
502
525
// if yes, we want to make the result subroutine DIE a child of the
503
526
// subroutine's self-type.
504
- let self_type = cx. tcx . impl_of_method ( instance. def_id ( ) ) . and_then ( |impl_def_id| {
527
+ if let Some ( impl_def_id ) = cx. tcx . impl_of_method ( instance. def_id ( ) ) {
505
528
// If the method does *not* belong to a trait, proceed
506
529
if cx. tcx . trait_id_of_impl ( impl_def_id) . is_none ( ) {
507
530
let impl_self_ty = cx. tcx . subst_and_normalize_erasing_regions (
@@ -512,39 +535,34 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
512
535
513
536
// Only "class" methods are generally understood by LLVM,
514
537
// so avoid methods on other types (e.g., `<*mut T>::null`).
515
- match impl_self_ty. kind ( ) {
516
- ty:: Adt ( def, ..) if !def. is_box ( ) => {
517
- // Again, only create type information if full debuginfo is enabled
518
- if cx. sess ( ) . opts . debuginfo == DebugInfo :: Full
519
- && !impl_self_ty. needs_subst ( )
520
- {
521
- Some ( type_di_node ( cx, impl_self_ty) )
522
- } else {
523
- Some ( namespace:: item_namespace ( cx, def. did ( ) ) )
524
- }
538
+ if let ty:: Adt ( def, ..) = impl_self_ty. kind ( ) && !def. is_box ( ) {
539
+ // Again, only create type information if full debuginfo is enabled
540
+ if cx. sess ( ) . opts . debuginfo == DebugInfo :: Full
541
+ && !impl_self_ty. needs_subst ( )
542
+ {
543
+ return ( type_di_node ( cx, impl_self_ty) , true ) ;
544
+ } else {
545
+ return ( namespace:: item_namespace ( cx, def. did ( ) ) , false ) ;
525
546
}
526
- _ => None ,
527
547
}
528
548
} else {
529
549
// For trait method impls we still use the "parallel namespace"
530
550
// strategy
531
- None
532
551
}
533
- } ) ;
552
+ }
534
553
535
- self_type. unwrap_or_else ( || {
536
- namespace:: item_namespace (
537
- cx,
538
- DefId {
539
- krate : instance. def_id ( ) . krate ,
540
- index : cx
541
- . tcx
542
- . def_key ( instance. def_id ( ) )
543
- . parent
544
- . expect ( "get_containing_scope: missing parent?" ) ,
545
- } ,
546
- )
547
- } )
554
+ let scope = namespace:: item_namespace (
555
+ cx,
556
+ DefId {
557
+ krate : instance. def_id ( ) . krate ,
558
+ index : cx
559
+ . tcx
560
+ . def_key ( instance. def_id ( ) )
561
+ . parent
562
+ . expect ( "get_containing_scope: missing parent?" ) ,
563
+ } ,
564
+ ) ;
565
+ ( scope, false )
548
566
}
549
567
}
550
568
0 commit comments