@@ -73,7 +73,7 @@ getFieldDescriptorKindForDie(CompilerType type) {
7373 return swift::reflection::FieldDescriptorKind::Class;
7474 case lldb::eTypeClassStruct:
7575 return swift::reflection::FieldDescriptorKind::Struct;
76- case lldb::eTypeClassEnumeration :
76+ case lldb::eTypeClassUnion :
7777 return swift::reflection::FieldDescriptorKind::Enum;
7878 default :
7979 LLDB_LOG (GetLog (LLDBLog::Types),
@@ -203,7 +203,12 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
203203 std::vector<std::unique_ptr<swift::reflection::FieldRecordBase>>
204204 getFieldRecordsFromEnum (const DWARFDIE &die,
205205 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;
207212 auto variant_part = die.GetFirstChild ();
208213 for (DWARFDIE child_die : variant_part.children ()) {
209214 auto tag = child_die.Tag ();
@@ -227,11 +232,69 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
227232 bool is_indirect_case = false ;
228233 // Unused by type info construction.
229234 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));
233245 }
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 ();
235298 }
236299};
237300} // namespace
@@ -261,8 +324,8 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor(
261324 die.GetAttributeValueAsUnsigned (DW_AT_byte_size, LLDB_INVALID_ADDRESS);
262325 if (byte_size == LLDB_INVALID_ADDRESS)
263326 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 );
266329
267330 // TODO: this seems simple to calculate but maybe we should encode the stride
268331 // in DWARF? That's what reflection metadata does.
@@ -278,6 +341,97 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor(
278341 type.GetMangledTypeName ());
279342}
280343
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+ const auto spare_bits_mask_die_it =
368+ llvm::find_if (die.children (), [&](const DWARFDIE &child_die) {
369+ return child_die.Tag () == llvm::dwarf::DW_TAG_APPLE_spare_bits_mask;
370+ });
371+
372+ if (spare_bits_mask_die_it == child_die.children ().end ())
373+ return nullptr ;
374+
375+ auto spare_bits_mask_die = *spare_bits_mask_die_it;
376+ DWARFAttributes attributes = spare_bits_mask_die.GetAttributes ();
377+ assert (attributes.Size () == 1 &&
378+ " Unexpected attributes on spare bits mask die" );
379+ if (attributes.Size () != 1 )
380+ return nullptr ;
381+
382+ dw_attr_t attribute = attributes.AttributeAtIndex (0 );
383+ assert (attribute == llvm::dwarf::DW_AT_const_value &&
384+ " Unexpected attribute type on spare bits mask die" );
385+ if (attribute != llvm::dwarf::DW_AT_const_value)
386+ return nullptr ;
387+
388+ DWARFFormValue form_value;
389+ attributes.ExtractFormValueAtIndex (0 , form_value);
390+
391+ if (!form_value.IsValid ()) {
392+ if (auto *log = GetLog (LLDBLog::Types)) {
393+ std::stringstream ss;
394+ TR->dump (ss);
395+ LLDB_LOG (log,
396+ " Could not produce MultiPayloadEnumTypeInfo for typeref: {0}" ,
397+ ss.str ());
398+ }
399+ return nullptr ;
400+ }
401+ // If there's a block data, this is a number bigger than 64 bits already
402+ // encoded as an array.
403+ if (form_value.BlockData ()) {
404+ uint64_t block_length = form_value.Unsigned ();
405+ std::vector<uint8_t > bytes (form_value.BlockData (),
406+ form_value.BlockData () + block_length);
407+ return std::make_unique<DWARFMultiPayloadEnumDescriptorImpl>(
408+ type.GetMangledTypeName (), *die.GetDIERef (),
409+ std::move (bytes), byte_offset);
410+ }
411+
412+ // If there is no block data, the spare bits mask is encoded as a single 64
413+ // bit number. Convert this to a byte array with only the amount of bytes
414+ // necessary to cover the whole number (see
415+ // MultiPayloadEnumDescriptorBuilder::layout on GenReflection.cpp for a
416+ // similar calculation when emitting this into metadata).
417+ llvm::APInt bits (64 , form_value.Unsigned ());
418+ auto bitsInMask = bits.getActiveBits ();
419+ uint32_t bytesInMask = (bitsInMask + 7 ) / 8 ;
420+ auto wordsInMask = (bytesInMask + 3 ) / 4 ;
421+ bits = bits.zextOrTrunc (wordsInMask * 32 );
422+
423+ std::vector<uint8_t > bytes;
424+ for (size_t i = 0 ; i < bytesInMask; ++i) {
425+ uint8_t byte = bits.extractBitsAsZExtValue (8 , 0 );
426+ bytes.push_back (byte);
427+ bits.lshrInPlace (8 );
428+ }
429+
430+ return std::make_unique<DWARFMultiPayloadEnumDescriptorImpl>(
431+ type.GetMangledTypeName (), *die.GetDIERef (), std::move (bytes),
432+ byte_offset);
433+ }
434+
281435namespace {
282436DWARFDIE FindSuperClassDIE (DWARFDIE &die) {
283437 const auto inheritance_die_it =
0 commit comments