[clang] [llvm] Non constant size and offset in DWARF (PR #141106)
Tom Tromey via cfe-commits
cfe-commits at lists.llvm.org
Wed May 28 11:17:06 PDT 2025
https://github.com/tromey updated https://github.com/llvm/llvm-project/pull/141106
>From cfe92c4b3a70db136de8e82a4fa0d8b11c5e57fe Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey at adacore.com>
Date: Wed, 14 May 2025 09:10:54 -0600
Subject: [PATCH 1/4] Make it simpler to add metadata to DIType
This patch changes code in DebugInfoMetadata.h to use symbolic
constants to refer to metadata slots. This makes it a little simpler
(but still not entirely seamless) to add metadata to DIType.
---
llvm/include/llvm/IR/DebugInfoMetadata.h | 106 ++++++++++++++++-------
1 file changed, 76 insertions(+), 30 deletions(-)
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index d82c69aebb026..9d0fd99ff035e 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -716,6 +716,8 @@ class DIType : public DIScope {
uint32_t NumExtraInhabitants;
protected:
+ static constexpr unsigned N_OPERANDS = 3;
+
DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags,
@@ -1042,6 +1044,8 @@ class DIStringType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
+ static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS;
+
unsigned Encoding;
DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
@@ -1117,11 +1121,15 @@ class DIStringType : public DIType {
unsigned getEncoding() const { return Encoding; }
- Metadata *getRawStringLength() const { return getOperand(3); }
+ Metadata *getRawStringLength() const { return getOperand(MY_FIRST_OPERAND); }
- Metadata *getRawStringLengthExp() const { return getOperand(4); }
+ Metadata *getRawStringLengthExp() const {
+ return getOperand(MY_FIRST_OPERAND + 1);
+ }
- Metadata *getRawStringLocationExp() const { return getOperand(5); }
+ Metadata *getRawStringLocationExp() const {
+ return getOperand(MY_FIRST_OPERAND + 2);
+ }
};
/// Derived types.
@@ -1163,6 +1171,8 @@ class DIDerivedType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
+ static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS;
+
/// The DWARF address space of the memory pointed to or referenced by a
/// pointer or reference type respectively.
std::optional<unsigned> DWARFAddressSpace;
@@ -1239,7 +1249,7 @@ class DIDerivedType : public DIType {
/// Get the base type this is derived from.
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
- Metadata *getRawBaseType() const { return getOperand(3); }
+ Metadata *getRawBaseType() const { return getOperand(MY_FIRST_OPERAND); }
/// \returns The DWARF address space of the memory pointed to or referenced by
/// a pointer or reference type respectively.
@@ -1258,7 +1268,7 @@ class DIDerivedType : public DIType {
/// TODO: Separate out types that need this extra operand: pointer-to-member
/// types and member fields (static members and ivars).
Metadata *getExtraData() const { return getRawExtraData(); }
- Metadata *getRawExtraData() const { return getOperand(4); }
+ Metadata *getRawExtraData() const { return getOperand(MY_FIRST_OPERAND + 1); }
/// Get the template parameters from a template alias.
DITemplateParameterArray getTemplateParams() const {
@@ -1269,7 +1279,9 @@ class DIDerivedType : public DIType {
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
- Metadata *getRawAnnotations() const { return getOperand(5); }
+ Metadata *getRawAnnotations() const {
+ return getOperand(MY_FIRST_OPERAND + 2);
+ }
/// Get casted version of extra data.
/// @{
@@ -1313,6 +1325,8 @@ class DISubrangeType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
+ static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS;
+
DISubrangeType(LLVMContext &C, StorageType Storage, unsigned Line,
uint64_t SizeInBits, uint32_t AlignInBits, DIFlags Flags,
ArrayRef<Metadata *> Ops);
@@ -1367,15 +1381,23 @@ class DISubrangeType : public DIType {
/// Get the base type this is derived from.
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
- Metadata *getRawBaseType() const { return getOperand(3); }
+ Metadata *getRawBaseType() const { return getOperand(MY_FIRST_OPERAND); }
- Metadata *getRawLowerBound() const { return getOperand(4).get(); }
+ Metadata *getRawLowerBound() const {
+ return getOperand(MY_FIRST_OPERAND + 1).get();
+ }
- Metadata *getRawUpperBound() const { return getOperand(5).get(); }
+ Metadata *getRawUpperBound() const {
+ return getOperand(MY_FIRST_OPERAND + 2).get();
+ }
- Metadata *getRawStride() const { return getOperand(6).get(); }
+ Metadata *getRawStride() const {
+ return getOperand(MY_FIRST_OPERAND + 3).get();
+ }
- Metadata *getRawBias() const { return getOperand(7).get(); }
+ Metadata *getRawBias() const {
+ return getOperand(MY_FIRST_OPERAND + 4).get();
+ }
BoundType getLowerBound() const {
return convertRawToBound(getRawLowerBound());
@@ -1402,6 +1424,8 @@ class DICompositeType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
+ static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS;
+
unsigned RuntimeLang;
std::optional<uint32_t> EnumKind;
@@ -1563,41 +1587,55 @@ class DICompositeType : public DIType {
DITemplateParameterArray getTemplateParams() const {
return cast_or_null<MDTuple>(getRawTemplateParams());
}
- StringRef getIdentifier() const { return getStringOperand(7); }
+ StringRef getIdentifier() const {
+ return getStringOperand(MY_FIRST_OPERAND + 4);
+ }
unsigned getRuntimeLang() const { return RuntimeLang; }
std::optional<uint32_t> getEnumKind() const { return EnumKind; }
- Metadata *getRawBaseType() const { return getOperand(3); }
- Metadata *getRawElements() const { return getOperand(4); }
- Metadata *getRawVTableHolder() const { return getOperand(5); }
- Metadata *getRawTemplateParams() const { return getOperand(6); }
- MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
- Metadata *getRawDiscriminator() const { return getOperand(8); }
+ Metadata *getRawBaseType() const { return getOperand(MY_FIRST_OPERAND); }
+ Metadata *getRawElements() const { return getOperand(MY_FIRST_OPERAND + 1); }
+ Metadata *getRawVTableHolder() const {
+ return getOperand(MY_FIRST_OPERAND + 2);
+ }
+ Metadata *getRawTemplateParams() const {
+ return getOperand(MY_FIRST_OPERAND + 3);
+ }
+ MDString *getRawIdentifier() const {
+ return getOperandAs<MDString>(MY_FIRST_OPERAND + 4);
+ }
+ Metadata *getRawDiscriminator() const {
+ return getOperand(MY_FIRST_OPERAND + 5);
+ }
DIDerivedType *getDiscriminator() const {
- return getOperandAs<DIDerivedType>(8);
+ return getOperandAs<DIDerivedType>(MY_FIRST_OPERAND + 5);
+ }
+ Metadata *getRawDataLocation() const {
+ return getOperand(MY_FIRST_OPERAND + 6);
}
- Metadata *getRawDataLocation() const { return getOperand(9); }
DIVariable *getDataLocation() const {
return dyn_cast_or_null<DIVariable>(getRawDataLocation());
}
DIExpression *getDataLocationExp() const {
return dyn_cast_or_null<DIExpression>(getRawDataLocation());
}
- Metadata *getRawAssociated() const { return getOperand(10); }
+ Metadata *getRawAssociated() const {
+ return getOperand(MY_FIRST_OPERAND + 7);
+ }
DIVariable *getAssociated() const {
return dyn_cast_or_null<DIVariable>(getRawAssociated());
}
DIExpression *getAssociatedExp() const {
return dyn_cast_or_null<DIExpression>(getRawAssociated());
}
- Metadata *getRawAllocated() const { return getOperand(11); }
+ Metadata *getRawAllocated() const { return getOperand(MY_FIRST_OPERAND + 8); }
DIVariable *getAllocated() const {
return dyn_cast_or_null<DIVariable>(getRawAllocated());
}
DIExpression *getAllocatedExp() const {
return dyn_cast_or_null<DIExpression>(getRawAllocated());
}
- Metadata *getRawRank() const { return getOperand(12); }
+ Metadata *getRawRank() const { return getOperand(MY_FIRST_OPERAND + 9); }
ConstantInt *getRankConst() const {
if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
return dyn_cast_or_null<ConstantInt>(MD->getValue());
@@ -1607,17 +1645,23 @@ class DICompositeType : public DIType {
return dyn_cast_or_null<DIExpression>(getRawRank());
}
- Metadata *getRawAnnotations() const { return getOperand(13); }
+ Metadata *getRawAnnotations() const {
+ return getOperand(MY_FIRST_OPERAND + 10);
+ }
DINodeArray getAnnotations() const {
return cast_or_null<MDTuple>(getRawAnnotations());
}
- Metadata *getRawSpecification() const { return getOperand(14); }
+ Metadata *getRawSpecification() const {
+ return getOperand(MY_FIRST_OPERAND + 11);
+ }
DIType *getSpecification() const {
return cast_or_null<DIType>(getRawSpecification());
}
- Metadata *getRawBitStride() const { return getOperand(15); }
+ Metadata *getRawBitStride() const {
+ return getOperand(MY_FIRST_OPERAND + 12);
+ }
ConstantInt *getBitStrideConst() const {
if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawBitStride()))
return dyn_cast_or_null<ConstantInt>(MD->getValue());
@@ -1636,15 +1680,15 @@ class DICompositeType : public DIType {
assert(is_contained(Elements->operands(), Op) &&
"Lost a member during member list replacement");
#endif
- replaceOperandWith(4, Elements.get());
+ replaceOperandWith(MY_FIRST_OPERAND + 1, Elements.get());
}
void replaceVTableHolder(DIType *VTableHolder) {
- replaceOperandWith(5, VTableHolder);
+ replaceOperandWith(MY_FIRST_OPERAND + 2, VTableHolder);
}
void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
- replaceOperandWith(6, TemplateParams.get());
+ replaceOperandWith(MY_FIRST_OPERAND + 3, TemplateParams.get());
}
/// @}
@@ -1660,6 +1704,8 @@ class DISubroutineType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;
+ static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS;
+
/// The calling convention used with DW_AT_calling_convention. Actually of
/// type dwarf::CallingConvention.
uint8_t CC;
@@ -1705,7 +1751,7 @@ class DISubroutineType : public DIType {
return cast_or_null<MDTuple>(getRawTypeArray());
}
- Metadata *getRawTypeArray() const { return getOperand(3); }
+ Metadata *getRawTypeArray() const { return getOperand(MY_FIRST_OPERAND); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DISubroutineTypeKind;
>From bc0042cd9e989c1bc4dbdbe85b6829b92905a835 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey at adacore.com>
Date: Wed, 14 May 2025 10:47:24 -0600
Subject: [PATCH 2/4] Use metadata for size and offset in DIType
This changes DIType to use metadata for the size and offset
information. This patch doesn't have any functional changes yet; the
test is in the next patch.
---
clang/lib/CodeGen/CGDebugInfo.cpp | 4 +-
llvm/include/llvm/IR/DebugInfoMetadata.h | 393 ++++++++++++++----
llvm/lib/AsmParser/LLParser.cpp | 110 +++--
llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 95 ++++-
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 35 +-
llvm/lib/IR/DIBuilder.cpp | 46 +-
llvm/lib/IR/DebugInfoMetadata.cpp | 101 +++--
llvm/lib/IR/LLVMContextImpl.h | 76 ++--
llvm/lib/IR/Verifier.cpp | 18 +
.../unittests/IR/DebugTypeODRUniquingTest.cpp | 6 +-
10 files changed, 622 insertions(+), 262 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 5772c07154144..775f759294e82 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -834,8 +834,8 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
ObjTy = DBuilder.createStructType(TheCU, "objc_object", TheCU->getFile(), 0,
- 0, 0, llvm::DINode::FlagZero, nullptr,
- llvm::DINodeArray());
+ (uint64_t)0, 0, llvm::DINode::FlagZero,
+ nullptr, llvm::DINodeArray());
DBuilder.replaceArrays(
ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 9d0fd99ff035e..f8343e8310780 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -711,42 +711,33 @@ std::optional<StringRef> DIScope::getSource() const {
class DIType : public DIScope {
unsigned Line;
DIFlags Flags;
- uint64_t SizeInBits;
- uint64_t OffsetInBits;
uint32_t NumExtraInhabitants;
protected:
- static constexpr unsigned N_OPERANDS = 3;
+ static constexpr unsigned N_OPERANDS = 5;
DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
- unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags,
- ArrayRef<Metadata *> Ops)
+ unsigned Line, uint32_t AlignInBits, uint32_t NumExtraInhabitants,
+ DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIScope(C, ID, Storage, Tag, Ops) {
- init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants,
- Flags);
+ init(Line, AlignInBits, NumExtraInhabitants, Flags);
}
~DIType() = default;
- void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, uint32_t NumExtraInhabitants,
+ void init(unsigned Line, uint32_t AlignInBits, uint32_t NumExtraInhabitants,
DIFlags Flags) {
this->Line = Line;
this->Flags = Flags;
- this->SizeInBits = SizeInBits;
this->SubclassData32 = AlignInBits;
- this->OffsetInBits = OffsetInBits;
this->NumExtraInhabitants = NumExtraInhabitants;
}
/// Change fields in place.
- void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits,
+ void mutate(unsigned Tag, unsigned Line, uint32_t AlignInBits,
uint32_t NumExtraInhabitants, DIFlags Flags) {
assert(isDistinct() && "Only distinct nodes can mutate");
setTag(Tag);
- init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants,
- Flags);
+ init(Line, AlignInBits, NumExtraInhabitants, Flags);
}
public:
@@ -755,10 +746,8 @@ class DIType : public DIScope {
}
unsigned getLine() const { return Line; }
- uint64_t getSizeInBits() const { return SizeInBits; }
uint32_t getAlignInBits() const;
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
- uint64_t getOffsetInBits() const { return OffsetInBits; }
uint32_t getNumExtraInhabitants() const { return NumExtraInhabitants; }
DIFlags getFlags() const { return Flags; }
@@ -768,6 +757,26 @@ class DIType : public DIScope {
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ Metadata *getRawSizeInBits() const { return getOperand(3); }
+ uint64_t getSizeInBits() const {
+ if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawSizeInBits())) {
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(MD->getValue())) {
+ return CI->getZExtValue();
+ }
+ }
+ return 0;
+ }
+
+ Metadata *getRawOffsetInBits() const { return getOperand(4); }
+ uint64_t getOffsetInBits() const {
+ if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawOffsetInBits())) {
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(MD->getValue())) {
+ return CI->getZExtValue();
+ }
+ }
+ return 0;
+ }
+
/// Returns a new temporary DIType with updated Flags
TempDIType cloneWithFlags(DIFlags NewFlags) const {
auto NewTy = clone();
@@ -833,18 +842,18 @@ class DIBasicType : public DIType {
protected:
DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
ArrayRef<Metadata *> Ops)
- : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
+ : DIType(C, DIBasicTypeKind, Storage, Tag, 0, AlignInBits,
NumExtraInhabitants, Flags, Ops),
Encoding(Encoding) {}
DIBasicType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
ArrayRef<Metadata *> Ops)
- : DIType(C, ID, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
- NumExtraInhabitants, Flags, Ops),
+ : DIType(C, ID, Storage, Tag, 0, AlignInBits, NumExtraInhabitants, Flags,
+ Ops),
Encoding(Encoding) {}
~DIBasicType() = default;
@@ -861,11 +870,21 @@ class DIBasicType : public DIType {
MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
+ StorageType Storage, bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ return getImpl(Context, Tag, Name, SizeInBitsNode, AlignInBits, Encoding,
+ NumExtraInhabitants, Flags, Storage, ShouldCreate);
+ }
+ static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding,
+ uint32_t NumExtraInhabitants, DIFlags Flags,
StorageType Storage, bool ShouldCreate = true);
TempDIBasicType cloneImpl() const {
- return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
- getAlignInBits(), getEncoding(),
+ return getTemporary(getContext(), getTag(), getRawName(),
+ getRawSizeInBits(), getAlignInBits(), getEncoding(),
getNumExtraInhabitants(), getFlags());
}
@@ -898,6 +917,12 @@ class DIBasicType : public DIType {
uint32_t NumExtraInhabitants, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding,
NumExtraInhabitants, Flags))
+ DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, MDString *Name, Metadata *SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding,
+ uint32_t NumExtraInhabitants, DIFlags Flags),
+ (Tag, Name, SizeInBits, AlignInBits, Encoding,
+ NumExtraInhabitants, Flags))
TempDIBasicType clone() const { return cloneImpl(); }
@@ -929,29 +954,28 @@ class DIFixedPointType : public DIBasicType {
APInt Denominator;
DIFixedPointType(LLVMContext &C, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
- DIFlags Flags, unsigned Kind, int Factor,
- ArrayRef<Metadata *> Ops)
- : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, SizeInBits,
- AlignInBits, Encoding, 0, Flags, Ops),
+ uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
+ unsigned Kind, int Factor, ArrayRef<Metadata *> Ops)
+ : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits,
+ Encoding, 0, Flags, Ops),
Kind(Kind), Factor(Factor) {
assert(Kind == FixedPointBinary || Kind == FixedPointDecimal);
}
DIFixedPointType(LLVMContext &C, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
- DIFlags Flags, unsigned Kind, APInt Numerator,
- APInt Denominator, ArrayRef<Metadata *> Ops)
- : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, SizeInBits,
- AlignInBits, Encoding, 0, Flags, Ops),
+ uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
+ unsigned Kind, APInt Numerator, APInt Denominator,
+ ArrayRef<Metadata *> Ops)
+ : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits,
+ Encoding, 0, Flags, Ops),
Kind(Kind), Factor(0), Numerator(Numerator), Denominator(Denominator) {
assert(Kind == FixedPointRational);
}
DIFixedPointType(LLVMContext &C, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
- DIFlags Flags, unsigned Kind, int Factor, APInt Numerator,
+ uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
+ unsigned Kind, int Factor, APInt Numerator,
APInt Denominator, ArrayRef<Metadata *> Ops)
- : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, SizeInBits,
- AlignInBits, Encoding, 0, Flags, Ops),
+ : DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits,
+ Encoding, 0, Flags, Ops),
Kind(Kind), Factor(Factor), Numerator(Numerator),
Denominator(Denominator) {}
~DIFixedPointType() = default;
@@ -961,20 +985,42 @@ class DIFixedPointType : public DIBasicType {
uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
DIFlags Flags, unsigned Kind, int Factor, APInt Numerator,
APInt Denominator, StorageType Storage, bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
+ SizeInBitsNode, AlignInBits, Encoding, Flags, Kind, Factor,
+ Numerator, Denominator, Storage, ShouldCreate);
+ }
+ static DIFixedPointType *
+ getImpl(LLVMContext &Context, unsigned Tag, StringRef Name,
+ Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ DIFlags Flags, unsigned Kind, int Factor, APInt Numerator,
+ APInt Denominator, StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
SizeInBits, AlignInBits, Encoding, Flags, Kind, Factor,
Numerator, Denominator, Storage, ShouldCreate);
}
static DIFixedPointType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ uint32_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ DIFlags Flags, unsigned Kind, int Factor, APInt Numerator,
+ APInt Denominator, StorageType Storage, bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ return getImpl(Context, Tag, Name, SizeInBitsNode, AlignInBits, Encoding,
+ Flags, Kind, Factor, Numerator, Denominator, Storage,
+ ShouldCreate);
+ }
+ static DIFixedPointType *
+ getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
+ Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding,
DIFlags Flags, unsigned Kind, int Factor, APInt Numerator,
APInt Denominator, StorageType Storage, bool ShouldCreate = true);
TempDIFixedPointType cloneImpl() const {
- return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
- getAlignInBits(), getEncoding(), getFlags(), Kind,
- Factor, Numerator, Denominator);
+ return getTemporary(getContext(), getTag(), getRawName(),
+ getRawSizeInBits(), getAlignInBits(), getEncoding(),
+ getFlags(), Kind, Factor, Numerator, Denominator);
}
public:
@@ -1005,6 +1051,13 @@ class DIFixedPointType : public DIBasicType {
APInt Denominator),
(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, Kind,
Factor, Numerator, Denominator))
+ DEFINE_MDNODE_GET(DIFixedPointType,
+ (unsigned Tag, MDString *Name, Metadata *SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
+ unsigned Kind, int Factor, APInt Numerator,
+ APInt Denominator),
+ (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags, Kind,
+ Factor, Numerator, Denominator))
TempDIFixedPointType clone() const { return cloneImpl(); }
@@ -1049,10 +1102,10 @@ class DIStringType : public DIType {
unsigned Encoding;
DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ uint32_t AlignInBits, unsigned Encoding,
ArrayRef<Metadata *> Ops)
- : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
- 0, FlagZero, Ops),
+ : DIType(C, DIStringTypeKind, Storage, Tag, 0, AlignInBits, 0, FlagZero,
+ Ops),
Encoding(Encoding) {}
~DIStringType() = default;
@@ -1062,8 +1115,10 @@ class DIStringType : public DIType {
uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding, StorageType Storage,
bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
- StringLength, StrLenExp, StrLocationExp, SizeInBits,
+ StringLength, StrLenExp, StrLocationExp, SizeInBitsNode,
AlignInBits, Encoding, Storage, ShouldCreate);
}
static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
@@ -1071,12 +1126,24 @@ class DIStringType : public DIType {
Metadata *StrLenExp, Metadata *StrLocationExp,
uint64_t SizeInBits, uint32_t AlignInBits,
unsigned Encoding, StorageType Storage,
+ bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ return getImpl(Context, Tag, Name, StringLength, StrLenExp, StrLocationExp,
+ SizeInBitsNode, AlignInBits, Encoding, Storage,
+ ShouldCreate);
+ }
+ static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *StringLength,
+ Metadata *StrLenExp, Metadata *StrLocationExp,
+ Metadata *SizeInBits, uint32_t AlignInBits,
+ unsigned Encoding, StorageType Storage,
bool ShouldCreate = true);
TempDIStringType cloneImpl() const {
return getTemporary(getContext(), getTag(), getRawName(),
getRawStringLength(), getRawStringLengthExp(),
- getRawStringLocationExp(), getSizeInBits(),
+ getRawStringLocationExp(), getRawSizeInBits(),
getAlignInBits(), getEncoding());
}
@@ -1100,6 +1167,13 @@ class DIStringType : public DIType {
unsigned Encoding),
(Tag, Name, StringLength, StringLengthExp,
StringLocationExp, SizeInBits, AlignInBits, Encoding))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp, Metadata *StringLocationExp,
+ Metadata *SizeInBits, uint32_t AlignInBits,
+ unsigned Encoding),
+ (Tag, Name, StringLength, StringLengthExp,
+ StringLocationExp, SizeInBits, AlignInBits, Encoding))
TempDIStringType clone() const { return cloneImpl(); }
@@ -1178,13 +1252,12 @@ class DIDerivedType : public DIType {
std::optional<unsigned> DWARFAddressSpace;
DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
- unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits,
+ unsigned Line, uint32_t AlignInBits,
std::optional<unsigned> DWARFAddressSpace,
std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
ArrayRef<Metadata *> Ops)
- : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
- AlignInBits, OffsetInBits, 0, Flags, Ops),
+ : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, AlignInBits, 0, Flags,
+ Ops),
DWARFAddressSpace(DWARFAddressSpace) {
if (PtrAuthData)
SubclassData32 = PtrAuthData->RawData;
@@ -1198,6 +1271,40 @@ class DIDerivedType : public DIType {
std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
Metadata *ExtraData, DINodeArray Annotations, StorageType Storage,
bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ auto *OffsetInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits));
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
+ Line, Scope, BaseType, SizeInBitsNode, AlignInBits,
+ OffsetInBitsNode, DWARFAddressSpace, PtrAuthData, Flags,
+ ExtraData, Annotations.get(), Storage, ShouldCreate);
+ }
+ static DIDerivedType *
+ getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, DIFile *File,
+ unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits,
+ std::optional<unsigned> DWARFAddressSpace,
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
+ Metadata *ExtraData, DINodeArray Annotations, StorageType Storage,
+ bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ auto *OffsetInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits));
+ return getImpl(Context, Tag, Name, File, Line, Scope, BaseType,
+ SizeInBitsNode, AlignInBits, OffsetInBitsNode,
+ DWARFAddressSpace, PtrAuthData, Flags, ExtraData,
+ Annotations.get(), Storage, ShouldCreate);
+ }
+ static DIDerivedType *
+ getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
+ unsigned Line, DIScope *Scope, DIType *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits,
+ std::optional<unsigned> DWARFAddressSpace,
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
+ Metadata *ExtraData, DINodeArray Annotations, StorageType Storage,
+ bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
DWARFAddressSpace, PtrAuthData, Flags, ExtraData,
@@ -1206,26 +1313,26 @@ class DIDerivedType : public DIType {
static 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,
+ 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 = true);
TempDIDerivedType cloneImpl() const {
- return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
- getScope(), getBaseType(), getSizeInBits(),
- getAlignInBits(), getOffsetInBits(),
- getDWARFAddressSpace(), getPtrAuthData(), getFlags(),
- getExtraData(), getAnnotations());
+ return getTemporary(
+ getContext(), getTag(), getRawName(), getFile(), getLine(), getScope(),
+ getBaseType(), getRawSizeInBits(), getAlignInBits(),
+ getRawOffsetInBits(), getDWARFAddressSpace(), getPtrAuthData(),
+ getFlags(), getExtraData(), getRawAnnotations());
}
public:
DEFINE_MDNODE_GET(DIDerivedType,
(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,
std::optional<unsigned> DWARFAddressSpace,
std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
Metadata *ExtraData = nullptr,
@@ -1233,6 +1340,28 @@ class DIDerivedType : public DIType {
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData,
Flags, ExtraData, Annotations))
+ DEFINE_MDNODE_GET(DIDerivedType,
+ (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+ DIScope *Scope, DIType *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits,
+ std::optional<unsigned> DWARFAddressSpace,
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
+ Metadata *ExtraData = nullptr,
+ DINodeArray Annotations = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData,
+ Flags, ExtraData, Annotations))
+ DEFINE_MDNODE_GET(DIDerivedType,
+ (unsigned Tag, MDString *Name, DIFile *File, unsigned Line,
+ DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits,
+ std::optional<unsigned> DWARFAddressSpace,
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
+ Metadata *ExtraData = nullptr,
+ DINodeArray Annotations = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData,
+ Flags, ExtraData, Annotations))
DEFINE_MDNODE_GET(DIDerivedType,
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
@@ -1328,8 +1457,7 @@ class DISubrangeType : public DIType {
static constexpr unsigned MY_FIRST_OPERAND = DIType::N_OPERANDS;
DISubrangeType(LLVMContext &C, StorageType Storage, unsigned Line,
- uint64_t SizeInBits, uint32_t AlignInBits, DIFlags Flags,
- ArrayRef<Metadata *> Ops);
+ uint32_t AlignInBits, DIFlags Flags, ArrayRef<Metadata *> Ops);
~DISubrangeType() = default;
@@ -1339,22 +1467,24 @@ class DISubrangeType : public DIType {
DIFlags Flags, DIType *BaseType, Metadata *LowerBound,
Metadata *UpperBound, Metadata *Stride, Metadata *Bias,
StorageType Storage, bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
- Scope, SizeInBits, AlignInBits, Flags, BaseType, LowerBound,
- UpperBound, Stride, Bias, Storage, ShouldCreate);
+ Scope, SizeInBitsNode, AlignInBits, Flags, BaseType,
+ LowerBound, UpperBound, Stride, Bias, Storage, ShouldCreate);
}
static DISubrangeType *getImpl(LLVMContext &Context, MDString *Name,
Metadata *File, unsigned Line, Metadata *Scope,
- uint64_t SizeInBits, uint32_t AlignInBits,
+ Metadata *SizeInBits, uint32_t AlignInBits,
DIFlags Flags, Metadata *BaseType,
Metadata *LowerBound, Metadata *UpperBound,
Metadata *Stride, Metadata *Bias,
StorageType Storage, bool ShouldCreate = true);
TempDISubrangeType cloneImpl() const {
- return getTemporary(getContext(), getName(), getFile(), getLine(),
- getScope(), getSizeInBits(), getAlignInBits(),
+ return getTemporary(getContext(), getRawName(), getFile(), getLine(),
+ getScope(), getRawSizeInBits(), getAlignInBits(),
getFlags(), getBaseType(), getRawLowerBound(),
getRawUpperBound(), getRawStride(), getRawBias());
}
@@ -1364,9 +1494,10 @@ class DISubrangeType : public DIType {
public:
DEFINE_MDNODE_GET(DISubrangeType,
(MDString * Name, Metadata *File, unsigned Line,
- Metadata *Scope, uint64_t SizeInBits, uint32_t AlignInBits,
- DIFlags Flags, Metadata *BaseType, Metadata *LowerBound,
- Metadata *UpperBound, Metadata *Stride, Metadata *Bias),
+ Metadata *Scope, Metadata *SizeInBits,
+ uint32_t AlignInBits, DIFlags Flags, Metadata *BaseType,
+ Metadata *LowerBound, Metadata *UpperBound,
+ Metadata *Stride, Metadata *Bias),
(Name, File, Line, Scope, SizeInBits, AlignInBits, Flags,
BaseType, LowerBound, UpperBound, Stride, Bias))
DEFINE_MDNODE_GET(DISubrangeType,
@@ -1430,27 +1561,24 @@ class DICompositeType : public DIType {
std::optional<uint32_t> EnumKind;
DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
- unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Line, unsigned RuntimeLang, uint32_t AlignInBits,
uint32_t NumExtraInhabitants,
std::optional<uint32_t> EnumKind, DIFlags Flags,
ArrayRef<Metadata *> Ops)
- : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
- AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops),
+ : DIType(C, DICompositeTypeKind, Storage, Tag, Line, AlignInBits,
+ NumExtraInhabitants, Flags, Ops),
RuntimeLang(RuntimeLang), EnumKind(EnumKind) {}
~DICompositeType() = default;
/// Change fields in place.
void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
- uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
- uint32_t NumExtraInhabitants, std::optional<uint32_t> EnumKind,
- DIFlags Flags) {
+ uint32_t AlignInBits, uint32_t NumExtraInhabitants,
+ std::optional<uint32_t> EnumKind, DIFlags Flags) {
assert(isDistinct() && "Only distinct nodes can mutate");
assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
this->RuntimeLang = RuntimeLang;
this->EnumKind = EnumKind;
- DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
- NumExtraInhabitants, Flags);
+ DIType::mutate(Tag, Line, AlignInBits, NumExtraInhabitants, Flags);
}
static DICompositeType *
@@ -1464,6 +1592,52 @@ class DICompositeType : public DIType {
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
Metadata *Rank, DINodeArray Annotations, Metadata *BitStride,
StorageType Storage, bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ auto *OffsetInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits));
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
+ Line, Scope, BaseType, SizeInBitsNode, AlignInBits,
+ OffsetInBitsNode, 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,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
+ DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
+ std::optional<uint32_t> EnumKind, Metadata *VTableHolder,
+ Metadata *TemplateParams, MDString *Identifier,
+ Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
+ Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
+ Metadata *Specification, uint32_t NumExtraInhabitants,
+ Metadata *BitStride, StorageType Storage, bool ShouldCreate = true) {
+ auto *SizeInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), SizeInBits));
+ auto *OffsetInBitsNode = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), OffsetInBits));
+ return getImpl(Context, Tag, Name, File, Line, Scope, BaseType,
+ SizeInBitsNode, AlignInBits, OffsetInBitsNode, Flags,
+ Elements, RuntimeLang, EnumKind, VTableHolder,
+ TemplateParams, Identifier, Discriminator, DataLocation,
+ Associated, Allocated, Rank, Annotations, Specification,
+ NumExtraInhabitants, BitStride, Storage, ShouldCreate);
+ }
+ static DICompositeType *
+ getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
+ unsigned Line, DIScope *Scope, DIType *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits, DIType *Specification,
+ uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements,
+ unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
+ DIType *VTableHolder, DITemplateParameterArray TemplateParams,
+ StringRef Identifier, DIDerivedType *Discriminator,
+ Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
+ 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(),
@@ -1475,7 +1649,7 @@ class DICompositeType : public DIType {
static 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,
+ Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
std::optional<uint32_t> EnumKind, Metadata *VTableHolder,
Metadata *TemplateParams, MDString *Identifier,
@@ -1486,13 +1660,14 @@ class DICompositeType : public DIType {
TempDICompositeType cloneImpl() const {
return getTemporary(
- getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
- getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
- getFlags(), getElements(), getRuntimeLang(), getEnumKind(),
- getVTableHolder(), getTemplateParams(), getIdentifier(),
- getDiscriminator(), getRawDataLocation(), getRawAssociated(),
- getRawAllocated(), getRawRank(), getAnnotations(), getSpecification(),
- getNumExtraInhabitants(), getRawBitStride());
+ getContext(), getTag(), getRawName(), getFile(), getLine(), getScope(),
+ getBaseType(), getRawSizeInBits(), getAlignInBits(),
+ getRawOffsetInBits(), getFlags(), getRawElements(), getRuntimeLang(),
+ getEnumKind(), getVTableHolder(), getRawTemplateParams(),
+ getRawIdentifier(), getDiscriminator(), getRawDataLocation(),
+ getRawAssociated(), getRawAllocated(), getRawRank(),
+ getRawAnnotations(), getSpecification(), getNumExtraInhabitants(),
+ getRawBitStride());
}
public:
@@ -1532,6 +1707,42 @@ class DICompositeType : public DIType {
TemplateParams, Identifier, Discriminator, DataLocation, Associated,
Allocated, Rank, Annotations, Specification, NumExtraInhabitants,
BitStride))
+ DEFINE_MDNODE_GET(
+ DICompositeType,
+ (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+ DIScope *Scope, DIType *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags,
+ DINodeArray Elements, unsigned RuntimeLang,
+ std::optional<uint32_t> EnumKind, DIType *VTableHolder,
+ DITemplateParameterArray TemplateParams = nullptr,
+ StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
+ Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
+ Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
+ DINodeArray Annotations = nullptr, DIType *Specification = nullptr,
+ 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,
+ BitStride))
+ DEFINE_MDNODE_GET(
+ DICompositeType,
+ (unsigned Tag, MDString *Name, Metadata *File, 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 = nullptr, MDString *Identifier = nullptr,
+ 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 *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,
+ BitStride))
TempDICompositeType clone() const { return cloneImpl(); }
@@ -1545,8 +1756,8 @@ class DICompositeType : public DIType {
static 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 *Specification,
+ Metadata *BaseType, 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,
@@ -1568,8 +1779,8 @@ class DICompositeType : public DIType {
static 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 *Specification,
+ Metadata *BaseType, 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,
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 7acea6f477b24..f6fc1796d7362 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -4821,6 +4821,35 @@ struct MDSignedOrMDField : MDEitherFieldImpl<MDSignedField, MDField> {
}
};
+struct MDUnsignedOrMDField : MDEitherFieldImpl<MDUnsignedField, MDField> {
+ MDUnsignedOrMDField(uint64_t Default = 0, bool AllowNull = true)
+ : ImplTy(MDUnsignedField(Default), MDField(AllowNull)) {}
+
+ MDUnsignedOrMDField(uint64_t Default, uint64_t Max, bool AllowNull = true)
+ : ImplTy(MDUnsignedField(Default, Max), MDField(AllowNull)) {}
+
+ bool isMDUnsignedField() const { return WhatIs == IsTypeA; }
+ bool isMDField() const { return WhatIs == IsTypeB; }
+ uint64_t getMDUnsignedValue() const {
+ assert(isMDUnsignedField() && "Wrong field type");
+ return A.Val;
+ }
+ Metadata *getMDFieldValue() const {
+ assert(isMDField() && "Wrong field type");
+ return B.Val;
+ }
+
+ Metadata *getValueAsMetadata(LLVMContext &Context) const {
+ if (isMDUnsignedField()) {
+ return ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), getMDUnsignedValue()));
+ } else if (isMDField()) {
+ return getMDFieldValue();
+ }
+ return nullptr;
+ }
+};
+
} // end anonymous namespace
namespace llvm {
@@ -5204,6 +5233,29 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
return true;
}
+template <>
+bool LLParser::parseMDField(LocTy Loc, StringRef Name,
+ MDUnsignedOrMDField &Result) {
+ // Try to parse an unsigned int.
+ if (Lex.getKind() == lltok::APSInt) {
+ MDUnsignedField Res = Result.A;
+ if (!parseMDField(Loc, Name, Res)) {
+ Result.assign(Res);
+ return false;
+ }
+ return true;
+ }
+
+ // Otherwise, try to parse as an MDField.
+ MDField Res = Result.B;
+ if (!parseMDField(Loc, Name, Res)) {
+ Result.assign(Res);
+ return false;
+ }
+
+ return true;
+}
+
template <>
bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
LocTy ValueLoc = Lex.getLoc();
@@ -5385,7 +5437,7 @@ bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(line, LineField, ); \
OPTIONAL(scope, MDField, ); \
OPTIONAL(baseType, MDField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(lowerBound, MDSignedOrMDField, ); \
@@ -5409,10 +5461,10 @@ bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) {
Metadata *Stride = convToMetadata(stride);
Metadata *Bias = convToMetadata(bias);
- Result = GET_OR_DISTINCT(DISubrangeType,
- (Context, name.Val, file.Val, line.Val, scope.Val,
- size.Val, align.Val, flags.Val, baseType.Val,
- LowerBound, UpperBound, Stride, Bias));
+ Result = GET_OR_DISTINCT(
+ DISubrangeType, (Context, name.Val, file.Val, line.Val, scope.Val,
+ size.getValueAsMetadata(Context), align.Val, flags.Val,
+ baseType.Val, LowerBound, UpperBound, Stride, Bias));
return false;
}
@@ -5520,7 +5572,7 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
OPTIONAL(name, MDStringField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(encoding, DwarfAttEncodingField, ); \
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
@@ -5528,7 +5580,8 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
- Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val,
+ Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val,
+ size.getValueAsMetadata(Context),
align.Val, encoding.Val,
num_extra_inhabitants.Val, flags.Val));
return false;
@@ -5543,7 +5596,7 @@ bool LLParser::parseDIFixedPointType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
OPTIONAL(name, MDStringField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(encoding, DwarfAttEncodingField, ); \
OPTIONAL(flags, DIFlagField, ); \
@@ -5555,7 +5608,8 @@ bool LLParser::parseDIFixedPointType(MDNode *&Result, bool IsDistinct) {
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(DIFixedPointType,
- (Context, tag.Val, name.Val, size.Val, align.Val,
+ (Context, tag.Val, name.Val,
+ size.getValueAsMetadata(Context), align.Val,
encoding.Val, flags.Val, kind.Val, factor.Val,
numerator.Val, denominator.Val));
return false;
@@ -5570,7 +5624,7 @@ bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(stringLength, MDField, ); \
OPTIONAL(stringLengthExpression, MDField, ); \
OPTIONAL(stringLocationExpression, MDField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(encoding, DwarfAttEncodingField, );
PARSE_MD_FIELDS();
@@ -5579,7 +5633,8 @@ bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) {
Result = GET_OR_DISTINCT(
DIStringType,
(Context, tag.Val, name.Val, stringLength.Val, stringLengthExpression.Val,
- stringLocationExpression.Val, size.Val, align.Val, encoding.Val));
+ stringLocationExpression.Val, size.getValueAsMetadata(Context),
+ align.Val, encoding.Val));
return false;
}
@@ -5600,9 +5655,9 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(line, LineField, ); \
OPTIONAL(scope, MDField, ); \
REQUIRED(baseType, MDField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
- OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(extraData, MDField, ); \
OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \
@@ -5625,11 +5680,11 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) {
(unsigned)ptrAuthExtraDiscriminator.Val, ptrAuthIsaPointer.Val,
ptrAuthAuthenticatesNullValues.Val);
- Result = GET_OR_DISTINCT(DIDerivedType,
- (Context, tag.Val, name.Val, file.Val, line.Val,
- scope.Val, baseType.Val, size.Val, align.Val,
- offset.Val, DWARFAddressSpace, PtrAuthData,
- flags.Val, extraData.Val, annotations.Val));
+ Result = GET_OR_DISTINCT(
+ DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val,
+ baseType.Val, size.getValueAsMetadata(Context), align.Val,
+ offset.getValueAsMetadata(Context), DWARFAddressSpace,
+ PtrAuthData, flags.Val, extraData.Val, annotations.Val));
return false;
}
@@ -5641,9 +5696,9 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(line, LineField, ); \
OPTIONAL(scope, MDField, ); \
OPTIONAL(baseType, MDField, ); \
- OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
- OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(elements, MDField, ); \
OPTIONAL(runtimeLang, DwarfLangField, ); \
@@ -5678,12 +5733,12 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
if (identifier.Val)
if (auto *CT = DICompositeType::buildODRType(
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
- scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
- 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,
- bitStride.Val)) {
+ scope.Val, baseType.Val, size.getValueAsMetadata(Context),
+ align.Val, offset.getValueAsMetadata(Context), 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, bitStride.Val)) {
Result = CT;
return false;
}
@@ -5693,7 +5748,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
Result = GET_OR_DISTINCT(
DICompositeType,
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
- size.Val, align.Val, offset.Val, flags.Val, elements.Val,
+ size.getValueAsMetadata(Context), align.Val,
+ offset.getValueAsMetadata(Context), flags.Val, elements.Val,
runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val,
identifier.Val, discriminator.Val, dataLocation.Val, associated.Val,
allocated.Val, Rank, annotations.Val, specification.Val,
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 1cd1797c1092d..51f81228505fa 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -1525,15 +1525,24 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() < 6 || Record.size() > 8)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = (Record.size() > 6)
? static_cast<DINode::DIFlags>(Record[6])
: DINode::FlagZero;
uint32_t NumExtraInhabitants = (Record.size() > 7) ? Record[7] : 0;
+ Metadata *SizeInBits;
+ if (SizeIsMetadata) {
+ SizeInBits = getMDOrNull(Record[3]);
+ } else {
+ SizeInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[3]));
+ }
+
MetadataList.assignValue(
GET_OR_DISTINCT(DIBasicType,
- (Context, Record[1], getMDString(Record[2]), Record[3],
+ (Context, Record[1], getMDString(Record[2]), SizeInBits,
Record[4], Record[5], NumExtraInhabitants, Flags)),
NextMetadataNo);
NextMetadataNo++;
@@ -1543,9 +1552,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() < 11)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[6]);
+ Metadata *SizeInBits;
+ if (SizeIsMetadata) {
+ SizeInBits = getMDOrNull(Record[3]);
+ } else {
+ SizeInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[3]));
+ }
+
size_t Offset = 9;
auto ReadWideInt = [&]() {
@@ -1565,7 +1583,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
MetadataList.assignValue(
GET_OR_DISTINCT(DIFixedPointType,
- (Context, Record[1], getMDString(Record[2]), Record[3],
+ (Context, Record[1], getMDString(Record[2]), SizeInBits,
Record[4], Record[5], Flags, Record[7], Record[8],
Numerator, Denominator)),
NextMetadataNo);
@@ -1576,17 +1594,26 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() > 9 || Record.size() < 8)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
bool SizeIs8 = Record.size() == 8;
// StringLocationExp (i.e. Record[5]) is added at a later time
// than the other fields. The code here enables backward compatibility.
Metadata *StringLocationExp = SizeIs8 ? nullptr : getMDOrNull(Record[5]);
unsigned Offset = SizeIs8 ? 5 : 6;
+ Metadata *SizeInBits;
+ if (SizeIsMetadata) {
+ SizeInBits = getMDOrNull(Record[Offset]);
+ } else {
+ SizeInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[Offset]));
+ }
+
MetadataList.assignValue(
GET_OR_DISTINCT(DIStringType,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), getMDOrNull(Record[4]),
- StringLocationExp, Record[Offset], Record[Offset + 1],
+ StringLocationExp, SizeInBits, Record[Offset + 1],
Record[Offset + 2])),
NextMetadataNo);
NextMetadataNo++;
@@ -1615,15 +1642,28 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
PtrAuthData.emplace(Record[14]);
}
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
+
+ Metadata *SizeInBits, *OffsetInBits;
+ if (SizeIsMetadata) {
+ SizeInBits = getMDOrNull(Record[7]);
+ OffsetInBits = getMDOrNull(Record[9]);
+ } else {
+ SizeInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[7]));
+ OffsetInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[9]));
+ }
+
MetadataList.assignValue(
GET_OR_DISTINCT(DIDerivedType,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), Record[4],
getDITypeRefOrNull(Record[5]),
- getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- Record[9], DWARFAddressSpace, PtrAuthData, Flags,
+ getDITypeRefOrNull(Record[6]), SizeInBits, Record[8],
+ OffsetInBits, DWARFAddressSpace, PtrAuthData, Flags,
getDITypeRefOrNull(Record[11]), Annotations)),
NextMetadataNo);
NextMetadataNo++;
@@ -1633,13 +1673,23 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() != 13)
return error("Invalid record");
- IsDistinct = Record[0];
+ IsDistinct = Record[0] & 1;
+ bool SizeIsMetadata = Record[0] & 2;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7]);
+
+ Metadata *SizeInBits;
+ if (SizeIsMetadata) {
+ SizeInBits = getMDOrNull(Record[5]);
+ } else {
+ SizeInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[5]));
+ }
+
MetadataList.assignValue(
GET_OR_DISTINCT(DISubrangeType,
(Context, getMDString(Record[1]),
getMDOrNull(Record[2]), Record[3],
- getMDOrNull(Record[4]), Record[5], Record[6], Flags,
+ getMDOrNull(Record[4]), SizeInBits, Record[6], Flags,
getDITypeRefOrNull(Record[8]), getMDOrNull(Record[9]),
getMDOrNull(Record[10]), getMDOrNull(Record[11]),
getMDOrNull(Record[12]))),
@@ -1654,18 +1704,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
// If we have a UUID and this is not a forward declaration, lookup the
// mapping.
IsDistinct = Record[0] & 0x1;
- bool IsNotUsedInTypeRef = Record[0] >= 2;
+ bool IsNotUsedInTypeRef = Record[0] & 2;
+ bool SizeIsMetadata = Record[0] & 4;
unsigned Tag = Record[1];
MDString *Name = getMDString(Record[2]);
Metadata *File = getMDOrNull(Record[3]);
unsigned Line = Record[4];
Metadata *Scope = getDITypeRefOrNull(Record[5]);
Metadata *BaseType = nullptr;
- uint64_t SizeInBits = Record[7];
if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
uint32_t AlignInBits = Record[8];
- uint64_t OffsetInBits = 0;
+ Metadata *OffsetInBits = nullptr;
uint32_t NumExtraInhabitants = (Record.size() > 22) ? Record[22] : 0;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
Metadata *Elements = nullptr;
@@ -1712,7 +1762,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
TemplateParams = getMDOrNull(Record[14]);
} else {
BaseType = getDITypeRefOrNull(Record[6]);
- OffsetInBits = Record[9];
+
+ if (SizeIsMetadata) {
+ OffsetInBits = getMDOrNull(Record[9]);
+ } else {
+ OffsetInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[9]));
+ }
+
Elements = getMDOrNull(Record[11]);
VTableHolder = getDITypeRefOrNull(Record[13]);
TemplateParams = getMDOrNull(Record[14]);
@@ -1740,6 +1797,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() > 24 && Record[24] != dwarf::DW_APPLE_ENUM_KIND_invalid)
EnumKind = Record[24];
+ Metadata *SizeInBits;
+ if (SizeIsMetadata) {
+ SizeInBits = getMDOrNull(Record[7]);
+ } else {
+ SizeInBits = ConstantAsMetadata::get(
+ ConstantInt::get(Type::getInt64Ty(Context), Record[7]));
+ }
+
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index f8748babb1625..7b81d7ea4dbd0 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1899,10 +1899,11 @@ void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N,
void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- Record.push_back(N->isDistinct());
+ const unsigned SizeIsMetadata = 0x2;
+ Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
- Record.push_back(N->getSizeInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits()));
Record.push_back(N->getAlignInBits());
Record.push_back(N->getEncoding());
Record.push_back(N->getFlags());
@@ -1915,10 +1916,11 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
void ModuleBitcodeWriter::writeDIFixedPointType(
const DIFixedPointType *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- Record.push_back(N->isDistinct());
+ const unsigned SizeIsMetadata = 0x2;
+ Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
- Record.push_back(N->getSizeInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits()));
Record.push_back(N->getAlignInBits());
Record.push_back(N->getEncoding());
Record.push_back(N->getFlags());
@@ -1944,13 +1946,14 @@ void ModuleBitcodeWriter::writeDIFixedPointType(
void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- Record.push_back(N->isDistinct());
+ const unsigned SizeIsMetadata = 0x2;
+ Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getStringLength()));
Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp()));
Record.push_back(VE.getMetadataOrNullID(N->getStringLocationExp()));
- Record.push_back(N->getSizeInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits()));
Record.push_back(N->getAlignInBits());
Record.push_back(N->getEncoding());
@@ -1961,16 +1964,17 @@ void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N,
void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- Record.push_back(N->isDistinct());
+ const unsigned SizeIsMetadata = 0x2;
+ Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Record.push_back(N->getLine());
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
- Record.push_back(N->getSizeInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits()));
Record.push_back(N->getAlignInBits());
- Record.push_back(N->getOffsetInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawOffsetInBits()));
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getExtraData()));
@@ -1995,12 +1999,13 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
void ModuleBitcodeWriter::writeDISubrangeType(const DISubrangeType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- Record.push_back(N->isDistinct());
+ const unsigned SizeIsMetadata = 0x2;
+ Record.push_back(SizeIsMetadata | (unsigned)N->isDistinct());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Record.push_back(N->getLine());
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
- Record.push_back(N->getSizeInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits()));
Record.push_back(N->getAlignInBits());
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
@@ -2017,16 +2022,18 @@ void ModuleBitcodeWriter::writeDICompositeType(
const DICompositeType *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
const unsigned IsNotUsedInOldTypeRef = 0x2;
- Record.push_back(IsNotUsedInOldTypeRef | (unsigned)N->isDistinct());
+ const unsigned SizeIsMetadata = 0x4;
+ Record.push_back(SizeIsMetadata | IsNotUsedInOldTypeRef |
+ (unsigned)N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Record.push_back(N->getLine());
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
- Record.push_back(N->getSizeInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawSizeInBits()));
Record.push_back(N->getAlignInBits());
- Record.push_back(N->getOffsetInBits());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawOffsetInBits()));
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getElements().get()));
Record.push_back(N->getRuntimeLang());
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 90da9f3acfe57..6d633044f47bb 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -326,21 +326,22 @@ DIStringType *DIBuilder::createStringType(StringRef Name,
}
DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {
- return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0,
- 0, 0, std::nullopt, std::nullopt, DINode::FlagZero);
+ return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy,
+ (uint64_t)0, 0, (uint64_t)0, std::nullopt,
+ std::nullopt, DINode::FlagZero);
}
DIDerivedType *DIBuilder::createPtrAuthQualifiedType(
DIType *FromTy, unsigned Key, bool IsAddressDiscriminated,
unsigned ExtraDiscriminator, bool IsaPointer,
bool AuthenticatesNullValues) {
- return DIDerivedType::get(VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "",
- nullptr, 0, nullptr, FromTy, 0, 0, 0, std::nullopt,
- std::optional<DIDerivedType::PtrAuthData>(
- std::in_place, Key, IsAddressDiscriminated,
- ExtraDiscriminator, IsaPointer,
- AuthenticatesNullValues),
- DINode::FlagZero);
+ return DIDerivedType::get(
+ VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", nullptr, 0, nullptr,
+ FromTy, (uint64_t)0, 0, (uint64_t)0, std::nullopt,
+ std::optional<DIDerivedType::PtrAuthData>(
+ std::in_place, Key, IsAddressDiscriminated, ExtraDiscriminator,
+ IsaPointer, AuthenticatesNullValues),
+ DINode::FlagZero);
}
DIDerivedType *
@@ -382,9 +383,9 @@ DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,
DINode::DIFlags Flags,
DINodeArray Annotations) {
return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,
- LineNo, getNonCompileUnitScope(Context), Ty, 0,
- AlignInBits, 0, std::nullopt, std::nullopt, Flags,
- nullptr, Annotations);
+ LineNo, getNonCompileUnitScope(Context), Ty,
+ (uint64_t)0, AlignInBits, (uint64_t)0, std::nullopt,
+ std::nullopt, Flags, nullptr, Annotations);
}
DIDerivedType *
@@ -393,17 +394,17 @@ DIBuilder::createTemplateAlias(DIType *Ty, StringRef Name, DIFile *File,
DINodeArray TParams, uint32_t AlignInBits,
DINode::DIFlags Flags, DINodeArray Annotations) {
return DIDerivedType::get(VMContext, dwarf::DW_TAG_template_alias, Name, File,
- LineNo, getNonCompileUnitScope(Context), Ty, 0,
- AlignInBits, 0, std::nullopt, std::nullopt, Flags,
- TParams.get(), Annotations);
+ LineNo, getNonCompileUnitScope(Context), Ty,
+ (uint64_t)0, AlignInBits, (uint64_t)0, std::nullopt,
+ std::nullopt, Flags, TParams.get(), Annotations);
}
DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) {
assert(Ty && "Invalid type!");
assert(FriendTy && "Invalid friend type!");
return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty,
- FriendTy, 0, 0, 0, std::nullopt, std::nullopt,
- DINode::FlagZero);
+ FriendTy, (uint64_t)0, 0, (uint64_t)0, std::nullopt,
+ std::nullopt, DINode::FlagZero);
}
DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy,
@@ -449,8 +450,9 @@ DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope,
Constant *Discriminant,
DIType *Ty) {
auto *V = DICompositeType::get(VMContext, dwarf::DW_TAG_variant, {}, nullptr,
- 0, getNonCompileUnitScope(Scope), {}, 0, 0, 0,
- DINode::FlagZero, Elements, 0, {}, nullptr);
+ 0, getNonCompileUnitScope(Scope), {},
+ (uint64_t)0, 0, (uint64_t)0, DINode::FlagZero,
+ Elements, 0, {}, nullptr);
trackIfUnresolved(V);
return createVariantMemberType(Scope, {}, nullptr, 0, 0, 0, 0, Discriminant,
@@ -478,9 +480,9 @@ DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File,
unsigned Tag, uint32_t AlignInBits) {
Flags |= DINode::FlagStaticMember;
return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber,
- getNonCompileUnitScope(Scope), Ty, 0, AlignInBits,
- 0, std::nullopt, std::nullopt, Flags,
- getConstantOrNull(Val));
+ getNonCompileUnitScope(Scope), Ty, (uint64_t)0,
+ AlignInBits, (uint64_t)0, std::nullopt,
+ std::nullopt, Flags, getConstantOrNull(Val));
}
DIDerivedType *
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 6735bf7dc52db..49ff1afaf2eb7 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -824,25 +824,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
@@ -882,18 +880,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 {
@@ -913,18 +910,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 {
@@ -956,17 +953,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);
@@ -1003,8 +1000,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) {
@@ -1013,11 +1010,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>
@@ -1029,8 +1026,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,
@@ -1046,20 +1043,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,
@@ -1085,12 +1083,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)
@@ -1102,7 +1101,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,
@@ -1137,7 +1136,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,
@@ -1145,7 +1144,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);
}
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 21f5c06ea24f3..3e55ff884966c 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -488,27 +488,28 @@ template <> struct MDNodeKeyImpl<DIEnumerator> {
template <> struct MDNodeKeyImpl<DIBasicType> {
unsigned Tag;
MDString *Name;
- uint64_t SizeInBits;
+ Metadata *SizeInBits;
uint32_t AlignInBits;
unsigned Encoding;
uint32_t NumExtraInhabitants;
unsigned Flags;
- MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
+ MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, unsigned Flags)
: Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
Encoding(Encoding), NumExtraInhabitants(NumExtraInhabitants),
Flags(Flags) {}
MDNodeKeyImpl(const DIBasicType *N)
- : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
- AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
+ : Tag(N->getTag()), Name(N->getRawName()),
+ SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
+ Encoding(N->getEncoding()),
NumExtraInhabitants(N->getNumExtraInhabitants()), Flags(N->getFlags()) {
}
bool isKeyOf(const DIBasicType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
- SizeInBits == RHS->getSizeInBits() &&
+ SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
Encoding == RHS->getEncoding() &&
NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
@@ -523,7 +524,7 @@ template <> struct MDNodeKeyImpl<DIBasicType> {
template <> struct MDNodeKeyImpl<DIFixedPointType> {
unsigned Tag;
MDString *Name;
- uint64_t SizeInBits;
+ Metadata *SizeInBits;
uint32_t AlignInBits;
unsigned Encoding;
unsigned Flags;
@@ -532,20 +533,21 @@ template <> struct MDNodeKeyImpl<DIFixedPointType> {
APInt Numerator;
APInt Denominator;
- MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
+ MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits,
uint32_t AlignInBits, unsigned Encoding, unsigned Flags,
unsigned Kind, int Factor, APInt Numerator, APInt Denominator)
: Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
Encoding(Encoding), Flags(Flags), Kind(Kind), Factor(Factor),
Numerator(Numerator), Denominator(Denominator) {}
MDNodeKeyImpl(const DIFixedPointType *N)
- : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
- AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
- Flags(N->getFlags()), Kind(N->getKind()), Factor(N->getFactorRaw()),
- Numerator(N->getNumeratorRaw()), Denominator(N->getDenominatorRaw()) {}
+ : Tag(N->getTag()), Name(N->getRawName()),
+ SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
+ Encoding(N->getEncoding()), Flags(N->getFlags()), Kind(N->getKind()),
+ Factor(N->getFactorRaw()), Numerator(N->getNumeratorRaw()),
+ Denominator(N->getDenominatorRaw()) {}
bool isKeyOf(const DIFixedPointType *RHS) const {
- return Name == RHS->getRawName() && SizeInBits == RHS->getSizeInBits() &&
+ return Name == RHS->getRawName() && SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() && Kind == RHS->getKind() &&
(RHS->isRational() ? (Numerator == RHS->getNumerator() &&
Denominator == RHS->getDenominator())
@@ -563,13 +565,13 @@ template <> struct MDNodeKeyImpl<DIStringType> {
Metadata *StringLength;
Metadata *StringLengthExp;
Metadata *StringLocationExp;
- uint64_t SizeInBits;
+ Metadata *SizeInBits;
uint32_t AlignInBits;
unsigned Encoding;
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
Metadata *StringLengthExp, Metadata *StringLocationExp,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding)
+ Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding)
: Tag(Tag), Name(Name), StringLength(StringLength),
StringLengthExp(StringLengthExp), StringLocationExp(StringLocationExp),
SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {}
@@ -578,7 +580,7 @@ template <> struct MDNodeKeyImpl<DIStringType> {
StringLength(N->getRawStringLength()),
StringLengthExp(N->getRawStringLengthExp()),
StringLocationExp(N->getRawStringLocationExp()),
- SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()),
+ SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
Encoding(N->getEncoding()) {}
bool isKeyOf(const DIStringType *RHS) const {
@@ -586,7 +588,7 @@ template <> struct MDNodeKeyImpl<DIStringType> {
StringLength == RHS->getRawStringLength() &&
StringLengthExp == RHS->getRawStringLengthExp() &&
StringLocationExp == RHS->getRawStringLocationExp() &&
- SizeInBits == RHS->getSizeInBits() &&
+ SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
Encoding == RHS->getEncoding();
}
@@ -606,8 +608,8 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
unsigned Line;
Metadata *Scope;
Metadata *BaseType;
- uint64_t SizeInBits;
- uint64_t OffsetInBits;
+ Metadata *SizeInBits;
+ Metadata *OffsetInBits;
uint32_t AlignInBits;
std::optional<unsigned> DWARFAddressSpace;
std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
@@ -616,8 +618,8 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
Metadata *Annotations;
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
- Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits,
+ Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits,
std::optional<unsigned> DWARFAddressSpace,
std::optional<DIDerivedType::PtrAuthData> PtrAuthData,
unsigned Flags, Metadata *ExtraData, Metadata *Annotations)
@@ -629,8 +631,8 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
MDNodeKeyImpl(const DIDerivedType *N)
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
- BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
- OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
+ BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
+ OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
DWARFAddressSpace(N->getDWARFAddressSpace()),
PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()),
ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {}
@@ -639,9 +641,9 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
File == RHS->getRawFile() && Line == RHS->getLine() &&
Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
- SizeInBits == RHS->getSizeInBits() &&
+ SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
- OffsetInBits == RHS->getOffsetInBits() &&
+ OffsetInBits == RHS->getRawOffsetInBits() &&
DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() &&
ExtraData == RHS->getRawExtraData() &&
@@ -670,7 +672,7 @@ template <> struct MDNodeKeyImpl<DISubrangeType> {
Metadata *File;
unsigned Line;
Metadata *Scope;
- uint64_t SizeInBits;
+ Metadata *SizeInBits;
uint32_t AlignInBits;
unsigned Flags;
Metadata *BaseType;
@@ -680,7 +682,7 @@ template <> struct MDNodeKeyImpl<DISubrangeType> {
Metadata *Bias;
MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
- uint64_t SizeInBits, uint32_t AlignInBits, unsigned Flags,
+ Metadata *SizeInBits, uint32_t AlignInBits, unsigned Flags,
Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
Metadata *Stride, Metadata *Bias)
: Name(Name), File(File), Line(Line), Scope(Scope),
@@ -689,7 +691,7 @@ template <> struct MDNodeKeyImpl<DISubrangeType> {
Stride(Stride), Bias(Bias) {}
MDNodeKeyImpl(const DISubrangeType *N)
: Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()),
- Scope(N->getRawScope()), SizeInBits(N->getSizeInBits()),
+ Scope(N->getRawScope()), SizeInBits(N->getRawSizeInBits()),
AlignInBits(N->getAlignInBits()), Flags(N->getFlags()),
BaseType(N->getRawBaseType()), LowerBound(N->getRawLowerBound()),
UpperBound(N->getRawUpperBound()), Stride(N->getRawStride()),
@@ -713,7 +715,7 @@ template <> struct MDNodeKeyImpl<DISubrangeType> {
return Name == RHS->getRawName() && File == RHS->getRawFile() &&
Line == RHS->getLine() && Scope == RHS->getRawScope() &&
- SizeInBits == RHS->getSizeInBits() &&
+ SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() && Flags == RHS->getFlags() &&
BaseType == RHS->getRawBaseType() &&
BoundsEqual(LowerBound, RHS->getRawLowerBound()) &&
@@ -781,8 +783,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
unsigned Line;
Metadata *Scope;
Metadata *BaseType;
- uint64_t SizeInBits;
- uint64_t OffsetInBits;
+ Metadata *SizeInBits;
+ Metadata *OffsetInBits;
uint32_t AlignInBits;
unsigned Flags;
Metadata *Elements;
@@ -801,8 +803,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
Metadata *BitStride;
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
- Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
+ Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
+ uint32_t AlignInBits, Metadata *OffsetInBits, unsigned Flags,
Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
MDString *Identifier, Metadata *Discriminator,
@@ -822,8 +824,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
MDNodeKeyImpl(const DICompositeType *N)
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
- BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
- OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
+ BaseType(N->getRawBaseType()), SizeInBits(N->getRawSizeInBits()),
+ OffsetInBits(N->getRawOffsetInBits()), AlignInBits(N->getAlignInBits()),
Flags(N->getFlags()), Elements(N->getRawElements()),
RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()),
TemplateParams(N->getRawTemplateParams()),
@@ -840,10 +842,10 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
File == RHS->getRawFile() && Line == RHS->getLine() &&
Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
- SizeInBits == RHS->getSizeInBits() &&
+ SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
- OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
- Elements == RHS->getRawElements() &&
+ OffsetInBits == RHS->getRawOffsetInBits() &&
+ Flags == RHS->getFlags() && Elements == RHS->getRawElements() &&
RuntimeLang == RHS->getRuntimeLang() &&
VTableHolder == RHS->getRawVTableHolder() &&
TemplateParams == RHS->getRawTemplateParams() &&
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index fdb4ddaafbbcc..a58034f6451cb 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1173,6 +1173,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) {
@@ -1234,6 +1238,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) {
@@ -1314,6 +1322,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.
@@ -1401,6 +1414,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) {
diff --git a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
index e1ce671852c8b..6716796e71c5a 100644
--- a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
+++ b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
@@ -141,12 +141,12 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
DO_FOR_FIELD(BaseType) \
DO_FOR_FIELD(Elements) \
DO_FOR_FIELD(VTableHolder) \
- DO_FOR_FIELD(TemplateParams)
+ DO_FOR_FIELD(TemplateParams) \
+ DO_FOR_FIELD(SizeInBits) \
+ DO_FOR_FIELD(OffsetInBits)
#define FOR_EACH_INLINEFIELD() \
DO_FOR_FIELD(Line) \
- DO_FOR_FIELD(SizeInBits) \
DO_FOR_FIELD(AlignInBits) \
- DO_FOR_FIELD(OffsetInBits) \
DO_FOR_FIELD(NumExtraInhabitants) \
DO_FOR_FIELD(RuntimeLang) \
DO_FOR_FIELD(EnumKind)
>From 8eef3a9e89d3fc2aa584987dd80f495978243684 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey at adacore.com>
Date: Fri, 16 May 2025 10:22:18 -0600
Subject: [PATCH 3/4] Change DWARF writer to handle dynamic offsets and sizes
This updates the DWARF writer to emit dynamic offsets and sizes for
members.
---
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 202 ++++++++++++++--------
llvm/test/DebugInfo/dynamic-bitfield.ll | 62 +++++++
2 files changed, 192 insertions(+), 72 deletions(-)
create mode 100644 llvm/test/DebugInfo/dynamic-bitfield.ll
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 5a1ac5d662704..ed50183859d00 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1002,7 +1002,6 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
// Add name if not anonymous or intermediate type.
StringRef Name = CTy->getName();
- uint64_t Size = CTy->getSizeInBits() >> 3;
uint16_t Tag = Buffer.getTag();
switch (Tag) {
@@ -1165,15 +1164,29 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
if (Tag == dwarf::DW_TAG_enumeration_type ||
Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type) {
- // Add size if non-zero (derived types might be zero-sized.)
- // Ignore the size if it's a non-enum forward decl.
- // TODO: Do we care about size for enum forward declarations?
- if (Size &&
- (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type))
- addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);
- else if (!CTy->isForwardDecl())
- // Add zero size if it is not a forward declaration.
- addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0);
+ if (auto *Var = dyn_cast_or_null<DIVariable>(CTy->getRawSizeInBits())) {
+ if (auto *VarDIE = getDIE(Var)) {
+ addDIEEntry(Buffer, dwarf::DW_AT_bit_size, *VarDIE);
+ }
+ } else if (auto *Exp =
+ dyn_cast_or_null<DIExpression>(CTy->getRawSizeInBits())) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Exp);
+ addBlock(Buffer, dwarf::DW_AT_bit_size, DwarfExpr.finalize());
+ } else {
+ uint64_t Size = CTy->getSizeInBits() >> 3;
+ // Add size if non-zero (derived types might be zero-sized.)
+ // Ignore the size if it's a non-enum forward decl.
+ // TODO: Do we care about size for enum forward declarations?
+ if (Size &&
+ (!CTy->isForwardDecl() || Tag == dwarf::DW_TAG_enumeration_type))
+ addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);
+ else if (!CTy->isForwardDecl())
+ // Add zero size if it is not a forward declaration.
+ addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0);
+ }
// If we're a forward decl, say so.
if (CTy->isForwardDecl())
@@ -1840,74 +1853,119 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
} else {
- uint64_t Size = DT->getSizeInBits();
- uint64_t FieldSize = DD->getBaseTypeSize(DT);
- uint32_t AlignInBytes = DT->getAlignInBytes();
- uint64_t OffsetInBytes;
+ uint64_t Size = 0;
+ uint64_t FieldSize = 0;
bool IsBitfield = DT->isBitField();
- if (IsBitfield) {
- // Handle bitfield, assume bytes are 8 bits.
- if (DD->useDWARF2Bitfields())
- addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8);
- addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size);
-
- assert(DT->getOffsetInBits() <=
- (uint64_t)std::numeric_limits<int64_t>::max());
- int64_t Offset = DT->getOffsetInBits();
- // We can't use DT->getAlignInBits() here: AlignInBits for member type
- // is non-zero if and only if alignment was forced (e.g. _Alignas()),
- // which can't be done with bitfields. Thus we use FieldSize here.
- uint32_t AlignInBits = FieldSize;
- uint32_t AlignMask = ~(AlignInBits - 1);
- // The bits from the start of the storage unit to the start of the field.
- uint64_t StartBitOffset = Offset - (Offset & AlignMask);
- // The byte offset of the field's aligned storage unit inside the struct.
- OffsetInBytes = (Offset - StartBitOffset) / 8;
-
- if (DD->useDWARF2Bitfields()) {
- uint64_t HiMark = (Offset + FieldSize) & AlignMask;
- uint64_t FieldOffset = (HiMark - FieldSize);
- Offset -= FieldOffset;
-
- // Maybe we need to work from the other end.
- if (Asm->getDataLayout().isLittleEndian())
- Offset = FieldSize - (Offset + Size);
-
- if (Offset < 0)
- addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
- Offset);
- else
- addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,
- (uint64_t)Offset);
- OffsetInBytes = FieldOffset >> 3;
- } else {
- addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset);
+
+ // Handle the size.
+ if (auto *Var = dyn_cast_or_null<DIVariable>(DT->getRawSizeInBits())) {
+ if (auto *VarDIE = getDIE(Var)) {
+ addDIEEntry(MemberDie, dwarf::DW_AT_bit_size, *VarDIE);
}
+ } else if (auto *Exp =
+ dyn_cast_or_null<DIExpression>(DT->getRawSizeInBits())) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Exp);
+ addBlock(MemberDie, dwarf::DW_AT_bit_size, DwarfExpr.finalize());
} else {
- // This is not a bitfield.
- OffsetInBytes = DT->getOffsetInBits() / 8;
- if (AlignInBytes)
- addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
- AlignInBytes);
+ Size = DT->getSizeInBits();
+ FieldSize = DD->getBaseTypeSize(DT);
+ if (IsBitfield) {
+ // Handle bitfield, assume bytes are 8 bits.
+ if (DD->useDWARF2Bitfields())
+ addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt,
+ FieldSize / 8);
+ addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size);
+ }
}
- if (DD->getDwarfVersion() <= 2) {
- DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
- addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
- addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
- addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
- } else if (!IsBitfield || DD->useDWARF2Bitfields()) {
- // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are
- // interpreted as location-list pointers. Interpreting constants as
- // pointers is not expected, so we use DW_FORM_udata to encode the
- // constants here.
- if (DD->getDwarfVersion() == 3)
- addUInt(MemberDie, dwarf::DW_AT_data_member_location,
- dwarf::DW_FORM_udata, OffsetInBytes);
- else
- addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,
- OffsetInBytes);
+ // Handle the location. DW_AT_data_bit_offset won't allow an
+ // expression until DWARF 6, but it can be used as an extension.
+ // See https://dwarfstd.org/issues/250501.1.html
+ if (auto *Var = dyn_cast_or_null<DIVariable>(DT->getRawOffsetInBits())) {
+ if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 6) {
+ if (auto *VarDIE = getDIE(Var)) {
+ addDIEEntry(MemberDie, dwarf::DW_AT_data_bit_offset, *VarDIE);
+ }
+ }
+ } else if (auto *Expr =
+ dyn_cast_or_null<DIExpression>(DT->getRawOffsetInBits())) {
+ if (!Asm->TM.Options.DebugStrictDwarf || DD->getDwarfVersion() >= 6) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Expr);
+ addBlock(MemberDie, dwarf::DW_AT_data_bit_offset, DwarfExpr.finalize());
+ }
+ } else {
+ uint32_t AlignInBytes = DT->getAlignInBytes();
+ uint64_t OffsetInBytes;
+
+ if (IsBitfield) {
+ assert(DT->getOffsetInBits() <=
+ (uint64_t)std::numeric_limits<int64_t>::max());
+ int64_t Offset = DT->getOffsetInBits();
+ // We can't use DT->getAlignInBits() here: AlignInBits for member type
+ // is non-zero if and only if alignment was forced (e.g. _Alignas()),
+ // which can't be done with bitfields. Thus we use FieldSize here.
+ uint32_t AlignInBits = FieldSize;
+ uint32_t AlignMask = ~(AlignInBits - 1);
+ // The bits from the start of the storage unit to the start of the
+ // field.
+ uint64_t StartBitOffset = Offset - (Offset & AlignMask);
+ // The byte offset of the field's aligned storage unit inside the
+ // struct.
+ OffsetInBytes = (Offset - StartBitOffset) / 8;
+
+ if (DD->useDWARF2Bitfields()) {
+ uint64_t HiMark = (Offset + FieldSize) & AlignMask;
+ uint64_t FieldOffset = (HiMark - FieldSize);
+ Offset -= FieldOffset;
+
+ // Maybe we need to work from the other end.
+ if (Asm->getDataLayout().isLittleEndian())
+ Offset = FieldSize - (Offset + Size);
+
+ if (Offset < 0)
+ addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
+ Offset);
+ else
+ addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,
+ (uint64_t)Offset);
+ OffsetInBytes = FieldOffset >> 3;
+ } else {
+ addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt,
+ Offset);
+ }
+ } else {
+ // This is not a bitfield.
+ OffsetInBytes = DT->getOffsetInBits() / 8;
+ if (AlignInBytes)
+ addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
+ AlignInBytes);
+ }
+
+ if (DD->getDwarfVersion() <= 2) {
+ DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
+ addUInt(*MemLocationDie, dwarf::DW_FORM_data1,
+ dwarf::DW_OP_plus_uconst);
+ addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
+ addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
+ } else if (!IsBitfield || DD->useDWARF2Bitfields()) {
+ // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are
+ // interpreted as location-list pointers. Interpreting constants as
+ // pointers is not expected, so we use DW_FORM_udata to encode the
+ // constants here.
+ if (DD->getDwarfVersion() == 3)
+ addUInt(MemberDie, dwarf::DW_AT_data_member_location,
+ dwarf::DW_FORM_udata, OffsetInBytes);
+ else
+ addUInt(MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,
+ OffsetInBytes);
+ }
}
}
diff --git a/llvm/test/DebugInfo/dynamic-bitfield.ll b/llvm/test/DebugInfo/dynamic-bitfield.ll
new file mode 100644
index 0000000000000..1a5ed81774538
--- /dev/null
+++ b/llvm/test/DebugInfo/dynamic-bitfield.ll
@@ -0,0 +1,62 @@
+; RUN: llc -O0 -filetype=obj -o - %s | llvm-dwarfdump -v -debug-info - | FileCheck %s
+
+; A basic test of using a DIExpression for DW_AT_data_bit_offset and
+; DW_AT_bit_size.
+
+source_filename = "bitfield.c"
+
+%struct.PackedBits = type <{ i8, i32 }>
+
+ at s = common global %struct.PackedBits zeroinitializer, align 1, !dbg !2
+ at value = common global i32 zeroinitializer, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!4}
+!llvm.module.flags = !{!17, !18, !19}
+!llvm.ident = !{!20}
+
+!0 = distinct !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = !DIGlobalVariable(name: "value", scope: !4, file: !5, line: 8, type: !15, isLocal: false, isDefinition: true)
+!2 = distinct !DIGlobalVariableExpression(var: !3, expr: !DIExpression())
+!3 = !DIGlobalVariable(name: "s", scope: !4, file: !5, line: 8, type: !8, isLocal: false, isDefinition: true)
+
+
+!4 = distinct !DICompileUnit(language: DW_LANG_C99, file: !5, producer: "clang version 3.9.0 (trunk 267633)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !6, globals: !7)
+!5 = !DIFile(filename: "bitfield.c", directory: "/Volumes/Data/llvm")
+!6 = !{}
+!7 = !{!0, !2}
+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "PackedBits", file: !5, line: 3, size: 40, elements: !9)
+!9 = !{!10, !12, !16}
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !5, line: 5, baseType: !11, size: 8)
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"a"
+; CHECK-NOT: DW_TAG
+; CHECK-NOT: DW_AT_bit_offset
+; CHECK-NOT: DW_AT_data_bit_offset
+; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
+!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!12 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !5, line: 6, baseType: !13, size: !3, offset: !3, flags: DIFlagBitField)
+!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint32_t", file: !14, line: 183, baseType: !15)
+!14 = !DIFile(filename: "/Volumes/Data/llvm/_build.ninja.release/bin/../lib/clang/3.9.0/include/stdint.h", directory: "/Volumes/Data/llvm")
+!15 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"b"
+; CHECK-NOT: DW_TAG
+; CHECK-NOT: DW_AT_bit_offset
+; CHECK-NOT: DW_AT_byte_size
+; CHECK: DW_AT_bit_size [DW_FORM_ref4] ({{.*}})
+; CHECK-NEXT: DW_AT_data_bit_offset [DW_FORM_ref4] ({{.*}})
+; CHECK-NOT: DW_AT_data_member_location
+!16 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !8, file: !5, line: 7, baseType: !13, size: !DIExpression(DW_OP_constu, 27), offset: !DIExpression(DW_OP_constu, 13), flags: DIFlagBitField)
+!17 = !{i32 2, !"Dwarf Version", i32 4}
+!18 = !{i32 2, !"Debug Info Version", i32 3}
+!19 = !{i32 1, !"PIC Level", i32 2}
+; CHECK: DW_TAG_member
+; CHECK-NEXT: DW_AT_name{{.*}}"c"
+; CHECK-NOT: DW_TAG
+; CHECK-NOT: DW_AT_bit_offset
+; CHECK-NOT: DW_AT_byte_size
+; CHECK: DW_AT_bit_size [DW_FORM_exprloc] (DW_OP_lit27)
+; CHECK-NEXT: DW_AT_data_bit_offset [DW_FORM_exprloc] (DW_OP_lit13)
+; CHECK-NOT: DW_AT_data_member_location
+; CHECK: DW_TAG
+!20 = !{!"clang version 3.9.0 (trunk 267633)"}
>From 90a46a78f2c2bb78666436a086bdc968788701ca Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey at adacore.com>
Date: Wed, 21 May 2025 12:16:43 -0600
Subject: [PATCH 4/4] Expose dynamic sizes and offsets via DIBuilder
This adds some new DIBuilder methods to expose the new dynamic size
and offset functionality.
---
llvm/include/llvm/IR/DIBuilder.h | 60 +++++++++++++++++++++++++++++
llvm/lib/IR/DIBuilder.cpp | 40 +++++++++++++++++++
llvm/unittests/IR/DebugInfoTest.cpp | 29 ++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 4ce71bd3dad58..1e1a4cb0af9ba 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -365,6 +365,24 @@ namespace llvm {
uint64_t BaseOffset, uint32_t VBPtrOffset,
DINode::DIFlags Flags);
+ /// Create debugging information entry for a member.
+ /// \param Scope Member scope.
+ /// \param Name Member name.
+ /// \param File File where this member is defined.
+ /// \param LineNo Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param OffsetInBits Member offset.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Ty Parent type.
+ /// \param Annotations Member annotations.
+ DIDerivedType *createMemberType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNo,
+ Metadata *SizeInBits, uint32_t AlignInBits,
+ Metadata *OffsetInBits,
+ DINode::DIFlags Flags, DIType *Ty,
+ DINodeArray Annotations = nullptr);
+
/// Create debugging information entry for a member.
/// \param Scope Member scope.
/// \param Name Member name.
@@ -419,6 +437,25 @@ namespace llvm {
DIDerivedType *createVariantMemberType(DIScope *Scope, DINodeArray Elements,
Constant *Discriminant, DIType *Ty);
+ /// Create debugging information entry for a bit field member.
+ /// \param Scope Member scope.
+ /// \param Name Member name.
+ /// \param File File where this member is defined.
+ /// \param LineNo Line number.
+ /// \param SizeInBits Member size.
+ /// \param OffsetInBits Member offset.
+ /// \param StorageOffsetInBits Member storage offset.
+ /// \param Flags Flags to encode member attribute.
+ /// \param Ty Parent type.
+ /// \param Annotations Member annotations.
+ DIDerivedType *createBitFieldMemberType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNo,
+ Metadata *SizeInBits,
+ Metadata *OffsetInBits,
+ uint64_t StorageOffsetInBits,
+ DINode::DIFlags Flags, DIType *Ty,
+ DINodeArray Annotations = nullptr);
+
/// Create debugging information entry for a bit field member.
/// \param Scope Member scope.
/// \param Name Member name.
@@ -510,6 +547,29 @@ namespace llvm {
unsigned RunTimeLang = 0, DIType *VTableHolder = nullptr,
MDNode *TemplateParms = nullptr, StringRef UniqueIdentifier = "");
+ /// Create debugging information entry for a struct.
+ /// \param Scope Scope in which this struct is defined.
+ /// \param Name Struct name.
+ /// \param File File where this member is defined.
+ /// \param LineNumber Line number.
+ /// \param SizeInBits Member size.
+ /// \param AlignInBits Member alignment.
+ /// \param Flags Flags to encode member attribute, e.g. private
+ /// \param Elements Struct elements.
+ /// \param RunTimeLang Optional parameter, Objective-C runtime version.
+ /// \param UniqueIdentifier A unique identifier for the struct.
+ /// \param Specification The type that this type completes. This is used by
+ /// Swift to represent generic types.
+ /// \param NumExtraInhabitants The number of extra inhabitants of the type.
+ /// An extra inhabitant is a bit pattern that does not represent a valid
+ /// value for instances of a given type. This is used by the Swift language.
+ DICompositeType *createStructType(
+ DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
+ Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
+ DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
+ DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
+ DIType *Specification = nullptr, uint32_t NumExtraInhabitants = 0);
+
/// Create debugging information entry for a struct.
/// \param Scope Scope in which this struct is defined.
/// \param Name Struct name.
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 6d633044f47bb..91310323646b3 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -429,6 +429,16 @@ DIDerivedType *DIBuilder::createMemberType(
std::nullopt, Flags, nullptr, Annotations);
}
+DIDerivedType *DIBuilder::createMemberType(
+ DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
+ Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
+ DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {
+ return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
+ LineNumber, getNonCompileUnitScope(Scope), Ty,
+ SizeInBits, AlignInBits, OffsetInBits, std::nullopt,
+ std::nullopt, Flags, nullptr, Annotations);
+}
+
static ConstantAsMetadata *getConstantOrNull(Constant *C) {
if (C)
return ConstantAsMetadata::get(C);
@@ -459,6 +469,20 @@ DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope,
DINode::FlagZero, V);
}
+DIDerivedType *DIBuilder::createBitFieldMemberType(
+ DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
+ Metadata *SizeInBits, Metadata *OffsetInBits, uint64_t StorageOffsetInBits,
+ DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {
+ Flags |= DINode::FlagBitField;
+ return DIDerivedType::get(
+ VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
+ getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0,
+ OffsetInBits, std::nullopt, std::nullopt, Flags,
+ ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64),
+ StorageOffsetInBits)),
+ Annotations);
+}
+
DIDerivedType *DIBuilder::createBitFieldMemberType(
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits,
@@ -563,6 +587,22 @@ DICompositeType *DIBuilder::createClassType(
return R;
}
+DICompositeType *DIBuilder::createStructType(
+ DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
+ Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
+ DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,
+ DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification,
+ uint32_t NumExtraInhabitants) {
+ auto *R = DICompositeType::get(
+ VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
+ getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,
+ Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, VTableHolder,
+ nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, Specification, NumExtraInhabitants);
+ trackIfUnresolved(R);
+ return R;
+}
+
DICompositeType *DIBuilder::createStructType(
DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp
index 8748371ae4b47..f011a7e9017d5 100644
--- a/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/llvm/unittests/IR/DebugInfoTest.cpp
@@ -1336,4 +1336,33 @@ TEST(DIBuilder, CompositeTypes) {
EXPECT_EQ(Enum->getTag(), dwarf::DW_TAG_enumeration_type);
}
+TEST(DIBuilder, DynamicOffsetAndSize) {
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M(new Module("MyModule", Ctx));
+ DIBuilder DIB(*M);
+ DIScope *Scope = DISubprogram::getDistinct(
+ Ctx, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
+ DINode::FlagZero, DISubprogram::SPFlagZero, nullptr);
+ DIFile *F = DIB.createFile("main.adb", "/");
+
+ DIVariable *Len = DIB.createAutoVariable(Scope, "length", F, 0, nullptr,
+ false, DINode::FlagZero, 0);
+
+ DICompositeType *Struct = DIB.createStructType(
+ Scope, "some_record", F, 18, Len, 8, DINode::FlagZero, nullptr, {});
+ EXPECT_EQ(Struct->getTag(), dwarf::DW_TAG_structure_type);
+
+ SmallVector<uint64_t, 4> ops;
+ ops.push_back(llvm::dwarf::DW_OP_push_object_address);
+ DIExpression::appendOffset(ops, 3);
+ ops.push_back(llvm::dwarf::DW_OP_deref);
+ DIExpression *Expr = DIB.createExpression(ops);
+
+ DIDerivedType *Field = DIB.createMemberType(Scope, "field", F, 23, Len, 0,
+ Expr, DINode::FlagZero, Struct);
+
+ EXPECT_EQ(Field->getRawOffsetInBits(), Expr);
+ EXPECT_EQ(Field->getRawSizeInBits(), Len);
+}
+
} // end namespace
More information about the cfe-commits
mailing list