aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DIBuilder.cpp
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2025-05-12 08:55:38 -0600
committerGitHub <noreply@github.com>2025-05-12 07:55:38 -0700
commit386f2ca03bdbcf5d08e5ec417bdad6c3de01acb6 (patch)
treec38ffea89a3b66ef87b88c0cc70c854f18ffc35b /llvm/lib/IR/DIBuilder.cpp
parentf687ed9ff717372a7c751a3bf4ef7e33eb481fd6 (diff)
downloadllvm-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.cpp13
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,