@@ -910,9 +910,12 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
910
910
if (!ts)
911
911
return {};
912
912
913
+ lldb::addr_t pointer = LLDB_INVALID_ADDRESS;
913
914
ExecutionContext exe_ctx;
914
- if (valobj)
915
+ if (valobj) {
915
916
exe_ctx = valobj->GetExecutionContextRef ();
917
+ pointer = valobj->GetPointerValue ();
918
+ }
916
919
917
920
// Deal with the LLDB-only SILPackType variant.
918
921
if (auto pack_element_type = ts->GetSILPackElementAtIndex (type, idx)) {
@@ -935,6 +938,12 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
935
938
[&](const swift::reflection::FieldInfo &field,
936
939
llvm::Optional<TypeSystemSwift::TupleElement> tuple,
937
940
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;
938
947
child_name = tuple ? tuple->element_name .GetStringRef ().str () : field.Name ;
939
948
child_byte_size = field.TI .getSize ();
940
949
child_byte_offset = field.Offset ;
@@ -943,13 +952,36 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
943
952
child_is_base_class = false ;
944
953
child_is_deref_of_parent = false ;
945
954
language_flags = 0 ;
955
+ if (is_indirect_enum)
956
+ language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
946
957
// SwiftASTContext hardcodes the members of protocols as raw
947
958
// pointers. Remote Mirrors reports them as UnknownObject instead.
948
959
if (hide_existentials && ts->IsExistentialType (type.GetOpaqueQualType ()))
949
960
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().
953
985
if (result.IsFunctionType ())
954
986
child_byte_size = ts->GetPointerByteSize ();
955
987
return result;
@@ -1001,7 +1033,7 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1001
1033
child_is_base_class = false ;
1002
1034
child_is_deref_of_parent = false ;
1003
1035
language_flags = 0 ;
1004
- return ts->GetRawPointerType ();
1036
+ return ts->GetRawPointerType ();
1005
1037
}
1006
1038
}
1007
1039
return get_from_field_info (fields[idx], tuple, true );
@@ -1013,20 +1045,8 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1013
1045
// Skip non-payload cases.
1014
1046
if (!enum_case.TR )
1015
1047
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 );
1030
1050
}
1031
1051
LLDB_LOGF (GetLog (LLDBLog::Types), " index %zu is out of bounds (%d)" , idx,
1032
1052
eti->getNumPayloadCases ());
@@ -1055,10 +1075,9 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1055
1075
if (!instance_ts)
1056
1076
return {};
1057
1077
1058
- // LLDBTypeInfoProvider needs to kept alive until as long as supers gets accessed.
1078
+ // LLDBTypeInfoProvider needs to be kept alive while supers gets accessed.
1059
1079
llvm::SmallVector<SuperClassType, 2 > supers;
1060
1080
LLDBTypeInfoProvider tip (*this , *instance_ts);
1061
- lldb::addr_t pointer = valobj->GetPointerValue ();
1062
1081
reflection_ctx->ForEachSuperClassType (
1063
1082
&tip, pointer, [&](SuperClassType sc) -> bool {
1064
1083
if (!found_start) {
@@ -1984,62 +2003,38 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_IndirectEnumCase(
1984
2003
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
1985
2004
TypeAndOrName &class_type_or_name, Address &address,
1986
2005
Value::ValueType &value_type) {
1987
- static ConstString g_offset (" offset" );
1988
-
1989
- DataExtractor data;
1990
2006
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);
2002
2009
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 ();
2007
2012
if (box_addr == LLDB_INVALID_ADDRESS)
2008
2013
return false ;
2009
2014
2010
- box_addr = MaskMaybeBridgedPointer (m_process, box_addr);
2015
+ box_addr =
2016
+ MaskMaybeBridgedPointer (m_process, box_addr);
2011
2017
lldb::addr_t box_location = m_process.ReadPointerFromMemory (box_addr, error);
2012
2018
if (box_location == LLDB_INVALID_ADDRESS)
2013
2019
return false ;
2014
-
2020
+
2015
2021
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 ());
2026
2024
if (type_info.AllSet (eTypeIsSwift) &&
2027
2025
type_info.AnySet (eTypeIsClass | eTypeIsProtocol)) {
2028
2026
ExecutionContext exe_ctx = in_value.GetExecutionContextRef ();
2029
2027
ValueObjectSP valobj_sp = ValueObjectMemory::Create (
2030
- exe_ctx.GetBestExecutionContextScope (), " _" , box_value, payload_type );
2028
+ exe_ctx.GetBestExecutionContextScope (), " _" , box_value, child_type );
2031
2029
if (!valobj_sp)
2032
2030
return false ;
2033
2031
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);
2040
2034
} else {
2041
2035
// This is most likely a statically known type.
2042
2036
address.SetLoadAddress (box_value, &m_process.GetTarget ());
2037
+ value_type = Value::GetValueTypeFromAddressType (eAddressTypeLoad);
2043
2038
return true ;
2044
2039
}
2045
2040
}
0 commit comments