[llvm] [BPF] Support for `DW_TAG_variant_part` in BTF generation (PR #155783)

Michal R via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 7 00:25:04 PDT 2025


================
@@ -301,21 +303,61 @@ void BTFTypeStruct::completeType(BTFDebug &BDebug) {
 
   BTFType.NameOff = BDebug.addString(STy->getName());
 
+  uint64_t InitialOffset = 0;
+  if (STy->getTag() == dwarf::DW_TAG_variant_part) {
+    // Variant parts have a discriminator, which has its own memory location at
+    // the beginning, and variants, which share the memory location afterwards.
+    // LLVM DI doesn't consider discriminator as an element and instead keeps
+    // it as a separate reference.
+    // To keep BTF simple, let's represent the structure as an union with
+    // discriminator as the first element and apply offsets to the other
+    // elements.
+    struct BTF::BTFMember Discriminator;
+    const auto *DDTy = STy->getDiscriminator();
+
+    InitialOffset += DDTy->getOffsetInBits() + DDTy->getSizeInBits();
+
+    Discriminator.NameOff = BDebug.addString(DDTy->getName());
+    Discriminator.Offset = DDTy->getOffsetInBits();
+    const auto *BaseTy = DDTy->getBaseType();
+    Discriminator.Type = BDebug.getTypeId(BaseTy);
+
+    Members.push_back(Discriminator);
+  }
+
   // Add struct/union members.
   const DINodeArray Elements = STy->getElements();
   for (const auto *Element : Elements) {
     struct BTF::BTFMember BTFMember;
-    const auto *DDTy = cast<DIDerivedType>(Element);
 
-    BTFMember.NameOff = BDebug.addString(DDTy->getName());
-    if (HasBitField) {
-      uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
-      BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
-    } else {
-      BTFMember.Offset = DDTy->getOffsetInBits();
+    switch (Element->getTag()) {
+    case dwarf::DW_TAG_member: {
+      const auto *DDTy = cast<DIDerivedType>(Element);
+
+      BTFMember.NameOff = BDebug.addString(DDTy->getName());
+      uint64_t Offset;
+      if (HasBitField) {
+        uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
----------------
vadorovsky wrote:

Good point. Sorry that I misinterpreted your and Yonhong's previous comments about removing `HasBitField` as "don't handle bitfields for Rust at all".

https://github.com/llvm/llvm-project/pull/155783


More information about the llvm-commits mailing list