diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index 9336f2a454ae47..caf8f055e6e4cd 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -617,6 +617,7 @@ HANDLE_DW_AT(0x3e07, LLVM_apinotes, 0, APPLE) HANDLE_DW_AT(0x3e08, LLVM_ptrauth_isa_pointer, 0, LLVM) HANDLE_DW_AT(0x3e09, LLVM_ptrauth_authenticates_null_values, 0, LLVM) HANDLE_DW_AT(0x3e0a, LLVM_ptrauth_authentication_mode, 0, LLVM) +HANDLE_DW_AT(0x3e0b, LLVM_num_extra_inhabitants, 0, LLVM) // Apple extensions. diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index a5655f630fc4f0..046890d0c7e1f1 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -225,9 +225,13 @@ namespace llvm { /// \param SizeInBits Size of the type. /// \param Encoding DWARF encoding code, e.g., dwarf::DW_ATE_float. /// \param Flags Optional DWARF attributes, e.g., DW_AT_endianity. + /// \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. DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, - DINode::DIFlags Flags = DINode::FlagZero); + DINode::DIFlags Flags = DINode::FlagZero, + uint32_t NumExtraInhabitants = 0); /// Create debugging information entry for a string /// type. @@ -484,11 +488,15 @@ namespace llvm { /// \param Elements Struct elements. /// \param RunTimeLang Optional parameter, Objective-C runtime version. /// \param UniqueIdentifier A unique identifier for the struct. + /// \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, uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0, - DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = ""); + DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "", + uint32_t NumExtraInhabitants = 0); /// Create debugging information entry for an union. /// \param Scope Scope in which this union is defined. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index d2b4e900438d37..5c8394e45c9d7f 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -712,31 +712,38 @@ class DIType : public DIScope { DIFlags Flags; uint64_t SizeInBits; uint64_t OffsetInBits; + uint32_t NumExtraInhabitants; protected: DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, DIFlags Flags, ArrayRef Ops) + uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags, + ArrayRef Ops) : DIScope(C, ID, Storage, Tag, Ops) { - init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags); + init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, + Flags); } ~DIType() = default; void init(unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, DIFlags Flags) { + uint64_t OffsetInBits, 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, DIFlags Flags) { + uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t NumExtraInhabitants, DIFlags Flags) { assert(isDistinct() && "Only distinct nodes can mutate"); setTag(Tag); - init(Line, SizeInBits, AlignInBits, OffsetInBits, Flags); + init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, + Flags); } public: @@ -749,6 +756,7 @@ class DIType : public DIScope { 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; } DIScope *getScope() const { return cast_or_null(getRawScope()); } @@ -820,49 +828,63 @@ class DIBasicType : public DIType { DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, ArrayRef Ops) + uint32_t NumExtraInhabitants, DIFlags Flags, + ArrayRef Ops) : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, - Flags, Ops), + NumExtraInhabitants, Flags, Ops), Encoding(Encoding) {} ~DIBasicType() = default; static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, - bool ShouldCreate = true) { + uint32_t NumExtraInhabitants, DIFlags Flags, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), - SizeInBits, AlignInBits, Encoding, Flags, Storage, - ShouldCreate); + SizeInBits, AlignInBits, Encoding, NumExtraInhabitants, + Flags, Storage, ShouldCreate); } static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, - bool ShouldCreate = true); + uint32_t NumExtraInhabitants, DIFlags Flags, + StorageType Storage, bool ShouldCreate = true); TempDIBasicType cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getSizeInBits(), - getAlignInBits(), getEncoding(), getFlags()); + getAlignInBits(), getEncoding(), + getNumExtraInhabitants(), getFlags()); } public: DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name), - (Tag, Name, 0, 0, 0, FlagZero)) + (Tag, Name, 0, 0, 0, 0, FlagZero)) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name, uint64_t SizeInBits), - (Tag, Name, SizeInBits, 0, 0, FlagZero)) + (Tag, Name, SizeInBits, 0, 0, 0, FlagZero)) DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, MDString *Name, uint64_t SizeInBits), - (Tag, Name, SizeInBits, 0, 0, FlagZero)) + (Tag, Name, SizeInBits, 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, Flags)) + (Tag, Name, SizeInBits, AlignInBits, Encoding, 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, Flags)) + (Tag, Name, SizeInBits, AlignInBits, Encoding, 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)) + DEFINE_MDNODE_GET(DIBasicType, + (unsigned Tag, MDString *Name, uint64_t SizeInBits, + uint32_t AlignInBits, unsigned Encoding, + uint32_t NumExtraInhabitants, DIFlags Flags), + (Tag, Name, SizeInBits, AlignInBits, Encoding, + NumExtraInhabitants, Flags)) TempDIBasicType clone() const { return cloneImpl(); } @@ -890,7 +912,7 @@ class DIStringType : public DIType { uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, ArrayRef Ops) : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0, - FlagZero, Ops), + 0, FlagZero, Ops), Encoding(Encoding) {} ~DIStringType() = default; @@ -1016,7 +1038,7 @@ class DIDerivedType : public DIType { std::optional PtrAuthData, DIFlags Flags, ArrayRef Ops) : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, - AlignInBits, OffsetInBits, Flags, Ops), + AlignInBits, OffsetInBits, 0, Flags, Ops), DWARFAddressSpace(DWARFAddressSpace) { if (PtrAuthData) SubclassData32 = PtrAuthData->RawData; @@ -1157,39 +1179,43 @@ class DICompositeType : public DIType { DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, + uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t NumExtraInhabitants, DIFlags Flags, ArrayRef Ops) : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits, - AlignInBits, OffsetInBits, Flags, Ops), + AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops), RuntimeLang(RuntimeLang) {} ~DICompositeType() = default; /// Change fields in place. void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - DIFlags Flags) { + uint32_t NumExtraInhabitants, DIFlags Flags) { assert(isDistinct() && "Only distinct nodes can mutate"); assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate"); this->RuntimeLang = RuntimeLang; - DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags); + DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, + NumExtraInhabitants, Flags); } static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, - DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, + uint32_t AlignInBits, uint64_t OffsetInBits, + uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements, + unsigned RuntimeLang, DIType *VTableHolder, DITemplateParameterArray TemplateParams, StringRef Identifier, DIDerivedType *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, DINodeArray Annotations, StorageType Storage, bool ShouldCreate = true) { - return getImpl( - Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, - BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(), - RuntimeLang, VTableHolder, TemplateParams.get(), - getCanonicalMDString(Context, Identifier), Discriminator, DataLocation, - Associated, Allocated, Rank, Annotations.get(), Storage, ShouldCreate); + return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, + Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, + Flags, Elements.get(), RuntimeLang, VTableHolder, + TemplateParams.get(), + getCanonicalMDString(Context, Identifier), Discriminator, + DataLocation, Associated, Allocated, Rank, Annotations.get(), + NumExtraInhabitants, Storage, ShouldCreate); } static DICompositeType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, @@ -1199,7 +1225,8 @@ class DICompositeType : public DIType { Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, - Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); + Metadata *Annotations, uint32_t NumExtraInhabitants, + StorageType Storage, bool ShouldCreate = true); TempDICompositeType cloneImpl() const { return getTemporary( @@ -1208,7 +1235,7 @@ class DICompositeType : public DIType { getFlags(), getElements(), getRuntimeLang(), getVTableHolder(), getTemplateParams(), getIdentifier(), getDiscriminator(), getRawDataLocation(), getRawAssociated(), getRawAllocated(), - getRawRank(), getAnnotations()); + getRawRank(), getAnnotations(), getNumExtraInhabitants()); } public: @@ -1222,11 +1249,11 @@ class DICompositeType : public DIType { StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, Metadata *Rank = nullptr, - DINodeArray Annotations = nullptr), + DINodeArray Annotations = nullptr, uint32_t NumExtraInhabitants = 0), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, - Annotations)) + OffsetInBits, NumExtraInhabitants, Flags, Elements, RuntimeLang, + VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, + Associated, Allocated, Rank, Annotations)) DEFINE_MDNODE_GET( DICompositeType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, @@ -1236,11 +1263,12 @@ class DICompositeType : public DIType { 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 *Rank = nullptr, Metadata *Annotations = nullptr, + uint32_t NumExtraInhabitants = 0), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, - Annotations)) + Annotations, NumExtraInhabitants)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1255,8 +1283,8 @@ class DICompositeType : public DIType { 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, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, + uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags, + Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations); @@ -1272,15 +1300,14 @@ class DICompositeType : public DIType { /// /// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns /// nullptr. - 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, DIFlags Flags, Metadata *Elements, - unsigned RuntimeLang, Metadata *VTableHolder, - Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations); + 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, + uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, + Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations); DIType *getBaseType() const { return cast_or_null(getRawBaseType()); } DINodeArray getElements() const { diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 8ddb2efb0e26c2..b46127b4183c9f 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5329,12 +5329,14 @@ bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) { OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \ OPTIONAL(align, 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.Val, - align.Val, encoding.Val, flags.Val)); + align.Val, encoding.Val, + num_extra_inhabitants.Val, flags.Val)); return false; } @@ -5432,7 +5434,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { OPTIONAL(associated, MDField, ); \ OPTIONAL(allocated, MDField, ); \ OPTIONAL(rank, MDSignedOrMDField, ); \ - OPTIONAL(annotations, MDField, ); + OPTIONAL(annotations, MDField, ); \ + OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5447,10 +5450,11 @@ 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, flags.Val, - elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, - discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, - Rank, annotations.Val)) { + scope.Val, baseType.Val, size.Val, align.Val, offset.Val, + num_extra_inhabitants.Val, flags.Val, elements.Val, runtimeLang.Val, + vtableHolder.Val, templateParams.Val, discriminator.Val, + dataLocation.Val, associated.Val, allocated.Val, Rank, + annotations.Val)) { Result = CT; return false; } @@ -5463,7 +5467,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { size.Val, align.Val, offset.Val, flags.Val, elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank, - annotations.Val)); + annotations.Val, num_extra_inhabitants.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index ada1597b399206..8ca46a4ce821a5 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1525,18 +1525,19 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_BASIC_TYPE: { - if (Record.size() < 6 || Record.size() > 7) + if (Record.size() < 6 || Record.size() > 8) return error("Invalid record"); IsDistinct = Record[0]; DINode::DIFlags Flags = (Record.size() > 6) ? static_cast(Record[6]) : DINode::FlagZero; + uint32_t NumExtraInhabitants = (Record.size() > 7) ? Record[7] : 0; MetadataList.assignValue( GET_OR_DISTINCT(DIBasicType, (Context, Record[1], getMDString(Record[2]), Record[3], - Record[4], Record[5], Flags)), + Record[4], Record[5], NumExtraInhabitants, Flags)), NextMetadataNo); NextMetadataNo++; break; @@ -1599,7 +1600,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_COMPOSITE_TYPE: { - if (Record.size() < 16 || Record.size() > 22) + if (Record.size() < 16 || Record.size() > 23) return error("Invalid record"); // If we have a UUID and this is not a forward declaration, lookup the @@ -1617,6 +1618,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( return error("Alignment value is too large"); uint32_t AlignInBits = Record[8]; uint64_t OffsetInBits = 0; + uint32_t NumExtraInhabitants = (Record.size() > 22) ? Record[22] : 0; DINode::DIFlags Flags = static_cast(Record[10]); Metadata *Elements = nullptr; unsigned RuntimeLang = Record[12]; @@ -1681,9 +1683,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Identifier) CT = DICompositeType::buildODRType( Context, *Identifier, Tag, Name, File, Line, Scope, BaseType, - SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations); + SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, + Elements, RuntimeLang, VTableHolder, TemplateParams, Discriminator, + DataLocation, Associated, Allocated, Rank, Annotations); // Create a node if we didn't get a lazy ODR type. if (!CT) @@ -1692,7 +1694,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations)); + Allocated, Rank, Annotations, NumExtraInhabitants)); if (!IsNotUsedInTypeRef && Identifier) MetadataList.addTypeRef(*Identifier, *cast(CT)); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index ee9cc4b6e0c0eb..de01750857bba3 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1863,6 +1863,7 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N, Record.push_back(N->getAlignInBits()); Record.push_back(N->getEncoding()); Record.push_back(N->getFlags()); + Record.push_back(N->getNumExtraInhabitants()); Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev); Record.clear(); @@ -1945,6 +1946,7 @@ void ModuleBitcodeWriter::writeDICompositeType( Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated())); Record.push_back(VE.getMetadataOrNullID(N->getRawRank())); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); + Record.push_back(N->getNumExtraInhabitants()); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 75b80add8e3dba..c6d9fcfb0b76c1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -734,6 +734,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) { addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_big); else if (BTy->isLittleEndian()) addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little); + + if (uint32_t NumExtraInhabitants = BTy->getNumExtraInhabitants()) + addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt, + NumExtraInhabitants); } void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) { @@ -1089,6 +1093,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { if (uint32_t AlignInBytes = CTy->getAlignInBytes()) addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, AlignInBytes); + + if (uint32_t NumExtraInhabitants = CTy->getNumExtraInhabitants()) + addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt, + NumExtraInhabitants); } } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 6adb8d6a742255..5614ffe4627d64 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2132,6 +2132,7 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N, Printer.printInt("align", N->getAlignInBits()); Printer.printDwarfEnum("encoding", N->getEncoding(), dwarf::AttributeEncodingString); + Printer.printInt("num_extra_inhabitants", N->getNumExtraInhabitants()); Printer.printDIFlags("flags", N->getFlags()); Out << ")"; } @@ -2200,6 +2201,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, Printer.printInt("size", N->getSizeInBits()); Printer.printInt("align", N->getAlignInBits()); Printer.printInt("offset", N->getOffsetInBits()); + Printer.printInt("num_extra_inhabitants", N->getNumExtraInhabitants()); Printer.printDIFlags("flags", N->getFlags()); Printer.printMetadata("elements", N->getRawElements()); Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(), diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 447a9d65174636..da9cc7e3b662bc 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -266,10 +266,11 @@ DIBasicType *DIBuilder::createNullPtrType() { DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, - DINode::DIFlags Flags) { + DINode::DIFlags Flags, + uint32_t NumExtraInhabitants) { assert(!Name.empty() && "Unable to create type without name"); return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits, - 0, Encoding, Flags); + 0, Encoding, NumExtraInhabitants, Flags); } DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) { @@ -521,11 +522,14 @@ DICompositeType *DIBuilder::createStructType( DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang, - DIType *VTableHolder, StringRef UniqueIdentifier) { + DIType *VTableHolder, StringRef UniqueIdentifier, + 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, VTableHolder, nullptr, UniqueIdentifier); + Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + NumExtraInhabitants); trackIfUnresolved(R); return R; } @@ -551,7 +555,7 @@ DIBuilder::createVariantPart(DIScope *Scope, StringRef Name, DIFile *File, auto *R = DICompositeType::get( VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber, getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags, - Elements, 0, nullptr, nullptr, UniqueIdentifier, Discriminator); + Elements, 0, nullptr, nullptr, UniqueIdentifier, 0, Discriminator); trackIfUnresolved(R); return R; } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index fb4326e5547138..f7268a51406283 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -663,14 +663,16 @@ DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value, DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, - DIFlags Flags, StorageType Storage, - bool ShouldCreate) { + uint32_t NumExtraInhabitants, DIFlags Flags, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIBasicType, - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)); + DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits, + Encoding, NumExtraInhabitants, Flags)); Metadata *Ops[] = {nullptr, nullptr, Name}; - DEFINE_GETIMPL_STORE(DIBasicType, - (Tag, SizeInBits, AlignInBits, Encoding, Flags), Ops); + DEFINE_GETIMPL_STORE( + DIBasicType, + (Tag, SizeInBits, AlignInBits, Encoding, NumExtraInhabitants, Flags), + Ops); } std::optional DIBasicType::getSignedness() const { @@ -768,8 +770,8 @@ DICompositeType *DICompositeType::getImpl( Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations, StorageType Storage, - bool ShouldCreate) { + Metadata *Rank, Metadata *Annotations, uint32_t NumExtraInhabitants, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); // Keep this in sync with buildODRType. @@ -778,25 +780,25 @@ DICompositeType *DICompositeType::getImpl( AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations)); + Rank, Annotations, NumExtraInhabitants)); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, Annotations}; - DEFINE_GETIMPL_STORE( - DICompositeType, - (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags), - Ops); + DEFINE_GETIMPL_STORE(DICompositeType, + (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, + OffsetInBits, NumExtraInhabitants, 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, - DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, - Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations) { + uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, + Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -806,7 +808,8 @@ DICompositeType *DICompositeType::buildODRType( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, - DataLocation, Associated, Allocated, Rank, Annotations); + DataLocation, Associated, Allocated, Rank, Annotations, + NumExtraInhabitants); if (CT->getTag() != Tag) return nullptr; @@ -818,7 +821,7 @@ DICompositeType *DICompositeType::buildODRType( // Mutate CT in place. Keep this in sync with getImpl. CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, - Flags); + NumExtraInhabitants, Flags); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, Allocated, @@ -835,10 +838,10 @@ 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, - DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, - Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, - Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations) { + uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, + unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, + Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) return nullptr; @@ -848,7 +851,7 @@ DICompositeType *DICompositeType::getODRType( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations); + Allocated, Rank, Annotations, NumExtraInhabitants); } else { if (CT->getTag() != Tag) return nullptr; @@ -867,7 +870,7 @@ DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage, DIFlags Flags, uint8_t CC, ArrayRef Ops) : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0, - 0, 0, 0, Flags, Ops), + 0, 0, 0, 0, Flags, Ops), CC(CC) {} DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags, diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 971091f3040614..1912b1a6b7f3df 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -465,22 +465,28 @@ template <> struct MDNodeKeyImpl { uint64_t SizeInBits; uint32_t AlignInBits; unsigned Encoding; + uint32_t NumExtraInhabitants; unsigned Flags; MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, unsigned Flags) + uint32_t AlignInBits, unsigned Encoding, + uint32_t NumExtraInhabitants, unsigned Flags) : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), - Encoding(Encoding), Flags(Flags) {} + 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()), - Flags(N->getFlags()) {} + NumExtraInhabitants(N->getNumExtraInhabitants()), Flags(N->getFlags()) { + } bool isKeyOf(const DIBasicType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && SizeInBits == RHS->getSizeInBits() && AlignInBits == RHS->getAlignInBits() && - Encoding == RHS->getEncoding() && Flags == RHS->getFlags(); + Encoding == RHS->getEncoding() && + NumExtraInhabitants == RHS->getNumExtraInhabitants() && + Flags == RHS->getFlags(); } unsigned getHashValue() const { @@ -649,6 +655,7 @@ template <> struct MDNodeKeyImpl { Metadata *Allocated; Metadata *Rank; Metadata *Annotations; + uint32_t NumExtraInhabitants; MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, @@ -657,7 +664,8 @@ template <> struct MDNodeKeyImpl { Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, - Metadata *Allocated, Metadata *Rank, Metadata *Annotations) + Metadata *Allocated, Metadata *Rank, Metadata *Annotations, + uint32_t NumExtraInhabitants) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), Flags(Flags), Elements(Elements), @@ -665,7 +673,7 @@ template <> struct MDNodeKeyImpl { TemplateParams(TemplateParams), Identifier(Identifier), Discriminator(Discriminator), DataLocation(DataLocation), Associated(Associated), Allocated(Allocated), Rank(Rank), - Annotations(Annotations) {} + Annotations(Annotations), NumExtraInhabitants(NumExtraInhabitants) {} MDNodeKeyImpl(const DICompositeType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), @@ -678,7 +686,8 @@ template <> struct MDNodeKeyImpl { Discriminator(N->getRawDiscriminator()), DataLocation(N->getRawDataLocation()), Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()), - Rank(N->getRawRank()), Annotations(N->getRawAnnotations()) {} + Rank(N->getRawRank()), Annotations(N->getRawAnnotations()), + NumExtraInhabitants(N->getNumExtraInhabitants()) {} bool isKeyOf(const DICompositeType *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && @@ -696,7 +705,8 @@ template <> struct MDNodeKeyImpl { DataLocation == RHS->getRawDataLocation() && Associated == RHS->getRawAssociated() && Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank() && - Annotations == RHS->getRawAnnotations(); + Annotations == RHS->getRawAnnotations() && + NumExtraInhabitants == RHS->getNumExtraInhabitants(); } unsigned getHashValue() const { diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll index 06144b261373f4..7faaf50496def9 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, !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: !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, !44, !45} +!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, !47, !48} ; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -111,3 +111,9 @@ ; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) !46 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) + +; CHECK: !DIBasicType(name: "ExtraInhabitantBasicType", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254) +!47 = !DIBasicType(name: "ExtraInhabitantBasicType", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254) + +;CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !10, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") +!48 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !12, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType") diff --git a/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll b/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll new file mode 100644 index 00000000000000..6d35f2b2fc9da9 --- /dev/null +++ b/llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll @@ -0,0 +1,41 @@ +; RUN: llc %s -filetype=obj -mtriple arm64e-apple-darwin -o - \ +; RUN: | llvm-dwarfdump - | FileCheck %s + +; CHECK: DW_TAG_base_type +; CHECK: DW_AT_name ("ExtraInhabitantBasicType") +; CHECK: DW_AT_LLVM_num_extra_inhabitants (0xfe) + +; CHECK: DW_TAG_structure_type +; CHECK: DW_AT_name ("ExtraInhabitantCompositeType") +; CHECK: DW_AT_LLVM_num_extra_inhabitants (0x42) + +; CHECK: DW_TAG_structure_type +; CHECK: DW_AT_name ("NoExtraInhabitantType") +; CHECK-NOT: DW_AT_LLVM_num_extra_inhabitants + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +@p = common global i8* null, align 8, !dbg !100 +@q = common global i8* null, align 8, !dbg !102 +@r = common global i8* null, align 8, !dbg !105 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!6, !7} + +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5) +!3 = !DIFile(filename: "/tmp/p.c", directory: "/") +!4 = !{} +!5 = !{!100, !102, !105} +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} + +!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 = !DICompositeType(tag: DW_TAG_structure_type, name: "NoExtraInhabitantType", file: !3, size: 64, identifier: "MangledNoExtraInhabitantType") + +!100 = !DIGlobalVariableExpression(var: !101, expr: !DIExpression()) +!101 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !10, isLocal: false, isDefinition: true) +!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression()) +!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true) +!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true) +!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression()) diff --git a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp index e3a7facb8575b9..e9f8146df75742 100644 --- a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp +++ b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp @@ -30,8 +30,8 @@ TEST(DebugTypeODRUniquingTest, getODRType) { // Without a type map, this should return null. EXPECT_FALSE(DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr)); + nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Enable the mapping. There still shouldn't be a type. Context.enableDebugTypeODRUniquing(); @@ -40,24 +40,23 @@ TEST(DebugTypeODRUniquingTest, getODRType) { // Create some ODR-uniqued type. auto &CT = *DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); EXPECT_EQ(UUID.getString(), CT.getIdentifier()); // Check that we get it back, even if we change a field. EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); + EXPECT_EQ(&CT, DICompositeType::getODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, + 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, + 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr)); EXPECT_EQ(&CT, DICompositeType::getODRType( - Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, - nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr)); - EXPECT_EQ(&CT, DICompositeType::getODRType( - Context, UUID, dwarf::DW_TAG_class_type, - MDString::get(Context, "name"), nullptr, 0, nullptr, - nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr)); + Context, UUID, dwarf::DW_TAG_class_type, + MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0, + 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Check that it's discarded with the type map. Context.disableDebugTypeODRUniquing(); @@ -76,7 +75,7 @@ TEST(DebugTypeODRUniquingTest, buildODRType) { MDString &UUID = *MDString::get(Context, "Type"); auto &CT = *DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, + nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); @@ -84,35 +83,35 @@ TEST(DebugTypeODRUniquingTest, buildODRType) { // Update with another forward decl. This should be a no-op. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, - 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr)); + 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, + nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); EXPECT_FALSE(DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr, - nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, + nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Update with a definition. This time we should see a change. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, nullptr, + 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); EXPECT_FALSE(CT.isForwardDecl()); // Further updates should be ignored. EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, - 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr)); + 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, + nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); EXPECT_FALSE(CT.isForwardDecl()); EXPECT_EQ(&CT, DICompositeType::buildODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, - 111u, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, - 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr)); + 111u, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagZero, + nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); EXPECT_NE(111u, CT.getLine()); } @@ -123,7 +122,7 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { // Build an ODR type that's a forward decl with no other fields set. MDString &UUID = *MDString::get(Context, "UUID"); auto &CT = *DICompositeType::buildODRType( - Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, + Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); @@ -141,6 +140,7 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { DO_FOR_FIELD(SizeInBits) \ DO_FOR_FIELD(AlignInBits) \ DO_FOR_FIELD(OffsetInBits) \ + DO_FOR_FIELD(NumExtraInhabitants) \ DO_FOR_FIELD(RuntimeLang) // Create all the fields. @@ -153,12 +153,12 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { #undef DO_FOR_FIELD // Replace all the fields with new values that are distinct from each other. - EXPECT_EQ(&CT, - DICompositeType::buildODRType( - Context, UUID, 0, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DINode::FlagArtificial, Elements, - RuntimeLang, VTableHolder, TemplateParams, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr)); + EXPECT_EQ(&CT, DICompositeType::buildODRType( + Context, UUID, 0, Name, File, Line, Scope, BaseType, + SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, + DINode::FlagArtificial, Elements, RuntimeLang, + VTableHolder, TemplateParams, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); // Confirm that all the right fields got updated. #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X()); diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 778fd4d4994f44..fbdab1975df725 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -1772,44 +1772,48 @@ TEST_F(DIEnumeratorTest, getWithLargeValues) { typedef MetadataTest DIBasicTypeTest; TEST_F(DIBasicTypeTest, get) { - auto *N = - DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7, - DINode::FlagZero); + auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, + 26, 7, 100, DINode::FlagZero); EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag()); EXPECT_EQ("special", N->getName()); EXPECT_EQ(33u, N->getSizeInBits()); EXPECT_EQ(26u, N->getAlignInBits()); EXPECT_EQ(7u, N->getEncoding()); EXPECT_EQ(0u, N->getLine()); + EXPECT_EQ(100u, N->getNumExtraInhabitants()); EXPECT_EQ(DINode::FlagZero, N->getFlags()); EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 7, DINode::FlagZero)); + 26, 7, 100, DINode::FlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, - "special", 33, 26, 7, DINode::FlagZero)); - EXPECT_NE(N, - DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7, - DINode::FlagZero)); + "special", 33, 26, 7, 100, DINode::FlagZero)); + EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, + 7, 100, DINode::FlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32, - 26, 7, DINode::FlagZero)); + 26, 7, 100, DINode::FlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 25, 7, DINode::FlagZero)); + 25, 7, 100, DINode::FlagZero)); + EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 6, DINode::FlagZero)); + 26, 7, 99, DINode::FlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 7, DINode::FlagBigEndian)); + 26, 6, 100, DINode::FlagZero)); EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, - 26, 7, DINode::FlagLittleEndian)); + 26, 7, 100, DINode::FlagBigEndian)); + EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, + 26, 7, 100, DINode::FlagLittleEndian)); TempDIBasicType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } TEST_F(DIBasicTypeTest, getWithLargeValues) { - auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", - UINT64_MAX, UINT32_MAX - 1, 7, DINode::FlagZero); + auto *N = + DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", UINT64_MAX, + UINT32_MAX - 1, 7, UINT32_MAX, DINode::FlagZero); EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); + EXPECT_EQ(UINT32_MAX, N->getNumExtraInhabitants()); } TEST_F(DIBasicTypeTest, getUnspecified) { @@ -1829,7 +1833,7 @@ typedef MetadataTest DITypeTest; TEST_F(DITypeTest, clone) { // Check that DIType has a specialized clone that returns TempDIType. DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32, - dwarf::DW_ATE_signed, DINode::FlagZero); + 0, dwarf::DW_ATE_signed, DINode::FlagZero); TempDIType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));