-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bit stride to DICompositeType #131680
Conversation
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-debuginfo Author: Tom Tromey (tromey) ChangesIn Ada, an array can be packed and the elements can take less space than their natural object size. For example, for this type: type Packed_Array is array (4 .. 8) of Boolean; ... each element of the array occupies a single bit, even though the "natural" size for a Boolean in memory is a byte. In DWARF, this is represented by putting a DW_AT_bit_stride onto the array type itself. This patch adds a bit stride to DICompositeType so that gnat-llvm can emit DWARF for these sorts of arrays. This also fixes a bug in MetadataLoader.cpp, introduced in #124752. I don't know how to write a separate test case for that, but I believe the new array-bitstride.ll will fail if that fix is backed out. Patch is 32.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131680.diff 14 Files Affected:
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index c0567090fdd2a..a005a3ea9545c 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -6336,7 +6336,10 @@ array is currently associated. The optional ``allocated`` is a
DIExpression that describes whether the allocatable array is currently
allocated. The optional ``rank`` is a DIExpression that describes the
rank (number of dimensions) of fortran assumed rank array (rank is
-known at runtime).
+known at runtime). The optional ``bitStride`` is an unsigned constant
+that describes the number of bits occupied by an element of the array;
+this is only needed if it differs from the element type's natural
+size, and is normally used for packed arrays.
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
descriptors <DIEnumerator>`, each representing the definition of an enumeration
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 92a0b7a16d039..b63e564dfd36b 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -609,13 +609,15 @@ namespace llvm {
/// \param Rank The rank attribute of a descriptor-based
/// Fortran array, either a DIExpression* or
/// a DIVariable*.
+ /// \param BitStride The bit size of an element of the array.
DICompositeType *createArrayType(
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,
PointerUnion<DIExpression *, DIVariable *> DataLocation = nullptr,
PointerUnion<DIExpression *, DIVariable *> Associated = nullptr,
PointerUnion<DIExpression *, DIVariable *> Allocated = nullptr,
- PointerUnion<DIExpression *, DIVariable *> Rank = nullptr);
+ PointerUnion<DIExpression *, DIVariable *> Rank = nullptr,
+ Metadata *BitStride = nullptr);
/// Create debugging information entry for a vector type.
/// \param Size Array size.
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 7826514cd3e44..62a59ddaee599 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1302,15 +1302,15 @@ class DICompositeType : public DIType {
DIType *VTableHolder, DITemplateParameterArray TemplateParams,
StringRef Identifier, DIDerivedType *Discriminator,
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank, DINodeArray Annotations, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
- Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
- Flags, Elements.get(), RuntimeLang, EnumKind, VTableHolder,
- TemplateParams.get(),
- getCanonicalMDString(Context, Identifier), Discriminator,
- DataLocation, Associated, Allocated, Rank, Annotations.get(),
- Specification, NumExtraInhabitants, Storage, ShouldCreate);
+ Metadata *Rank, DINodeArray Annotations, Metadata *BitStride,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(
+ Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
+ RuntimeLang, EnumKind, VTableHolder, TemplateParams.get(),
+ getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
+ Associated, Allocated, Rank, Annotations.get(), Specification,
+ NumExtraInhabitants, BitStride, Storage, ShouldCreate);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -1322,7 +1322,7 @@ class DICompositeType : public DIType {
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
Metadata *Specification, uint32_t NumExtraInhabitants,
- StorageType Storage, bool ShouldCreate = true);
+ Metadata *BitStride, StorageType Storage, bool ShouldCreate = true);
TempDICompositeType cloneImpl() const {
return getTemporary(
@@ -1332,7 +1332,7 @@ class DICompositeType : public DIType {
getVTableHolder(), getTemplateParams(), getIdentifier(),
getDiscriminator(), getRawDataLocation(), getRawAssociated(),
getRawAllocated(), getRawRank(), getAnnotations(), getSpecification(),
- getNumExtraInhabitants());
+ getNumExtraInhabitants(), getRawBitStride());
}
public:
@@ -1348,11 +1348,12 @@ class DICompositeType : public DIType {
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
DINodeArray Annotations = nullptr, DIType *Specification = nullptr,
- uint32_t NumExtraInhabitants = 0),
+ uint32_t NumExtraInhabitants = 0, Metadata *BitStride = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements,
RuntimeLang, EnumKind, VTableHolder, TemplateParams, Identifier,
- Discriminator, DataLocation, Associated, Allocated, Rank, Annotations))
+ Discriminator, DataLocation, Associated, Allocated, Rank, Annotations,
+ BitStride))
DEFINE_MDNODE_GET(
DICompositeType,
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
@@ -1364,11 +1365,13 @@ class DICompositeType : public DIType {
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
- Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0),
+ Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0,
+ Metadata *BitStride = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder,
TemplateParams, Identifier, Discriminator, DataLocation, Associated,
- Allocated, Rank, Annotations, Specification, NumExtraInhabitants))
+ Allocated, Rank, Annotations, Specification, NumExtraInhabitants,
+ BitStride))
TempDICompositeType clone() const { return cloneImpl(); }
@@ -1389,7 +1392,7 @@ class DICompositeType : public DIType {
Metadata *VTableHolder, Metadata *TemplateParams,
Metadata *Discriminator, Metadata *DataLocation,
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
- Metadata *Annotations);
+ Metadata *Annotations, Metadata *BitStride);
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
MDString &Identifier);
@@ -1412,7 +1415,7 @@ class DICompositeType : public DIType {
Metadata *VTableHolder, Metadata *TemplateParams,
Metadata *Discriminator, Metadata *DataLocation,
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
- Metadata *Annotations);
+ Metadata *Annotations, Metadata *BitStride);
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
DINodeArray getElements() const {
@@ -1477,6 +1480,14 @@ class DICompositeType : public DIType {
DIType *getSpecification() const {
return cast_or_null<DIType>(getRawSpecification());
}
+
+ Metadata *getRawBitStride() const { return getOperand(15); }
+ ConstantInt *getBitStrideConst() const {
+ if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawBitStride()))
+ return dyn_cast_or_null<ConstantInt>(MD->getValue());
+ return nullptr;
+ }
+
/// Replace operands.
///
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index c8d792981793d..f7438231fdde9 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -5612,7 +5612,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(rank, MDSignedOrMDField, ); \
OPTIONAL(annotations, MDField, ); \
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
- OPTIONAL(specification, MDField, );
+ OPTIONAL(specification, MDField, ); \
+ OPTIONAL(bitStride, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -5635,7 +5636,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
specification.Val, num_extra_inhabitants.Val, flags.Val,
elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val,
templateParams.Val, discriminator.Val, dataLocation.Val,
- associated.Val, allocated.Val, Rank, annotations.Val)) {
+ associated.Val, allocated.Val, Rank, annotations.Val,
+ bitStride.Val)) {
Result = CT;
return false;
}
@@ -5649,7 +5651,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val,
identifier.Val, discriminator.Val, dataLocation.Val, associated.Val,
allocated.Val, Rank, annotations.Val, specification.Val,
- num_extra_inhabitants.Val));
+ num_extra_inhabitants.Val, bitStride.Val));
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 1baf0a9214e00..1331c19a69daf 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -1618,7 +1618,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_COMPOSITE_TYPE: {
- if (Record.size() < 16 || Record.size() > 25)
+ if (Record.size() < 16 || Record.size() > 26)
return error("Invalid record");
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1651,6 +1651,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
Metadata *Rank = nullptr;
Metadata *Annotations = nullptr;
Metadata *Specification = nullptr;
+ Metadata *BitStride = nullptr;
auto *Identifier = getMDString(Record[15]);
// If this module is being parsed so that it can be ThinLTO imported
// into another module, composite types only need to be imported as
@@ -1702,10 +1703,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() > 23) {
Specification = getMDOrNull(Record[23]);
}
+ // FIXME
+ if (Record.size() > 25)
+ BitStride = getMDOrNull(Record[25]);
}
- if (Record.size() > 25 && Record[25] != dwarf::DW_APPLE_ENUM_KIND_invalid)
- EnumKind = Record[25];
+ if (Record.size() > 24 && Record[24] != dwarf::DW_APPLE_ENUM_KIND_invalid)
+ EnumKind = Record[24];
DICompositeType *CT = nullptr;
if (Identifier)
@@ -1714,17 +1718,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
SizeInBits, AlignInBits, OffsetInBits, Specification,
NumExtraInhabitants, Flags, Elements, RuntimeLang, EnumKind,
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
- Allocated, Rank, Annotations);
+ Allocated, Rank, Annotations, BitStride);
// Create a node if we didn't get a lazy ODR type.
if (!CT)
- CT = GET_OR_DISTINCT(DICompositeType,
- (Context, Tag, Name, File, Line, Scope, BaseType,
- SizeInBits, AlignInBits, OffsetInBits, Flags,
- Elements, RuntimeLang, EnumKind, VTableHolder,
- TemplateParams, Identifier, Discriminator,
- DataLocation, Associated, Allocated, Rank,
- Annotations, Specification, NumExtraInhabitants));
+ CT = GET_OR_DISTINCT(
+ DICompositeType,
+ (Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
+ VTableHolder, TemplateParams, Identifier, Discriminator,
+ DataLocation, Associated, Allocated, Rank, Annotations,
+ Specification, NumExtraInhabitants, BitStride));
if (!IsNotUsedInTypeRef && Identifier)
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index f6510a7a1549d..09f893891fe49 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1990,6 +1990,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
Record.push_back(VE.getMetadataOrNullID(N->getRawSpecification()));
Record.push_back(
N->getEnumKind().value_or(dwarf::DW_APPLE_ENUM_KIND_invalid));
+ Record.push_back(VE.getMetadataOrNullID(N->getRawBitStride()));
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
Record.clear();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 383fbfb3fbd2b..081828ea358af 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1663,6 +1663,10 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
}
+ if (auto *BitStride = CTy->getBitStrideConst()) {
+ addUInt(Buffer, dwarf::DW_AT_bit_stride, {}, BitStride->getZExtValue());
+ }
+
// Emit the element type.
addType(Buffer, CTy->getBaseType());
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index ae68da0182dc4..74dff4f59cdbd 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2308,6 +2308,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
Printer.printDwarfEnum("enumKind", *EnumKind, dwarf::EnumKindString,
/*ShouldSkipZero=*/false);
+ Printer.printMetadata("bitStride", N->getRawBitStride());
Out << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index f127ca8d94295..9e7aea882c593 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -611,7 +611,7 @@ DICompositeType *DIBuilder::createArrayType(
PointerUnion<DIExpression *, DIVariable *> DL,
PointerUnion<DIExpression *, DIVariable *> AS,
PointerUnion<DIExpression *, DIVariable *> AL,
- PointerUnion<DIExpression *, DIVariable *> RK) {
+ PointerUnion<DIExpression *, DIVariable *> RK, Metadata *BitStride) {
auto *R = DICompositeType::get(
VMContext, dwarf::DW_TAG_array_type, Name, File, LineNumber,
getNonCompileUnitScope(Scope), Ty, Size, AlignInBits, 0, DINode::FlagZero,
@@ -623,7 +623,8 @@ DICompositeType *DIBuilder::createArrayType(
isa<DIExpression *>(AL) ? (Metadata *)cast<DIExpression *>(AL)
: (Metadata *)cast<DIVariable *>(AL),
isa<DIExpression *>(RK) ? (Metadata *)cast<DIExpression *>(RK)
- : (Metadata *)cast<DIVariable *>(RK));
+ : (Metadata *)cast<DIVariable *>(RK),
+ nullptr, nullptr, 0, BitStride);
trackIfUnresolved(R);
return R;
}
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index f975d4ca33ad9..ae3d79fc17a59 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -813,8 +813,8 @@ DICompositeType *DICompositeType::getImpl(
Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
- Metadata *Specification, uint32_t NumExtraInhabitants, StorageType Storage,
- bool ShouldCreate) {
+ Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride,
+ StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
// Keep this in sync with buildODRType.
@@ -823,11 +823,11 @@ DICompositeType *DICompositeType::getImpl(
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
- Annotations, Specification, NumExtraInhabitants));
+ Annotations, Specification, NumExtraInhabitants, BitStride));
Metadata *Ops[] = {File, Scope, Name, BaseType,
Elements, VTableHolder, TemplateParams, Identifier,
Discriminator, DataLocation, Associated, Allocated,
- Rank, Annotations, Specification};
+ Rank, Annotations, Specification, BitStride};
DEFINE_GETIMPL_STORE(DICompositeType,
(Tag, Line, RuntimeLang, SizeInBits, AlignInBits,
OffsetInBits, NumExtraInhabitants, EnumKind, Flags),
@@ -842,7 +842,7 @@ DICompositeType *DICompositeType::buildODRType(
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank, Metadata *Annotations) {
+ Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -853,7 +853,7 @@ DICompositeType *DICompositeType::buildODRType(
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
EnumKind, VTableHolder, TemplateParams, &Identifier,
Discriminator, DataLocation, Associated, Allocated, Rank,
- Annotations, Specification, NumExtraInhabitants);
+ Annotations, Specification, NumExtraInhabitants, BitStride);
if (CT->getTag() != Tag)
return nullptr;
@@ -868,7 +868,7 @@ DICompositeType *DICompositeType::buildODRType(
Metadata *Ops[] = {File, Scope, Name, BaseType,
Elements, VTableHolder, TemplateParams, &Identifier,
Discriminator, DataLocation, Associated, Allocated,
- Rank, Annotations, Specification};
+ 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)
@@ -885,7 +885,7 @@ DICompositeType *DICompositeType::getODRType(
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
- Metadata *Rank, Metadata *Annotations) {
+ Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
assert(!Identifier.getString().empty() && "Expected valid identifier");
if (!Context.isODRUniquingDebugTypes())
return nullptr;
@@ -896,7 +896,7 @@ DICompositeType *DICompositeType::getODRType(
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation,
Associated, Allocated, Rank, Annotations, Specification,
- NumExtraInhabitants);
+ NumExtraInhabitants, BitStride);
} else {
if (CT->getTag() != Tag)
return nullptr;
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 72ea3104cc7d5..a18cf...
[truncated]
|
In Ada, an array can be packed and the elements can take less space than their natural object size. For example, for this type: type Packed_Array is array (4 .. 8) of Boolean; pragma pack (Packed_Array); ... each element of the array occupies a single bit, even though the "natural" size for a Boolean in memory is a byte. In DWARF, this is represented by putting a DW_AT_bit_stride onto the array type itself. This patch adds a bit stride to DICompositeType so that gnat-llvm can emit DWARF for these sorts of arrays.
d8955fa
to
90e9554
Compare
This new version rebases on top of the recently-committed bug fix that was separated out, and also removes a stray "FIXME" that I'd left in from when I tripped over that buglet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes LGTM.
The only thing I'm wondering is if we need this also in DIBasicType or other parts of the type graph?
I am not sure yet. I have a pretty long list of DWARF issues with Ada and I'm working my way through them incrementally. I know the Ada compiler can produce wrapper types when the value is narrower than the allocated object. However these are currently done in the front end and communicated to the debugger via a specially-named struct wrapper... I'd like to change this but it's a fairly low priority considering that it already works. I'm not sure if there are other cases to consider. |
The only thing we might consider is if it makes sense to store it in a common base class instead. But we can also revisit that decision if we actually need it later ... |
This has been approved, could someone please merge it? Thank you. |
In Ada, an array can be packed and the elements can take less space than their natural object size. For example, for this type:
type Packed_Array is array (4 .. 8) of Boolean;
pragma pack (Packed_Array);
... each element of the array occupies a single bit, even though the "natural" size for a Boolean in memory is a byte.
In DWARF, this is represented by putting a DW_AT_bit_stride onto the array type itself.
This patch adds a bit stride to DICompositeType so that gnat-llvm can emit DWARF for these sorts of arrays.