@@ -13,6 +13,8 @@ use gimli::write::{
1313} ;
1414use gimli:: { AArch64 , Encoding , Format , LineEncoding , Register , RiscV , RunTimeEndian , X86_64 } ;
1515use indexmap:: IndexSet ;
16+ use rustc_codegen_ssa:: debuginfo:: type_names;
17+ use rustc_hir:: def_id:: DefIdMap ;
1618use rustc_session:: Session ;
1719
1820pub ( crate ) use self :: emit:: { DebugReloc , DebugRelocName } ;
@@ -29,6 +31,7 @@ pub(crate) struct DebugContext {
2931 dwarf : DwarfUnit ,
3032 unit_range_list : RangeList ,
3133 stack_pointer_register : Register ,
34+ namespace_map : DefIdMap < UnitEntryId > ,
3235
3336 should_remap_filepaths : bool ,
3437}
@@ -122,25 +125,74 @@ impl DebugContext {
122125 dwarf,
123126 unit_range_list : RangeList ( Vec :: new ( ) ) ,
124127 stack_pointer_register,
128+ namespace_map : DefIdMap :: default ( ) ,
125129 should_remap_filepaths,
126130 }
127131 }
128132
129- pub ( crate ) fn define_function (
133+ fn item_namespace ( & mut self , tcx : TyCtxt < ' _ > , def_id : DefId ) -> UnitEntryId {
134+ if let Some ( & scope) = self . namespace_map . get ( & def_id) {
135+ return scope;
136+ }
137+
138+ let def_key = tcx. def_key ( def_id) ;
139+ let parent_scope = def_key
140+ . parent
141+ . map ( |parent| self . item_namespace ( tcx, DefId { krate : def_id. krate , index : parent } ) )
142+ . unwrap_or ( self . dwarf . unit . root ( ) ) ;
143+
144+ let namespace_name = {
145+ let mut output = String :: new ( ) ;
146+ type_names:: push_item_name ( tcx, def_id, false , & mut output) ;
147+ output
148+ } ;
149+ let namespace_name_id = self . dwarf . strings . add ( namespace_name) ;
150+
151+ let scope = self . dwarf . unit . add ( parent_scope, gimli:: DW_TAG_namespace ) ;
152+ let scope_entry = self . dwarf . unit . get_mut ( scope) ;
153+ scope_entry. set ( gimli:: DW_AT_name , AttributeValue :: StringRef ( namespace_name_id) ) ;
154+
155+ self . namespace_map . insert ( def_id, scope) ;
156+ scope
157+ }
158+
159+ pub ( crate ) fn define_function < ' tcx > (
130160 & mut self ,
131- tcx : TyCtxt < ' _ > ,
132- name : & str ,
161+ tcx : TyCtxt < ' tcx > ,
162+ instance : Instance < ' tcx > ,
163+ linkage_name : & str ,
133164 function_span : Span ,
134165 ) -> FunctionDebugContext {
135166 let ( file, line, column) = DebugContext :: get_span_loc ( tcx, function_span, function_span) ;
136167
137168 let file_id = self . add_source_file ( & file) ;
138169
139170 // FIXME: add to appropriate scope instead of root
140- let scope = self . dwarf . unit . root ( ) ;
171+ let scope = self . item_namespace ( tcx, tcx. parent ( instance. def_id ( ) ) ) ;
172+
173+ let mut name = String :: new ( ) ;
174+ type_names:: push_item_name ( tcx, instance. def_id ( ) , false , & mut name) ;
175+
176+ // Find the enclosing function, in case this is a closure.
177+ let enclosing_fn_def_id = tcx. typeck_root_def_id ( instance. def_id ( ) ) ;
178+
179+ // We look up the generics of the enclosing function and truncate the args
180+ // to their length in order to cut off extra stuff that might be in there for
181+ // closures or coroutines.
182+ let generics = tcx. generics_of ( enclosing_fn_def_id) ;
183+ let args = instance. args . truncate_to ( tcx, generics) ;
184+
185+ type_names:: push_generic_params (
186+ tcx,
187+ tcx. normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , args) ,
188+ enclosing_fn_def_id,
189+ & mut name,
190+ ) ;
141191
142192 let entry_id = self . dwarf . unit . add ( scope, gimli:: DW_TAG_subprogram ) ;
143193 let entry = self . dwarf . unit . get_mut ( entry_id) ;
194+ let linkage_name_id =
195+ if name != linkage_name { Some ( self . dwarf . strings . add ( linkage_name) ) } else { None } ;
144196 let name_id = self . dwarf . strings . add ( name) ;
145197
146198 // These will be replaced in FunctionDebugContext::finalize. They are
@@ -153,6 +205,9 @@ impl DebugContext {
153205 frame_base_expr. op_reg ( self . stack_pointer_register ) ;
154206 entry. set ( gimli:: DW_AT_frame_base , AttributeValue :: Exprloc ( frame_base_expr) ) ;
155207
208+ if let Some ( linkage_name_id) = linkage_name_id {
209+ entry. set ( gimli:: DW_AT_linkage_name , AttributeValue :: StringRef ( linkage_name_id) ) ;
210+ }
156211 // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
157212 // FIXME only include the function name and not the full mangled symbol
158213 entry. set ( gimli:: DW_AT_name , AttributeValue :: StringRef ( name_id) ) ;
0 commit comments