diff options
| author | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2024-03-27 12:43:47 +0000 |
|---|---|---|
| committer | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2024-03-27 12:43:47 +0000 |
| commit | e48d7d242fcf378d66d27dddea546029239bd5c6 (patch) | |
| tree | eceb9490802c307dc8aebdaebb8907559d85b407 | |
| parent | c76c269aa466b786d4ca3a78dae9cb84912406ed (diff) | |
| download | rust-e48d7d242fcf378d66d27dddea546029239bd5c6.tar.gz rust-e48d7d242fcf378d66d27dddea546029239bd5c6.zip | |
Emit namespace debuginfo
| -rw-r--r-- | src/base.rs | 2 | ||||
| -rw-r--r-- | src/debuginfo/mod.rs | 63 |
2 files changed, 60 insertions, 5 deletions
diff --git a/src/base.rs b/src/base.rs index dbce6d165d2..4e60f820594 100644 --- a/src/base.rs +++ b/src/base.rs @@ -70,7 +70,7 @@ pub(crate) fn codegen_fn<'tcx>( let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance); let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { - Some(debug_context.define_function(tcx, &symbol_name, mir.span)) + Some(debug_context.define_function(tcx, instance, &symbol_name, mir.span)) } else { None }; diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 44ee2b822a9..2b5f472c5fc 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -13,6 +13,8 @@ use gimli::write::{ }; use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_hir::def_id::DefIdMap; use rustc_session::Session; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; @@ -29,6 +31,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, stack_pointer_register: Register, + namespace_map: DefIdMap<UnitEntryId>, should_remap_filepaths: bool, } @@ -122,14 +125,42 @@ impl DebugContext { dwarf, unit_range_list: RangeList(Vec::new()), stack_pointer_register, + namespace_map: DefIdMap::default(), should_remap_filepaths, } } - pub(crate) fn define_function( + fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId { + if let Some(&scope) = self.namespace_map.get(&def_id) { + return scope; + } + + let def_key = tcx.def_key(def_id); + let parent_scope = def_key + .parent + .map(|parent| self.item_namespace(tcx, DefId { krate: def_id.krate, index: parent })) + .unwrap_or(self.dwarf.unit.root()); + + let namespace_name = { + let mut output = String::new(); + type_names::push_item_name(tcx, def_id, false, &mut output); + output + }; + let namespace_name_id = self.dwarf.strings.add(namespace_name); + + let scope = self.dwarf.unit.add(parent_scope, gimli::DW_TAG_namespace); + let scope_entry = self.dwarf.unit.get_mut(scope); + scope_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(namespace_name_id)); + + self.namespace_map.insert(def_id, scope); + scope + } + + pub(crate) fn define_function<'tcx>( &mut self, - tcx: TyCtxt<'_>, - name: &str, + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span); @@ -137,10 +168,31 @@ impl DebugContext { let file_id = self.add_source_file(&file); // FIXME: add to appropriate scope instead of root - let scope = self.dwarf.unit.root(); + let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); + + let mut name = String::new(); + type_names::push_item_name(tcx, instance.def_id(), false, &mut name); + + // Find the enclosing function, in case this is a closure. + let enclosing_fn_def_id = tcx.typeck_root_def_id(instance.def_id()); + + // We look up the generics of the enclosing function and truncate the args + // to their length in order to cut off extra stuff that might be in there for + // closures or coroutines. + let generics = tcx.generics_of(enclosing_fn_def_id); + let args = instance.args.truncate_to(tcx, generics); + + type_names::push_generic_params( + tcx, + tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), + enclosing_fn_def_id, + &mut name, + ); let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram); let entry = self.dwarf.unit.get_mut(entry_id); + let linkage_name_id = + if name != linkage_name { Some(self.dwarf.strings.add(linkage_name)) } else { None }; let name_id = self.dwarf.strings.add(name); // These will be replaced in FunctionDebugContext::finalize. They are @@ -153,6 +205,9 @@ impl DebugContext { frame_base_expr.op_reg(self.stack_pointer_register); entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + if let Some(linkage_name_id) = linkage_name_id { + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); + } // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. // FIXME only include the function name and not the full mangled symbol entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); |
