diff options
author | Tom Tromey <tromey@adacore.com> | 2025-06-25 12:20:35 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-25 11:20:35 -0700 |
commit | 3b90597c2ceaae86608214f6b62b43e55823102b (patch) | |
tree | 3c8c3d739d99734bee8bc6bd5ed9d82d5b2d65bc /llvm/lib/IR/DebugInfoMetadata.cpp | |
parent | 487581b826a5339410aaf306eafedc7b806b25e3 (diff) | |
download | llvm-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.cpp | 101 |
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); } |