[Mlir-commits] [llvm] [mlir] [llvm][DebugInfo] Add new DW_AT_APPLE_enum_kind to encode enum_extensibility (PR #124752)
Michael Buch
llvmlistbot at llvm.org
Wed Feb 5 09:09:01 PST 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/124752
>From b1de0d923fa705981dce2d8d9dee35f87305a078 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
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 7b47bc88ddb25f..c52622879b885e 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 2bb84fbc864d8e..724a14ccc7aeaf 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 3be819c0a76eeb..0301259f0f4364 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 6c479415b9ed27..8bee9f4703dd9c 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<uint32_t> 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<uint32_t> 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<uint32_t> 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 5ea8c0d7b448dc..8515d8eda85686 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<uint32_t> 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<uint32_t> EnumKind, DIFlags Flags,
ArrayRef<Metadata *> 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<uint32_t> EnumKind,
+ DIFlags Flags) {
assert(isDistinct() && "Only distinct nodes can mutate");
assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
this->RuntimeLang = RuntimeLang;
+ this->EnumKind = EnumKind;
DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
NumExtraInhabitants, Flags);
}
@@ -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<uint32_t> 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<uint32_t> EnumKind, Metadata *VTableHolder,
+ Metadata *TemplateParams, MDString *Identifier,
+ Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
+ Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
+ Metadata *Specification, uint32_t NumExtraInhabitants,
+ 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<uint32_t> 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<uint32_t> EnumKind, Metadata *VTableHolder,
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0),
(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<uint32_t> 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<uint32_t> EnumKind,
+ Metadata *VTableHolder, Metadata *TemplateParams,
+ Metadata *Discriminator, Metadata *DataLocation,
+ Metadata *Associated, Metadata *Allocated, Metadata *Rank,
+ Metadata *Annotations);
DIType *getBaseType() const { return cast_or_null<DIType>(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<uint32_t> 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 5ea507c009bdc6..9bc5a79da49c61 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 fa0079bac435c1..610ffe7d69be49 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<MDUnsignedField &>(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<unsigned> 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 0cd5dfbd023e4e..b9b10a541b2632 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<unsigned>(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 1caa8480efc518..413d9f68e6cc3b 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<DINode::DIFlags>(Record[10]);
Metadata *Elements = nullptr;
unsigned RuntimeLang = Record[12];
+ std::optional<uint32_t> 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<DICompositeType>(CT));
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 31c96400dd0fe5..28518607222af0 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 d3450b8b0556fd..3426780d553fe9 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<DICompileUnit>(Context) || isa<DIFile>(Context) ||
isa<DINamespace>(Context) || isa<DICommonBlock>(Context);
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index a37a8901489cf7..c8ed4e19f1b612 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 d9bd4f11e89a39..e27015892928ca 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<MDTuple>(TemplateParams), UniqueIdentifier);
+ OffsetInBits, Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt,
+ VTableHolder, cast_or_null<MDTuple>(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<uint32_t> 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<DIExpression *, DIVariable *> 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<DIExpression *>(DL) ? (Metadata *)cast<DIExpression *>(DL)
: (Metadata *)cast<DIVariable *>(DL),
isa<DIExpression *>(AS) ? (Metadata *)cast<DIExpression *>(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<uint32_t> 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<uint32_t> 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 915cdd301f2c7e..32e659d43edcfc 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<uint32_t> EnumKind,
+ Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
+ Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
+ Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
+ Metadata *Specification, uint32_t NumExtraInhabitants, 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<uint32_t> 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<uint32_t> 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 00000000000000..399d80c7780725
--- /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"
+
+ at oe = global i32 0, align 4, !dbg !0
+ at 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 00000000000000..5b391f82dac323
--- /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 7180b8183c50a7..7c673b01661888 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 628221339c89bf..8fe40a94ee546a 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<uint32_t> 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<DINode::DIFlags>(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<DINode::DIFlags>(5);
MDTuple *Elements = getTuple();
unsigned RuntimeLang = 6;
+ std::optional<uint32_t> 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<DINode::DIFlags>(5);
unsigned RuntimeLang = 6;
+ std::optional<uint32_t> 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<DINode::DIFlags>(5);
unsigned RuntimeLang = 6;
+ std::optional<uint32_t> EnumKind = 1;
StringRef Identifier = "some id";
DIDerivedType *Discriminator = cast<DIDerivedType>(getDerivedType());
DIDerivedType *Discriminator2 = cast<DIDerivedType>(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<DINode::DIFlags>(3);
unsigned RuntimeLang = 6;
+ std::optional<uint32_t> 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 96e863b257c95e..885ba3e2e0581c 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 <michaelbuch12 at gmail.com>
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 0301259f0f4364..397b4b164386d8 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 <michaelbuch12 at gmail.com>
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 cf734de49acd62..1d3ed6f3262f91 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<llvm::DINode::DIFlags>(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<llvm::DINode::DIFlags>(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()),
More information about the Mlir-commits
mailing list