@@ -73,7 +73,7 @@ getFieldDescriptorKindForDie(CompilerType type) {
73
73
return swift::reflection::FieldDescriptorKind::Class;
74
74
case lldb::eTypeClassStruct:
75
75
return swift::reflection::FieldDescriptorKind::Struct;
76
- case lldb::eTypeClassEnumeration :
76
+ case lldb::eTypeClassUnion :
77
77
return swift::reflection::FieldDescriptorKind::Enum;
78
78
default :
79
79
LLDB_LOG (GetLog (LLDBLog::Types),
@@ -203,7 +203,12 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
203
203
std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>>
204
204
getFieldRecordsFromEnum (const DWARFDIE &die,
205
205
plugin::dwarf::DWARFASTParser *dwarf_parser) {
206
- std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>> fields;
206
+ // Type lowering expects the payload fields to come before the non-payload
207
+ // ones.
208
+ std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>>
209
+ payload_fields;
210
+ std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>>
211
+ non_payload_fields;
207
212
auto variant_part = die.GetFirstChild ();
208
213
for (DWARFDIE child_die : variant_part.children ()) {
209
214
auto tag = child_die.Tag ();
@@ -227,11 +232,69 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
227
232
bool is_indirect_case = false ;
228
233
// Unused by type info construction.
229
234
bool is_var = false ;
230
- fields.emplace_back (std::make_unique<DWARFFieldRecordImpl>(
231
- is_indirect_case, is_var, ConstString (member_field_name),
232
- member_mangled_typename));
235
+
236
+ // If there is a type, this case has a payload.
237
+ if (member_type)
238
+ payload_fields.emplace_back (std::make_unique<DWARFFieldRecordImpl>(
239
+ is_indirect_case, is_var, ConstString (member_field_name),
240
+ member_mangled_typename));
241
+ else
242
+ non_payload_fields.emplace_back (std::make_unique<DWARFFieldRecordImpl>(
243
+ is_indirect_case, is_var, ConstString (member_field_name),
244
+ member_mangled_typename));
233
245
}
234
- return fields;
246
+ // Add the non-payload cases to the end.
247
+ payload_fields.insert (payload_fields.end (),
248
+ std::make_move_iterator (non_payload_fields.begin ()),
249
+ std::make_move_iterator (non_payload_fields.end ()));
250
+ return payload_fields;
251
+ }
252
+ };
253
+
254
+ class DWARFMultiPayloadEnumDescriptorImpl
255
+ : public swift::reflection::MultiPayloadEnumDescriptorBase {
256
+ ConstString m_mangled_name;
257
+ DIERef m_die_ref;
258
+ std::vector<uint8_t > m_spare_bits_mask;
259
+ uint64_t m_byte_offset;
260
+
261
+ public:
262
+ ~DWARFMultiPayloadEnumDescriptorImpl () override = default ;
263
+
264
+ DWARFMultiPayloadEnumDescriptorImpl (ConstString mangled_name, DIERef die_ref,
265
+ std::vector<uint8_t > &&spare_bits_mask,
266
+ uint64_t byte_offset)
267
+ : swift::reflection::MultiPayloadEnumDescriptorBase(),
268
+ m_mangled_name (mangled_name), m_die_ref(die_ref),
269
+ m_spare_bits_mask(std::move(spare_bits_mask)),
270
+ m_byte_offset(byte_offset) {}
271
+
272
+ llvm::StringRef getMangledTypeName () override {
273
+ return m_mangled_name.GetStringRef ();
274
+ }
275
+
276
+ uint32_t getContentsSizeInWords () const override {
277
+ return m_spare_bits_mask.size () / 4 ;
278
+ }
279
+
280
+ size_t getSizeInBytes () const override { return m_spare_bits_mask.size (); }
281
+
282
+ uint32_t getFlags () const override { return usesPayloadSpareBits (); }
283
+
284
+ bool usesPayloadSpareBits () const override {
285
+ return !m_spare_bits_mask.empty ();
286
+ }
287
+
288
+ uint32_t getPayloadSpareBitMaskByteOffset () const override {
289
+ return m_byte_offset;
290
+ }
291
+
292
+ uint32_t getPayloadSpareBitMaskByteCount () const override {
293
+ return getSizeInBytes ();
294
+ }
295
+
296
+ const uint8_t *getPayloadSpareBits () const override {
297
+ return m_spare_bits_mask.data ();
235
298
}
236
299
};
237
300
} // namespace
@@ -261,8 +324,8 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor(
261
324
die.GetAttributeValueAsUnsigned (DW_AT_byte_size, LLDB_INVALID_ADDRESS);
262
325
if (byte_size == LLDB_INVALID_ADDRESS)
263
326
return {};
264
- auto alignment = die. GetAttributeValueAsUnsigned (
265
- DW_AT_alignment, byte_size == 0 ? 1 : byte_size );
327
+
328
+ auto alignment = die. GetAttributeValueAsUnsigned ( DW_AT_alignment, 8 );
266
329
267
330
// TODO: this seems simple to calculate but maybe we should encode the stride
268
331
// in DWARF? That's what reflection metadata does.
@@ -278,6 +341,83 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor(
278
341
type.GetMangledTypeName ());
279
342
}
280
343
344
+ std::unique_ptr<swift::reflection::MultiPayloadEnumDescriptorBase>
345
+ DWARFASTParserSwift::getMultiPayloadEnumDescriptor (
346
+ const swift::reflection::TypeRef *TR) {
347
+ if (!Target::GetGlobalProperties ().GetSwiftEnableFullDwarfDebugging ())
348
+ return nullptr ;
349
+
350
+ auto pair = getTypeAndDie (m_swift_typesystem, TR);
351
+ if (!pair)
352
+ return nullptr ;
353
+
354
+ auto [type, die] = *pair;
355
+ if (!die)
356
+ return nullptr ;
357
+
358
+ auto kind = getFieldDescriptorKindForDie (type);
359
+ if (!kind)
360
+ return nullptr ;
361
+
362
+ auto child_die = die.GetFirstChild ();
363
+ auto bit_offset =
364
+ child_die.GetAttributeValueAsUnsigned (llvm::dwarf::DW_AT_bit_offset, 0 );
365
+
366
+ auto byte_offset = (bit_offset + 7 ) / 8 ;
367
+
368
+ const auto &attributes = child_die.GetAttributes ();
369
+ auto spare_bits_mask_idx =
370
+ attributes.FindAttributeIndex (llvm::dwarf::DW_AT_APPLE_spare_bits_mask);
371
+ if (spare_bits_mask_idx == UINT32_MAX)
372
+ return nullptr ;
373
+
374
+ DWARFFormValue form_value;
375
+ attributes.ExtractFormValueAtIndex (spare_bits_mask_idx, form_value);
376
+
377
+ if (!form_value.IsValid ()) {
378
+ if (auto *log = GetLog (LLDBLog::Types)) {
379
+ std::stringstream ss;
380
+ TR->dump (ss);
381
+ LLDB_LOG (log,
382
+ " Could not produce MultiPayloadEnumTypeInfo for typeref: {0}" ,
383
+ ss.str ());
384
+ }
385
+ return nullptr ;
386
+ }
387
+ // If there's a block data, this is a number bigger than 64 bits already
388
+ // encoded as an array.
389
+ if (form_value.BlockData ()) {
390
+ uint64_t block_length = form_value.Unsigned ();
391
+ std::vector<uint8_t > bytes (form_value.BlockData (),
392
+ form_value.BlockData () + block_length);
393
+ return std::make_unique<DWARFMultiPayloadEnumDescriptorImpl>(
394
+ type.GetMangledTypeName (), *die.GetDIERef (),
395
+ std::move (bytes), byte_offset);
396
+ }
397
+
398
+ // If there is no block data, the spare bits mask is encoded as a single 64
399
+ // bit number. Convert this to a byte array with only the amount of bytes
400
+ // necessary to cover the whole number (see
401
+ // MultiPayloadEnumDescriptorBuilder::layout on GenReflection.cpp for a
402
+ // similar calculation when emitting this into metadata).
403
+ llvm::APInt bits (64 , form_value.Unsigned ());
404
+ auto bitsInMask = bits.getActiveBits ();
405
+ uint32_t bytesInMask = (bitsInMask + 7 ) / 8 ;
406
+ auto wordsInMask = (bytesInMask + 3 ) / 4 ;
407
+ bits = bits.zextOrTrunc (wordsInMask * 32 );
408
+
409
+ std::vector<uint8_t > bytes;
410
+ for (size_t i = 0 ; i < bytesInMask; ++i) {
411
+ uint8_t byte = bits.extractBitsAsZExtValue (8 , 0 );
412
+ bytes.push_back (byte);
413
+ bits.lshrInPlace (8 );
414
+ }
415
+
416
+ return std::make_unique<DWARFMultiPayloadEnumDescriptorImpl>(
417
+ type.GetMangledTypeName (), *die.GetDIERef (), std::move (bytes),
418
+ byte_offset);
419
+ }
420
+
281
421
namespace {
282
422
DWARFDIE FindSuperClassDIE (DWARFDIE &die) {
283
423
const auto inheritance_die_it =
0 commit comments