@@ -322,7 +322,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
322322 let tcx = self . tcx ;
323323
324324 let def_id = instance. def_id ( ) ;
325- let containing_scope = get_containing_scope ( self , instance) ;
325+ let ( containing_scope, is_method ) = get_containing_scope ( self , instance) ;
326326 let span = tcx. def_span ( def_id) ;
327327 let loc = self . lookup_debug_loc ( span. lo ( ) ) ;
328328 let file_metadata = file_metadata ( self , & loc. file ) ;
@@ -378,8 +378,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
378378 }
379379 }
380380
381- unsafe {
382- return llvm:: LLVMRustDIBuilderCreateFunction (
381+ // When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because
382+ // LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
383+ // When we use this `decl` below, the subprogram definition gets created at the CU level
384+ // with a DW_AT_specification pointing back to the type's declaration.
385+ let decl = is_method. then ( || unsafe {
386+ llvm:: LLVMRustDIBuilderCreateMethod (
387+ DIB ( self ) ,
388+ containing_scope,
389+ name. as_ptr ( ) . cast ( ) ,
390+ name. len ( ) ,
391+ linkage_name. as_ptr ( ) . cast ( ) ,
392+ linkage_name. len ( ) ,
393+ file_metadata,
394+ loc. line ,
395+ function_type_metadata,
396+ flags,
397+ spflags & !DISPFlags :: SPFlagDefinition ,
398+ template_parameters,
399+ )
400+ } ) ;
401+
402+ return unsafe {
403+ llvm:: LLVMRustDIBuilderCreateFunction (
383404 DIB ( self ) ,
384405 containing_scope,
385406 name. as_ptr ( ) . cast ( ) ,
@@ -394,9 +415,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
394415 spflags,
395416 maybe_definition_llfn,
396417 template_parameters,
397- None ,
398- ) ;
399- }
418+ decl ,
419+ )
420+ } ;
400421
401422 fn get_function_signature < ' ll , ' tcx > (
402423 cx : & CodegenCx < ' ll , ' tcx > ,
@@ -493,14 +514,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
493514 names
494515 }
495516
517+ /// Returns a scope, plus `true` if that's a type scope for "class" methods,
518+ /// otherwise `false` for plain namespace scopes.
496519 fn get_containing_scope < ' ll , ' tcx > (
497520 cx : & CodegenCx < ' ll , ' tcx > ,
498521 instance : Instance < ' tcx > ,
499- ) -> & ' ll DIScope {
522+ ) -> ( & ' ll DIScope , bool ) {
500523 // First, let's see if this is a method within an inherent impl. Because
501524 // if yes, we want to make the result subroutine DIE a child of the
502525 // subroutine's self-type.
503- let self_type = cx. tcx . impl_of_method ( instance. def_id ( ) ) . and_then ( |impl_def_id| {
526+ if let Some ( impl_def_id ) = cx. tcx . impl_of_method ( instance. def_id ( ) ) {
504527 // If the method does *not* belong to a trait, proceed
505528 if cx. tcx . trait_id_of_impl ( impl_def_id) . is_none ( ) {
506529 let impl_self_ty = cx. tcx . subst_and_normalize_erasing_regions (
@@ -511,39 +534,33 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
511534
512535 // Only "class" methods are generally understood by LLVM,
513536 // so avoid methods on other types (e.g., `<*mut T>::null`).
514- match impl_self_ty. kind ( ) {
515- ty:: Adt ( def, ..) if !def. is_box ( ) => {
516- // Again, only create type information if full debuginfo is enabled
517- if cx. sess ( ) . opts . debuginfo == DebugInfo :: Full
518- && !impl_self_ty. has_param ( )
519- {
520- Some ( type_di_node ( cx, impl_self_ty) )
521- } else {
522- Some ( namespace:: item_namespace ( cx, def. did ( ) ) )
523- }
537+ if let ty:: Adt ( def, ..) = impl_self_ty. kind ( ) && !def. is_box ( ) {
538+ // Again, only create type information if full debuginfo is enabled
539+ if cx. sess ( ) . opts . debuginfo == DebugInfo :: Full && !impl_self_ty. has_param ( )
540+ {
541+ return ( type_di_node ( cx, impl_self_ty) , true ) ;
542+ } else {
543+ return ( namespace:: item_namespace ( cx, def. did ( ) ) , false ) ;
524544 }
525- _ => None ,
526545 }
527546 } else {
528547 // For trait method impls we still use the "parallel namespace"
529548 // strategy
530- None
531549 }
532- } ) ;
550+ }
533551
534- self_type. unwrap_or_else ( || {
535- namespace:: item_namespace (
536- cx,
537- DefId {
538- krate : instance. def_id ( ) . krate ,
539- index : cx
540- . tcx
541- . def_key ( instance. def_id ( ) )
542- . parent
543- . expect ( "get_containing_scope: missing parent?" ) ,
544- } ,
545- )
546- } )
552+ let scope = namespace:: item_namespace (
553+ cx,
554+ DefId {
555+ krate : instance. def_id ( ) . krate ,
556+ index : cx
557+ . tcx
558+ . def_key ( instance. def_id ( ) )
559+ . parent
560+ . expect ( "get_containing_scope: missing parent?" ) ,
561+ } ,
562+ ) ;
563+ ( scope, false )
547564 }
548565 }
549566
0 commit comments