@@ -910,9 +910,12 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
910910 if (!ts)
911911 return {};
912912
913+ lldb::addr_t pointer = LLDB_INVALID_ADDRESS;
913914 ExecutionContext exe_ctx;
914- if (valobj)
915+ if (valobj) {
915916 exe_ctx = valobj->GetExecutionContextRef ();
917+ pointer = valobj->GetPointerValue ();
918+ }
916919
917920 // Deal with the LLDB-only SILPackType variant.
918921 if (auto pack_element_type = ts->GetSILPackElementAtIndex (type, idx)) {
@@ -935,6 +938,12 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
935938 [&](const swift::reflection::FieldInfo &field,
936939 llvm::Optional<TypeSystemSwift::TupleElement> tuple,
937940 bool hide_existentials) -> CompilerType {
941+ bool is_indirect_enum =
942+ !field.Offset && field.TR &&
943+ llvm::isa<swift::reflection::BuiltinTypeRef>(field.TR ) &&
944+ llvm::isa<swift::reflection::ReferenceTypeInfo>(field.TI ) &&
945+ llvm::cast<swift::reflection::ReferenceTypeInfo>(field.TI )
946+ .getReferenceKind () == swift::reflection::ReferenceKind::Strong;
938947 child_name = tuple ? tuple->element_name .GetStringRef ().str () : field.Name ;
939948 child_byte_size = field.TI .getSize ();
940949 child_byte_offset = field.Offset ;
@@ -943,13 +952,36 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
943952 child_is_base_class = false ;
944953 child_is_deref_of_parent = false ;
945954 language_flags = 0 ;
955+ if (is_indirect_enum)
956+ language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
946957 // SwiftASTContext hardcodes the members of protocols as raw
947958 // pointers. Remote Mirrors reports them as UnknownObject instead.
948959 if (hide_existentials && ts->IsExistentialType (type.GetOpaqueQualType ()))
949960 return ts->GetRawPointerType ();
950- CompilerType result =
951- tuple ? tuple->element_type : GetTypeFromTypeRef (*ts, field.TR );
952- // Bug-for-bug compatibility. See comment in SwiftASTContext::GetBitSize().
961+ CompilerType result;
962+ if (tuple)
963+ result = tuple->element_type ;
964+ else if (is_indirect_enum) {
965+ ThreadSafeReflectionContext reflection_ctx = GetReflectionContext ();
966+ if (!reflection_ctx)
967+ return {};
968+ // The indirect enum field should point to a closure context.
969+ LLDBTypeInfoProvider tip (*this , *ts);
970+ lldb::addr_t instance = MaskMaybeBridgedPointer (m_process, pointer);
971+ auto *ti = reflection_ctx->GetTypeInfoFromInstance (instance, &tip);
972+ if (!ti)
973+ return {};
974+ auto *rti = llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti);
975+ if (rti->getFields ().size () < 1 )
976+ return {};
977+ auto &field = rti->getFields ()[0 ];
978+ auto *type_ref = field.TR ;
979+ result = GetTypeFromTypeRef (*ts, type_ref);
980+ child_byte_offset = field.Offset ;
981+ } else
982+ result = GetTypeFromTypeRef (*ts, field.TR );
983+ // Bug-for-bug compatibility. See comment in
984+ // SwiftASTContext::GetBitSize().
953985 if (result.IsFunctionType ())
954986 child_byte_size = ts->GetPointerByteSize ();
955987 return result;
@@ -1001,7 +1033,7 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10011033 child_is_base_class = false ;
10021034 child_is_deref_of_parent = false ;
10031035 language_flags = 0 ;
1004- return ts->GetRawPointerType ();
1036+ return ts->GetRawPointerType ();
10051037 }
10061038 }
10071039 return get_from_field_info (fields[idx], tuple, true );
@@ -1013,20 +1045,8 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10131045 // Skip non-payload cases.
10141046 if (!enum_case.TR )
10151047 continue ;
1016- if (i++ == idx) {
1017- auto is_indirect = [](const swift::reflection::FieldInfo &field) {
1018- // FIXME: This is by observation. What's the correct condition?
1019- if (auto *tr =
1020- llvm::dyn_cast_or_null<swift::reflection::BuiltinTypeRef>(
1021- field.TR ))
1022- return llvm::StringRef (tr->getMangledName ()).equals (" Bo" );
1023- return false ;
1024- };
1025- auto result = get_from_field_info (enum_case, {}, true );
1026- if (is_indirect (enum_case))
1027- language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
1028- return result;
1029- }
1048+ if (i++ == idx)
1049+ return get_from_field_info (enum_case, {}, true );
10301050 }
10311051 LLDB_LOGF (GetLog (LLDBLog::Types), " index %zu is out of bounds (%d)" , idx,
10321052 eti->getNumPayloadCases ());
@@ -1055,10 +1075,9 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10551075 if (!instance_ts)
10561076 return {};
10571077
1058- // LLDBTypeInfoProvider needs to kept alive until as long as supers gets accessed.
1078+ // LLDBTypeInfoProvider needs to be kept alive while supers gets accessed.
10591079 llvm::SmallVector<SuperClassType, 2 > supers;
10601080 LLDBTypeInfoProvider tip (*this , *instance_ts);
1061- lldb::addr_t pointer = valobj->GetPointerValue ();
10621081 reflection_ctx->ForEachSuperClassType (
10631082 &tip, pointer, [&](SuperClassType sc) -> bool {
10641083 if (!found_start) {
@@ -1984,62 +2003,38 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_IndirectEnumCase(
19842003 ValueObject &in_value, lldb::DynamicValueType use_dynamic,
19852004 TypeAndOrName &class_type_or_name, Address &address,
19862005 Value::ValueType &value_type) {
1987- static ConstString g_offset (" offset" );
1988-
1989- DataExtractor data;
19902006 Status error;
1991- if (!(in_value.GetParent () && in_value.GetParent ()->GetData (data, error) &&
1992- error.Success ()))
1993- return false ;
1994-
1995- bool has_payload;
1996- bool is_indirect;
1997- CompilerType payload_type;
1998- if (!SwiftASTContext::GetSelectedEnumCase (
1999- in_value.GetParent ()->GetCompilerType (), data, nullptr , &has_payload,
2000- &payload_type, &is_indirect))
2001- return false ;
2007+ CompilerType child_type = in_value.GetCompilerType ();
2008+ class_type_or_name.SetCompilerType (child_type);
20022009
2003- if (has_payload && is_indirect && payload_type)
2004- class_type_or_name.SetCompilerType (payload_type);
2005-
2006- lldb::addr_t box_addr = in_value.GetValueAsUnsigned (LLDB_INVALID_ADDRESS);
2010+ auto *enum_obj = in_value.GetParent ();
2011+ lldb::addr_t box_addr = enum_obj->GetPointerValue ();
20072012 if (box_addr == LLDB_INVALID_ADDRESS)
20082013 return false ;
20092014
2010- box_addr = MaskMaybeBridgedPointer (m_process, box_addr);
2015+ box_addr =
2016+ MaskMaybeBridgedPointer (m_process, box_addr);
20112017 lldb::addr_t box_location = m_process.ReadPointerFromMemory (box_addr, error);
20122018 if (box_location == LLDB_INVALID_ADDRESS)
20132019 return false ;
2014-
2020+
20152021 box_location = MaskMaybeBridgedPointer (m_process, box_location);
2016- ProcessStructReader reader (&m_process, box_location, GetBoxMetadataType ());
2017- uint32_t offset = reader.GetField <uint32_t >(g_offset);
2018- lldb::addr_t box_value = box_addr + offset;
2019-
2020- // try to read one byte at the box value
2021- m_process.ReadUnsignedIntegerFromMemory (box_value, 1 , 0 , error);
2022- if (error.Fail ()) // and if that fails, then we're off in no man's land
2023- return false ;
2024-
2025- Flags type_info (payload_type.GetTypeInfo ());
2022+ lldb::addr_t box_value = box_addr + in_value.GetByteOffset ();
2023+ Flags type_info (child_type.GetTypeInfo ());
20262024 if (type_info.AllSet (eTypeIsSwift) &&
20272025 type_info.AnySet (eTypeIsClass | eTypeIsProtocol)) {
20282026 ExecutionContext exe_ctx = in_value.GetExecutionContextRef ();
20292027 ValueObjectSP valobj_sp = ValueObjectMemory::Create (
2030- exe_ctx.GetBestExecutionContextScope (), " _" , box_value, payload_type );
2028+ exe_ctx.GetBestExecutionContextScope (), " _" , box_value, child_type );
20312029 if (!valobj_sp)
20322030 return false ;
20332031
2034- if (!GetDynamicTypeAndAddress (*valobj_sp, use_dynamic, class_type_or_name,
2035- address, value_type))
2036- return false ;
2037-
2038- address.SetRawAddress (box_value);
2039- return true ;
2032+ return GetDynamicTypeAndAddress (*valobj_sp, use_dynamic, class_type_or_name,
2033+ address, value_type);
20402034 } else {
20412035 // This is most likely a statically known type.
20422036 address.SetLoadAddress (box_value, &m_process.GetTarget ());
2037+ value_type = Value::GetValueTypeFromAddressType (eAddressTypeLoad);
20432038 return true ;
20442039 }
20452040}
0 commit comments