Skip to content

Conversation

@Michael137
Copy link
Member

One (DWARF-spec compliant) exmample is: #164372, where we attach a DW_AT_bit_size to _BitInt types that can't be exactly described by a byte-size.

This patch adds support for DW_AT_bit_size to DWARFASTParserClang when parsing type tags.

Note, we don't use this bit-size yet, but will do so in follow-up patches.

One (DWARF-spec compliant) exmample is: llvm#164372, where we attach a `DW_AT_bit_size` to `_BitInt` types that can't be exactly described by a byte-size.

This patch adds support for `DW_AT_bit_size` to `DWARFASTParserClang`
when parsing type tags.

Note, we don't use this bit-size yet, but will do so in follow-up
patches.
@llvmbot
Copy link
Member

llvmbot commented Oct 30, 2025

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

Changes

One (DWARF-spec compliant) exmample is: #164372, where we attach a DW_AT_bit_size to _BitInt types that can't be exactly described by a byte-size.

This patch adds support for DW_AT_bit_size to DWARFASTParserClang when parsing type tags.

Note, we don't use this bit-size yet, but will do so in follow-up patches.


Full diff: https://github.com/llvm/llvm-project/pull/165686.diff

3 Files Affected:

  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+6-2)
  • (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (+1)
  • (modified) lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp (+90)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 82e9d867c3ac0..71dc3de4137d4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -450,6 +450,10 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
       byte_size = form_value.Unsigned();
       break;
 
+    case DW_AT_bit_size:
+      data_bit_size = form_value.Unsigned();
+      break;
+
     case DW_AT_alignment:
       alignment = form_value.Unsigned();
       break;
@@ -810,13 +814,13 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
     // there...
     [[fallthrough]];
 
-  case DW_TAG_base_type:
+  case DW_TAG_base_type: {
     resolve_state = Type::ResolveState::Full;
     clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
         attrs.name.GetStringRef(), attrs.encoding,
         attrs.byte_size.value_or(0) * 8);
     break;
-
+  }
   case DW_TAG_pointer_type:
     encoding_data_type = Type::eEncodingIsPointerUID;
     break;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index da58f4c146226..f5f707129d67d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -574,6 +574,7 @@ struct ParsedDWARFTypeAttributes {
   lldb_private::plugin::dwarf::DWARFFormValue type;
   lldb::LanguageType class_language = lldb::eLanguageTypeUnknown;
   std::optional<uint64_t> byte_size;
+  std::optional<uint64_t> data_bit_size;
   std::optional<uint64_t> alignment;
   size_t calling_convention = llvm::dwarf::DW_CC_normal;
   uint32_t bit_stride = 0;
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index 0cae01de2902a..646426b5cb31f 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -1617,3 +1617,93 @@ TEST_F(DWARFASTParserClangTests, TestObjectPointer_IndexEncoding) {
     EXPECT_EQ(param_die, ast_parser.GetObjectParameter(sub2, context_die));
   }
 }
+
+TEST_F(DWARFASTParserClangTests, TestTypeBitSize) {
+  // Tests that we correctly parse DW_AT_bit_size of a DW_AT_base_type.
+
+  const char *yamldata = R"(
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_AARCH64
+DWARF:
+  debug_str:
+    - _BitInt(2)
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_data2
+        - Code:            0x2
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute: DW_AT_name
+              Form:      DW_FORM_strp
+            - Attribute: DW_AT_encoding
+              Form:      DW_FORM_data1
+            - Attribute: DW_AT_byte_size
+              Form:      DW_FORM_data1
+            - Attribute: DW_AT_bit_size
+              Form:      DW_FORM_data1
+
+  debug_info:
+     - Version:  5
+       UnitType: DW_UT_compile
+       AddrSize: 8
+       Entries:
+
+# DW_TAG_compile_unit
+#   DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
+
+        - AbbrCode: 0x1
+          Values:
+            - Value: 0x04
+
+#   DW_TAG_base_type
+#     DW_AT_name [DW_FORM_strp] ('_BitInt(2)')
+
+        - AbbrCode: 0x2
+          Values:
+            - Value: 0x0
+            - Value: 0x3e
+            - Value: 0x01
+            - Value: 0x02
+...
+)";
+
+  YAMLModuleTester t(yamldata);
+
+  DWARFUnit *unit = t.GetDwarfUnit();
+  ASSERT_NE(unit, nullptr);
+  const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
+  ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
+  ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
+  DWARFDIE cu_die(unit, cu_entry);
+
+  auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+  auto &ast_ctx = *holder->GetAST();
+  DWARFASTParserClangStub ast_parser(ast_ctx);
+
+  auto type_die = cu_die.GetFirstChild();
+  ASSERT_TRUE(type_die.IsValid());
+  ASSERT_EQ(type_die.Tag(), DW_TAG_base_type);
+
+  ParsedDWARFTypeAttributes attrs(type_die);
+  EXPECT_EQ(attrs.byte_size.value_or(0), 1U);
+  EXPECT_EQ(attrs.data_bit_size.value_or(0), 2U);
+
+  SymbolContext sc;
+  auto type_sp =
+      ast_parser.ParseTypeFromDWARF(sc, type_die, /*type_is_new_ptr=*/nullptr);
+  ASSERT_NE(type_sp, nullptr);
+
+  EXPECT_EQ(llvm::expectedToOptional(type_sp->GetByteSize(nullptr)).value_or(0),
+            1U);
+}

@Michael137 Michael137 merged commit 9ed8896 into llvm:main Oct 30, 2025
16 of 18 checks passed
@Michael137 Michael137 deleted the lldb/bit-size-parsing branch October 30, 2025 16:31
Michael137 added a commit that referenced this pull request Oct 31, 2025
Depends on:
* #165686

This patch ensures we make use of the `DW_AT_bit_size` on
`DW_TAG_base_type`s (which since
#164372 can exist on
`_BitInt`s) and adjusts `TypeSystemClang` to recognize `_BitInt`.

For DWARF from older versions of Clang that didn't emit a
`DW_AT_bit_size`, we would create `_BitInt`s using the byte-size. Not
sure we can do much better than that. But the situation beforehand
wasn't much better.

Before:
```
(lldb) v
(char) a = '\x01'
(unsigned char) b = '\x01'
(long) c = 2
(unsigned long) d = 2
```

After:
```
(lldb) v
(_BitInt(2)) a = 1
(unsigned _BitInt(2)) b = 1
(_BitInt(52)) c = 2
(unsigned _BitInt(52)) d = 2
```

Fixes #110273
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Oct 31, 2025
Depends on:
* llvm/llvm-project#165686

This patch ensures we make use of the `DW_AT_bit_size` on
`DW_TAG_base_type`s (which since
llvm/llvm-project#164372 can exist on
`_BitInt`s) and adjusts `TypeSystemClang` to recognize `_BitInt`.

For DWARF from older versions of Clang that didn't emit a
`DW_AT_bit_size`, we would create `_BitInt`s using the byte-size. Not
sure we can do much better than that. But the situation beforehand
wasn't much better.

Before:
```
(lldb) v
(char) a = '\x01'
(unsigned char) b = '\x01'
(long) c = 2
(unsigned long) d = 2
```

After:
```
(lldb) v
(_BitInt(2)) a = 1
(unsigned _BitInt(2)) b = 1
(_BitInt(52)) c = 2
(unsigned _BitInt(52)) d = 2
```

Fixes llvm/llvm-project#110273
luciechoi pushed a commit to luciechoi/llvm-project that referenced this pull request Nov 1, 2025
One (DWARF-spec compliant) exmample is:
llvm#164372, where we attach a
`DW_AT_bit_size` to `_BitInt` types that can't be exactly described by a
byte-size.

This patch adds support for `DW_AT_bit_size` to `DWARFASTParserClang`
when parsing type tags.

Note, we don't use this bit-size yet, but will do so in follow-up
patches.
DEBADRIBASAK pushed a commit to DEBADRIBASAK/llvm-project that referenced this pull request Nov 3, 2025
One (DWARF-spec compliant) exmample is:
llvm#164372, where we attach a
`DW_AT_bit_size` to `_BitInt` types that can't be exactly described by a
byte-size.

This patch adds support for `DW_AT_bit_size` to `DWARFASTParserClang`
when parsing type tags.

Note, we don't use this bit-size yet, but will do so in follow-up
patches.
DEBADRIBASAK pushed a commit to DEBADRIBASAK/llvm-project that referenced this pull request Nov 3, 2025
Depends on:
* llvm#165686

This patch ensures we make use of the `DW_AT_bit_size` on
`DW_TAG_base_type`s (which since
llvm#164372 can exist on
`_BitInt`s) and adjusts `TypeSystemClang` to recognize `_BitInt`.

For DWARF from older versions of Clang that didn't emit a
`DW_AT_bit_size`, we would create `_BitInt`s using the byte-size. Not
sure we can do much better than that. But the situation beforehand
wasn't much better.

Before:
```
(lldb) v
(char) a = '\x01'
(unsigned char) b = '\x01'
(long) c = 2
(unsigned long) d = 2
```

After:
```
(lldb) v
(_BitInt(2)) a = 1
(unsigned _BitInt(2)) b = 1
(_BitInt(52)) c = 2
(unsigned _BitInt(52)) d = 2
```

Fixes llvm#110273
Michael137 added a commit to swiftlang/llvm-project that referenced this pull request Nov 4, 2025
One (DWARF-spec compliant) exmample is:
llvm#164372, where we attach a
`DW_AT_bit_size` to `_BitInt` types that can't be exactly described by a
byte-size.

This patch adds support for `DW_AT_bit_size` to `DWARFASTParserClang`
when parsing type tags.

Note, we don't use this bit-size yet, but will do so in follow-up
patches.

(cherry picked from commit 9ed8896)
Michael137 added a commit to swiftlang/llvm-project that referenced this pull request Nov 4, 2025
Depends on:
* llvm#165686

This patch ensures we make use of the `DW_AT_bit_size` on
`DW_TAG_base_type`s (which since
llvm#164372 can exist on
`_BitInt`s) and adjusts `TypeSystemClang` to recognize `_BitInt`.

For DWARF from older versions of Clang that didn't emit a
`DW_AT_bit_size`, we would create `_BitInt`s using the byte-size. Not
sure we can do much better than that. But the situation beforehand
wasn't much better.

Before:
```
(lldb) v
(char) a = '\x01'
(unsigned char) b = '\x01'
(long) c = 2
(unsigned long) d = 2
```

After:
```
(lldb) v
(_BitInt(2)) a = 1
(unsigned _BitInt(2)) b = 1
(_BitInt(52)) c = 2
(unsigned _BitInt(52)) d = 2
```

Fixes llvm#110273

(cherry picked from commit deb54ba)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants