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:
parent
a45f0d724e
commit
060deec4b1
3 changed files with 36 additions and 15 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue