[llvm] [BPF] Support for `DW_TAG_variant_part` in BTF generation (PR #155783)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 12 10:56:31 PDT 2025
https://github.com/eddyz87 requested changes to this pull request.
I think this change is fine, but just realized an unfortunate quirk regarding discriminator handling. Consider the following example:
```rust
pub enum Adt {
First { a: u32, b: i32 },
Second(u32, i32),
}
pub static X: Adt = Adt::First{a:0, b:0};
```
With corresponding IR:
```
!7 = !DICompositeType(tag: DW_TAG_variant_part, scope: !4, file: !5, size: 96, align: 32, elements: !8, ..., discriminator: !22)
!8 = !{!9, !17}
!9 = !DIDerivedType(tag: DW_TAG_member, name: "First", scope: !7, file: !5, baseType: !10, size: 96, align: 32, extraData: i32 0)
!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "First", ..., elements: !11, ...)
!11 = !{!12, !14}
!12 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !10, file: !5, baseType: !13, size: 32, align: 32, offset: 32, flags: DIFlagPublic)
...
!22 = !DIDerivedType(tag: DW_TAG_member, scope: !4, file: !5, baseType: !13, size: 32, align: 32, flags: DIFlagArtificial)
```
And corresponding DWARF:
```c
0x0000003d: DW_TAG_structure_type
DW_AT_name ("Adt")
DW_AT_byte_size (0x0c)
DW_AT_accessibility (DW_ACCESS_public)
DW_AT_alignment (4)
0x00000045: DW_TAG_variant_part
DW_AT_discr (0x0000004a)
0x0000004a: DW_TAG_member
DW_AT_type (0x000000b2 "u32")
DW_AT_alignment (4)
DW_AT_data_member_location (0x00)
DW_AT_artificial (true)
0x00000051: DW_TAG_variant
DW_AT_discr_value (0x00)
0x00000053: DW_TAG_member
DW_AT_name ("First")
DW_AT_type (0x0000006e "test_debug_info::Adt::First")
DW_AT_alignment (4)
DW_AT_data_member_location (0x00)
0x0000005e: NULL
0x0000005f: DW_TAG_variant
DW_AT_discr_value (0x01)
0x00000061: DW_TAG_member
DW_AT_name ("Second")
DW_AT_type (0x0000008f "test_debug_info::Adt::Second")
DW_AT_alignment (4)
DW_AT_data_member_location (0x00)
0x0000006c: NULL
0x0000006d: NULL
0x0000006e: DW_TAG_structure_type
DW_AT_name ("First")
DW_AT_byte_size (0x0c)
DW_AT_accessibility (DW_ACCESS_public)
DW_AT_alignment (4)
0x00000076: DW_TAG_member
DW_AT_name ("a")
DW_AT_type (0x000000b2 "u32")
DW_AT_alignment (4)
DW_AT_data_member_location (0x04)
DW_AT_accessibility (DW_ACCESS_public)
0x00000082: DW_TAG_member
DW_AT_name ("b")
DW_AT_type (0x000000b9 "i32")
DW_AT_alignment (4)
DW_AT_data_member_location (0x08)
DW_AT_accessibility (DW_ACCESS_public)
0x0000008e: NULL
```
Note how offsets for `a` and `b` are shifted by 4 bytes and variant part itself has three members, beside First and Second there is also an anonymous member `0x0000004a`, representing a descriminator at offset 0.
Meaning that in BTF union representing the variant part has to have three members, not two. Which is a bit inconvenient, as it is not a part of "elements", but instead a separate "discriminator" reference.
Wdyt?
https://github.com/llvm/llvm-project/pull/155783
More information about the llvm-commits
mailing list