aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DebugInfoMetadata.cpp
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2025-06-25 12:20:35 -0600
committerGitHub <noreply@github.com>2025-06-25 11:20:35 -0700
commit3b90597c2ceaae86608214f6b62b43e55823102b (patch)
tree3c8c3d739d99734bee8bc6bd5ed9d82d5b2d65bc /llvm/lib/IR/DebugInfoMetadata.cpp
parent487581b826a5339410aaf306eafedc7b806b25e3 (diff)
downloadllvm-3b90597c2ceaae86608214f6b62b43e55823102b.zip
llvm-3b90597c2ceaae86608214f6b62b43e55823102b.tar.gz
llvm-3b90597c2ceaae86608214f6b62b43e55823102b.tar.bz2
Non constant size and offset in DWARF (#141106)
In Ada, a record type can have a non-constant size, and a field can appear at a non-constant bit offset in a record. To support this, this patch changes DIType to record the size and offset using metadata, rather than plain integers. In addition to a constant offset, both DIVariable and DIExpression are now supported here. One thing of note in this patch is the choice of how exactly to represent a non-constant bit offset, with the difficulty being that DWARF 5 does not support this. DWARF 3 did have a way to support a non-constant byte offset, combined with a constant bit offset within the byte, but this was deprecated in DWARF 4 and removed from DWARF 5. This patch takes a simple approach: a DWARF extension allowing the use of an expression with DW_AT_data_bit_offset. There is a corresponding DWARF issue, see https://dwarfstd.org/issues/250501.1.html. The main reason for this approach is that it keeps API simplicity: just a single value is needed, rather than having separate data describing the byte offset and the bit within the byte.
Diffstat (limited to 'llvm/lib/IR/DebugInfoMetadata.cpp')
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp101
1 files changed, 50 insertions, 51 deletions
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 473114b..44b0f0d 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -825,25 +825,23 @@ DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {
}
DISubrangeType::DISubrangeType(LLVMContext &C, StorageType Storage,
- unsigned Line, uint64_t SizeInBits,
- uint32_t AlignInBits, DIFlags Flags,
- ArrayRef<Metadata *> Ops)
+ unsigned Line, uint32_t AlignInBits,
+ DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, DISubrangeTypeKind, Storage, dwarf::DW_TAG_subrange_type, Line,
- SizeInBits, AlignInBits, 0, 0, Flags, Ops) {}
+ AlignInBits, 0, Flags, Ops) {}
DISubrangeType *DISubrangeType::getImpl(
LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
- Metadata *Scope, uint64_t SizeInBits, uint32_t AlignInBits, DIFlags Flags,
+ Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags,
Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DISubrangeType, (Name, File, Line, Scope, SizeInBits,
AlignInBits, Flags, BaseType,
LowerBound, UpperBound, Stride, Bias));
- Metadata *Ops[] = {File, Scope, Name, BaseType,
- LowerBound, UpperBound, Stride, Bias};
- DEFINE_GETIMPL_STORE(DISubrangeType, (Line, SizeInBits, AlignInBits, Flags),
- Ops);
+ Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr,
+ BaseType, LowerBound, UpperBound, Stride, Bias};
+ DEFINE_GETIMPL_STORE(DISubrangeType, (Line, AlignInBits, Flags), Ops);
}
DISubrangeType::BoundType
@@ -883,18 +881,17 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
}
DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
- MDString *Name, uint64_t SizeInBits,
+ MDString *Name, Metadata *SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits,
Encoding, NumExtraInhabitants, Flags));
- Metadata *Ops[] = {nullptr, nullptr, Name};
- DEFINE_GETIMPL_STORE(
- DIBasicType,
- (Tag, SizeInBits, AlignInBits, Encoding, NumExtraInhabitants, Flags),
- Ops);
+ Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr};
+ DEFINE_GETIMPL_STORE(DIBasicType,
+ (Tag, AlignInBits, Encoding, NumExtraInhabitants, Flags),
+ Ops);
}
std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
@@ -914,18 +911,18 @@ std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
DIFixedPointType *
DIFixedPointType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
- uint64_t SizeInBits, uint32_t AlignInBits,
+ Metadata *SizeInBits, uint32_t AlignInBits,
unsigned Encoding, DIFlags Flags, unsigned Kind,
int Factor, APInt Numerator, APInt Denominator,
StorageType Storage, bool ShouldCreate) {
DEFINE_GETIMPL_LOOKUP(DIFixedPointType,
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags,
Kind, Factor, Numerator, Denominator));
- Metadata *Ops[] = {nullptr, nullptr, Name};
- DEFINE_GETIMPL_STORE(DIFixedPointType,
- (Tag, SizeInBits, AlignInBits, Encoding, Flags, Kind,
- Factor, Numerator, Denominator),
- Ops);
+ Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr};
+ DEFINE_GETIMPL_STORE(
+ DIFixedPointType,
+ (Tag, AlignInBits, Encoding, Flags, Kind, Factor, Numerator, Denominator),
+ Ops);
}
bool DIFixedPointType::isSigned() const {
@@ -957,17 +954,17 @@ DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *StringLength,
Metadata *StringLengthExp,
Metadata *StringLocationExp,
- uint64_t SizeInBits, uint32_t AlignInBits,
+ Metadata *SizeInBits, uint32_t AlignInBits,
unsigned Encoding, StorageType Storage,
bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIStringType,
(Tag, Name, StringLength, StringLengthExp,
StringLocationExp, SizeInBits, AlignInBits, Encoding));
- Metadata *Ops[] = {nullptr, nullptr, Name,
- StringLength, StringLengthExp, StringLocationExp};
- DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),
- Ops);
+ Metadata *Ops[] = {nullptr, nullptr, Name,
+ SizeInBits, nullptr, StringLength,
+ StringLengthExp, StringLocationExp};
+ DEFINE_GETIMPL_STORE(DIStringType, (Tag, AlignInBits, Encoding), Ops);
}
DIType *DIDerivedType::getClassType() const {
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
@@ -1004,8 +1001,8 @@ Constant *DIDerivedType::getDiscriminantValue() const {
DIDerivedType *DIDerivedType::getImpl(
LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
- unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits,
std::optional<unsigned> DWARFAddressSpace,
std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData,
Metadata *Annotations, StorageType Storage, bool ShouldCreate) {
@@ -1014,11 +1011,11 @@ DIDerivedType *DIDerivedType::getImpl(
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, DWARFAddressSpace,
PtrAuthData, Flags, ExtraData, Annotations));
- Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations};
- DEFINE_GETIMPL_STORE(DIDerivedType,
- (Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
- DWARFAddressSpace, PtrAuthData, Flags),
- Ops);
+ Metadata *Ops[] = {File, Scope, Name, SizeInBits,
+ OffsetInBits, BaseType, ExtraData, Annotations};
+ DEFINE_GETIMPL_STORE(
+ DIDerivedType,
+ (Tag, Line, AlignInBits, DWARFAddressSpace, PtrAuthData, Flags), Ops);
}
std::optional<DIDerivedType::PtrAuthData>
@@ -1030,8 +1027,8 @@ DIDerivedType::getPtrAuthData() const {
DICompositeType *DICompositeType::getImpl(
LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
- unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
+ unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
@@ -1047,20 +1044,21 @@ DICompositeType *DICompositeType::getImpl(
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
Annotations, Specification, NumExtraInhabitants, BitStride));
- Metadata *Ops[] = {File, Scope, Name, BaseType,
- Elements, VTableHolder, TemplateParams, Identifier,
- Discriminator, DataLocation, Associated, Allocated,
- Rank, Annotations, Specification, BitStride};
+ Metadata *Ops[] = {File, Scope, Name, SizeInBits,
+ OffsetInBits, BaseType, Elements, VTableHolder,
+ TemplateParams, Identifier, Discriminator, DataLocation,
+ Associated, Allocated, Rank, Annotations,
+ Specification, BitStride};
DEFINE_GETIMPL_STORE(DICompositeType,
- (Tag, Line, RuntimeLang, SizeInBits, AlignInBits,
- OffsetInBits, NumExtraInhabitants, EnumKind, Flags),
+ (Tag, Line, RuntimeLang, AlignInBits,
+ NumExtraInhabitants, EnumKind, Flags),
Ops);
}
DICompositeType *DICompositeType::buildODRType(
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
- uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
+ Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
@@ -1086,12 +1084,13 @@ DICompositeType *DICompositeType::buildODRType(
return CT;
// Mutate CT in place. Keep this in sync with getImpl.
- CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
- NumExtraInhabitants, EnumKind, Flags);
- Metadata *Ops[] = {File, Scope, Name, BaseType,
- Elements, VTableHolder, TemplateParams, &Identifier,
- Discriminator, DataLocation, Associated, Allocated,
- Rank, Annotations, Specification, BitStride};
+ CT->mutate(Tag, Line, RuntimeLang, AlignInBits, NumExtraInhabitants, EnumKind,
+ Flags);
+ Metadata *Ops[] = {File, Scope, Name, SizeInBits,
+ OffsetInBits, BaseType, Elements, VTableHolder,
+ TemplateParams, &Identifier, Discriminator, DataLocation,
+ Associated, Allocated, Rank, Annotations,
+ Specification, BitStride};
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
"Mismatched number of operands");
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
@@ -1103,7 +1102,7 @@ DICompositeType *DICompositeType::buildODRType(
DICompositeType *DICompositeType::getODRType(
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
- uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
+ Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
@@ -1138,7 +1137,7 @@ DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
DIFlags Flags, uint8_t CC,
ArrayRef<Metadata *> Ops)
: DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
- 0, 0, 0, 0, Flags, Ops),
+ 0, 0, Flags, Ops),
CC(CC) {}
DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
@@ -1146,7 +1145,7 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
StorageType Storage,
bool ShouldCreate) {
DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray));
- Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray};
+ Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr, nullptr, TypeArray};
DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
}