diff options
author | Tom Tromey <tromey@adacore.com> | 2025-05-12 08:55:38 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-12 07:55:38 -0700 |
commit | 386f2ca03bdbcf5d08e5ec417bdad6c3de01acb6 (patch) | |
tree | c38ffea89a3b66ef87b88c0cc70c854f18ffc35b /llvm/lib/IR/DIBuilder.cpp | |
parent | f687ed9ff717372a7c751a3bf4ef7e33eb481fd6 (diff) | |
download | llvm-386f2ca03bdbcf5d08e5ec417bdad6c3de01acb6.zip llvm-386f2ca03bdbcf5d08e5ec417bdad6c3de01acb6.tar.gz llvm-386f2ca03bdbcf5d08e5ec417bdad6c3de01acb6.tar.bz2 |
Allow multi-member variants in DWARF (#139300)
Currently, each variant in the variant part of a structure type can only
contain a single member. This was sufficient for Rust, where each
variant is represented as its own type.
However, this isn't really enough for Ada, where a variant can have
multiple members.
This patch adds support for this scenario. This is done by allowing the
use of DW_TAG_variant by DICompositeType, and then changing the DWARF
generator to recognize when a DIDerivedType representing a variant holds
one of these. In this case, the fields from the DW_TAG_variant are
inlined into the variant, like so:
```
<4><7d>: Abbrev Number: 9 (DW_TAG_variant)
<7e> DW_AT_discr_value : 74
<5><7f>: Abbrev Number: 7 (DW_TAG_member)
<80> DW_AT_name : (indirect string, offset: 0x43): field0
<84> DW_AT_type : <0xa7>
<88> DW_AT_alignment : 8
<89> DW_AT_data_member_location: 0
<5><8a>: Abbrev Number: 7 (DW_TAG_member)
<8b> DW_AT_name : (indirect string, offset: 0x4a): field1
<8f> DW_AT_type : <0xa7>
<93> DW_AT_alignment : 8
<94> DW_AT_data_member_location: 8
```
Note that the intermediate DIDerivedType is still needed in this
situation, because that is where the discriminants are stored.
Diffstat (limited to 'llvm/lib/IR/DIBuilder.cpp')
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index d9cc49f..90da9f3 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -444,6 +444,19 @@ DIDerivedType *DIBuilder::createVariantMemberType( std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant)); } +DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope, + DINodeArray Elements, + Constant *Discriminant, + DIType *Ty) { + auto *V = DICompositeType::get(VMContext, dwarf::DW_TAG_variant, {}, nullptr, + 0, getNonCompileUnitScope(Scope), {}, 0, 0, 0, + DINode::FlagZero, Elements, 0, {}, nullptr); + + trackIfUnresolved(V); + return createVariantMemberType(Scope, {}, nullptr, 0, 0, 0, 0, Discriminant, + DINode::FlagZero, V); +} + DIDerivedType *DIBuilder::createBitFieldMemberType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits, |