[llvm] [llvm][DebugInfo] Add support for _BitInt in DWARFTypePrinter (PR #168382)
Michael Buch via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 17 07:00:03 PST 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/168382
>From 9b33d9ae5f6ccec648195c722dc5c66de956e3ec Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 17 Nov 2025 14:49:26 +0000
Subject: [PATCH 1/2] [llvm][DebugInfo] Add support for _BitInt in
DWARFTypePrinter
As of recent, LLVM includes the bit-size as a `DW_AT_bit_size` (and as part of `DW_AT_name`) of `_BitInt`s in DWARF. This allows us to mark `_BitInt`s as "reconstitutable" when compiling with `-gsimple-template-names`. However, before doing so we need to make sure the `DWARFTypePrinter` can reconstruct template parameter values that have `_BitInt` type. This patch adds support for printing `DW_TAG_template_value_parameter`s that have `_BitInt` type. Since `-gsimple-template-names` only omits template parameters that are `<= 64` bit wide, we don't support `_BitInt`s larger than 64 bits.
---
.../llvm/DebugInfo/DWARF/DWARFTypePrinter.h | 44 +++++-
.../DebugInfo/DWARF/DWARFDieTest.cpp | 140 ++++++++++++++++++
2 files changed, 180 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
index a760f773055d2..9f6bcfb873b4d 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
#include <string>
@@ -78,6 +79,12 @@ template <typename DieType> struct DWARFTypePrinter {
}
return false;
}
+
+ /// If FormValue is a valid constant Form, print into \c OS the integral value
+ /// casted to the type referred to by \c Cast.
+ template <typename FormValueType>
+ void appendCastedValue(const FormValueType &FormValue, DieType Cast,
+ bool IsUnsigned);
};
template <typename DieType>
@@ -413,6 +420,31 @@ DieType DWARFTypePrinter<DieType>::appendQualifiedNameBefore(DieType D) {
return appendUnqualifiedNameBefore(D);
}
+template <typename DieType>
+template <typename FormValueType>
+void DWARFTypePrinter<DieType>::appendCastedValue(
+ const FormValueType &FormValue, DieType Cast, bool IsUnsigned) {
+ std::string ValStr;
+ if (IsUnsigned) {
+ std::optional<uint64_t> UVal = FormValue.getAsUnsignedConstant();
+ if (!UVal)
+ return;
+
+ ValStr = std::to_string(*UVal);
+ } else {
+ std::optional<int64_t> SVal = FormValue.getAsSignedConstant();
+ if (!SVal)
+ return;
+
+ ValStr = std::to_string(*SVal);
+ }
+
+ OS << '(';
+ appendQualifiedName(Cast);
+ OS << ')';
+ OS << std::move(ValStr);
+}
+
template <typename DieType>
bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
bool *FirstParameter) {
@@ -438,13 +470,11 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
DieType T = detail::resolveReferencedType(C);
Sep();
if (T.getTag() == dwarf::DW_TAG_enumeration_type) {
- OS << '(';
- appendQualifiedName(T);
- OS << ')';
auto V = C.find(dwarf::DW_AT_const_value);
- OS << std::to_string(*V->getAsSignedConstant());
+ appendCastedValue(*V, T, /*IsUnsigned=*/false);
continue;
}
+
// /Maybe/ we could do pointer/reference type parameters, looking for the
// symbol in the ELF symbol table to get back to the variable...
// but probably not worth it.
@@ -539,6 +569,12 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
else
OS << llvm::format("'\\U%08" PRIx64 "'", Val);
}
+ // FIXME: Handle _BitInt's larger than 64-bits which are emitted as
+ // block data.
+ } else if (Name.starts_with("_BitInt")) {
+ appendCastedValue(*V, T, /*IsUnsigned=*/false);
+ } else if (Name.starts_with("unsigned _BitInt")) {
+ appendCastedValue(*V, T, /*IsUnsigned=*/true);
}
continue;
}
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
index f566bee170236..a3fafec9e7813 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
@@ -839,4 +839,144 @@ TEST(DWARFDie, DWARFTypePrinterTest) {
testAppendQualifiedName(Ctx->getDIEForOffset(0x1a), "t1<t3<int> >::t2");
testAppendQualifiedName(Ctx->getDIEForOffset(0x28), "t3<int>::my_int");
}
+
+TEST(DWARFDie, DWARFTypePrinterTest_BitInt) {
+ // Make sure we can reconstruct the case where a template value parameter
+ // is a _BitInt.
+
+ // DW_TAG_compile_unit
+ // DW_TAG_base_type
+ // DW_AT_name ("_BitInt(2)")
+ // DW_AT_bit_size ("2")
+ // DW_TAG_base_type
+ // DW_AT_name ("_BitInt(65)")
+ // DW_AT_bit_size ("65")
+ // DW_TAG_base_type
+ // DW_AT_name ("unsigned _BitInt(2)")
+ // DW_AT_bit_size ("2")
+ // DW_TAG_base_type
+ // DW_AT_name ("unsigned _BitInt(65)")
+ // DW_AT_bit_size ("65")
+ // DW_TAG_structure_type
+ // DW_AT_name ("foo")
+ // DW_TAG_template_value_parameter
+ // DW_AT_type ("_BitInt(2)")
+ // DW_AT_const_value (DW_FORM_sdata "-1")
+ // DW_TAG_template_value_parameter
+ // DW_AT_type ("unsigned _BitInt(2)")
+ // DW_AT_const_value (DW_FORM_udata "12")
+ // DW_TAG_template_value_parameter
+ // DW_AT_type ("_BitInt(65)")
+ // DW_AT_const_value (DW_FORM_block1 "1")
+ // DW_TAG_template_value_parameter
+ // DW_AT_type ("unsigned _BitInt(65)")
+ // DW_AT_const_value (DW_FORM_block1 "1")
+ // NULL
+ // NULL
+ const char *yamldata = R"(
+ debug_abbrev:
+ - ID: 0
+ Table:
+ - Code: 0x1
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ - Code: 0x2
+ Tag: DW_TAG_base_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Code: 0x3
+ Tag: DW_TAG_structure_type
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Code: 0x4
+ Tag: DW_TAG_template_value_parameter
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Attribute: DW_AT_const_value
+ Form: DW_FORM_sdata
+ - Code: 0x5
+ Tag: DW_TAG_template_value_parameter
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Attribute: DW_AT_const_value
+ Form: DW_FORM_udata
+ - Code: 0x6
+ Tag: DW_TAG_template_value_parameter
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Attribute: DW_AT_const_value
+ Form: DW_FORM_block1
+ debug_info:
+ - Version: 4
+ AddrSize: 8
+ Entries:
+ - AbbrCode: 0x1
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0xDEADBEEFDEADBEEF
+ CStr: _BitInt(2)
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0xDEADBEEFDEADBEEF
+ CStr: _BitInt(65)
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0xDEADBEEFDEADBEEF
+ CStr: unsigned _BitInt(2)
+ - AbbrCode: 0x2
+ Values:
+ - Value: 0xDEADBEEFDEADBEEF
+ CStr: unsigned _BitInt(65)
+ - AbbrCode: 0x3
+ Values:
+ - Value: 0xDEADBEEFDEADBEEF
+ CStr: foo
+ - AbbrCode: 0x4
+ Values:
+ - Value: 0x0000000c
+ - Value: 0xffffffffffffffff
+ - AbbrCode: 0x5
+ Values:
+ - Value: 0x00000025
+ - Value: 12
+ - AbbrCode: 0x6
+ Values:
+ - Value: 0x00000018
+ - Value: 0x0F
+ BlockData: [ 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ - AbbrCode: 0x6
+ Values:
+ - Value: 0x0000003a
+ - Value: 0x0F
+ BlockData: [ 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ - AbbrCode: 0x0
+ - AbbrCode: 0x0
+)";
+ Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =
+ DWARFYAML::emitDebugSections(StringRef(yamldata),
+ /*IsLittleEndian=*/true,
+ /*Is64BitAddrSize=*/true);
+ ASSERT_THAT_EXPECTED(Sections, Succeeded());
+ std::unique_ptr<DWARFContext> Ctx =
+ DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);
+
+ // FIXME: support _BitInt's with block forms. Currently they are just omitted.
+ // Will be necessary once -gsimple-template-names emit template value
+ // parameters with bit-width larger than 64.
+ testAppendAndTerminateTemplateParameters(
+ Ctx->getDIEForOffset(0x50),
+ "<(_BitInt(2))-1, (unsigned _BitInt(2))12, , >");
+}
} // end anonymous namespace
>From 59fb0bd36c519781fc0506e29fba21fa673ac993 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 17 Nov 2025 14:59:44 +0000
Subject: [PATCH 2/2] fixup! remove redundant header
---
llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
index 9f6bcfb873b4d..9108c718c4794 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
@@ -13,7 +13,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FormatVariadic.h"
#include <string>
More information about the llvm-commits
mailing list