diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 5c8efdf1fb6f3..1acba96bc273a 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -264,7 +264,8 @@ namespace llvm { createPointerType(DIType *PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits = 0, std::optional DWARFAddressSpace = std::nullopt, - StringRef Name = "", DINodeArray Annotations = nullptr); + StringRef Name = "", DINodeArray Annotations = nullptr, + uint32_t NumExtraInhabitants = 0, DIScope *Scope = nullptr); /// Create a __ptrauth qualifier. DIDerivedType *createPtrAuthQualifiedType(DIType *FromTy, unsigned Key, diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index f2ad3f0183ca9..b3e5ba71b33ab 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1009,12 +1009,12 @@ class DIDerivedType : public DIType { DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, + uint64_t OffsetInBits, uint32_t NumExtraInhabitants, std::optional DWARFAddressSpace, std::optional PtrAuthData, DIFlags Flags, ArrayRef Ops) : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, - AlignInBits, OffsetInBits, 0, Flags, Ops), + AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops), DWARFAddressSpace(DWARFAddressSpace) { if (PtrAuthData) SubclassData32 = PtrAuthData->Payload.RawData; @@ -1024,51 +1024,57 @@ class DIDerivedType : public DIType { getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, std::optional - PtrAuthData, DIFlags Flags, Metadata *ExtraData, DINodeArray - Annotations, StorageType Storage, bool ShouldCreate = true) { + uint32_t NumExtraInhabitants, + std::optional DWARFAddressSpace, + std::optional 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, - Annotations.get(), Storage, ShouldCreate); + NumExtraInhabitants, DWARFAddressSpace, PtrAuthData, Flags, + ExtraData, Annotations.get(), Storage, ShouldCreate); } 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, - std::optional DWARFAddressSpace, std::optional PtrAuthData, - DIFlags Flags, Metadata *ExtraData, Metadata *Annotations, - StorageType Storage, bool ShouldCreate = true); + uint32_t NumExtraInhabitants, + std::optional DWARFAddressSpace, + std::optional 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()); + getNumExtraInhabitants(), getDWARFAddressSpace(), getPtrAuthData(), + getFlags(), getExtraData(), getAnnotations()); } 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, - std::optional DWARFAddressSpace, std::optional PtrAuthData, DIFlags Flags, - Metadata *ExtraData = nullptr, - Metadata *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, - uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, std::optional 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, Metadata *File, unsigned Line, + Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t NumExtraInhabitants, std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData = nullptr, Metadata *Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, NumExtraInhabitants, DWARFAddressSpace, PtrAuthData, Flags, + ExtraData, Annotations)) + DEFINE_MDNODE_GET( + DIDerivedType, + (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, + DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t NumExtraInhabitants, std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData = nullptr, DINodeArray Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, NumExtraInhabitants, DWARFAddressSpace, PtrAuthData, Flags, + ExtraData, Annotations)) TempDIDerivedType clone() const { return cloneImpl(); } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f9a3fcfd1fb8b..bf37577b9d282 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5024,6 +5024,7 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \ + OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(extraData, MDField, ); \ OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \ @@ -5043,11 +5044,11 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { (unsigned)ptrAuthKey.Val, ptrAuthIsAddressDiscriminated.Val, (unsigned)ptrAuthExtraDiscriminator.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.Val, align.Val, offset.Val, + num_extra_inhabitants.Val, DWARFAddressSpace, PtrAuthData, + flags.Val, extraData.Val, annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 612a06d8cc72c..b823ce83e013d 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1539,7 +1539,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_DERIVED_TYPE: { - if (Record.size() < 12 || Record.size() > 15) + if (Record.size() < 12 || Record.size() > 16) return error("Invalid record"); // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means @@ -1553,19 +1553,24 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( Annotations = getMDOrNull(Record[13]); std::optional PtrAuthData; - if (Record.size() > 14 && Record[14]) + // We encode UINT32_MAX as the null case of PtrAuthData. + if (Record.size() > 14 && Record[14] && Record[14] != UINT32_MAX) PtrAuthData = DIDerivedType::PtrAuthData(Record[14]); + uint32_t NumExtraInhabitants = 0; + if (Record.size() > 15) + NumExtraInhabitants = Record[15]; + IsDistinct = Record[0]; DINode::DIFlags Flags = static_cast(Record[10]); 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[11]), Annotations)), + 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], + NumExtraInhabitants, DWARFAddressSpace, PtrAuthData, Flags, + getDITypeRefOrNull(Record[11]), Annotations)), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 6e89e92d17005..31677065615e5 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1744,8 +1744,19 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, Record.push_back(0); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); - if (auto PtrAuthData = N->getPtrAuthData()) + auto NumExtraInhabitants = N->getNumExtraInhabitants(); + auto PtrAuthData = N->getPtrAuthData(); + + if (PtrAuthData) Record.push_back(PtrAuthData->Payload.RawData); + else if (NumExtraInhabitants) + // If there is no PtrAuthData, but NumExtraInhabitants exists, emit + // PtrAuthData as UINT32_MAX as a representation of the null case. We need + // this to disambiguate between the two fields as they're both optional. + Record.push_back(UINT32_MAX); + + if (NumExtraInhabitants) + Record.push_back(NumExtraInhabitants); Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index b745b5ba6b274..5b016cf30628c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -790,6 +790,15 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { && Tag != dwarf::DW_TAG_rvalue_reference_type) addUInt(Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size); + // Add align info if available. + if (uint32_t AlignInBytes = DTy->getAlignInBytes()) + addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, AlignInBytes); + + if (uint32_t NumExtraInhabitants = DTy->getNumExtraInhabitants()) { + addUInt(Buffer, dwarf::DW_AT_APPLE_num_extra_inhabitants, std::nullopt, + NumExtraInhabitants); + } + if (Tag == dwarf::DW_TAG_ptr_to_member_type) addDIEEntry(Buffer, dwarf::DW_AT_containing_type, *getOrCreateTypeDIE(cast(DTy)->getClassType())); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index b61d217ec90a5..676379028152d 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2048,6 +2048,8 @@ static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N, Printer.printBool("ptrAuthIsAddressDiscriminated", *AddrDisc); if (auto Disc = N->getPtrAuthExtraDiscriminator()) Printer.printInt("ptrAuthExtraDiscriminator", *Disc); + if (auto NumExtraInhabitants = N->getNumExtraInhabitants()) + Printer.printInt("num_extra_inhabitants", NumExtraInhabitants); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 2ef7d91a43fee..8af87f80f8821 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -296,8 +296,11 @@ 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, /*Name=*/"", /*File=*/nullptr, /*Line=*/0, + /*Scope=*/nullptr, FromTy, /*SizeInBits=*/0, + /*AlignInBits=*/0, /*OffsetInBits=*/0, /*NumExtraInhabitants=*/0, + std::nullopt, std::nullopt, DINode::FlagZero); } DIDerivedType * @@ -305,23 +308,25 @@ DIBuilder::createPtrAuthQualifiedType(DIType *FromTy, unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator) { return DIDerivedType::get( - VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", nullptr, 0, nullptr, - FromTy, 0, 0, 0, std::nullopt, + VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, /*Name=*/"", /*File=*/nullptr, + /*Line=*/0, /*Scope=*/nullptr, FromTy, /*SizeInBits=*/0, + /*AlignInBits=*/0, /*OffsetInBits=*/0, /*NumExtraInhabitants=*/0, + std::nullopt, std::optional( {Key, IsAddressDiscriminated, ExtraDiscriminator}), DINode::FlagZero); } -DIDerivedType * -DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits, - uint32_t AlignInBits, - std::optional DWARFAddressSpace, - StringRef Name, DINodeArray Annotations) { +DIDerivedType *DIBuilder::createPointerType( + DIType *PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits, + std::optional DWARFAddressSpace, StringRef Name, + DINodeArray Annotations, uint32_t NumExtraInhabitants, DIScope *Scope) { // FIXME: Why is there a name here? - return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name, - nullptr, 0, nullptr, PointeeTy, SizeInBits, - AlignInBits, 0, DWARFAddressSpace, std::nullopt, DINode::FlagZero, - nullptr, Annotations); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_pointer_type, Name, + /*File=*/nullptr, /*Line=*/0, Scope, PointeeTy, SizeInBits, + AlignInBits, /*OffsetInBits=*/0, NumExtraInhabitants, + DWARFAddressSpace, std::nullopt, DINode::FlagZero, nullptr, Annotations); } DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, @@ -329,9 +334,11 @@ DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags) { - return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "", - nullptr, 0, nullptr, PointeeTy, SizeInBits, - AlignInBits, 0, std::nullopt, std::nullopt, Flags, Base); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_ptr_to_member_type, /*Name=*/"", + /*File=*/nullptr, /*Line=*/0, /*Scope=*/nullptr, PointeeTy, SizeInBits, + AlignInBits, /*OffsetInBits=*/0, /*NumExtraInhabitants=*/0, std::nullopt, + std::nullopt, Flags, Base); } DIDerivedType * @@ -339,9 +346,10 @@ DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits, uint32_t AlignInBits, std::optional DWARFAddressSpace) { assert(RTy && "Unable to create reference type"); - return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy, - SizeInBits, AlignInBits, 0, DWARFAddressSpace, {}, - DINode::FlagZero); + return DIDerivedType::get( + VMContext, Tag, /*Name=*/"", /*File=*/nullptr, /*Line=*/0, + /*Scope=*/nullptr, RTy, SizeInBits, AlignInBits, /*OffsetInBits=*/0, + /*NumExtraInhabitants=*/0, DWARFAddressSpace, {}, DINode::FlagZero); } DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, @@ -350,16 +358,20 @@ 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, + /*SizeInBits=*/0, AlignInBits, /*OffsetInBits=*/0, + /*NumExtraInhabitants=*/0, std::nullopt, + std::nullopt, Flags, nullptr, 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); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_friend, /*Name=*/"", /*File=*/nullptr, + /*Line=*/0, Ty, FriendTy, + /*SizeInBits=*/0, /*AlignInBits=*/0, /*OffsetInBits=*/0, + /*NumExtraInhabitants=*/0, std::nullopt, std::nullopt, DINode::FlagZero); } DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, @@ -370,8 +382,9 @@ DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, Metadata *ExtraData = ConstantAsMetadata::get( ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset)); return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr, - 0, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt, std::nullopt, - Flags, ExtraData); + /*Line=*/0, Ty, BaseTy, /*SizeInBits=*/0, + /*AlignInBits=*/0, /*OffsetInBits=*/0, BaseOffset, + std::nullopt, std::nullopt, Flags, ExtraData); } DIDerivedType *DIBuilder::createMemberType( @@ -380,8 +393,9 @@ DIDerivedType *DIBuilder::createMemberType( 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); + SizeInBits, AlignInBits, OffsetInBits, + /*NumExtraInhabitants=*/0, std::nullopt, + std::nullopt, Flags, nullptr, Annotations); } static ConstantAsMetadata *getConstantOrNull(Constant *C) { @@ -394,10 +408,11 @@ DIDerivedType *DIBuilder::createVariantMemberType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) { - return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, - LineNumber, getNonCompileUnitScope(Scope), Ty, - SizeInBits, AlignInBits, OffsetInBits, std::nullopt, std::nullopt, - Flags, getConstantOrNull(Discriminant)); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits, + /*NumExtraInhabitants=*/0, std::nullopt, std::nullopt, Flags, + getConstantOrNull(Discriminant)); } DIDerivedType *DIBuilder::createBitFieldMemberType( @@ -407,8 +422,8 @@ DIDerivedType *DIBuilder::createBitFieldMemberType( 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, + getNonCompileUnitScope(Scope), Ty, SizeInBits, /* AlignInBits=*/ 0, + OffsetInBits, /*NumExtraInhabitants=*/ 0, std::nullopt, std::nullopt, Flags, ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64), StorageOffsetInBits)), Annotations); @@ -421,9 +436,10 @@ DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, uint32_t AlignInBits) { Flags |= DINode::FlagStaticMember; return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, - LineNumber, getNonCompileUnitScope(Scope), Ty, 0, - AlignInBits, 0, std::nullopt, std::nullopt, Flags, - getConstantOrNull(Val)); + LineNumber, getNonCompileUnitScope(Scope), Ty, + /*SizeInBits=*/ 0, AlignInBits, /*OffsetInBits=*/ 0, + /*NumExtraInhabitants=*/ 0, std::nullopt, + std::nullopt, Flags, getConstantOrNull(Val)); } DIDerivedType * @@ -433,8 +449,9 @@ DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber, DIType *Ty, MDNode *PropertyNode) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(File), Ty, - SizeInBits, AlignInBits, OffsetInBits, std::nullopt, std::nullopt, - Flags, PropertyNode); + SizeInBits, AlignInBits, OffsetInBits, + /*NumExtraInhabitants=*/ 0, std::nullopt, + std::nullopt, Flags, PropertyNode); } DIObjCProperty * @@ -572,10 +589,10 @@ DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, DIType *Ty) { - auto *R = - DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, LineNo, - getNonCompileUnitScope(Scope), Ty, SizeInBits, - AlignInBits, 0, std::nullopt, std::nullopt, DINode::FlagZero); + auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, + LineNo, getNonCompileUnitScope(Scope), Ty, + SizeInBits, AlignInBits, 0, 0, std::nullopt, + std::nullopt, DINode::FlagZero); trackIfUnresolved(R); return R; } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 56ae2f084ce36..b1811520eb498 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -729,18 +729,19 @@ 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, - std::optional DWARFAddressSpace, std::optional PtrAuthData, - DIFlags Flags, Metadata *ExtraData, Metadata *Annotations, - StorageType Storage, bool ShouldCreate) { + uint32_t AlignInBits, uint64_t OffsetInBits, uint32_t NumExtraInhabitants, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, + Metadata *Annotations, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIDerivedType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, - Flags, ExtraData, Annotations)); + AlignInBits, OffsetInBits, NumExtraInhabitants, + DWARFAddressSpace, PtrAuthData, Flags, ExtraData, + Annotations)); Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations}; DEFINE_GETIMPL_STORE( - DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, + DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, DWARFAddressSpace, PtrAuthData, Flags), Ops); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index e30d57777a0c9..a4492a6bf4a6b 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -544,6 +544,7 @@ template <> struct MDNodeKeyImpl { Metadata *BaseType; uint64_t SizeInBits; uint64_t OffsetInBits; + uint32_t NumExtraInhabitants; uint32_t AlignInBits; std::optional DWARFAddressSpace; std::optional PtrAuthData; @@ -554,19 +555,22 @@ template <> struct MDNodeKeyImpl { MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t NumExtraInhabitants, std::optional DWARFAddressSpace, std::optional PtrAuthData, unsigned Flags, Metadata *ExtraData, Metadata *Annotations) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), - AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), - PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData), - Annotations(Annotations) {} + NumExtraInhabitants(NumExtraInhabitants), AlignInBits(AlignInBits), + DWARFAddressSpace(DWARFAddressSpace), PtrAuthData(PtrAuthData), + Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {} 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()), + OffsetInBits(N->getOffsetInBits()), + NumExtraInhabitants(N->getNumExtraInhabitants()), + AlignInBits(N->getAlignInBits()), DWARFAddressSpace(N->getDWARFAddressSpace()), PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()), ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} @@ -578,9 +582,11 @@ template <> struct MDNodeKeyImpl { SizeInBits == RHS->getSizeInBits() && AlignInBits == RHS->getAlignInBits() && OffsetInBits == RHS->getOffsetInBits() && + NumExtraInhabitants == RHS->getNumExtraInhabitants() && DWARFAddressSpace == RHS->getDWARFAddressSpace() && PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() && - ExtraData == RHS->getRawExtraData() && Annotations == RHS->getRawAnnotations(); + ExtraData == RHS->getRawExtraData() && + Annotations == RHS->getRawAnnotations(); } unsigned getHashValue() const { diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll index f9b285a4c0d5a..cbbc6fc22fb1f 100644 --- a/llvm/test/Assembler/debug-info.ll +++ b/llvm/test/Assembler/debug-info.ll @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45} +; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46} ; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -108,3 +108,6 @@ ;CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !10, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") !45 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !12, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") + +;CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 32, align: 32, dwarfAddressSpace: 1, num_extra_inhabitants: 42) +!46 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32, dwarfAddressSpace: 1, num_extra_inhabitants: 42) diff --git a/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll b/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll index 7c552aa10e29c..570ab9ddc5864 100644 --- a/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll +++ b/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll @@ -6,10 +6,15 @@ ; CHECK: DW_TAG_structure_type ; CHECK: DW_AT_APPLE_num_extra_inhabitants (0x42) + + +; CHECK: DW_TAG_pointer_type +; CHECK: DW_AT_APPLE_num_extra_inhabitants (0x64) target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" @p = common global i8* null, align 8, !dbg !0 @q = common global i8* null, align 8, !dbg !8 +@r = common global i8* null, align 8, !dbg !12 !llvm.dbg.cu = !{!2} !llvm.module.flags = !{!6, !7} @@ -19,7 +24,7 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5) !3 = !DIFile(filename: "/tmp/p.c", directory: "/") !4 = !{} -!5 = !{!0, !8} +!5 = !{!0, !8, !12} !6 = !{i32 2, !"Dwarf Version", i32 4} !7 = !{i32 2, !"Debug Info Version", i32 3} @@ -27,4 +32,7 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" !9 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true) !10 = !DIBasicType(name: "ExtraInhabitantBasicType", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254) !11 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !3, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") +!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression()) +!13 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !14, isLocal: false, isDefinition: true) +!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 32, align: 32, dwarfAddressSpace: 1, num_extra_inhabitants: 100) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index cf75a5b5967d3..2108e9a887cb7 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -104,9 +104,10 @@ class MetadataTest : public testing::Test { return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); } DIType *getDerivedType() { - return DIDerivedType::getDistinct( - Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, - getBasicType("basictype"), 1, 2, 0, std::nullopt, {}, DINode::FlagZero); + return DIDerivedType::getDistinct(Context, dwarf::DW_TAG_pointer_type, "", + nullptr, 0, nullptr, + getBasicType("basictype"), 1, 2, 0, 3, + std::nullopt, {}, DINode::FlagZero); } Constant *getConstant() { return ConstantInt::get(Type::getInt32Ty(Context), Counter++); @@ -461,7 +462,7 @@ TEST_F(MDNodeTest, PrintTree) { auto *StructTy = cast(getCompositeType()); DIType *PointerTy = DIDerivedType::getDistinct( Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, StructTy, - 1, 2, 0, std::nullopt, {}, DINode::FlagZero); + 1, 2, 0, 3, std::nullopt, {}, DINode::FlagZero); StructTy->replaceElements(MDTuple::get(Context, PointerTy)); auto *Var = DILocalVariable::get(Context, Scope, "foo", File, @@ -1875,9 +1876,9 @@ TEST_F(DIDerivedTypeTest, get) { auto *N = DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, - BaseType, 2, 3, 4, DWARFAddressSpace, std::nullopt, Flags5, ExtraData); + BaseType, 2, 3, 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData); auto *N1 = DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", - File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, + File, 1, Scope, N, 2, 3, 4, 5, DWARFAddressSpace, PtrAuthData, Flags5, ExtraData); EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag()); EXPECT_EQ("something", N->getName()); @@ -1888,6 +1889,7 @@ TEST_F(DIDerivedTypeTest, get) { EXPECT_EQ(2u, N->getSizeInBits()); EXPECT_EQ(3u, N->getAlignInBits()); EXPECT_EQ(4u, N->getOffsetInBits()); + EXPECT_EQ(5u, N->getNumExtraInhabitants()); EXPECT_EQ(DWARFAddressSpace, *N->getDWARFAddressSpace()); EXPECT_EQ(std::nullopt, N->getPtrAuthData()); EXPECT_EQ(PtrAuthData, N1->getPtrAuthData()); @@ -1895,59 +1897,63 @@ TEST_F(DIDerivedTypeTest, get) { EXPECT_EQ(ExtraData, N->getExtraData()); EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else", - File, 1, Scope, BaseType, 2, 3, 4, + File, 1, Scope, BaseType, 2, 3, 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", getFile(), 1, Scope, BaseType, 2, - 3, 4, DWARFAddressSpace, std::nullopt, Flags5, + 3, 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 2, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, getSubprogram(), - BaseType, 2, 3, 4, DWARFAddressSpace, + BaseType, 2, 3, 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE( N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", - File, 1, Scope, getBasicType("basic2"), 2, 3, 4, + File, 1, Scope, getBasicType("basic2"), 2, 3, 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 3, 3, - 4, DWARFAddressSpace, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 2, - 4, DWARFAddressSpace, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 5, DWARFAddressSpace, std::nullopt, Flags5, + 5, 5, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); + EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, + "something", File, 1, Scope, BaseType, 2, 2, + 4, 6, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace + 1, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace + 1, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N1, DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, - "", File, 1, Scope, N, 2, 3, 4, + "", File, 1, Scope, N, 2, 3, 4, 5, DWARFAddressSpace, std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, std::nullopt, Flags4, + 4, 5, DWARFAddressSpace, std::nullopt, Flags4, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, std::nullopt, Flags5, + 4, 5, DWARFAddressSpace, std::nullopt, Flags5, getTuple())); TempDIDerivedType Temp = N->clone(); @@ -1966,16 +1972,18 @@ TEST_F(DIDerivedTypeTest, getWithLargeValues) { auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, - std::nullopt, Flags, ExtraData); + UINT32_MAX - 4, std::nullopt, Flags, ExtraData); EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits()); - EXPECT_EQ(UINT32_MAX - 3, *N->getDWARFAddressSpace()); + EXPECT_EQ(UINT32_MAX - 3, N->getNumExtraInhabitants()); + EXPECT_EQ(UINT32_MAX - 4, *N->getDWARFAddressSpace()); - auto *N1 = DIDerivedType::get( - Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", File, 1, Scope, N, - UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, - DIDerivedType::PtrAuthData(7, true, 0xffff), Flags, ExtraData); + auto *N1 = DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", + File, 1, Scope, N, UINT64_MAX, UINT32_MAX - 1, + UINT64_MAX - 2, UINT32_MAX - 3, UINT32_MAX - 4, + DIDerivedType::PtrAuthData(7, true, 0xffff), + Flags, ExtraData); EXPECT_EQ(7U, *N1->getPtrAuthKey()); EXPECT_EQ(true, *N1->isPtrAuthAddressDiscriminated()); EXPECT_EQ(0xffffU, *N1->getPtrAuthExtraDiscriminator());