Skip to content

Commit 0b433bd

Browse files
committed
[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.
1 parent 040d9c9 commit 0b433bd

File tree

4 files changed

+6227
-5748
lines changed

4 files changed

+6227
-5748
lines changed

cross-project-tests/debuginfo-tests/clang_llvm_roundtrip/Inputs/simplified_template_names.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ struct t12 {
9595

9696
template <decltype(ns::AnonEnum1)> void f10() {}
9797

98+
template <typename T, T V> void f11() {}
99+
98100
int main() {
99101
struct {
100102
} A;
@@ -239,8 +241,10 @@ int main() {
239241
f1<void(t8)>();
240242
operator_not_really<int>();
241243
t12 v4;
242-
f1<_BitInt(3)>();
243-
f1<const unsigned _BitInt(5)>();
244+
f11<_BitInt(3), 2>();
245+
f11<const unsigned _BitInt(5), 2>();
246+
f11<_BitInt(65), 2>();
247+
f11<const unsigned _BitInt(65), 2>();
244248
f1<void(t1<>, t1<>)>();
245249
f1<int t1<>::*>();
246250
void fcc() __attribute__((swiftcall));

llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ template <typename DieType> struct DWARFTypePrinter {
7878
}
7979
return false;
8080
}
81+
82+
/// If FormValue is a valid constant Form, print into \c OS the integral value
83+
/// casted to the type referred to by \c Cast.
84+
template <typename FormValueType>
85+
void appendCastedValue(const FormValueType &FormValue, DieType Cast,
86+
bool IsUnsigned);
8187
};
8288

8389
template <typename DieType>
@@ -413,6 +419,31 @@ DieType DWARFTypePrinter<DieType>::appendQualifiedNameBefore(DieType D) {
413419
return appendUnqualifiedNameBefore(D);
414420
}
415421

422+
template <typename DieType>
423+
template <typename FormValueType>
424+
void DWARFTypePrinter<DieType>::appendCastedValue(
425+
const FormValueType &FormValue, DieType Cast, bool IsUnsigned) {
426+
std::string ValStr;
427+
if (IsUnsigned) {
428+
std::optional<uint64_t> UVal = FormValue.getAsUnsignedConstant();
429+
if (!UVal)
430+
return;
431+
432+
ValStr = std::to_string(*UVal);
433+
} else {
434+
std::optional<int64_t> SVal = FormValue.getAsSignedConstant();
435+
if (!SVal)
436+
return;
437+
438+
ValStr = std::to_string(*SVal);
439+
}
440+
441+
OS << '(';
442+
appendQualifiedName(Cast);
443+
OS << ')';
444+
OS << std::move(ValStr);
445+
}
446+
416447
template <typename DieType>
417448
bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
418449
bool *FirstParameter) {
@@ -438,13 +469,11 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
438469
DieType T = detail::resolveReferencedType(C);
439470
Sep();
440471
if (T.getTag() == dwarf::DW_TAG_enumeration_type) {
441-
OS << '(';
442-
appendQualifiedName(T);
443-
OS << ')';
444472
auto V = C.find(dwarf::DW_AT_const_value);
445-
OS << std::to_string(*V->getAsSignedConstant());
473+
appendCastedValue(*V, T, /*IsUnsigned=*/false);
446474
continue;
447475
}
476+
448477
// /Maybe/ we could do pointer/reference type parameters, looking for the
449478
// symbol in the ELF symbol table to get back to the variable...
450479
// but probably not worth it.
@@ -539,6 +568,12 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
539568
else
540569
OS << llvm::format("'\\U%08" PRIx64 "'", Val);
541570
}
571+
// FIXME: Handle _BitInt's larger than 64-bits which are emitted as
572+
// block data.
573+
} else if (Name.starts_with("_BitInt")) {
574+
appendCastedValue(*V, T, /*IsUnsigned=*/false);
575+
} else if (Name.starts_with("unsigned _BitInt")) {
576+
appendCastedValue(*V, T, /*IsUnsigned=*/true);
542577
}
543578
continue;
544579
}

0 commit comments

Comments
 (0)