Skip to content

Commit 2b5ff47

Browse files
Merge pull request #7375 from adrian-prantl/refactor-remove-ast6
Remove SwiftASTContext from enum handling
2 parents c8a49e0 + d7ebeac commit 2b5ff47

File tree

8 files changed

+105
-131
lines changed

8 files changed

+105
-131
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/ReflectionContext.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ class TargetReflectionContext
127127
return type_info;
128128
}
129129

130+
const swift::reflection::TypeInfo *
131+
GetTypeInfoFromInstance(lldb::addr_t instance,
132+
swift::remote::TypeInfoProvider *provider) override {
133+
return m_reflection_ctx.getInstanceTypeInfo(instance, provider);
134+
}
135+
130136
swift::reflection::MemoryReader &GetReader() override {
131137
return m_reflection_ctx.getReader();
132138
}
@@ -169,6 +175,17 @@ class TargetReflectionContext
169175
return false;
170176
}
171177

178+
llvm::Optional<int32_t>
179+
ProjectEnumValue(swift::remote::RemoteAddress enum_addr,
180+
const swift::reflection::TypeRef *enum_type_ref,
181+
swift::remote::TypeInfoProvider *provider) override {
182+
int32_t case_idx;
183+
if (m_reflection_ctx.projectEnumValue(enum_addr, enum_type_ref, &case_idx,
184+
provider))
185+
return case_idx;
186+
return {};
187+
}
188+
172189
llvm::Optional<std::pair<const swift::reflection::TypeRef *,
173190
swift::reflection::RemoteAddress>>
174191
ProjectExistentialAndUnwrapClass(

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 58 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
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
}

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ class SwiftLanguageRuntimeImpl {
243243
virtual const swift::reflection::TypeInfo *
244244
GetTypeInfo(const swift::reflection::TypeRef *type_ref,
245245
swift::remote::TypeInfoProvider *provider) = 0;
246+
virtual const swift::reflection::TypeInfo *
247+
GetTypeInfoFromInstance(lldb::addr_t instance,
248+
swift::remote::TypeInfoProvider *provider) = 0;
246249
virtual swift::remote::MemoryReader &GetReader() = 0;
247250
virtual const swift::reflection::TypeRef *
248251
LookupSuperclass(const swift::reflection::TypeRef *tr) = 0;
@@ -255,6 +258,10 @@ class SwiftLanguageRuntimeImpl {
255258
ProjectExistentialAndUnwrapClass(
256259
swift::remote::RemoteAddress existential_addess,
257260
const swift::reflection::TypeRef &existential_tr) = 0;
261+
virtual llvm::Optional<int32_t>
262+
ProjectEnumValue(swift::remote::RemoteAddress enum_addr,
263+
const swift::reflection::TypeRef *enum_type_ref,
264+
swift::remote::TypeInfoProvider *provider) = 0;
258265
virtual const swift::reflection::TypeRef *
259266
ReadTypeFromMetadata(lldb::addr_t metadata_address,
260267
bool skip_artificial_subclasses = false) = 0;

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5085,6 +5085,11 @@ bool SwiftASTContext::IsPossibleDynamicType(opaque_compiler_type_t type,
50855085
can_type->isAnyExistentialType())
50865086
return true;
50875087

5088+
if (!IsImportedType(type) &&
5089+
(swift::isa<swift::EnumType>(can_type) ||
5090+
swift::isa<swift::BoundGenericEnumType>(can_type)))
5091+
return true;
5092+
50885093
// Dynamic Self types are resolved inside DoArchetypeBindingForType(),
50895094
// right before the actual archetype binding.
50905095
if (can_type->hasDynamicSelfType())

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ class SwiftASTContext : public TypeSystemSwift {
801801
uint32_t GetNumPointeeChildren(lldb::opaque_compiler_type_t type);
802802

803803
bool IsImportedType(lldb::opaque_compiler_type_t type,
804-
CompilerType *original_type) override;
804+
CompilerType *original_type = nullptr) override;
805805

806806
CompilerType GetReferentType(lldb::opaque_compiler_type_t type) override;
807807
CompilerType GetStaticSelfType(lldb::opaque_compiler_type_t type) override;

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,9 +2220,10 @@ bool TypeSystemSwiftTypeRef::IsPossibleDynamicType(opaque_compiler_type_t type,
22202220
case Node::Kind::ProtocolListWithAnyObject:
22212221
case Node::Kind::ExistentialMetatype:
22222222
case Node::Kind::DynamicSelf:
2223+
case Node::Kind::Enum:
2224+
case Node::Kind::BoundGenericEnum:
22232225
return true;
2224-
case Node::Kind::BoundGenericStructure:
2225-
case Node::Kind::BoundGenericEnum: {
2226+
case Node::Kind::BoundGenericStructure: {
22262227
if (node->getNumChildren() < 2)
22272228
return false;
22282229
NodePointer type_list = node->getLastChild();
@@ -3109,7 +3110,7 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
31093110
assert(Equivalent(child_is_base_class, ast_child_is_base_class));
31103111
assert(Equivalent(child_is_deref_of_parent, ast_child_is_deref_of_parent));
31113112
// There are cases where only the runtime correctly detects an indirect enum.
3112-
ast_language_flags |= language_flags & LanguageFlags::eIsIndirectEnumCase;
3113+
ast_language_flags |= (language_flags & LanguageFlags::eIsIndirectEnumCase);
31133114
assert(Equivalent(language_flags, ast_language_flags));
31143115
});
31153116
#endif

lldb/test/API/lang/swift/foundation_value_types/indexpath/main.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func main() {
1616
var short_path = IndexPath(indexes: [1,2])
1717
var very_short_path = IndexPath(indexes: [1])
1818
var empty_path = IndexPath()
19-
print("done!") //% self.expect("frame variable path", substrs=['5 indices'])
19+
print("done!") //% self.expect("frame variable path -d run", substrs=['5 indices'])
2020
//% self.expect("frame variable short_path", substrs=['2 indices'])
2121
//% self.expect("frame variable very_short_path", substrs=['1 index'])
2222
//% self.expect("frame variable empty_path", substrs=['0 indices'])

0 commit comments

Comments
 (0)