diff options
| author | Michael Woerister <michaelwoerister@posteo> | 2022-07-08 17:09:32 +0200 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo> | 2022-08-12 10:53:08 +0200 |
| commit | 8433e2a66fad920e1312c02dc4395ceed98a2705 (patch) | |
| tree | fb4464b442675098c90b5196faef3b965ab941a0 /compiler/rustc_codegen_llvm/src/debuginfo | |
| parent | dfb2c89e5e409f7979131dd73ea7ec3518f2b5d9 (diff) | |
| download | rust-8433e2a66fad920e1312c02dc4395ceed98a2705.tar.gz rust-8433e2a66fad920e1312c02dc4395ceed98a2705.zip | |
[debuginfo] Remove the notion of a 'fallback variant' from the CPP-like enum debuginfo encoding.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/debuginfo')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 7a32e255043..c88dfed7e47 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -105,14 +105,6 @@ const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0; /// that case. Both `DISCR_BEGIN` and `DISCR_END` are inclusive bounds. /// Note that these ranges can wrap around, so that `DISCR_END < DISCR_BEGIN`. /// -/// The field in the top-level union that corresponds to the dataful variant -/// is called `variant_fallback` instead of `variant<index>`. This is mainly -/// an optimization that enables a shorter NatVis definition. That way we -/// only need to specify a `tag == variantX.DISCR_EXACT` entry for the indexed -/// variants. Otherwise we'd need to have that and then an additional entry -/// checking `in_range(variantX.DISCR_BEGIN, variantX.DISCR_END)` for each -/// index. -/// /// Single-variant enums don't actually have a tag field. In this case we /// emit a static tag field (that always has the value 0) so we can use the /// same representation (and NatVis). @@ -123,6 +115,72 @@ const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0; /// Instead of the `tag` field, we generate two fields `tag128_lo` and `tag128_hi`, /// Instead of `DISCR_EXACT`, we generate `DISCR128_EXACT_LO` and `DISCR128_EXACT_HI`, /// and so on. +/// +/// +/// The following pseudocode shows how to decode an enum value in a debugger: +/// +/// ```ignore +/// +/// fn find_active_variant(enum_value) -> (VariantName, VariantValue) { +/// let is_128_bit = enum_value.has_field("tag128_lo"); +/// +/// if !is_128_bit { +/// // Note: `tag` can be a static field for enums with only one +/// // inhabited variant. +/// let tag = enum_value.field("tag").value; +/// +/// // For each variant, check if it is a match. Only one of them will match, +/// // so if we find it we can return it immediately. +/// for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) { +/// if variant_field.has_field("DISCR_EXACT") { +/// // This variant corresponds to a single tag value +/// if variant_field.field("DISCR_EXACT").value == tag { +/// return (variant_field.field("NAME"), variant_field.value); +/// } +/// } else { +/// // This is a range variant +/// let begin = variant_field.field("DISCR_BEGIN"); +/// let end = variant_field.field("DISCR_END"); +/// +/// if tag >= begin && tag <= end { +/// return (variant_field.field("NAME"), variant_field.value); +/// } +/// } +/// } +/// } else { +/// // Basically the same as with smaller tags, we just have to +/// // stitch the values together. +/// let tag: u128 = (enum_value.field("tag128_lo").value as u128) | +/// (enum_value.field("tag128_hi").value as u128 << 64); +/// +/// for variant_field in enum_value.fields().filter(|f| f.name.starts_with("variant")) { +/// if variant_field.has_field("DISCR128_EXACT_LO") { +/// let discr_exact = (variant_field.field("DISCR128_EXACT_LO" as u128) | +/// (variant_field.field("DISCR128_EXACT_HI") as u128 << 64); +/// +/// // This variant corresponds to a single tag value +/// if discr_exact.value == tag { +/// return (variant_field.field("NAME"), variant_field.value); +/// } +/// } else { +/// // This is a range variant +/// let begin = (variant_field.field("DISCR128_BEGIN_LO").value as u128) | +/// (variant_field.field("DISCR128_BEGIN_HI").value as u128 << 64); +/// let end = (variant_field.field("DISCR128_END_LO").value as u128) | +/// (variant_field.field("DISCR128_END_HI").value as u128 << 64); +/// +/// if tag >= begin && tag <= end { +/// return (variant_field.field("NAME"), variant_field.value); +/// } +/// } +/// } +/// } +/// +/// // We should have found an active variant at this point. +/// unreachable!(); +/// } +/// +/// ``` pub(super) fn build_enum_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, unique_type_id: UniqueTypeId<'tcx>, @@ -290,7 +348,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( build_field_di_node( cx, enum_type_di_node, - &variant_union_field_name(variant_index, None), + &variant_union_field_name(variant_index), // NOTE: We use the size and align of the entire type, not from variant_layout // since the later is sometimes smaller (if it has fewer fields). size_and_align_of(enum_type_and_layout), @@ -691,8 +749,7 @@ fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>( .source_info .unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)); - let field_name = - variant_union_field_name(variant_member_info.variant_index, dataful_variant_index); + let field_name = variant_union_field_name(variant_member_info.variant_index); let (size, align) = size_and_align_of(enum_type_and_layout); let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node( @@ -795,10 +852,7 @@ struct VariantFieldInfo<'ll> { discr: DiscrResult, } -fn variant_union_field_name( - variant_index: VariantIdx, - dataful_variant_index: Option<VariantIdx>, -) -> Cow<'static, str> { +fn variant_union_field_name(variant_index: VariantIdx) -> Cow<'static, str> { const PRE_ALLOCATED: [&str; 16] = [ "variant0", "variant1", @@ -818,10 +872,6 @@ fn variant_union_field_name( "variant15", ]; - if Some(variant_index) == dataful_variant_index { - return Cow::from("variant_fallback"); - } - PRE_ALLOCATED .get(variant_index.as_usize()) .map(|&s| Cow::from(s)) |
