From b1de0d923fa705981dce2d8d9dee35f87305a078 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 5 Feb 2025 11:54:23 +0000 Subject: [PATCH 1/3] [llvm][DebugInfo] Introduce new DW_AT_APPLE_enum_kind DWARF attribute --- llvm/include/llvm/AsmParser/LLToken.h | 1 + llvm/include/llvm/BinaryFormat/Dwarf.def | 14 +- llvm/include/llvm/BinaryFormat/Dwarf.h | 15 +- llvm/include/llvm/IR/DIBuilder.h | 18 +- llvm/include/llvm/IR/DebugInfoMetadata.h | 77 ++++---- llvm/lib/AsmParser/LLLexer.cpp | 1 + llvm/lib/AsmParser/LLParser.cpp | 43 +++- llvm/lib/BinaryFormat/Dwarf.cpp | 21 ++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 22 ++- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 3 + llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 3 + llvm/lib/IR/AsmWriter.cpp | 5 + llvm/lib/IR/DIBuilder.cpp | 57 +++--- llvm/lib/IR/DebugInfoMetadata.cpp | 44 +++-- .../AArch64/DW_AT_APPLE_enum_kind.ll | 56 ++++++ .../AArch64/DW_AT_APPLE_enum_kind.s | 44 +++++ .../unittests/IR/DebugTypeODRUniquingTest.cpp | 80 ++++---- llvm/unittests/IR/MetadataTest.cpp | 184 ++++++++++-------- .../Transforms/Utils/CloningTest.cpp | 3 +- 19 files changed, 459 insertions(+), 232 deletions(-) create mode 100644 llvm/test/DebugInfo/AArch64/DW_AT_APPLE_enum_kind.ll create mode 100644 llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_enum_kind.s diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index 7b47bc88ddb25..c52622879b885 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -497,6 +497,7 @@ enum Kind { DwarfMacinfo, // DW_MACINFO_foo ChecksumKind, // CSK_foo DbgRecordType, // dbg_foo + DwarfEnumKind, // DW_APPLE_ENUM_KIND_foo // Type valued tokens (TyVal). Type, diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index 2bb84fbc864d8..724a14ccc7aea 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -24,7 +24,8 @@ (defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \ defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \ defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \ - defined HANDLE_DW_END || defined HANDLE_DW_SECT) + defined HANDLE_DW_END || defined HANDLE_DW_SECT || \ + defined HANDLE_DW_APPLE_ENUM_KIND) #error "Missing macro definition of HANDLE_DW*" #endif @@ -146,6 +147,10 @@ #define HANDLE_DW_SECT(ID, NAME) #endif +#ifndef HANDLE_DW_APPLE_ENUM_KIND +#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME) +#endif + HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE) HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE) HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE) @@ -638,6 +643,7 @@ HANDLE_DW_AT(0x3fed, APPLE_property, 0, APPLE) HANDLE_DW_AT(0x3fee, APPLE_objc_direct, 0, APPLE) HANDLE_DW_AT(0x3fef, APPLE_sdk, 0, APPLE) HANDLE_DW_AT(0x3ff0, APPLE_origin, 0, APPLE) +HANDLE_DW_AT(0x3ff1, APPLE_enum_kind, 0, APPLE) // Attribute form encodings. HANDLE_DW_FORM(0x01, addr, 2, DWARF) @@ -1269,6 +1275,11 @@ HANDLE_DW_APPLE_PROPERTY(0x1000, nullability) HANDLE_DW_APPLE_PROPERTY(0x2000, null_resettable) HANDLE_DW_APPLE_PROPERTY(0x4000, class) +// Enum kinds. +// Keep in sync with EnumExtensibilityAttr::Kind. +HANDLE_DW_APPLE_ENUM_KIND(0x00, Closed) +HANDLE_DW_APPLE_ENUM_KIND(0x01, Open) + // DWARF v5 Unit Types. HANDLE_DW_UT(0x01, compile) HANDLE_DW_UT(0x02, type) @@ -1367,3 +1378,4 @@ HANDLE_DW_SECT(8, RNGLISTS) #undef HANDLE_DW_IDX #undef HANDLE_DW_END #undef HANDLE_DW_SECT +#undef HANDLE_DW_APPLE_ENUM_KIND diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 3be819c0a76ee..0301259f0f436 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -44,9 +44,10 @@ namespace dwarf { enum LLVMConstants : uint32_t { /// LLVM mock tags (see also llvm/BinaryFormat/Dwarf.def). /// \{ - DW_TAG_invalid = ~0U, ///< Tag for invalid results. - DW_VIRTUALITY_invalid = ~0U, ///< Virtuality for invalid results. - DW_MACINFO_invalid = ~0U, ///< Macinfo type for invalid results. + DW_TAG_invalid = ~0U, ///< Tag for invalid results. + DW_VIRTUALITY_invalid = ~0U, ///< Virtuality for invalid results. + DW_MACINFO_invalid = ~0U, ///< Macinfo type for invalid results. + DW_APPLE_ENUM_KIND_invalid = ~0U, ///< Virtuality for invalid results. /// \} /// Special values for an initial length field. @@ -198,6 +199,12 @@ enum VirtualityAttribute { DW_VIRTUALITY_max = 0x02 }; +enum EnumKindAttribute { +#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME) DW_APPLE_ENUM_KIND_##NAME = ID, +#include "llvm/BinaryFormat/Dwarf.def" + DW_APPLE_ENUM_KIND_max = 0x01 +}; + enum DefaultedMemberAttribute { #define HANDLE_DW_DEFAULTED(ID, NAME) DW_DEFAULTED_##NAME = ID, #include "llvm/BinaryFormat/Dwarf.def" @@ -981,6 +988,7 @@ StringRef AccessibilityString(unsigned Access); StringRef DefaultedMemberString(unsigned DefaultedEncodings); StringRef VisibilityString(unsigned Visibility); StringRef VirtualityString(unsigned Virtuality); +StringRef EnumKindString(unsigned EnumKind); StringRef LanguageString(unsigned Language); StringRef CaseString(unsigned Case); StringRef ConventionString(unsigned Convention); @@ -1020,6 +1028,7 @@ unsigned getOperationEncoding(StringRef OperationEncodingString); unsigned getSubOperationEncoding(unsigned OpEncoding, StringRef SubOperationEncodingString); unsigned getVirtuality(StringRef VirtualityString); +unsigned getEnumKind(StringRef EnumKindString); unsigned getLanguage(StringRef LanguageString); unsigned getCallingConvention(StringRef LanguageString); unsigned getAttributeEncoding(StringRef EncodingString); diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 6c479415b9ed2..8bee9f4703dd9 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -632,7 +632,8 @@ namespace llvm { DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements, DIType *UnderlyingType, unsigned RunTimeLang = 0, - StringRef UniqueIdentifier = "", bool IsScoped = false); + StringRef UniqueIdentifier = "", bool IsScoped = false, + std::optional EnumKind = std::nullopt); /// Create debugging information entry for a set. /// \param Scope Scope in which this set is defined. /// \param Name Set name. @@ -667,19 +668,20 @@ namespace llvm { static DIType *createObjectPointerType(DIType *Ty, bool Implicit); /// Create a permanent forward-declared type. - DICompositeType *createForwardDecl(unsigned Tag, StringRef Name, - DIScope *Scope, DIFile *F, unsigned Line, - unsigned RuntimeLang = 0, - uint64_t SizeInBits = 0, - uint32_t AlignInBits = 0, - StringRef UniqueIdentifier = ""); + DICompositeType * + createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, + unsigned Line, unsigned RuntimeLang = 0, + uint64_t SizeInBits = 0, uint32_t AlignInBits = 0, + StringRef UniqueIdentifier = "", + std::optional EnumKind = std::nullopt); /// Create a temporary forward-declared type. DICompositeType *createReplaceableCompositeType( unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line, unsigned RuntimeLang = 0, uint64_t SizeInBits = 0, uint32_t AlignInBits = 0, DINode::DIFlags Flags = DINode::FlagFwdDecl, - StringRef UniqueIdentifier = "", DINodeArray Annotations = nullptr); + StringRef UniqueIdentifier = "", DINodeArray Annotations = nullptr, + std::optional EnumKind = std::nullopt); /// Retain DIScope* in a module even if it is not referenced /// through debug info anchors. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 5ea8c0d7b448d..8515d8eda8568 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1176,24 +1176,28 @@ class DICompositeType : public DIType { friend class MDNode; unsigned RuntimeLang; + std::optional EnumKind; DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - uint32_t NumExtraInhabitants, DIFlags Flags, + uint32_t NumExtraInhabitants, + std::optional EnumKind, DIFlags Flags, ArrayRef Ops) : DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops), - RuntimeLang(RuntimeLang) {} + RuntimeLang(RuntimeLang), EnumKind(EnumKind) {} ~DICompositeType() = default; /// Change fields in place. void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - uint32_t NumExtraInhabitants, DIFlags Flags) { + uint32_t NumExtraInhabitants, std::optional EnumKind, + DIFlags Flags) { assert(isDistinct() && "Only distinct nodes can mutate"); assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate"); this->RuntimeLang = RuntimeLang; + this->EnumKind = EnumKind; DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags); } @@ -1203,15 +1207,15 @@ class DICompositeType : public DIType { unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIType *Specification, 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, + unsigned RuntimeLang, std::optional EnumKind, + 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, + Flags, Elements.get(), RuntimeLang, EnumKind, VTableHolder, TemplateParams.get(), getCanonicalMDString(Context, Identifier), Discriminator, DataLocation, Associated, Allocated, Rank, Annotations.get(), @@ -1222,21 +1226,21 @@ class DICompositeType : public DIType { 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, - MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation, - Metadata *Associated, Metadata *Allocated, Metadata *Rank, - Metadata *Annotations, Metadata *Specification, - uint32_t NumExtraInhabitants, StorageType Storage, - bool ShouldCreate = true); + std::optional EnumKind, Metadata *VTableHolder, + Metadata *TemplateParams, MDString *Identifier, + Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations, + Metadata *Specification, uint32_t NumExtraInhabitants, + StorageType Storage, bool ShouldCreate = true); TempDICompositeType cloneImpl() const { return getTemporary( getContext(), getTag(), getName(), getFile(), getLine(), getScope(), getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(), - getFlags(), getElements(), getRuntimeLang(), getVTableHolder(), - getTemplateParams(), getIdentifier(), getDiscriminator(), - getRawDataLocation(), getRawAssociated(), getRawAllocated(), - getRawRank(), getAnnotations(), getSpecification(), + getFlags(), getElements(), getRuntimeLang(), getEnumKind(), + getVTableHolder(), getTemplateParams(), getIdentifier(), + getDiscriminator(), getRawDataLocation(), getRawAssociated(), + getRawAllocated(), getRawRank(), getAnnotations(), getSpecification(), getNumExtraInhabitants()); } @@ -1246,7 +1250,8 @@ class DICompositeType : public DIType { (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, - DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder, + DINodeArray Elements, unsigned RuntimeLang, + std::optional EnumKind, DIType *VTableHolder, DITemplateParameterArray TemplateParams = nullptr, StringRef Identifier = "", DIDerivedType *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, @@ -1255,23 +1260,24 @@ class DICompositeType : public DIType { uint32_t NumExtraInhabitants = 0), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements, - RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, - DataLocation, Associated, Allocated, Rank, Annotations)) + RuntimeLang, EnumKind, VTableHolder, TemplateParams, Identifier, + Discriminator, DataLocation, Associated, Allocated, Rank, Annotations)) DEFINE_MDNODE_GET( DICompositeType, (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 *Elements, unsigned RuntimeLang, + std::optional EnumKind, Metadata *VTableHolder, Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr, Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr, Metadata *Associated = nullptr, Metadata *Allocated = nullptr, Metadata *Rank = nullptr, Metadata *Annotations = nullptr, Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, - Annotations, Specification, NumExtraInhabitants)) + OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier, Discriminator, DataLocation, Associated, + Allocated, Rank, Annotations, Specification, NumExtraInhabitants)) TempDICompositeType clone() const { return cloneImpl(); } @@ -1288,10 +1294,11 @@ class DICompositeType : public DIType { Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Metadata *Specification, 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); + unsigned RuntimeLang, std::optional EnumKind, + Metadata *VTableHolder, Metadata *TemplateParams, + Metadata *Discriminator, Metadata *DataLocation, + Metadata *Associated, Metadata *Allocated, Metadata *Rank, + Metadata *Annotations); static DICompositeType *getODRTypeIfExists(LLVMContext &Context, MDString &Identifier); @@ -1310,10 +1317,11 @@ class DICompositeType : public DIType { Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Metadata *Specification, 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); + unsigned RuntimeLang, std::optional EnumKind, + 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 { @@ -1327,6 +1335,7 @@ class DICompositeType : public DIType { } StringRef getIdentifier() const { return getStringOperand(7); } unsigned getRuntimeLang() const { return RuntimeLang; } + std::optional getEnumKind() const { return EnumKind; } Metadata *getRawBaseType() const { return getOperand(3); } Metadata *getRawElements() const { return getOperand(4); } diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 5ea507c009bdc..9bc5a79da49c6 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -975,6 +975,7 @@ lltok::Kind LLLexer::LexIdentifier() { DWKEYWORD(CC, DwarfCC); DWKEYWORD(OP, DwarfOp); DWKEYWORD(MACINFO, DwarfMacinfo); + DWKEYWORD(APPLE_ENUM_KIND, DwarfEnumKind); #undef DWKEYWORD diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fa0079bac435c..610ffe7d69be4 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4697,6 +4697,12 @@ struct DwarfCCField : public MDUnsignedField { DwarfCCField() : MDUnsignedField(0, dwarf::DW_CC_hi_user) {} }; +struct DwarfEnumKindField : public MDUnsignedField { + DwarfEnumKindField() + : MDUnsignedField(dwarf::DW_APPLE_ENUM_KIND_invalid, + dwarf::DW_APPLE_ENUM_KIND_max) {} +}; + struct EmissionKindField : public MDUnsignedField { EmissionKindField() : MDUnsignedField(0, DICompileUnit::LastEmissionKind) {} }; @@ -4870,6 +4876,25 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, return false; } +template <> +bool LLParser::parseMDField(LocTy Loc, StringRef Name, + DwarfEnumKindField &Result) { + if (Lex.getKind() == lltok::APSInt) + return parseMDField(Loc, Name, static_cast(Result)); + + if (Lex.getKind() != lltok::DwarfEnumKind) + return tokError("expected DWARF enum kind code"); + + unsigned EnumKind = dwarf::getEnumKind(Lex.getStrVal()); + if (EnumKind == dwarf::DW_APPLE_ENUM_KIND_invalid) + return tokError("invalid DWARF enum kind code" + Twine(" '") + + Lex.getStrVal() + "'"); + assert(EnumKind <= Result.Max && "Expected valid DWARF enum kind code"); + Result.assign(EnumKind); + Lex.Lex(); + return false; +} + template <> bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) { if (Lex.getKind() == lltok::APSInt) @@ -5489,6 +5514,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(elements, MDField, ); \ OPTIONAL(runtimeLang, DwarfLangField, ); \ + OPTIONAL(enumKind, DwarfEnumKindField, ); \ OPTIONAL(vtableHolder, MDField, ); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(identifier, MDStringField, ); \ @@ -5510,15 +5536,19 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { else if (rank.isMDField()) Rank = rank.getMDFieldValue(); + std::optional EnumKind; + if (enumKind.Val != dwarf::DW_APPLE_ENUM_KIND_invalid) + EnumKind = enumKind.Val; + // If this has an identifier try to build an ODR type. if (identifier.Val) if (auto *CT = DICompositeType::buildODRType( Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, offset.Val, specification.Val, num_extra_inhabitants.Val, flags.Val, - elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val, - discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, - Rank, annotations.Val)) { + elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val, + templateParams.Val, discriminator.Val, dataLocation.Val, + associated.Val, allocated.Val, Rank, annotations.Val)) { Result = CT; return false; } @@ -5529,9 +5559,10 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { DICompositeType, (Context, 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, identifier.Val, - discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank, - annotations.Val, specification.Val, num_extra_inhabitants.Val)); + runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val, + identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, + allocated.Val, Rank, annotations.Val, specification.Val, + num_extra_inhabitants.Val)); return false; } diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp index 0cd5dfbd023e4..b9b10a541b263 100644 --- a/llvm/lib/BinaryFormat/Dwarf.cpp +++ b/llvm/lib/BinaryFormat/Dwarf.cpp @@ -390,6 +390,25 @@ unsigned llvm::dwarf::getVirtuality(StringRef VirtualityString) { .Default(DW_VIRTUALITY_invalid); } +StringRef llvm::dwarf::EnumKindString(unsigned EnumKind) { + switch (EnumKind) { + default: + return StringRef(); +#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME) \ + case DW_APPLE_ENUM_KIND_##NAME: \ + return "DW_APPLE_ENUM_KIND_" #NAME; +#include "llvm/BinaryFormat/Dwarf.def" + } +} + +unsigned llvm::dwarf::getEnumKind(StringRef EnumKindString) { + return StringSwitch(EnumKindString) +#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME) \ + .Case("DW_APPLE_ENUM_KIND_" #NAME, DW_APPLE_ENUM_KIND_##NAME) +#include "llvm/BinaryFormat/Dwarf.def" + .Default(DW_APPLE_ENUM_KIND_invalid); +} + StringRef llvm::dwarf::LanguageString(unsigned Language) { switch (Language) { default: @@ -741,6 +760,8 @@ StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) { return LanguageString(Val); case DW_AT_defaulted: return DefaultedMemberString(Val); + case DW_AT_APPLE_enum_kind: + return EnumKindString(Val); } return StringRef(); diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 1caa8480efc51..413d9f68e6cc3 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1600,7 +1600,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_COMPOSITE_TYPE: { - if (Record.size() < 16 || Record.size() > 24) + if (Record.size() < 16 || Record.size() > 25) return error("Invalid record"); // If we have a UUID and this is not a forward declaration, lookup the @@ -1622,6 +1622,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( DINode::DIFlags Flags = static_cast(Record[10]); Metadata *Elements = nullptr; unsigned RuntimeLang = Record[12]; + std::optional EnumKind; + Metadata *VTableHolder = nullptr; Metadata *TemplateParams = nullptr; Metadata *Discriminator = nullptr; @@ -1683,24 +1685,28 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( Specification = getMDOrNull(Record[23]); } } + + if (Record.size() > 25 && Record[25] != dwarf::DW_APPLE_ENUM_KIND_invalid) + EnumKind = Record[25]; + DICompositeType *CT = nullptr; if (Identifier) CT = DICompositeType::buildODRType( Context, *Identifier, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Specification, - NumExtraInhabitants, Flags, Elements, RuntimeLang, VTableHolder, - TemplateParams, Discriminator, DataLocation, Associated, Allocated, - Rank, Annotations); + NumExtraInhabitants, Flags, Elements, RuntimeLang, EnumKind, + VTableHolder, TemplateParams, Discriminator, DataLocation, Associated, + Allocated, Rank, Annotations); // Create a node if we didn't get a lazy ODR type. if (!CT) CT = GET_OR_DISTINCT(DICompositeType, (Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, - Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations, Specification, - NumExtraInhabitants)); + Elements, RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier, Discriminator, + DataLocation, Associated, Allocated, Rank, + Annotations, Specification, 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 31c96400dd0fe..28518607222af 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Bitcode/BitcodeCommon.h" #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" @@ -1959,6 +1960,8 @@ void ModuleBitcodeWriter::writeDICompositeType( Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); Record.push_back(N->getNumExtraInhabitants()); Record.push_back(VE.getMetadataOrNullID(N->getRawSpecification())); + Record.push_back( + N->getEnumKind().value_or(dwarf::DW_APPLE_ENUM_KIND_invalid)); 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 d3450b8b0556f..3426780d553fe 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1624,6 +1624,9 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) { addFlag(Buffer, dwarf::DW_AT_enum_class); } + if (auto Kind = CTy->getEnumKind()) + addUInt(Buffer, dwarf::DW_AT_APPLE_enum_kind, dwarf::DW_FORM_data1, *Kind); + auto *Context = CTy->getScope(); bool IndexEnumerators = !Context || isa(Context) || isa(Context) || isa(Context) || isa(Context); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index a37a8901489cf..c8ed4e19f1b61 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2257,6 +2257,11 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, Printer.printMetadata("annotations", N->getRawAnnotations()); if (auto *Specification = N->getRawSpecification()) Printer.printMetadata("specification", Specification); + + if (auto EnumKind = N->getEnumKind()) + Printer.printDwarfEnum("enumKind", *EnumKind, dwarf::EnumKindString, + /*ShouldSkipZero=*/false); + Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index d9bd4f11e89a3..e27015892928c 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -511,8 +511,8 @@ DICompositeType *DIBuilder::createClassType( auto *R = DICompositeType::get( VMContext, dwarf::DW_TAG_class_type, Name, File, LineNumber, getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RunTimeLang, VTableHolder, - cast_or_null(TemplateParams), UniqueIdentifier); + OffsetInBits, Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, + VTableHolder, cast_or_null(TemplateParams), UniqueIdentifier); trackIfUnresolved(R); return R; } @@ -526,9 +526,9 @@ DICompositeType *DIBuilder::createStructType( 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, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, Specification, - NumExtraInhabitants); + Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, VTableHolder, + nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, Specification, NumExtraInhabitants); trackIfUnresolved(R); return R; } @@ -540,7 +540,8 @@ DICompositeType *DIBuilder::createUnionType( auto *R = DICompositeType::get( VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber, getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags, - Elements, RunTimeLang, nullptr, nullptr, UniqueIdentifier); + Elements, RunTimeLang, /*EnumKind=*/std::nullopt, nullptr, nullptr, + UniqueIdentifier); trackIfUnresolved(R); return R; } @@ -554,7 +555,8 @@ 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, /*EnumKind=*/std::nullopt, nullptr, nullptr, + UniqueIdentifier, Discriminator); trackIfUnresolved(R); return R; } @@ -565,17 +567,16 @@ DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes, return DISubroutineType::get(VMContext, Flags, CC, ParameterTypes); } -DICompositeType * -DIBuilder::createEnumerationType(DIScope *Scope, StringRef Name, DIFile *File, - unsigned LineNumber, uint64_t SizeInBits, - uint32_t AlignInBits, DINodeArray Elements, - DIType *UnderlyingType, unsigned RunTimeLang, - StringRef UniqueIdentifier, bool IsScoped) { +DICompositeType *DIBuilder::createEnumerationType( + DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, + uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements, + DIType *UnderlyingType, unsigned RunTimeLang, StringRef UniqueIdentifier, + bool IsScoped, std::optional EnumKind) { auto *CTy = DICompositeType::get( VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber, getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0, IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements, - RunTimeLang, nullptr, nullptr, UniqueIdentifier); + RunTimeLang, EnumKind, nullptr, nullptr, UniqueIdentifier); AllEnumTypes.emplace_back(CTy); trackIfUnresolved(CTy); return CTy; @@ -602,8 +603,8 @@ DIBuilder::createArrayType(uint64_t Size, uint32_t AlignInBits, DIType *Ty, PointerUnion RK) { auto *R = DICompositeType::get( VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, nullptr, Ty, Size, - AlignInBits, 0, DINode::FlagZero, Subscripts, 0, nullptr, nullptr, "", - nullptr, + AlignInBits, 0, DINode::FlagZero, Subscripts, 0, + /*EnumKind=*/std::nullopt, nullptr, nullptr, "", nullptr, isa(DL) ? (Metadata *)cast(DL) : (Metadata *)cast(DL), isa(AS) ? (Metadata *)cast(AS) @@ -621,7 +622,8 @@ DICompositeType *DIBuilder::createVectorType(uint64_t Size, DINodeArray Subscripts) { auto *R = DICompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, nullptr, Ty, Size, AlignInBits, 0, - DINode::FlagVector, Subscripts, 0, nullptr); + DINode::FlagVector, Subscripts, 0, + /*EnumKind=*/std::nullopt, nullptr); trackIfUnresolved(R); return R; } @@ -666,17 +668,16 @@ void DIBuilder::retainType(DIScope *T) { DIBasicType *DIBuilder::createUnspecifiedParameter() { return nullptr; } -DICompositeType * -DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, - DIFile *F, unsigned Line, unsigned RuntimeLang, - uint64_t SizeInBits, uint32_t AlignInBits, - StringRef UniqueIdentifier) { +DICompositeType *DIBuilder::createForwardDecl( + unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line, + unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, + StringRef UniqueIdentifier, std::optional EnumKind) { // FIXME: Define in terms of createReplaceableForwardDecl() by calling // replaceWithUniqued(). auto *RetTy = DICompositeType::get( VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, DINode::FlagFwdDecl, nullptr, RuntimeLang, - nullptr, nullptr, UniqueIdentifier); + /*EnumKind=*/EnumKind, nullptr, nullptr, UniqueIdentifier); trackIfUnresolved(RetTy); return RetTy; } @@ -684,14 +685,14 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, DICompositeType *DIBuilder::createReplaceableCompositeType( unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, - DINode::DIFlags Flags, StringRef UniqueIdentifier, - DINodeArray Annotations) { + DINode::DIFlags Flags, StringRef UniqueIdentifier, DINodeArray Annotations, + std::optional EnumKind) { auto *RetTy = DICompositeType::getTemporary( VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr, - SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, nullptr, - nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, - nullptr, Annotations) + SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, EnumKind, + nullptr, nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, + nullptr, nullptr, Annotations) .release(); trackIfUnresolved(RetTy); return RetTy; diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 915cdd301f2c7..32e659d43edcf 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -767,11 +767,12 @@ DICompositeType *DICompositeType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, - Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, - Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator, - Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, - Metadata *Rank, Metadata *Annotations, Metadata *Specification, - uint32_t NumExtraInhabitants, StorageType Storage, bool ShouldCreate) { + Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, + Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, + Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, + Metadata *Allocated, Metadata *Rank, Metadata *Annotations, + Metadata *Specification, uint32_t NumExtraInhabitants, StorageType Storage, + bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); // Keep this in sync with buildODRType. @@ -787,7 +788,7 @@ DICompositeType *DICompositeType::getImpl( Rank, Annotations, Specification}; DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits, AlignInBits, - OffsetInBits, NumExtraInhabitants, Flags), + OffsetInBits, NumExtraInhabitants, EnumKind, Flags), Ops); } @@ -796,10 +797,10 @@ DICompositeType *DICompositeType::buildODRType( Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Metadata *Specification, 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) { + Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, + 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; @@ -808,9 +809,9 @@ DICompositeType *DICompositeType::buildODRType( return CT = DICompositeType::getDistinct( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, &Identifier, Discriminator, - DataLocation, Associated, Allocated, Rank, Annotations, - Specification, NumExtraInhabitants); + EnumKind, VTableHolder, TemplateParams, &Identifier, + Discriminator, DataLocation, Associated, Allocated, Rank, + Annotations, Specification, NumExtraInhabitants); if (CT->getTag() != Tag) return nullptr; @@ -821,7 +822,7 @@ DICompositeType *DICompositeType::buildODRType( // Mutate CT in place. Keep this in sync with getImpl. CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, - NumExtraInhabitants, Flags); + NumExtraInhabitants, EnumKind, Flags); Metadata *Ops[] = {File, Scope, Name, BaseType, Elements, VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, Associated, Allocated, @@ -839,10 +840,10 @@ DICompositeType *DICompositeType::getODRType( Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Metadata *Specification, 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) { + Metadata *Elements, unsigned RuntimeLang, std::optional EnumKind, + 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; @@ -850,9 +851,10 @@ DICompositeType *DICompositeType::getODRType( if (!CT) { CT = DICompositeType::getDistinct( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, - TemplateParams, &Identifier, Discriminator, DataLocation, Associated, - Allocated, Rank, Annotations, Specification, NumExtraInhabitants); + AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, + VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation, + Associated, Allocated, Rank, Annotations, Specification, + NumExtraInhabitants); } else { if (CT->getTag() != Tag) return nullptr; diff --git a/llvm/test/DebugInfo/AArch64/DW_AT_APPLE_enum_kind.ll b/llvm/test/DebugInfo/AArch64/DW_AT_APPLE_enum_kind.ll new file mode 100644 index 0000000000000..399d80c778072 --- /dev/null +++ b/llvm/test/DebugInfo/AArch64/DW_AT_APPLE_enum_kind.ll @@ -0,0 +1,56 @@ +; RUN: llc < %s -filetype=obj -o %t +; RUN: llvm-dwarfdump -v %t | FileCheck %s + +; C++ source to regenerate: +; enum __attribute__((enum_extensibility(open))) OpenEnum { +; oe1 +; } oe; +; +; enum __attribute__((enum_extensibility(closed))) ClosedEnum { +; ce1 +; } ce; +; +; $ clang++ -O0 -g debug-info-enum-kind.cpp -c + + +; CHECK: .debug_abbrev contents: + +; CHECK: [3] DW_TAG_enumeration_type DW_CHILDREN_yes +; CHECK: DW_AT_APPLE_enum_kind DW_FORM_data1 + +; CHECK: .debug_info contents: + +; CHECK: DW_TAG_enumeration_type [3] +; CHECK-DAG: DW_AT_name {{.*}} string = "OpenEnum" +; CHECK-DAG: DW_AT_APPLE_enum_kind [DW_FORM_data1] (DW_APPLE_ENUM_KIND_Open) + +; CHECK: DW_TAG_enumeration_type [3] +; CHECK-DAG: DW_AT_name {{.*}} string = "ClosedEnum" +; CHECK-DAG: DW_AT_APPLE_enum_kind [DW_FORM_data1] (DW_APPLE_ENUM_KIND_Closed) + +source_filename = "enum.cpp" +target triple = "arm64-apple-macosx" + +@oe = global i32 0, align 4, !dbg !0 +@ce = global i32 0, align 4, !dbg !13 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15, !16} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "oe", scope: !2, file: !3, line: 3, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 21.0.0git", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !12, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/") +!3 = !DIFile(filename: "enum.cpp", directory: "/tmp") +!4 = !{!5, !9} +!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "OpenEnum", file: !3, line: 1, baseType: !6, size: 32, elements: !7, identifier: "_ZTS8OpenEnum", enumKind: DW_APPLE_ENUM_KIND_Open) +!6 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!7 = !{!8} +!8 = !DIEnumerator(name: "oe1", value: 0, isUnsigned: true) +!9 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "ClosedEnum", file: !3, line: 5, baseType: !6, size: 32, elements: !10, identifier: "_ZTS10ClosedEnum", enumKind: DW_APPLE_ENUM_KIND_Closed) +!10 = !{!11} +!11 = !DIEnumerator(name: "ce1", value: 0, isUnsigned: true) +!12 = !{!0, !13} +!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) +!14 = distinct !DIGlobalVariable(name: "ce", scope: !2, file: !3, line: 7, type: !9, isLocal: false, isDefinition: true) +!15 = !{i32 7, !"Dwarf Version", i32 5} +!16 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_enum_kind.s b/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_enum_kind.s new file mode 100644 index 0000000000000..5b391f82dac32 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_enum_kind.s @@ -0,0 +1,44 @@ +;; Demonstrate dumping DW_AT_APPLE_enum_kind. +; RUN: llvm-mc -triple=aarch64--darwin -filetype=obj < %s | \ +; RUN: llvm-dwarfdump -v - | FileCheck %s + +; CHECK: .debug_abbrev contents: +; CHECK: DW_AT_APPLE_enum_kind DW_FORM_data1 +; CHECK: .debug_info contents: +; CHECK: DW_AT_APPLE_enum_kind [DW_FORM_data1] (DW_APPLE_ENUM_KIND_Closed) +; CHECK: DW_AT_APPLE_enum_kind [DW_FORM_data1] (DW_APPLE_ENUM_KIND_Open) + + .section __DWARF,__debug_abbrev,regular,debug +Lsection_abbrev: + .byte 1 ; Abbreviation Code + .byte 17 ; DW_TAG_compile_unit + .byte 1 ; DW_CHILDREN_yes + .byte 0 ; EOM(1) + .byte 0 ; EOM(2) + .byte 2 ; Abbreviation Code + .byte 4 ; DW_TAG_enumeration_type + .byte 0 ; DW_CHILDREN_no + .ascii "\361\177" ; DW_AT_APPLE_enum_kind + .byte 11 ; DW_FORM_data1 + .byte 0 ; EOM(1) + .byte 0 ; EOM(2) + .byte 0 ; EOM(3) + .section __DWARF,__debug_info,regular,debug +Lsection_info: +Lcu_begin0: +.set Lset0, Ldebug_info_end0-Ldebug_info_start0 ; Length of Unit + .long Lset0 +Ldebug_info_start0: + .short 5 ; DWARF version number + .byte 1 ; DWARF Unit Type + .byte 8 ; Address Size (in bytes) +.set Lset1, Lsection_abbrev-Lsection_abbrev ; Offset Into Abbrev. Section + .long Lset1 + .byte 1 ; Abbrev [1] 0xc:0x40 DW_TAG_compile_unit + .byte 2 ; Abbrev [3] 0x2a:0x9 DW_TAG_enumeration_type + .byte 0 ; DW_APPLE_ENUM_KIND_Closed + .byte 2 ; Abbrev [3] 0x42:0x9 DW_TAG_enumeration_type + .byte 1 ; DW_APPLE_ENUM_KIND_Open + .byte 0 ; End Of Children Mark +Ldebug_info_end0: + diff --git a/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp index 7180b8183c50a..7c673b0166188 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, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, std::nullopt, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Enable the mapping. There still shouldn't be a type. Context.enableDebugTypeODRUniquing(); @@ -40,8 +40,8 @@ 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, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, std::nullopt, + 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. @@ -49,14 +49,14 @@ TEST(DebugTypeODRUniquingTest, getODRType) { EXPECT_EQ(&CT, DICompositeType::getODRType( Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, - nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, 0, std::nullopt, 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, nullptr, 0, DINode::FlagZero, nullptr, 0, + std::nullopt, 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, nullptr, 0, DINode::FlagZero, nullptr, 0, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); // Check that it's discarded with the type map. Context.disableDebugTypeODRUniquing(); @@ -75,43 +75,48 @@ 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, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, + std::nullopt, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr); EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); // 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, nullptr, 0, - DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr)); + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, + nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, + nullptr, 0, std::nullopt, 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, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); + nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0, + std::nullopt, 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, nullptr, 0, DINode::FlagZero, - nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr)); + nullptr, 0, std::nullopt, 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, nullptr, 0, - DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr)); + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, + nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, + nullptr, 0, std::nullopt, 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, nullptr, 0, - DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr)); + EXPECT_EQ(&CT, + DICompositeType::buildODRType( + Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 111u, + nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, + nullptr, 0, std::nullopt, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr)); EXPECT_NE(111u, CT.getLine()); } @@ -123,8 +128,8 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { MDString &UUID = *MDString::get(Context, "UUID"); auto &CT = *DICompositeType::buildODRType( Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, nullptr, - 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr); + 0, DINode::FlagFwdDecl, nullptr, 0, std::nullopt, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); // Create macros for running through all the fields except Identifier and Flags. #define FOR_EACH_MDFIELD() \ @@ -141,7 +146,8 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { DO_FOR_FIELD(AlignInBits) \ DO_FOR_FIELD(OffsetInBits) \ DO_FOR_FIELD(NumExtraInhabitants) \ - DO_FOR_FIELD(RuntimeLang) + DO_FOR_FIELD(RuntimeLang) \ + DO_FOR_FIELD(EnumKind) // Create all the fields. #define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X); @@ -157,8 +163,8 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { Context, UUID, 0, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, nullptr, NumExtraInhabitants, DINode::FlagArtificial, Elements, - RuntimeLang, VTableHolder, TemplateParams, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr)); + RuntimeLang, EnumKind, 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 628221339c89b..8fe40a94ee546 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -115,9 +115,10 @@ class MetadataTest : public testing::Test { return ConstantAsMetadata::get(getConstant()); } DIType *getCompositeType() { - return DICompositeType::getDistinct( - Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr, - 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, ""); + return DICompositeType::getDistinct(Context, dwarf::DW_TAG_structure_type, + "", nullptr, 0, nullptr, nullptr, 32, + 32, 0, DINode::FlagZero, nullptr, 0, + std::nullopt, nullptr, nullptr, ""); } Function *getFunction(StringRef Name) { return Function::Create( @@ -2001,11 +2002,12 @@ TEST_F(DICompositeTypeTest, get) { DIType *VTableHolder = getCompositeType(); MDTuple *TemplateParams = getTuple(); StringRef Identifier = "some id"; + std::optional EnumKind = 1; - auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier); + auto *N = DICompositeType::get( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier); EXPECT_EQ(Tag, N->getTag()); EXPECT_EQ(Name, N->getName()); EXPECT_EQ(File, N->getFile()); @@ -2021,84 +2023,91 @@ TEST_F(DICompositeTypeTest, get) { EXPECT_EQ(VTableHolder, N->getVTableHolder()); EXPECT_EQ(TemplateParams, N->getTemplateParams().get()); EXPECT_EQ(Identifier, N->getIdentifier()); + EXPECT_EQ(EnumKind, N->getEnumKind()); - EXPECT_EQ(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EXPECT_EQ(N, DICompositeType::get( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, + EnumKind, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get(Context, Tag + 1, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); - EXPECT_NE(N, DICompositeType::get(Context, Tag, "abc", File, Line, Scope, - BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, + Identifier)); + EXPECT_NE(N, DICompositeType::get( + Context, Tag, "abc", File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, + EnumKind, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, getFile(), Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, + Identifier)); EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line + 1, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); - EXPECT_NE(N, DICompositeType::get( - Context, Tag, Name, File, Line, getSubprogram(), BaseType, - SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, - RuntimeLang, VTableHolder, TemplateParams, Identifier)); - EXPECT_NE(N, DICompositeType::get( - Context, Tag, Name, File, Line, Scope, getBasicType("other"), - SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, - RuntimeLang, VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, + Identifier)); + EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, + getSubprogram(), BaseType, SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, + RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits + 1, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + getBasicType("other"), SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, + RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits, AlignInBits + 1, + BaseType, SizeInBits + 1, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, + Identifier)); + EXPECT_NE(N, DICompositeType::get( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits + 1, OffsetInBits, Flags, Elements, RuntimeLang, + EnumKind, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, Identifier)); DINode::DIFlags FlagsPOne = static_cast(Flags + 1); EXPECT_NE(N, DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, FlagsPOne, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, getTuple(), RuntimeLang, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1, - VTableHolder, TemplateParams, Identifier)); + EnumKind, VTableHolder, TemplateParams, Identifier)); EXPECT_NE(N, DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - getCompositeType(), TemplateParams, Identifier)); - EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, getTuple(), Identifier)); - EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, "other")); + EnumKind, getCompositeType(), TemplateParams, Identifier)); + EXPECT_NE(N, DICompositeType::get( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, + EnumKind, VTableHolder, getTuple(), Identifier)); + EXPECT_NE(N, DICompositeType::get( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, + EnumKind, VTableHolder, TemplateParams, "other")); // Be sure that missing identifiers get null pointers. EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, "") + EnumKind, VTableHolder, TemplateParams, "") ->getRawIdentifier()); EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams) + EnumKind, VTableHolder, TemplateParams) ->getRawIdentifier()); TempDICompositeType Temp = N->clone(); @@ -2118,14 +2127,15 @@ TEST_F(DICompositeTypeTest, getWithLargeValues) { DINode::DIFlags Flags = static_cast(5); MDTuple *Elements = getTuple(); unsigned RuntimeLang = 6; + std::optional EnumKind = 1; DIType *VTableHolder = getCompositeType(); MDTuple *TemplateParams = getTuple(); StringRef Identifier = "some id"; - auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, - BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier); + auto *N = DICompositeType::get( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder, + TemplateParams, Identifier); EXPECT_EQ(SizeInBits, N->getSizeInBits()); EXPECT_EQ(AlignInBits, N->getAlignInBits()); EXPECT_EQ(OffsetInBits, N->getOffsetInBits()); @@ -2143,11 +2153,13 @@ TEST_F(DICompositeTypeTest, replaceOperands) { uint64_t OffsetInBits = 4; DINode::DIFlags Flags = static_cast(5); unsigned RuntimeLang = 6; + std::optional EnumKind = 1; StringRef Identifier = "some id"; - auto *N = DICompositeType::get( - Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier); + auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope, + BaseType, SizeInBits, AlignInBits, + OffsetInBits, Flags, nullptr, RuntimeLang, + EnumKind, nullptr, nullptr, Identifier); auto *Elements = MDTuple::getDistinct(Context, {}); EXPECT_EQ(nullptr, N->getElements().get()); @@ -2188,6 +2200,7 @@ TEST_F(DICompositeTypeTest, variant_part) { uint64_t OffsetInBits = 4; DINode::DIFlags Flags = static_cast(5); unsigned RuntimeLang = 6; + std::optional EnumKind = 1; StringRef Identifier = "some id"; DIDerivedType *Discriminator = cast(getDerivedType()); DIDerivedType *Discriminator2 = cast(getDerivedType()); @@ -2196,22 +2209,22 @@ TEST_F(DICompositeTypeTest, variant_part) { auto *N = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - Discriminator); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, Discriminator); // Test the hashing. auto *Same = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - Discriminator); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, Discriminator); auto *Other = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - Discriminator2); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, Discriminator2); auto *NoDisc = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr); EXPECT_EQ(N, Same); EXPECT_NE(Same, Other); @@ -2233,6 +2246,7 @@ TEST_F(DICompositeTypeTest, dynamicArray) { uint64_t OffsetInBits = 4; DINode::DIFlags Flags = static_cast(3); unsigned RuntimeLang = 6; + std::optional EnumKind = 1; StringRef Identifier = "some id"; DIType *Type = getDerivedType(); Metadata *DlVar1 = DILocalVariable::get(Context, Scope, "dl_var1", File, 8, @@ -2257,18 +2271,18 @@ TEST_F(DICompositeTypeTest, dynamicArray) { ConstantAsMetadata *RankConst2 = ConstantAsMetadata::get(RankInt2); auto *N1 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DlVar1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DlVar1); auto *Same1 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DlVar1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DlVar1); auto *Other1 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DlVar2); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DlVar2); EXPECT_EQ(N1, Same1); EXPECT_NE(Same1, Other1); @@ -2276,18 +2290,18 @@ TEST_F(DICompositeTypeTest, dynamicArray) { auto *N2 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1); auto *Same2 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1); auto *Other2 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation2); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation2); EXPECT_EQ(N2, Same2); EXPECT_NE(Same2, Other2); @@ -2295,18 +2309,18 @@ TEST_F(DICompositeTypeTest, dynamicArray) { auto *N3 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1, nullptr, nullptr, Rank1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1, nullptr, nullptr, Rank1); auto *Same3 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1, nullptr, nullptr, Rank1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1, nullptr, nullptr, Rank1); auto *Other3 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1, nullptr, nullptr, Rank2); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1, nullptr, nullptr, Rank2); EXPECT_EQ(N3, Same3); EXPECT_NE(Same3, Other3); @@ -2314,18 +2328,18 @@ TEST_F(DICompositeTypeTest, dynamicArray) { auto *N4 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1, nullptr, nullptr, RankConst1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1, nullptr, nullptr, RankConst1); auto *Same4 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1, nullptr, nullptr, RankConst1); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1, nullptr, nullptr, RankConst1); auto *Other4 = DICompositeType::get( Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier, - nullptr, DataLocation1, nullptr, nullptr, RankConst2); + OffsetInBits, Flags, nullptr, RuntimeLang, EnumKind, nullptr, nullptr, + Identifier, nullptr, DataLocation1, nullptr, nullptr, RankConst2); EXPECT_EQ(N4, Same4); EXPECT_NE(Same4, Other4); diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp index 96e863b257c95..885ba3e2e0581 100644 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -514,7 +514,8 @@ class CloneFunc : public ::testing::Test { // cloning). auto *StructType = DICompositeType::getDistinct( C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr, - nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr); + nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, std::nullopt, nullptr, + nullptr); auto *InlinedSP = DBuilder.createFunction( CU, "inlined", "inlined", File, 8, FuncType, 9, DINode::FlagZero, DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition); From fc22f2951c53803af724c90543c7a0f2f0489d6c Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 5 Feb 2025 13:30:52 +0000 Subject: [PATCH 2/3] fixup! fix typo --- llvm/include/llvm/BinaryFormat/Dwarf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 0301259f0f436..397b4b164386d 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -47,7 +47,7 @@ enum LLVMConstants : uint32_t { DW_TAG_invalid = ~0U, ///< Tag for invalid results. DW_VIRTUALITY_invalid = ~0U, ///< Virtuality for invalid results. DW_MACINFO_invalid = ~0U, ///< Macinfo type for invalid results. - DW_APPLE_ENUM_KIND_invalid = ~0U, ///< Virtuality for invalid results. + DW_APPLE_ENUM_KIND_invalid = ~0U, ///< Enum kind for invalid results. /// \} /// Special values for an initial length field. From 115efeb97130fb783be752b3cb3ae943f1e6e049 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 5 Feb 2025 17:07:14 +0000 Subject: [PATCH 3/3] fixup! fix MLIR build --- mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index cf734de49acd6..1d3ed6f3262f9 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -151,7 +151,7 @@ DebugTranslation::translateTemporaryImpl(DICompositeTypeAttr attr) { attr.getAlignInBits(), /*OffsetInBits=*/0, /*Flags=*/static_cast(attr.getFlags()), - /*Elements=*/nullptr, /*RuntimeLang=*/0, + /*Elements=*/nullptr, /*RuntimeLang=*/0, /*EnumKind=*/std::nullopt, /*VTableHolder=*/nullptr); } @@ -187,7 +187,7 @@ DebugTranslation::translateImpl(DICompositeTypeAttr attr) { /*OffsetInBits=*/0, /*Flags=*/static_cast(attr.getFlags()), getMDTupleOrNull(attr.getElements()), - /*RuntimeLang=*/0, /*VTableHolder=*/nullptr, + /*RuntimeLang=*/0, /*EnumKind*/ std::nullopt, /*VTableHolder=*/nullptr, /*TemplateParams=*/nullptr, /*Identifier=*/nullptr, /*Discriminator=*/nullptr, getExpressionAttrOrNull(attr.getDataLocation()),