Skip to content
Merged
5 changes: 2 additions & 3 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,14 +1174,13 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
}

llvm::DIType *CGDebugInfo::CreateType(const BitIntType *Ty) {

StringRef Name = Ty->isUnsigned() ? "unsigned _BitInt" : "_BitInt";
llvm::dwarf::TypeKind Encoding = Ty->isUnsigned()
? llvm::dwarf::DW_ATE_unsigned
: llvm::dwarf::DW_ATE_signed;

return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty),
Encoding);
Encoding, llvm::DINode::FlagZero, 0,
Ty->getNumBits());
}

llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
Expand Down
8 changes: 8 additions & 0 deletions clang/test/DebugInfo/Generic/bit-int.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -x c++ %s -debug-info-kind=standalone -gno-column-info -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -x c %s -debug-info-kind=standalone -gno-column-info -emit-llvm -o - | FileCheck %s

unsigned _BitInt(17) a;
_BitInt(2) b;

// CHECK: !DIBasicType(name: "_BitInt", size: 8, dataSize: 2, encoding: DW_ATE_signed)
// CHECK: !DIBasicType(name: "unsigned _BitInt", size: 32, dataSize: 17, encoding: DW_ATE_unsigned)
7 changes: 6 additions & 1 deletion llvm/include/llvm/IR/DIBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,15 @@ namespace llvm {
/// \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.
/// \param DataSizeInBits Optionally describes the number of bits used by
/// the value of the object when this is less than the storage size of
/// SizeInBits. Default value of zero indicates the object value and storage
/// sizes are equal.
LLVM_ABI DIBasicType *
createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding,
DINode::DIFlags Flags = DINode::FlagZero,
uint32_t NumExtraInhabitants = 0);
uint32_t NumExtraInhabitants = 0,
uint32_t DataSizeInBits = 0);

/// Create debugging information entry for a binary fixed-point type.
/// \param Name Type name.
Expand Down
78 changes: 48 additions & 30 deletions llvm/include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -891,96 +891,114 @@ class DIBasicType : public DIType {
friend class MDNode;

unsigned Encoding;
/// Describes the number of bits used by the value of the object. Non-zero
/// when the value of an object does not fully occupy the storage size
/// specified by SizeInBits.
uint32_t DataSizeInBits;

protected:
DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
ArrayRef<Metadata *> Ops)
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits,
DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, DIBasicTypeKind, Storage, Tag, 0, AlignInBits,
NumExtraInhabitants, Flags, Ops),
Encoding(Encoding) {}
Encoding(Encoding), DataSizeInBits(DataSizeInBits) {}
DIBasicType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
ArrayRef<Metadata *> Ops)
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits,
DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, ID, Storage, Tag, 0, AlignInBits, NumExtraInhabitants, Flags,
Ops),
Encoding(Encoding) {}
Encoding(Encoding), DataSizeInBits(DataSizeInBits) {}
~DIBasicType() = default;

static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
uint32_t NumExtraInhabitants,
uint32_t DataSizeInBits, DIFlags Flags,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
SizeInBits, AlignInBits, Encoding, NumExtraInhabitants,
Flags, Storage, ShouldCreate);
DataSizeInBits, Flags, Storage, ShouldCreate);
}
static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
uint32_t NumExtraInhabitants,
uint32_t DataSizeInBits, 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);
NumExtraInhabitants, DataSizeInBits, Flags, Storage,
ShouldCreate);
}
LLVM_ABI 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);
LLVM_ABI static DIBasicType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
Metadata *SizeInBits, uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, DIFlags Flags,
StorageType Storage, bool ShouldCreate = true);

TempDIBasicType cloneImpl() const {
return getTemporary(getContext(), getTag(), getRawName(),
getRawSizeInBits(), getAlignInBits(), getEncoding(),
getNumExtraInhabitants(), getFlags());
getNumExtraInhabitants(), getDataSizeInBits(),
getFlags());
}

public:
DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
(Tag, Name, 0, 0, 0, 0, FlagZero))
(Tag, Name, 0, 0, 0, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits),
(Tag, Name, SizeInBits, 0, 0, 0, FlagZero))
(Tag, Name, SizeInBits, 0, 0, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, MDString *Name, uint64_t SizeInBits),
(Tag, Name, SizeInBits, 0, 0, 0, FlagZero))
(Tag, Name, SizeInBits, 0, 0, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding, 0, Flags))
(Tag, Name, SizeInBits, AlignInBits, Encoding, 0, 0, Flags))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding, 0, Flags))
(Tag, Name, SizeInBits, AlignInBits, Encoding, 0, 0, Flags))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding,
NumExtraInhabitants, Flags))
NumExtraInhabitants, 0, Flags))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits,
DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding,
NumExtraInhabitants, DataSizeInBits, Flags))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, MDString *Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags),
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits,
DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding,
NumExtraInhabitants, Flags))
NumExtraInhabitants, DataSizeInBits, Flags))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, MDString *Name, Metadata *SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags),
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits,
DIFlags Flags),
(Tag, Name, SizeInBits, AlignInBits, Encoding,
NumExtraInhabitants, Flags))
NumExtraInhabitants, DataSizeInBits, Flags))

TempDIBasicType clone() const { return cloneImpl(); }

unsigned getEncoding() const { return Encoding; }

uint32_t getDataSizeInBits() const { return DataSizeInBits; }

enum class Signedness { Signed, Unsigned };

/// Return the signedness of this type, or std::nullopt if this type is
Expand Down Expand Up @@ -1010,7 +1028,7 @@ class DIFixedPointType : public DIBasicType {
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags,
unsigned Kind, int Factor, ArrayRef<Metadata *> Ops)
: DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits,
Encoding, 0, Flags, Ops),
Encoding, 0, 0, Flags, Ops),
Kind(Kind), Factor(Factor) {
assert(Kind == FixedPointBinary || Kind == FixedPointDecimal);
}
Expand All @@ -1019,7 +1037,7 @@ class DIFixedPointType : public DIBasicType {
unsigned Kind, APInt Numerator, APInt Denominator,
ArrayRef<Metadata *> Ops)
: DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits,
Encoding, 0, Flags, Ops),
Encoding, 0, 0, Flags, Ops),
Kind(Kind), Factor(0), Numerator(Numerator), Denominator(Denominator) {
assert(Kind == FixedPointRational);
}
Expand All @@ -1028,7 +1046,7 @@ class DIFixedPointType : public DIBasicType {
unsigned Kind, int Factor, APInt Numerator,
APInt Denominator, ArrayRef<Metadata *> Ops)
: DIBasicType(C, DIFixedPointTypeKind, Storage, Tag, AlignInBits,
Encoding, 0, Flags, Ops),
Encoding, 0, 0, Flags, Ops),
Kind(Kind), Factor(Factor), Numerator(Numerator),
Denominator(Denominator) {}
~DIFixedPointType() = default;
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5642,16 +5642,17 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(name, MDStringField, ); \
OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(dataSize, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(encoding, DwarfAttEncodingField, ); \
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(flags, DIFlagField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val,
size.getValueAsMetadata(Context),
align.Val, encoding.Val,
num_extra_inhabitants.Val, flags.Val));
Result = GET_OR_DISTINCT(
DIBasicType,
(Context, tag.Val, name.Val, size.getValueAsMetadata(Context), align.Val,
encoding.Val, num_extra_inhabitants.Val, dataSize.Val, flags.Val));
return false;
}

Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Bitcode/Reader/MetadataLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_BASIC_TYPE: {
if (Record.size() < 6 || Record.size() > 8)
if (Record.size() < 6 || Record.size() > 9)
return error("Invalid record");

IsDistinct = Record[0] & 1;
Expand All @@ -1540,13 +1540,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
? static_cast<DINode::DIFlags>(Record[6])
: DINode::FlagZero;
uint32_t NumExtraInhabitants = (Record.size() > 7) ? Record[7] : 0;

uint32_t DataSizeInBits = (Record.size() > 8) ? Record[8] : 0;
Metadata *SizeInBits = getMetadataOrConstant(SizeIsMetadata, Record[3]);

MetadataList.assignValue(
GET_OR_DISTINCT(DIBasicType,
(Context, Record[1], getMDString(Record[2]), SizeInBits,
Record[4], Record[5], NumExtraInhabitants, Flags)),
Record[4], Record[5], NumExtraInhabitants,
DataSizeInBits, Flags)),
NextMetadataNo);
NextMetadataNo++;
break;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1925,6 +1925,7 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
Record.push_back(N->getEncoding());
Record.push_back(N->getFlags());
Record.push_back(N->getNumExtraInhabitants());
Record.push_back(N->getDataSizeInBits());

Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev);
Record.clear();
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1793,9 +1793,13 @@ void DwarfCompileUnit::createBaseTypeDIEs() {
"_" + Twine(Btr.BitSize)).toStringRef(Str));
addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
// Round up to smallest number of bytes that contains this number of bits.
// ExprRefedBaseTypes is populated with types referenced by
// DW_OP_LLVM_convert operations in location expressions. These are often
// byte-sized, but one common counter-example is 1-bit sized conversions
// from `i1` types. TODO: Should these use DW_AT_bit_size? See
// DwarfUnit::constructTypeDIE.
addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,
divideCeil(Btr.BitSize, 8));

Btr.Die = &Die;
}
}
Expand Down
15 changes: 13 additions & 2 deletions llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,8 +766,19 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
BTy->getEncoding());

uint64_t Size = BTy->getSizeInBits() >> 3;
addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);
uint64_t SizeInBytes = divideCeil(BTy->getSizeInBits(), 8);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know GCC emits both bit-size and byte-size, but is the byte-size here really useful if we have the bit-size?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm personally in favour of doing whatever is least surprising. I need to check with our debugger folks if they'd be ok with only keeping one, but if that's not the case we could stick it behind SCE tuning, if you feel strongly here about only emitting one? (@dwblaikie might also have opinions?)

FWIW LLDB doesn't seem to understand bit_size in this context (see this comment), though I haven't tried the same example emitting only bit_size (it could reasonably be that seeing both is confusing it? equally it might just not expect bit_size in this context).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this thing has a byte storage size, even if the arithmetic is done exactly to the number of bits specified? So I'd imagine we could want both - though it'd be a bit out-of-DWARF-spec which says a base type should have only one or the other. I guess really the thing has a byte_size, and a "number of bits used for arithmetic" - it's not really the size of the object, it's to do with the encoding/how the bits are used.

But I don't especially mind if we use the bit_size to encode "number of bits used for arithmetic", especially if GCC's already doing it.

Maybe file a DWARF issue as well.

Copy link
Contributor Author

@OCHyams OCHyams Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

though it'd be a bit out-of-DWARF-spec which says a base type should have only one or the other.

My optimisitic interpretation of the DWARF spec is that it especially is it allows it for base types (chpt 5, page end of 103 to top of 104):

A base type entry has a DW_AT_byte_size attribute or a DW_AT_bit_size attribute. [...] If the value of an object of the given type does not fully occupy the storage described by a byte size attribute, the base type entry may also have a DW_AT_bit_size and a DW_AT_data_bit_offset attribute

It says both "or" and "and" which is a bit ambiguous, but other types only say "or".

Copy link
Contributor Author

@OCHyams OCHyams Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I misunderstood what you were saying about the byte storage size. I get it now, I'll look into it tomorrow

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think the quoted parts you mentioned do refute/address my concerns - though perhaps the spec expects us to also emit a DW_AT_data_bit_offset of zero in this case? Again, I don't mind matching GCC if it's just a bit weird - though it wouldn't be hard or expensive to add DW_AT_data_bit_offset as well (especially if it's just always 0 and can be stored in the abbrev with implicit_const - but I guess that depends where the padding is and where the bits are stored (if they're LSB or MSB, etc))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the missing data_bit_offset in this case is ok too - the bit I quoted continues on a few sentences later:

The data bit offset attribute is the offset in bits from the beginning of the containing storage to the beginning of the value. Bits that are part of the offset are padding. If this attribute is omitted a default data bit offset of zero is assumed.

GCC gives us this DWARF:

0x000000a1:   DW_TAG_base_type
                DW_AT_byte_size (0x02)
                DW_AT_encoding  (DW_ATE_signed)
                DW_AT_bit_size  (0x0f)
                DW_AT_name      ("_BitInt(15)")

The only difference between that and my patched Clang is that our name is _BitInt and GCC's is _BitInt(15). (I'm happy to change that? not sure what's best - I suppose there's value to users if the bit-count is showing up in types in the debugger)

Copy link
Member

@Michael137 Michael137 Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only difference between that and my patched Clang is that our name is _BitInt and GCC's is _BitInt(15)

At least for LLDB, I'd have to double check how the type-name ends up being displayed. If it just uses the DW_AT_name then that would be great! But if we eventually can just create a clang::BitIntType from this DIE and the bit-ness, I think Clang's TypePrinter is capable of printing the typename as we would expect:

void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
if (T->isUnsigned())
OS << "unsigned ";
OS << "_BitInt(" << T->getNumBits() << ")";
spaceBeforePlaceHolder(OS);
}

In fact including the bit-ness in the name might make this a bit harder for LLDB. But probably still doable.

Not opposed to aligning with GCC either though. And might be useful for other consumers 🤷‍♂️ But maybe best for a separate patch?

There was an LLDB issue around _BitInt a while ago where we talked about what would need to be done to support the type properly: #110273 (comment)

addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, SizeInBytes);
if (BTy->getTag() == dwarf::Tag::DW_TAG_base_type) {
// DW_TAG_base_type:
// If the value of an object of the given type does not fully occupy the
// storage described by a byte size attribute, the base type entry may also
// have a DW_AT_bit_size [...] attribute.
// TODO: Do big endian targets need DW_AT_data_bit_offset? See discussion in
// pull request #164372.
if (uint64_t DataSizeInBits = BTy->getDataSizeInBits();
DataSizeInBits && DataSizeInBits != SizeInBytes * 8)
addUInt(Buffer, dwarf::DW_AT_bit_size, std::nullopt, DataSizeInBits);
}

if (BTy->isBigEndian())
addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2199,6 +2199,7 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
Printer.printString("name", N->getName());
Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
Printer.printInt("dataSize", N->getDataSizeInBits());
Printer.printDwarfEnum("encoding", N->getEncoding(),
dwarf::AttributeEncodingString);
Printer.printInt("num_extra_inhabitants", N->getNumExtraInhabitants());
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/IR/DIBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,12 @@ DIBasicType *DIBuilder::createNullPtrType() {
DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
unsigned Encoding,
DINode::DIFlags Flags,
uint32_t NumExtraInhabitants) {
uint32_t NumExtraInhabitants,
uint32_t DataSizeInBits) {
assert(!Name.empty() && "Unable to create type without name");
return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,
0, Encoding, NumExtraInhabitants, Flags);
0, Encoding, NumExtraInhabitants, DataSizeInBits,
Flags);
}

DIFixedPointType *
Expand Down
15 changes: 9 additions & 6 deletions llvm/lib/IR/DebugInfoMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,15 +872,18 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, DIFlags Flags,
uint32_t NumExtraInhabitants,
uint32_t DataSizeInBits, DIFlags Flags,
StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits,
Encoding, NumExtraInhabitants, Flags));
DEFINE_GETIMPL_LOOKUP(DIBasicType,
(Tag, Name, SizeInBits, AlignInBits, Encoding,
NumExtraInhabitants, DataSizeInBits, Flags));
Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr};
DEFINE_GETIMPL_STORE(DIBasicType,
(Tag, AlignInBits, Encoding, NumExtraInhabitants, Flags),
Ops);
DEFINE_GETIMPL_STORE(
DIBasicType,
(Tag, AlignInBits, Encoding, NumExtraInhabitants, DataSizeInBits, Flags),
Ops);
}

std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/IR/LLVMContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,27 +480,30 @@ template <> struct MDNodeKeyImpl<DIBasicType> {
uint32_t AlignInBits;
unsigned Encoding;
uint32_t NumExtraInhabitants;
uint32_t DataSizeInBits;
unsigned Flags;

MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *SizeInBits,
uint32_t AlignInBits, unsigned Encoding,
uint32_t NumExtraInhabitants, unsigned Flags)
uint32_t NumExtraInhabitants, uint32_t DataSizeInBits,
unsigned Flags)
: Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
Encoding(Encoding), NumExtraInhabitants(NumExtraInhabitants),
Flags(Flags) {}
DataSizeInBits(DataSizeInBits), Flags(Flags) {}
MDNodeKeyImpl(const DIBasicType *N)
: Tag(N->getTag()), Name(N->getRawName()),
SizeInBits(N->getRawSizeInBits()), AlignInBits(N->getAlignInBits()),
Encoding(N->getEncoding()),
NumExtraInhabitants(N->getNumExtraInhabitants()), Flags(N->getFlags()) {
}
NumExtraInhabitants(N->getNumExtraInhabitants()),
DataSizeInBits(N->getDataSizeInBits()), Flags(N->getFlags()) {}

bool isKeyOf(const DIBasicType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
SizeInBits == RHS->getRawSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
Encoding == RHS->getEncoding() &&
NumExtraInhabitants == RHS->getNumExtraInhabitants() &&
DataSizeInBits == RHS->getDataSizeInBits() &&
Flags == RHS->getFlags();
}

Expand Down
Loading
Loading