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/Verifier.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/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 70beb03..3e53ade 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1172,6 +1172,10 @@ void Verifier::visitDISubrangeType(const DISubrangeType &N) { CheckDI(!Bias || isa<ConstantAsMetadata>(Bias) || isa<DIVariable>(Bias) || isa<DIExpression>(Bias), "Bias must be signed constant or DIVariable or DIExpression", &N); + // Subrange types currently only support constant size. + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa<ConstantAsMetadata>(Size), + "SizeInBits must be a constant"); } void Verifier::visitDISubrange(const DISubrange &N) { @@ -1233,6 +1237,10 @@ void Verifier::visitDIBasicType(const DIBasicType &N) { N.getTag() == dwarf::DW_TAG_unspecified_type || N.getTag() == dwarf::DW_TAG_string_type, "invalid tag", &N); + // Basic types currently only support constant size. + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa<ConstantAsMetadata>(Size), + "SizeInBits must be a constant"); } void Verifier::visitDIFixedPointType(const DIFixedPointType &N) { @@ -1313,6 +1321,11 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) { "DWARF address space only applies to pointer or reference types", &N); } + + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa<ConstantAsMetadata>(Size) || isa<DIVariable>(Size) || + isa<DIExpression>(Size), + "SizeInBits must be a constant or DIVariable or DIExpression"); } /// Detect mutually exclusive flags. @@ -1400,6 +1413,11 @@ void Verifier::visitDICompositeType(const DICompositeType &N) { if (N.getTag() == dwarf::DW_TAG_array_type) { CheckDI(N.getRawBaseType(), "array types must have a base type", &N); } + + auto *Size = N.getRawSizeInBits(); + CheckDI(!Size || isa<ConstantAsMetadata>(Size) || isa<DIVariable>(Size) || + isa<DIExpression>(Size), + "SizeInBits must be a constant or DIVariable or DIExpression"); } void Verifier::visitDISubroutineType(const DISubroutineType &N) { |