@@ -55,9 +55,12 @@ getTypeAndDie(TypeSystemSwiftTypeRef &ts,
55
55
56
56
static std::optional<swift::reflection::FieldDescriptorKind>
57
57
getFieldDescriptorKindForDie (DWARFDIE &die) {
58
- if (die.Tag () == DW_TAG_structure_type)
58
+ if (die.Tag () == DW_TAG_structure_type) {
59
+ if (die.HasChildren () && die.GetFirstChild ().Tag () == llvm::dwarf::DW_TAG_variant_part)
60
+ return swift::reflection::FieldDescriptorKind::Enum;
59
61
return swift::reflection::FieldDescriptorKind::Struct;
60
- // TODO: handle more cases, for now we only support structs.
62
+ }
63
+ // TODO: handle more cases, for now we only support structs and enums.
61
64
return {};
62
65
}
63
66
@@ -134,10 +137,20 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
134
137
if (!die)
135
138
return {};
136
139
137
- // For now we only support structs.
138
- if (Kind != swift::reflection::FieldDescriptorKind::Struct)
140
+ switch (Kind) {
141
+ case swift::reflection::FieldDescriptorKind::Struct:
142
+ return getFieldRecordsFromStruct (die, dwarf_parser);
143
+ case swift::reflection::FieldDescriptorKind::Enum:
144
+ return getFieldRecordsFromEnum (die, dwarf_parser);
145
+ default :
146
+ // TODO: handle more cases.
139
147
return {};
148
+ }
149
+ }
140
150
151
+ std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>>
152
+ getFieldRecordsFromStruct (const DWARFDIE &die,
153
+ plugin::dwarf::DWARFASTParser *dwarf_parser) {
141
154
std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>> fields;
142
155
for (DWARFDIE child_die : die.children ()) {
143
156
auto tag = child_die.Tag ();
@@ -159,6 +172,40 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
159
172
}
160
173
return fields;
161
174
}
175
+
176
+ std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>>
177
+ getFieldRecordsFromEnum (const DWARFDIE &die,
178
+ plugin::dwarf::DWARFASTParser *dwarf_parser) {
179
+ std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>> fields;
180
+ auto variant_part = die.GetFirstChild ();
181
+ for (DWARFDIE child_die : variant_part.children ()) {
182
+ auto tag = child_die.Tag ();
183
+ if (tag != llvm::dwarf::DW_TAG_variant)
184
+ continue ;
185
+ auto member = child_die.GetFirstChild ();
186
+ tag = member.Tag ();
187
+ if (tag != llvm::dwarf::DW_TAG_member)
188
+ continue ;
189
+ const auto *member_field_name =
190
+ member.GetAttributeValueAsString (llvm::dwarf::DW_AT_name, " " );
191
+ auto *member_type = dwarf_parser->GetTypeForDIE (member);
192
+
193
+ // Empty enum cases don' have a type.
194
+ auto member_mangled_typename =
195
+ member_type
196
+ ? member_type->GetForwardCompilerType ().GetMangledTypeName ()
197
+ : ConstString ();
198
+
199
+ // Only matters for enums, so set to false for structs.
200
+ bool is_indirect_case = false ;
201
+ // Unused by type info construction.
202
+ bool is_var = false ;
203
+ fields.emplace_back (std::make_unique<DWARFFieldRecordImpl>(
204
+ is_indirect_case, is_var, ConstString (member_field_name),
205
+ member_mangled_typename));
206
+ }
207
+ return fields;
208
+ }
162
209
};
163
210
} // namespace
164
211
0 commit comments