1818#include " Plugins/ExpressionParser/Clang/ClangUtil.h"
1919#include " Plugins/TypeSystem/Clang/TypeSystemClang.h"
2020#include " Plugins/TypeSystem/Swift/SwiftDemangle.h"
21+ #include " lldb/Core/ValueObjectMemory.h"
2122#include " lldb/Symbol/Variable.h"
2223#include " lldb/Symbol/VariableList.h"
2324#include " lldb/Target/ProcessStructReader.h"
@@ -909,9 +910,12 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
909910 if (!ts)
910911 return {};
911912
913+ lldb::addr_t pointer = LLDB_INVALID_ADDRESS;
912914 ExecutionContext exe_ctx;
913- if (valobj)
915+ if (valobj) {
914916 exe_ctx = valobj->GetExecutionContextRef ();
917+ pointer = valobj->GetPointerValue ();
918+ }
915919
916920 // Deal with the LLDB-only SILPackType variant.
917921 if (auto pack_element_type = ts->GetSILPackElementAtIndex (type, idx)) {
@@ -934,6 +938,12 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
934938 [&](const swift::reflection::FieldInfo &field,
935939 llvm::Optional<TypeSystemSwift::TupleElement> tuple,
936940 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;
937947 child_name = tuple ? tuple->element_name .GetStringRef ().str () : field.Name ;
938948 child_byte_size = field.TI .getSize ();
939949 child_byte_offset = field.Offset ;
@@ -942,13 +952,36 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
942952 child_is_base_class = false ;
943953 child_is_deref_of_parent = false ;
944954 language_flags = 0 ;
955+ if (is_indirect_enum)
956+ language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
945957 // SwiftASTContext hardcodes the members of protocols as raw
946958 // pointers. Remote Mirrors reports them as UnknownObject instead.
947959 if (hide_existentials && ts->IsExistentialType (type.GetOpaqueQualType ()))
948960 return ts->GetRawPointerType ();
949- CompilerType result =
950- tuple ? tuple->element_type : GetTypeFromTypeRef (*ts, field.TR );
951- // 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().
952985 if (result.IsFunctionType ())
953986 child_byte_size = ts->GetPointerByteSize ();
954987 return result;
@@ -1000,7 +1033,7 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10001033 child_is_base_class = false ;
10011034 child_is_deref_of_parent = false ;
10021035 language_flags = 0 ;
1003- return ts->GetRawPointerType ();
1036+ return ts->GetRawPointerType ();
10041037 }
10051038 }
10061039 return get_from_field_info (fields[idx], tuple, true );
@@ -1012,20 +1045,8 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10121045 // Skip non-payload cases.
10131046 if (!enum_case.TR )
10141047 continue ;
1015- if (i++ == idx) {
1016- auto is_indirect = [](const swift::reflection::FieldInfo &field) {
1017- // FIXME: This is by observation. What's the correct condition?
1018- if (auto *tr =
1019- llvm::dyn_cast_or_null<swift::reflection::BuiltinTypeRef>(
1020- field.TR ))
1021- return llvm::StringRef (tr->getMangledName ()).equals (" Bo" );
1022- return false ;
1023- };
1024- auto result = get_from_field_info (enum_case, {}, true );
1025- if (is_indirect (enum_case))
1026- language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
1027- return result;
1028- }
1048+ if (i++ == idx)
1049+ return get_from_field_info (enum_case, {}, true );
10291050 }
10301051 LLDB_LOGF (GetLog (LLDBLog::Types), " index %zu is out of bounds (%d)" , idx,
10311052 eti->getNumPayloadCases ());
@@ -1054,10 +1075,9 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
10541075 if (!instance_ts)
10551076 return {};
10561077
1057- // LLDBTypeInfoProvider needs to kept alive until as long as supers gets accessed.
1078+ // LLDBTypeInfoProvider needs to be kept alive while supers gets accessed.
10581079 llvm::SmallVector<SuperClassType, 2 > supers;
10591080 LLDBTypeInfoProvider tip (*this , *instance_ts);
1060- lldb::addr_t pointer = valobj->GetPointerValue ();
10611081 reflection_ctx->ForEachSuperClassType (
10621082 &tip, pointer, [&](SuperClassType sc) -> bool {
10631083 if (!found_start) {
@@ -1983,95 +2003,38 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_IndirectEnumCase(
19832003 ValueObject &in_value, lldb::DynamicValueType use_dynamic,
19842004 TypeAndOrName &class_type_or_name, Address &address,
19852005 Value::ValueType &value_type) {
1986- static ConstString g_offset (" offset" );
1987-
1988- DataExtractor data;
19892006 Status error;
1990- if (!(in_value.GetParent () && in_value.GetParent ()->GetData (data, error) &&
1991- error.Success ()))
1992- return false ;
2007+ CompilerType child_type = in_value.GetCompilerType ();
2008+ class_type_or_name.SetCompilerType (child_type);
19932009
1994- bool has_payload;
1995- bool is_indirect;
1996- CompilerType payload_type;
1997- if (!SwiftASTContext::GetSelectedEnumCase (
1998- in_value.GetParent ()->GetCompilerType (), data, nullptr , &has_payload,
1999- &payload_type, &is_indirect))
2000- return false ;
2001-
2002- if (has_payload && is_indirect && payload_type)
2003- class_type_or_name.SetCompilerType (payload_type);
2004-
2005- 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 ();
20062012 if (box_addr == LLDB_INVALID_ADDRESS)
20072013 return false ;
20082014
2009- box_addr = MaskMaybeBridgedPointer (m_process, box_addr);
2015+ box_addr =
2016+ MaskMaybeBridgedPointer (m_process, box_addr);
20102017 lldb::addr_t box_location = m_process.ReadPointerFromMemory (box_addr, error);
20112018 if (box_location == LLDB_INVALID_ADDRESS)
20122019 return false ;
2013-
2020+
20142021 box_location = MaskMaybeBridgedPointer (m_process, box_location);
2015- ProcessStructReader reader (&m_process, box_location, GetBoxMetadataType ());
2016- uint32_t offset = reader.GetField <uint32_t >(g_offset);
2017- lldb::addr_t box_value = box_addr + offset;
2018-
2019- // try to read one byte at the box value
2020- m_process.ReadUnsignedIntegerFromMemory (box_value, 1 , 0 , error);
2021- if (error.Fail ()) // and if that fails, then we're off in no man's land
2022- return false ;
2023-
2024- Flags type_info (payload_type.GetTypeInfo ());
2025- if (type_info.AllSet (eTypeIsSwift | eTypeIsClass)) {
2026- lldb::addr_t old_box_value = box_value;
2027- box_value = m_process.ReadPointerFromMemory (box_value, error);
2028- if (box_value == LLDB_INVALID_ADDRESS)
2029- return false ;
2030-
2031- DataExtractor data (&box_value, m_process.GetAddressByteSize (),
2032- m_process.GetByteOrder (),
2033- m_process.GetAddressByteSize ());
2034- ValueObjectSP valobj_sp (ValueObject::CreateValueObjectFromData (
2035- " _" , data, m_process, payload_type));
2022+ lldb::addr_t box_value = box_addr + in_value.GetByteOffset ();
2023+ Flags type_info (child_type.GetTypeInfo ());
2024+ if (type_info.AllSet (eTypeIsSwift) &&
2025+ type_info.AnySet (eTypeIsClass | eTypeIsProtocol)) {
2026+ ExecutionContext exe_ctx = in_value.GetExecutionContextRef ();
2027+ ValueObjectSP valobj_sp = ValueObjectMemory::Create (
2028+ exe_ctx.GetBestExecutionContextScope (), " _" , box_value, child_type);
20362029 if (!valobj_sp)
20372030 return false ;
20382031
2039- if (!GetDynamicTypeAndAddress (*valobj_sp, use_dynamic, class_type_or_name,
2040- address, value_type))
2041- return false ;
2042-
2043- address.SetRawAddress (old_box_value);
2044- return true ;
2045- } else if (type_info.AllSet (eTypeIsSwift | eTypeIsProtocol)) {
2046- SwiftASTContext::ProtocolInfo protocol_info;
2047- if (!SwiftASTContext::GetProtocolTypeInfo (payload_type, protocol_info))
2048- return false ;
2049- auto ptr_size = m_process.GetAddressByteSize ();
2050- std::vector<uint8_t > buffer (ptr_size * protocol_info.m_num_storage_words ,
2051- 0 );
2052- for (uint32_t idx = 0 ; idx < protocol_info.m_num_storage_words ; idx++) {
2053- lldb::addr_t word = m_process.ReadUnsignedIntegerFromMemory (
2054- box_value + idx * ptr_size, ptr_size, 0 , error);
2055- if (error.Fail ())
2056- return false ;
2057- memcpy (&buffer[idx * ptr_size], &word, ptr_size);
2058- }
2059- DataExtractor data (&buffer[0 ], buffer.size (), m_process.GetByteOrder (),
2060- m_process.GetAddressByteSize ());
2061- ValueObjectSP valobj_sp (ValueObject::CreateValueObjectFromData (
2062- " _" , data, m_process, payload_type));
2063- if (!valobj_sp)
2064- return false ;
2065-
2066- if (!GetDynamicTypeAndAddress (*valobj_sp, use_dynamic, class_type_or_name,
2067- address, value_type))
2068- return false ;
2069-
2070- address.SetRawAddress (box_value);
2071- return true ;
2032+ return GetDynamicTypeAndAddress (*valobj_sp, use_dynamic, class_type_or_name,
2033+ address, value_type);
20722034 } else {
20732035 // This is most likely a statically known type.
20742036 address.SetLoadAddress (box_value, &m_process.GetTarget ());
2037+ value_type = Value::GetValueTypeFromAddressType (eAddressTypeLoad);
20752038 return true ;
20762039 }
20772040}
0 commit comments