Skip to content

Commit e48d7d2

Browse files
committed
Emit namespace debuginfo
1 parent c76c269 commit e48d7d2

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub(crate) fn codegen_fn<'tcx>(
7070
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
7171

7272
let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
73-
Some(debug_context.define_function(tcx, &symbol_name, mir.span))
73+
Some(debug_context.define_function(tcx, instance, &symbol_name, mir.span))
7474
} else {
7575
None
7676
};

src/debuginfo/mod.rs

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use gimli::write::{
1313
};
1414
use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64};
1515
use indexmap::IndexSet;
16+
use rustc_codegen_ssa::debuginfo::type_names;
17+
use rustc_hir::def_id::DefIdMap;
1618
use rustc_session::Session;
1719

1820
pub(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

Comments
 (0)