Skip to content

Commit eb8901b

Browse files
authored
[llvm][DebugInfo] Add new DW_AT_APPLE_enum_kind to encode enum_extensibility (#124752)
When creating `EnumDecl`s from DWARF for Objective-C `NS_ENUM`s, the Swift compiler tries to figure out if it should perform "swiftification" of that enum (which involves renaming the enumerator cases, etc.). The heuristics by which it determines whether we want to swiftify an enum is by checking the `enum_extensibility` attribute (because that's what `NS_ENUM` pretty much are). Currently LLDB fails to attach the `EnumExtensibilityAttr` to `EnumDecl`s it creates (because there's not enough info in DWARF to derive it), which means we have to fall back to re-building Swift modules on-the-fly, slowing down expression evaluation substantially. This happens around https://github.com/swiftlang/swift/blob/4b3931c8ce437b3f13f245e6423f95c94a5876ac/lib/ClangImporter/ImportEnumInfo.cpp#L37-L59 To speed up Swift exression evaluation, this patch proposes encoding the C/C++/Objective-C `enum_extensibility` attribute in DWARF via a new `DW_AT_APPLE_ENUM_KIND`. This would currently be only used from the LLDB Swift plugin. But may be of interest to other language plugins as well (though I haven't come up with a concrete use-case for it outside of Swift). I'm open to naming suggestions of the various new attributes/attribute constants proposed here. I tried to be as generic as possible if we wanted to extend it to other kinds of enum properties (e.g., flag enums). The new attribute would look as follows: ``` DW_TAG_enumeration_type DW_AT_type (0x0000003a "unsigned int") DW_AT_APPLE_enum_kind (DW_APPLE_ENUM_KIND_Closed) DW_AT_name ("ClosedEnum") DW_AT_byte_size (0x04) DW_AT_decl_file ("enum.c") DW_AT_decl_line (23) DW_TAG_enumeration_type DW_AT_type (0x0000003a "unsigned int") DW_AT_APPLE_enum_kind (DW_APPLE_ENUM_KIND_Open) DW_AT_name ("OpenEnum") DW_AT_byte_size (0x04) DW_AT_decl_file ("enum.c") DW_AT_decl_line (27) ``` Absence of the attribute means the extensibility of the enum is unknown and abides by whatever the language rules of that CU dictate. This does feel like a big hammer for quite a specific use-case, so I'm happy to discuss alternatives. Alternatives considered: * Re-using an existing DWARF attribute to express extensibility. E.g., a `DW_TAG_enumeration_type` could have a `DW_AT_count` or `DW_AT_upper_bound` indicating the number of enumerators, which could imply closed-ness. I felt like a dedicated attribute (which could be generalized further) seemed more applicable. But I'm open to re-using existing attributes. * Encoding the entire attribute string (i.e., `DW_TAG_LLVM_annotation ("enum_extensibility((open))")`) on the `DW_TAG_enumeration_type`. Then in LLDB somehow parse that out into a `EnumExtensibilityAttr`. I haven't found a great API in Clang to parse arbitrary strings into AST nodes (the ones I've found required fully formed C++ constructs). Though if someone knows of a good way to do this, happy to consider that too.
1 parent 5eed019 commit eb8901b

File tree

20 files changed

+461
-234
lines changed

20 files changed

+461
-234
lines changed

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ enum Kind {
498498
DwarfMacinfo, // DW_MACINFO_foo
499499
ChecksumKind, // CSK_foo
500500
DbgRecordType, // dbg_foo
501+
DwarfEnumKind, // DW_APPLE_ENUM_KIND_foo
501502

502503
// Type valued tokens (TyVal).
503504
Type,

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
2525
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
2626
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
27-
defined HANDLE_DW_END || defined HANDLE_DW_SECT)
27+
defined HANDLE_DW_END || defined HANDLE_DW_SECT || \
28+
defined HANDLE_DW_APPLE_ENUM_KIND)
2829
#error "Missing macro definition of HANDLE_DW*"
2930
#endif
3031

@@ -146,6 +147,10 @@
146147
#define HANDLE_DW_SECT(ID, NAME)
147148
#endif
148149

150+
#ifndef HANDLE_DW_APPLE_ENUM_KIND
151+
#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME)
152+
#endif
153+
149154
HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
150155
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
151156
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
@@ -638,6 +643,7 @@ HANDLE_DW_AT(0x3fed, APPLE_property, 0, APPLE)
638643
HANDLE_DW_AT(0x3fee, APPLE_objc_direct, 0, APPLE)
639644
HANDLE_DW_AT(0x3fef, APPLE_sdk, 0, APPLE)
640645
HANDLE_DW_AT(0x3ff0, APPLE_origin, 0, APPLE)
646+
HANDLE_DW_AT(0x3ff1, APPLE_enum_kind, 0, APPLE)
641647

642648
// Attribute form encodings.
643649
HANDLE_DW_FORM(0x01, addr, 2, DWARF)
@@ -1269,6 +1275,11 @@ HANDLE_DW_APPLE_PROPERTY(0x1000, nullability)
12691275
HANDLE_DW_APPLE_PROPERTY(0x2000, null_resettable)
12701276
HANDLE_DW_APPLE_PROPERTY(0x4000, class)
12711277

1278+
// Enum kinds.
1279+
// Keep in sync with EnumExtensibilityAttr::Kind.
1280+
HANDLE_DW_APPLE_ENUM_KIND(0x00, Closed)
1281+
HANDLE_DW_APPLE_ENUM_KIND(0x01, Open)
1282+
12721283
// DWARF v5 Unit Types.
12731284
HANDLE_DW_UT(0x01, compile)
12741285
HANDLE_DW_UT(0x02, type)
@@ -1367,3 +1378,4 @@ HANDLE_DW_SECT(8, RNGLISTS)
13671378
#undef HANDLE_DW_IDX
13681379
#undef HANDLE_DW_END
13691380
#undef HANDLE_DW_SECT
1381+
#undef HANDLE_DW_APPLE_ENUM_KIND

llvm/include/llvm/BinaryFormat/Dwarf.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ namespace dwarf {
4444
enum LLVMConstants : uint32_t {
4545
/// LLVM mock tags (see also llvm/BinaryFormat/Dwarf.def).
4646
/// \{
47-
DW_TAG_invalid = ~0U, ///< Tag for invalid results.
48-
DW_VIRTUALITY_invalid = ~0U, ///< Virtuality for invalid results.
49-
DW_MACINFO_invalid = ~0U, ///< Macinfo type for invalid results.
47+
DW_TAG_invalid = ~0U, ///< Tag for invalid results.
48+
DW_VIRTUALITY_invalid = ~0U, ///< Virtuality for invalid results.
49+
DW_MACINFO_invalid = ~0U, ///< Macinfo type for invalid results.
50+
DW_APPLE_ENUM_KIND_invalid = ~0U, ///< Enum kind for invalid results.
5051
/// \}
5152

5253
/// Special values for an initial length field.
@@ -198,6 +199,12 @@ enum VirtualityAttribute {
198199
DW_VIRTUALITY_max = 0x02
199200
};
200201

202+
enum EnumKindAttribute {
203+
#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME) DW_APPLE_ENUM_KIND_##NAME = ID,
204+
#include "llvm/BinaryFormat/Dwarf.def"
205+
DW_APPLE_ENUM_KIND_max = 0x01
206+
};
207+
201208
enum DefaultedMemberAttribute {
202209
#define HANDLE_DW_DEFAULTED(ID, NAME) DW_DEFAULTED_##NAME = ID,
203210
#include "llvm/BinaryFormat/Dwarf.def"
@@ -981,6 +988,7 @@ StringRef AccessibilityString(unsigned Access);
981988
StringRef DefaultedMemberString(unsigned DefaultedEncodings);
982989
StringRef VisibilityString(unsigned Visibility);
983990
StringRef VirtualityString(unsigned Virtuality);
991+
StringRef EnumKindString(unsigned EnumKind);
984992
StringRef LanguageString(unsigned Language);
985993
StringRef CaseString(unsigned Case);
986994
StringRef ConventionString(unsigned Convention);
@@ -1020,6 +1028,7 @@ unsigned getOperationEncoding(StringRef OperationEncodingString);
10201028
unsigned getSubOperationEncoding(unsigned OpEncoding,
10211029
StringRef SubOperationEncodingString);
10221030
unsigned getVirtuality(StringRef VirtualityString);
1031+
unsigned getEnumKind(StringRef EnumKindString);
10231032
unsigned getLanguage(StringRef LanguageString);
10241033
unsigned getCallingConvention(StringRef LanguageString);
10251034
unsigned getAttributeEncoding(StringRef EncodingString);

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,8 @@ namespace llvm {
632632
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
633633
uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,
634634
DIType *UnderlyingType, unsigned RunTimeLang = 0,
635-
StringRef UniqueIdentifier = "", bool IsScoped = false);
635+
StringRef UniqueIdentifier = "", bool IsScoped = false,
636+
std::optional<uint32_t> EnumKind = std::nullopt);
636637
/// Create debugging information entry for a set.
637638
/// \param Scope Scope in which this set is defined.
638639
/// \param Name Set name.
@@ -667,19 +668,20 @@ namespace llvm {
667668
static DIType *createObjectPointerType(DIType *Ty, bool Implicit);
668669

669670
/// Create a permanent forward-declared type.
670-
DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,
671-
DIScope *Scope, DIFile *F, unsigned Line,
672-
unsigned RuntimeLang = 0,
673-
uint64_t SizeInBits = 0,
674-
uint32_t AlignInBits = 0,
675-
StringRef UniqueIdentifier = "");
671+
DICompositeType *
672+
createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F,
673+
unsigned Line, unsigned RuntimeLang = 0,
674+
uint64_t SizeInBits = 0, uint32_t AlignInBits = 0,
675+
StringRef UniqueIdentifier = "",
676+
std::optional<uint32_t> EnumKind = std::nullopt);
676677

677678
/// Create a temporary forward-declared type.
678679
DICompositeType *createReplaceableCompositeType(
679680
unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,
680681
unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
681682
uint32_t AlignInBits = 0, DINode::DIFlags Flags = DINode::FlagFwdDecl,
682-
StringRef UniqueIdentifier = "", DINodeArray Annotations = nullptr);
683+
StringRef UniqueIdentifier = "", DINodeArray Annotations = nullptr,
684+
std::optional<uint32_t> EnumKind = std::nullopt);
683685

684686
/// Retain DIScope* in a module even if it is not referenced
685687
/// through debug info anchors.

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,24 +1176,28 @@ class DICompositeType : public DIType {
11761176
friend class MDNode;
11771177

11781178
unsigned RuntimeLang;
1179+
std::optional<uint32_t> EnumKind;
11791180

11801181
DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
11811182
unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
11821183
uint32_t AlignInBits, uint64_t OffsetInBits,
1183-
uint32_t NumExtraInhabitants, DIFlags Flags,
1184+
uint32_t NumExtraInhabitants,
1185+
std::optional<uint32_t> EnumKind, DIFlags Flags,
11841186
ArrayRef<Metadata *> Ops)
11851187
: DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
11861188
AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops),
1187-
RuntimeLang(RuntimeLang) {}
1189+
RuntimeLang(RuntimeLang), EnumKind(EnumKind) {}
11881190
~DICompositeType() = default;
11891191

11901192
/// Change fields in place.
11911193
void mutate(unsigned Tag, unsigned Line, unsigned RuntimeLang,
11921194
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
1193-
uint32_t NumExtraInhabitants, DIFlags Flags) {
1195+
uint32_t NumExtraInhabitants, std::optional<uint32_t> EnumKind,
1196+
DIFlags Flags) {
11941197
assert(isDistinct() && "Only distinct nodes can mutate");
11951198
assert(getRawIdentifier() && "Only ODR-uniqued nodes should mutate");
11961199
this->RuntimeLang = RuntimeLang;
1200+
this->EnumKind = EnumKind;
11971201
DIType::mutate(Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
11981202
NumExtraInhabitants, Flags);
11991203
}
@@ -1203,15 +1207,15 @@ class DICompositeType : public DIType {
12031207
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
12041208
uint32_t AlignInBits, uint64_t OffsetInBits, DIType *Specification,
12051209
uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements,
1206-
unsigned RuntimeLang, DIType *VTableHolder,
1207-
DITemplateParameterArray TemplateParams, StringRef Identifier,
1208-
DIDerivedType *Discriminator, Metadata *DataLocation,
1209-
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1210-
DINodeArray Annotations, StorageType Storage,
1210+
unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1211+
DIType *VTableHolder, DITemplateParameterArray TemplateParams,
1212+
StringRef Identifier, DIDerivedType *Discriminator,
1213+
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1214+
Metadata *Rank, DINodeArray Annotations, StorageType Storage,
12111215
bool ShouldCreate = true) {
12121216
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
12131217
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
1214-
Flags, Elements.get(), RuntimeLang, VTableHolder,
1218+
Flags, Elements.get(), RuntimeLang, EnumKind, VTableHolder,
12151219
TemplateParams.get(),
12161220
getCanonicalMDString(Context, Identifier), Discriminator,
12171221
DataLocation, Associated, Allocated, Rank, Annotations.get(),
@@ -1222,21 +1226,21 @@ class DICompositeType : public DIType {
12221226
unsigned Line, Metadata *Scope, Metadata *BaseType,
12231227
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
12241228
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
1225-
Metadata *VTableHolder, Metadata *TemplateParams,
1226-
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
1227-
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1228-
Metadata *Annotations, Metadata *Specification,
1229-
uint32_t NumExtraInhabitants, StorageType Storage,
1230-
bool ShouldCreate = true);
1229+
std::optional<uint32_t> EnumKind, Metadata *VTableHolder,
1230+
Metadata *TemplateParams, MDString *Identifier,
1231+
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
1232+
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
1233+
Metadata *Specification, uint32_t NumExtraInhabitants,
1234+
StorageType Storage, bool ShouldCreate = true);
12311235

12321236
TempDICompositeType cloneImpl() const {
12331237
return getTemporary(
12341238
getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
12351239
getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
1236-
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
1237-
getTemplateParams(), getIdentifier(), getDiscriminator(),
1238-
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
1239-
getRawRank(), getAnnotations(), getSpecification(),
1240+
getFlags(), getElements(), getRuntimeLang(), getEnumKind(),
1241+
getVTableHolder(), getTemplateParams(), getIdentifier(),
1242+
getDiscriminator(), getRawDataLocation(), getRawAssociated(),
1243+
getRawAllocated(), getRawRank(), getAnnotations(), getSpecification(),
12401244
getNumExtraInhabitants());
12411245
}
12421246

@@ -1246,7 +1250,8 @@ class DICompositeType : public DIType {
12461250
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
12471251
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
12481252
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1249-
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
1253+
DINodeArray Elements, unsigned RuntimeLang,
1254+
std::optional<uint32_t> EnumKind, DIType *VTableHolder,
12501255
DITemplateParameterArray TemplateParams = nullptr,
12511256
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
12521257
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
@@ -1255,23 +1260,24 @@ class DICompositeType : public DIType {
12551260
uint32_t NumExtraInhabitants = 0),
12561261
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
12571262
OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements,
1258-
RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator,
1259-
DataLocation, Associated, Allocated, Rank, Annotations))
1263+
RuntimeLang, EnumKind, VTableHolder, TemplateParams, Identifier,
1264+
Discriminator, DataLocation, Associated, Allocated, Rank, Annotations))
12601265
DEFINE_MDNODE_GET(
12611266
DICompositeType,
12621267
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
12631268
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
12641269
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
1265-
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
1270+
Metadata *Elements, unsigned RuntimeLang,
1271+
std::optional<uint32_t> EnumKind, Metadata *VTableHolder,
12661272
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
12671273
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
12681274
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
12691275
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
12701276
Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0),
12711277
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1272-
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
1273-
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
1274-
Annotations, Specification, NumExtraInhabitants))
1278+
OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder,
1279+
TemplateParams, Identifier, Discriminator, DataLocation, Associated,
1280+
Allocated, Rank, Annotations, Specification, NumExtraInhabitants))
12751281

12761282
TempDICompositeType clone() const { return cloneImpl(); }
12771283

@@ -1288,10 +1294,11 @@ class DICompositeType : public DIType {
12881294
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
12891295
uint64_t OffsetInBits, Metadata *Specification,
12901296
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
1291-
unsigned RuntimeLang, Metadata *VTableHolder,
1292-
Metadata *TemplateParams, Metadata *Discriminator,
1293-
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1294-
Metadata *Rank, Metadata *Annotations);
1297+
unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1298+
Metadata *VTableHolder, Metadata *TemplateParams,
1299+
Metadata *Discriminator, Metadata *DataLocation,
1300+
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1301+
Metadata *Annotations);
12951302
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
12961303
MDString &Identifier);
12971304

@@ -1310,10 +1317,11 @@ class DICompositeType : public DIType {
13101317
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
13111318
uint64_t OffsetInBits, Metadata *Specification,
13121319
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
1313-
unsigned RuntimeLang, Metadata *VTableHolder,
1314-
Metadata *TemplateParams, Metadata *Discriminator,
1315-
Metadata *DataLocation, Metadata *Associated,
1316-
Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
1320+
unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1321+
Metadata *VTableHolder, Metadata *TemplateParams,
1322+
Metadata *Discriminator, Metadata *DataLocation,
1323+
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1324+
Metadata *Annotations);
13171325

13181326
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
13191327
DINodeArray getElements() const {
@@ -1327,6 +1335,7 @@ class DICompositeType : public DIType {
13271335
}
13281336
StringRef getIdentifier() const { return getStringOperand(7); }
13291337
unsigned getRuntimeLang() const { return RuntimeLang; }
1338+
std::optional<uint32_t> getEnumKind() const { return EnumKind; }
13301339

13311340
Metadata *getRawBaseType() const { return getOperand(3); }
13321341
Metadata *getRawElements() const { return getOperand(4); }

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ lltok::Kind LLLexer::LexIdentifier() {
976976
DWKEYWORD(CC, DwarfCC);
977977
DWKEYWORD(OP, DwarfOp);
978978
DWKEYWORD(MACINFO, DwarfMacinfo);
979+
DWKEYWORD(APPLE_ENUM_KIND, DwarfEnumKind);
979980

980981
#undef DWKEYWORD
981982

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4704,6 +4704,12 @@ struct DwarfCCField : public MDUnsignedField {
47044704
DwarfCCField() : MDUnsignedField(0, dwarf::DW_CC_hi_user) {}
47054705
};
47064706

4707+
struct DwarfEnumKindField : public MDUnsignedField {
4708+
DwarfEnumKindField()
4709+
: MDUnsignedField(dwarf::DW_APPLE_ENUM_KIND_invalid,
4710+
dwarf::DW_APPLE_ENUM_KIND_max) {}
4711+
};
4712+
47074713
struct EmissionKindField : public MDUnsignedField {
47084714
EmissionKindField() : MDUnsignedField(0, DICompileUnit::LastEmissionKind) {}
47094715
};
@@ -4877,6 +4883,25 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name,
48774883
return false;
48784884
}
48794885

4886+
template <>
4887+
bool LLParser::parseMDField(LocTy Loc, StringRef Name,
4888+
DwarfEnumKindField &Result) {
4889+
if (Lex.getKind() == lltok::APSInt)
4890+
return parseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result));
4891+
4892+
if (Lex.getKind() != lltok::DwarfEnumKind)
4893+
return tokError("expected DWARF enum kind code");
4894+
4895+
unsigned EnumKind = dwarf::getEnumKind(Lex.getStrVal());
4896+
if (EnumKind == dwarf::DW_APPLE_ENUM_KIND_invalid)
4897+
return tokError("invalid DWARF enum kind code" + Twine(" '") +
4898+
Lex.getStrVal() + "'");
4899+
assert(EnumKind <= Result.Max && "Expected valid DWARF enum kind code");
4900+
Result.assign(EnumKind);
4901+
Lex.Lex();
4902+
return false;
4903+
}
4904+
48804905
template <>
48814906
bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) {
48824907
if (Lex.getKind() == lltok::APSInt)
@@ -5496,6 +5521,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
54965521
OPTIONAL(flags, DIFlagField, ); \
54975522
OPTIONAL(elements, MDField, ); \
54985523
OPTIONAL(runtimeLang, DwarfLangField, ); \
5524+
OPTIONAL(enumKind, DwarfEnumKindField, ); \
54995525
OPTIONAL(vtableHolder, MDField, ); \
55005526
OPTIONAL(templateParams, MDField, ); \
55015527
OPTIONAL(identifier, MDStringField, ); \
@@ -5517,15 +5543,19 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
55175543
else if (rank.isMDField())
55185544
Rank = rank.getMDFieldValue();
55195545

5546+
std::optional<unsigned> EnumKind;
5547+
if (enumKind.Val != dwarf::DW_APPLE_ENUM_KIND_invalid)
5548+
EnumKind = enumKind.Val;
5549+
55205550
// If this has an identifier try to build an ODR type.
55215551
if (identifier.Val)
55225552
if (auto *CT = DICompositeType::buildODRType(
55235553
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
55245554
scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
55255555
specification.Val, num_extra_inhabitants.Val, flags.Val,
5526-
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
5527-
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
5528-
Rank, annotations.Val)) {
5556+
elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val,
5557+
templateParams.Val, discriminator.Val, dataLocation.Val,
5558+
associated.Val, allocated.Val, Rank, annotations.Val)) {
55295559
Result = CT;
55305560
return false;
55315561
}
@@ -5536,9 +5566,10 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
55365566
DICompositeType,
55375567
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
55385568
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
5539-
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
5540-
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank,
5541-
annotations.Val, specification.Val, num_extra_inhabitants.Val));
5569+
runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val,
5570+
identifier.Val, discriminator.Val, dataLocation.Val, associated.Val,
5571+
allocated.Val, Rank, annotations.Val, specification.Val,
5572+
num_extra_inhabitants.Val));
55425573
return false;
55435574
}
55445575

0 commit comments

Comments
 (0)