Move outer fields of enums into variant parts in debuginfo

All fields except the discriminant (including `outer_fields`)
should be put into structures inside the variant part, which gives
an equivalent layout but offers us much better integration with
debuggers.
This commit is contained in:
lrh2000 2021-04-30 16:14:42 +08:00
parent a45f0d724e
commit 060deec4b1
3 changed files with 36 additions and 15 deletions

View File

@ -309,6 +309,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
unfinished_type,
member_holding_stub,
member_descriptions,
None,
);
MetadataCreationResult::new(metadata_stub, true)
}
@ -1459,6 +1460,7 @@ struct EnumMemberDescriptionFactory<'ll, 'tcx> {
layout: TyAndLayout<'tcx>,
tag_type_metadata: Option<&'ll DIType>,
containing_scope: &'ll DIScope,
common_members: Vec<Option<&'ll DIType>>,
span: Span,
}
@ -1523,6 +1525,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
self.enum_type,
variant_type_metadata,
member_descriptions,
Some(&self.common_members),
);
vec![MemberDescription {
name: if fallback { String::new() } else { variant_info.variant_name() },
@ -1572,6 +1575,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
self.enum_type,
variant_type_metadata,
member_descriptions,
Some(&self.common_members),
);
MemberDescription {
@ -1621,6 +1625,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
self.enum_type,
variant_type_metadata,
variant_member_descriptions,
Some(&self.common_members),
);
// Encode the information about the null variant in the union
@ -1695,6 +1700,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
self.enum_type,
variant_type_metadata,
member_descriptions,
Some(&self.common_members),
);
let niche_value = if i == dataful_variant {
@ -2102,6 +2108,7 @@ fn prepare_enum_metadata(
layout,
tag_type_metadata: discriminant_type_metadata,
containing_scope,
common_members: vec![],
span,
}),
);
@ -2171,7 +2178,7 @@ fn prepare_enum_metadata(
}
};
let mut outer_fields = match layout.variants {
let outer_fields = match layout.variants {
Variants::Single { .. } => vec![],
Variants::Multiple { .. } => {
let tuple_mdf = TupleMemberDescriptionFactory {
@ -2210,11 +2217,14 @@ fn prepare_enum_metadata(
variant_part_unique_type_id_str.len(),
)
};
outer_fields.push(Some(variant_part));
let struct_wrapper = {
// The variant part must be wrapped in a struct according to DWARF.
let type_array = create_DIArray(DIB(cx), &outer_fields);
// All fields except the discriminant (including `outer_fields`)
// should be put into structures inside the variant part, which gives
// an equivalent layout but offers us much better integration with
// debuggers.
let type_array = create_DIArray(DIB(cx), &[Some(variant_part)]);
let type_map = debug_context(cx).type_map.borrow();
let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
@ -2251,6 +2261,7 @@ fn prepare_enum_metadata(
layout,
tag_type_metadata: None,
containing_scope,
common_members: outer_fields,
span,
}),
)
@ -2283,7 +2294,13 @@ fn composite_type_metadata(
DIFlags::FlagZero,
);
// ... and immediately create and add the member descriptions.
set_members_of_composite_type(cx, composite_type, composite_type_metadata, member_descriptions);
set_members_of_composite_type(
cx,
composite_type,
composite_type_metadata,
member_descriptions,
None,
);
composite_type_metadata
}
@ -2293,6 +2310,7 @@ fn set_members_of_composite_type(
composite_type: Ty<'tcx>,
composite_type_metadata: &'ll DICompositeType,
member_descriptions: Vec<MemberDescription<'ll>>,
common_members: Option<&Vec<Option<&'ll DIType>>>,
) {
// In some rare cases LLVM metadata uniquing would lead to an existing type
// description being used instead of a new one created in
@ -2311,10 +2329,13 @@ fn set_members_of_composite_type(
}
}
let member_metadata: Vec<_> = member_descriptions
let mut member_metadata: Vec<_> = member_descriptions
.into_iter()
.map(|desc| Some(desc.into_metadata(cx, composite_type_metadata)))
.collect();
if let Some(other_members) = common_members {
member_metadata.extend(other_members.iter());
}
let type_params = compute_type_parameters(cx, composite_type);
unsafe {

View File

@ -7,31 +7,31 @@
// gdb-command:run
// gdb-command:print b
// gdb-check:$1 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
// gdb-check:$1 = <error reading variable>
// gdb-command:continue
// gdb-command:print b
// gdb-check:$2 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 3, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
// gdb-check:$2 = <error reading variable>
// gdb-command:continue
// gdb-command:print b
// gdb-check:$3 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 4, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {c: 7, d: 8}}}
// gdb-check:$3 = <error reading variable>
// gdb-command:continue
// gdb-command:print b
// gdb-check:$4 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 1, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
// gdb-check:$4 = <error reading variable>
// === LLDB TESTS ==================================================================================
// lldb-command:run
// lldb-command:print b
// lldbg-check:(generator_objects::main::generator-0) $0 = { 0 = 0x[...] }
// lldbg-check:(generator_objects::main::generator-0) $0 =
// lldb-command:continue
// lldb-command:print b
// lldbg-check:(generator_objects::main::generator-0) $1 = { 0 = 0x[...] }
// lldbg-check:(generator_objects::main::generator-0) $1 =
// lldb-command:continue
// lldb-command:print b
// lldbg-check:(generator_objects::main::generator-0) $2 = { 0 = 0x[...] }
// lldbg-check:(generator_objects::main::generator-0) $2 =
// lldb-command:continue
// lldb-command:print b
// lldbg-check:(generator_objects::main::generator-0) $3 = { 0 = 0x[...] }
// lldbg-check:(generator_objects::main::generator-0) $3 =
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
#![omit_gdb_pretty_printer_section]

View File

@ -14,7 +14,7 @@
// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
// gdb-command:print b
// gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <<variant>>: {[...]}}, <<variant>>: {[...]}}
// gdb-check:$2 = <error reading variable>
// === LLDB TESTS ==================================================================================
@ -24,7 +24,7 @@
// lldbg-check:(issue_57822::main::closure-1) $0 = { 0 = { 0 = 1 } }
// lldb-command:print b
// lldbg-check:(issue_57822::main::generator-3) $1 = { 0 = { 0 = 2 } }
// lldbg-check:(issue_57822::main::generator-3) $1 =
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
#![omit_gdb_pretty_printer_section]