diff options
| author | Michal R <vad.sol@proton.me> | 2025-10-20 20:07:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-20 11:07:55 -0700 |
| commit | ad582e383369fc32fffb016be68b1ba7812f2325 (patch) | |
| tree | 231aebbe45ec5371a1d99f70341fb5fc7842df48 /clang/lib/Frontend/CompilerInvocation.cpp | |
| parent | 5c86520eb3f223de7a383ed696ace59978b98261 (diff) | |
| download | llvm-ad582e383369fc32fffb016be68b1ba7812f2325.zip llvm-ad582e383369fc32fffb016be68b1ba7812f2325.tar.gz llvm-ad582e383369fc32fffb016be68b1ba7812f2325.tar.bz2 | |
[BPF] Support for `DW_TAG_variant_part` in BTF generation (#155783)
Variant part, represented by `DW_TAG_variant_part` is a structure with a
discriminant and different variants, from which only one can be active
and valid at the same time. The discriminant is the main difference
between variant parts and unions represented by `DW_TAG_union` type.
Variant parts are used by Rust enums, which look like:
```rust
pub enum MyEnum {
First { a: u32, b: i32 },
Second(u32),
}
```
This type's debug info is the following `DICompositeType` with
`DW_TAG_structure_type` tag:
```llvm
!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyEnum",
scope: !2, file: !5, size: 96, align: 32, flags: DIFlagPublic,
elements: !6, templateParams: !16,
identifier: "faba668fd9f71e9b7cf3b9ac5e8b93cb")
```
With one element being also a `DICompositeType`, but with
`DW_TAG_variant_part` tag:
```llvm
!6 = !{!7}
!7 = !DICompositeType(tag: DW_TAG_variant_part, scope: !4, file: !5,
size: 96, align: 32, elements: !8, templateParams: !16,
identifier: "e4aee046fc86d111657622fdcb8c42f7", discriminator: !21)
```
Which has a discriminator:
```llvm
!21 = !DIDerivedType(tag: DW_TAG_member, scope: !4, file: !5,
baseType: !13, size: 32, align: 32, flags: DIFlagArtificial)
```
Which then holds different variants as `DIDerivedType` elements with
`DW_TAG_member` tag:
```llvm
!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",
scope: !4, file: !5, size: 96, align: 32, flags: DIFlagPublic,
elements: !11, templateParams: !16,
identifier: "cc7748c842e275452db4205b190c8ff7")
!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)
!13 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned)
!14 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !10,
file: !5, baseType: !15, size: 32, align: 32, offset: 64,
flags: DIFlagPublic)
!15 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
!16 = !{}
!17 = !DIDerivedType(tag: DW_TAG_member, name: "Second", scope: !7,
file: !5, baseType: !18, size: 96, align: 32, extraData: i32 1)
!18 = !DICompositeType(tag: DW_TAG_structure_type, name: "Second",
scope: !4, file: !5, size: 96, align: 32, flags: DIFlagPublic,
elements: !19, templateParams: !16,
identifier: "a2094b1381f3082d504fbd0903aa7c06")
!19 = !{!20}
!20 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !18,
file: !5, baseType: !13, size: 32, align: 32, offset: 32,
flags: DIFlagPublic)
```
BPF backend was assuming that all the elements of any `DICompositeType`
have tag `DW_TAG_member` and are instances of `DIDerivedType`. However,
the single element of the outer composite type `!4` has tag
`DW_TAG_variant_part` and is an instance of `DICompositeType`. The
unconditional call of `cast<DIDerivedType>` on all elements was causing
an assertion failure when any Rust code with enums was compiled to the
BPF target.
Fix that by:
* Handling `DW_TAG_variant_part` in `visitStructType`.
* Replacing unconditional call of `cast<DIDerivedType>` over
`DICompositeType` elements with a `switch` statement, handling both
`DW_TAG_member` and `DW_TAG_variant_part` and casting the element to an
appropriate type (`DIDerivedType` or `DICompositeType`).
Fixes: https://github.com/llvm/llvm-project/issues/155778
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
0 files changed, 0 insertions, 0 deletions
