[clang] [llvm] [DebugInfo] Emit DW_AT_bit_size for _BitSize types and others (PR #164372)
    Orlando Cazalet-Hyams via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Tue Oct 21 00:54:54 PDT 2025
    
    
  
https://github.com/OCHyams created https://github.com/llvm/llvm-project/pull/164372
DW_TAG_base_type DIEs are permitted to have both byte_size and bit_size attributes "If the value of an object of the given type does not fully occupy the storage described by a byte size attribute"
Change Clang to emit the actual bit-size of _BitInt in debug metadata, and change LLVM to add DW_AT_bit_size to base_type DIEs when the condition above is true.
Fixes [#61952](https://github.com/llvm/llvm-project/issues/61952)
>From 83f7c7c070f1b3912b09974944c9e6783efe1983 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 20 Oct 2025 17:00:06 +0100
Subject: [PATCH] [DebugInfo] Emit DW_AT_bit_size for _BitSize types and others
DW_TAG_base_type DIEs are permitted to have both byte_size and bit_size
attributes "If the value of an object of the given type does not fully occupy
the storage described by a byte size attribute"
Change Clang to emit the actual bit-size of _BitInt in debug metadata, and
change LLVM to add DW_AT_bit_size to base_type DIEs when the condition above is
true.
---
 clang/lib/CodeGen/CGDebugInfo.cpp             |  4 +-
 clang/test/DebugInfo/Generic/bit-int.c        |  8 ++++
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   |  5 +++
 llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp     | 13 ++++++-
 llvm/test/DebugInfo/bit-int-size.ll           | 38 +++++++++++++++++++
 5 files changed, 63 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/DebugInfo/Generic/bit-int.c
 create mode 100644 llvm/test/DebugInfo/bit-int-size.ll
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 12e2813ef2ec7..2ad187de16acc 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1152,9 +1152,7 @@ llvm::DIType *CGDebugInfo::CreateType(const BitIntType *Ty) {
   llvm::dwarf::TypeKind Encoding = Ty->isUnsigned()
                                        ? llvm::dwarf::DW_ATE_unsigned
                                        : llvm::dwarf::DW_ATE_signed;
-
-  return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
-                                  Encoding);
+  return DBuilder.createBasicType(Name, Ty->getNumBits(), Encoding);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
diff --git a/clang/test/DebugInfo/Generic/bit-int.c b/clang/test/DebugInfo/Generic/bit-int.c
new file mode 100644
index 0000000000000..16b3d7a2582c9
--- /dev/null
+++ b/clang/test/DebugInfo/Generic/bit-int.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -x c++ %s -debug-info-kind=standalone -gno-column-info -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c   %s -debug-info-kind=standalone -gno-column-info -emit-llvm -o - | FileCheck %s
+
+unsigned _BitInt(2) a;
+_BitInt(2) b;
+
+// CHECK: !DIBasicType(name: "_BitInt", size: 2, encoding: DW_ATE_signed)
+// CHECK: !DIBasicType(name: "unsigned _BitInt", size: 2, encoding: DW_ATE_unsigned)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 518121e200190..6f68548aa25f4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1795,6 +1795,11 @@ void DwarfCompileUnit::createBaseTypeDIEs() {
     // Round up to smallest number of bytes that contains this number of bits.
     addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,
             divideCeil(Btr.BitSize, 8));
+    // If the value of an object of the given type does not fully occupy the
+    // storage described by a byte size attribute, the base type entry may also
+    // have a DW_AT_bit_size [...] attribute.
+    if (Btr.BitSize && (Btr.BitSize % 8))
+      addUInt(Die, dwarf::DW_AT_bit_size, std::nullopt, Btr.BitSize);
 
     Btr.Die = &Die;
   }
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e40fb768027b8..1253d9a463cbb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -766,8 +766,17 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
     addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
             BTy->getEncoding());
 
-  uint64_t Size = BTy->getSizeInBits() >> 3;
-  addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);
+  uint64_t SizeInBytes = divideCeil(BTy->getSizeInBits(), 8);
+  addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, SizeInBytes);
+  if (BTy->getTag() == dwarf::Tag::DW_TAG_base_type) {
+    // DW_TAG_base_type:
+    // If the value of an object of the given type does not fully occupy the
+    // storage described by a byte size attribute, the base type entry may also
+    // have a DW_AT_bit_size [...] attribute.
+    if (uint64_t SizeInBits = BTy->getSizeInBits();
+        SizeInBits && SizeInBits % 8)
+      addUInt(Buffer, dwarf::DW_AT_bit_size, std::nullopt, SizeInBits);
+  }
 
   if (BTy->isBigEndian())
     addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big);
diff --git a/llvm/test/DebugInfo/bit-int-size.ll b/llvm/test/DebugInfo/bit-int-size.ll
new file mode 100644
index 0000000000000..69ab756f4e288
--- /dev/null
+++ b/llvm/test/DebugInfo/bit-int-size.ll
@@ -0,0 +1,38 @@
+; RUN: %llc_dwarf %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
+; REQUIRES: object-emission
+
+;; Check base types with bit-sizes that don't fit fully fit within a byte
+;; multiple get both a a byte_size and bit_size attribute.
+
+; CHECK: DW_TAG_base_type
+; CHECK-NEXT: DW_AT_name      ("unsigned _BitInt")
+; CHECK-NEXT: DW_AT_encoding  (DW_ATE_unsigned)
+; CHECK-NEXT: DW_AT_byte_size (0x02)
+; CHECK-NEXT: DW_AT_bit_size  (0x09)
+
+; CHECK: DW_TAG_base_type
+; CHECK-NEXT: DW_AT_name      ("unsigned _BitInt")
+; CHECK-NEXT: DW_AT_encoding  (DW_ATE_signed)
+; CHECK-NEXT: DW_AT_byte_size (0x01)
+; CHECK-NEXT: DW_AT_bit_size  (0x02)
+
+ at a = global i8 0, align 1, !dbg !0
+ at b = global i8 0, align 1, !dbg !5
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!10, !11}
+!llvm.ident = !{!12}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !7, line: 4, type: !9, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 22.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "bit-int.c", directory: "/")
+!4 = !{!0, !5}
+!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
+!6 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !7, line: 5, type: !8, isLocal: false, isDefinition: true)
+!7 = !DIFile(filename: "bit-int.c", directory: "/")
+!8 = !DIBasicType(name: "_BitInt", size: 2, encoding: DW_ATE_signed)
+!9 = !DIBasicType(name: "unsigned _BitInt", size: 2, encoding: DW_ATE_unsigned)
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{i32 1, !"wchar_size", i32 4}
+!12 = !{!"clang version 22.0.0git"}
    
    
More information about the llvm-commits
mailing list