1
Fork 0

debuginfo: Set bitwidth appropriately in enum variant tags

Previously, we unconditionally set the bitwidth to 128-bits, the largest
an discrimnator would possibly be. Then, LLVM would cut down the constant by
chopping off leading zeroes before emitting the DWARF. LLVM only
supported 64-bit descriminators, so this would also have occasionally
resulted in truncated data (or an assert) if more than 64-bits were
used.

LLVM added support for 128-bit enumerators in llvm/llvm-project#125578

That patchset also trusts the constant to describe how wide the variant tag is.
As a result, we went from emitting tags that looked like:
DW_AT_discr_value     (0xfe)

(`form1`)

to emitting tags that looked like:
DW_AT_discr_value	(<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 )

This makes the `DW_AT_discr_value` encode at the bitwidth of the tag,
which:
1. Is probably closer to our intentions in terms of describing the data.
2. Doesn't invoke the 128-bit support which may not be supported by all
   debuggers / downstream tools.
3. Will result in smaller debug information.
This commit is contained in:
Matthew Maurer 2025-02-12 00:37:33 +00:00
parent 8c61cd4df8
commit d82219a4fa
2 changed files with 9 additions and 3 deletions

View file

@ -437,6 +437,12 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
.source_info
.unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER));
let discr = discr_value.opt_single_val().map(|value| {
let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout);
let size = cx.size_of(tag_base_type);
cx.const_uint_big(cx.type_ix(size.bits()), value)
});
unsafe {
llvm::LLVMRustDIBuilderCreateVariantMemberType(
DIB(cx),
@ -448,7 +454,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
enum_type_and_layout.size.bits(),
enum_type_and_layout.align.abi.bits() as u32,
Size::ZERO.bits(),
discr_value.opt_single_val().map(|value| cx.const_u128(value)),
discr,
DIFlags::FlagZero,
variant_member_info.variant_struct_type_di_node,
)