@@ -13,6 +13,8 @@ use gimli::write::{
13
13
} ;
14
14
use gimli:: { AArch64 , Encoding , Format , LineEncoding , Register , RiscV , RunTimeEndian , X86_64 } ;
15
15
use indexmap:: IndexSet ;
16
+ use rustc_codegen_ssa:: debuginfo:: type_names;
17
+ use rustc_hir:: def_id:: DefIdMap ;
16
18
use rustc_session:: Session ;
17
19
18
20
pub ( crate ) use self :: emit:: { DebugReloc , DebugRelocName } ;
@@ -29,6 +31,7 @@ pub(crate) struct DebugContext {
29
31
dwarf : DwarfUnit ,
30
32
unit_range_list : RangeList ,
31
33
stack_pointer_register : Register ,
34
+ namespace_map : DefIdMap < UnitEntryId > ,
32
35
33
36
should_remap_filepaths : bool ,
34
37
}
@@ -122,25 +125,74 @@ impl DebugContext {
122
125
dwarf,
123
126
unit_range_list : RangeList ( Vec :: new ( ) ) ,
124
127
stack_pointer_register,
128
+ namespace_map : DefIdMap :: default ( ) ,
125
129
should_remap_filepaths,
126
130
}
127
131
}
128
132
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 > (
130
160
& mut self ,
131
- tcx : TyCtxt < ' _ > ,
132
- name : & str ,
161
+ tcx : TyCtxt < ' tcx > ,
162
+ instance : Instance < ' tcx > ,
163
+ linkage_name : & str ,
133
164
function_span : Span ,
134
165
) -> FunctionDebugContext {
135
166
let ( file, line, column) = DebugContext :: get_span_loc ( tcx, function_span, function_span) ;
136
167
137
168
let file_id = self . add_source_file ( & file) ;
138
169
139
170
// 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
+ ) ;
141
191
142
192
let entry_id = self . dwarf . unit . add ( scope, gimli:: DW_TAG_subprogram ) ;
143
193
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 } ;
144
196
let name_id = self . dwarf . strings . add ( name) ;
145
197
146
198
// These will be replaced in FunctionDebugContext::finalize. They are
@@ -153,6 +205,9 @@ impl DebugContext {
153
205
frame_base_expr. op_reg ( self . stack_pointer_register ) ;
154
206
entry. set ( gimli:: DW_AT_frame_base , AttributeValue :: Exprloc ( frame_base_expr) ) ;
155
207
208
+ if let Some ( linkage_name_id) = linkage_name_id {
209
+ entry. set ( gimli:: DW_AT_linkage_name , AttributeValue :: StringRef ( linkage_name_id) ) ;
210
+ }
156
211
// Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
157
212
// FIXME only include the function name and not the full mangled symbol
158
213
entry. set ( gimli:: DW_AT_name , AttributeValue :: StringRef ( name_id) ) ;
0 commit comments