@@ -321,7 +321,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
321321 let tcx = self . tcx ;
322322
323323 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) ;
325325 let span = tcx. def_span ( def_id) ;
326326 let loc = self . lookup_debug_loc ( span. lo ( ) ) ;
327327 let file_metadata = file_metadata ( self , & loc. file ) ;
@@ -377,8 +377,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
377377 }
378378 }
379379
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 (
382403 DIB ( self ) ,
383404 containing_scope,
384405 name. as_ptr ( ) . cast ( ) ,
@@ -393,9 +414,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
393414 spflags,
394415 maybe_definition_llfn,
395416 template_parameters,
396- None ,
397- ) ;
398- }
417+ decl ,
418+ )
419+ } ;
399420
400421 fn get_function_signature < ' ll , ' tcx > (
401422 cx : & CodegenCx < ' ll , ' tcx > ,
@@ -494,14 +515,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
494515 names
495516 }
496517
518+ /// Returns a scope, plus `true` if that's a type scope for "class" methods,
519+ /// otherwise `false` for plain namespace scopes.
497520 fn get_containing_scope < ' ll , ' tcx > (
498521 cx : & CodegenCx < ' ll , ' tcx > ,
499522 instance : Instance < ' tcx > ,
500- ) -> & ' ll DIScope {
523+ ) -> ( & ' ll DIScope , bool ) {
501524 // First, let's see if this is a method within an inherent impl. Because
502525 // if yes, we want to make the result subroutine DIE a child of the
503526 // 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 ( ) ) {
505528 // If the method does *not* belong to a trait, proceed
506529 if cx. tcx . trait_id_of_impl ( impl_def_id) . is_none ( ) {
507530 let impl_self_ty = cx. tcx . subst_and_normalize_erasing_regions (
@@ -512,39 +535,34 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
512535
513536 // Only "class" methods are generally understood by LLVM,
514537 // 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 ) ;
525546 }
526- _ => None ,
527547 }
528548 } else {
529549 // For trait method impls we still use the "parallel namespace"
530550 // strategy
531- None
532551 }
533- } ) ;
552+ }
534553
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 )
548566 }
549567 }
550568
0 commit comments