Skip to content

Commit cb55826

Browse files
authored
Merge pull request #2215 from apple/lldb-Wire-up-TypeSystemSwiftTypeRef-GetNumChildren-next
[lldb] Wire-up TypeSystemSwiftTypeRef::GetNumChildren
2 parents 6e05e60 + 86d8986 commit cb55826

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

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

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,10 +1508,9 @@ template <> bool Equivalent<ConstString>(ConstString l, ConstString r) {
15081508
return l == r;
15091509
}
15101510

1511-
/// Version taylored to GetBitSize & friends.
1512-
template <>
1513-
bool Equivalent<llvm::Optional<uint64_t>>(llvm::Optional<uint64_t> l,
1514-
llvm::Optional<uint64_t> r) {
1511+
/// Version tailored to GetBitSize & friends.
1512+
template <typename T>
1513+
bool Equivalent(llvm::Optional<T> l, llvm::Optional<T> r) {
15151514
if (l == r)
15161515
return true;
15171516
// There are situations where SwiftASTContext incorrectly returns
@@ -1526,6 +1525,12 @@ bool Equivalent<llvm::Optional<uint64_t>>(llvm::Optional<uint64_t> l,
15261525
return false;
15271526
}
15281527

1528+
// Introduced for `GetNumChildren`.
1529+
template <typename T>
1530+
bool Equivalent(llvm::Optional<T> l, T r) {
1531+
return Equivalent(l, llvm::Optional<T>(r));
1532+
}
1533+
15291534
} // namespace
15301535
#endif
15311536

@@ -2066,13 +2071,34 @@ lldb::Encoding TypeSystemSwiftTypeRef::GetEncoding(opaque_compiler_type_t type,
20662071
lldb::Format TypeSystemSwiftTypeRef::GetFormat(opaque_compiler_type_t type) {
20672072
return m_swift_ast_context->GetFormat(ReconstructType(type));
20682073
}
2074+
20692075
uint32_t
20702076
TypeSystemSwiftTypeRef::GetNumChildren(opaque_compiler_type_t type,
20712077
bool omit_empty_base_classes,
20722078
const ExecutionContext *exe_ctx) {
2073-
return m_swift_ast_context->GetNumChildren(ReconstructType(type),
2074-
omit_empty_base_classes, exe_ctx);
2079+
if (exe_ctx)
2080+
if (auto *exe_scope = exe_ctx->GetBestExecutionContextScope())
2081+
if (auto *runtime =
2082+
SwiftLanguageRuntime::Get(exe_scope->CalculateProcess()))
2083+
if (auto num_children =
2084+
runtime->GetNumChildren(GetCanonicalType(type), nullptr)) {
2085+
// Use a lambda to intercept and unwrap the `Optional` return value.
2086+
return [&]() {
2087+
auto impl = [&]() { return num_children; };
2088+
VALIDATE_AND_RETURN(
2089+
impl, GetNumChildren, type,
2090+
(ReconstructType(type), omit_empty_base_classes, exe_ctx));
2091+
}().getValue();
2092+
}
2093+
2094+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
2095+
"Using SwiftASTContext::GetNumChildren fallback for type %s",
2096+
AsMangledName(type));
2097+
2098+
return m_swift_ast_context->GetNumChildren(
2099+
ReconstructType(type), omit_empty_base_classes, exe_ctx);
20752100
}
2101+
20762102
uint32_t TypeSystemSwiftTypeRef::GetNumFields(opaque_compiler_type_t type) {
20772103
return m_swift_ast_context->GetNumFields(ReconstructType(type));
20782104
}

lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,8 +1010,23 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
10101010
// Structs and Tuples.
10111011
if (auto *rti =
10121012
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti)) {
1013-
auto fields = rti->getFields();
1014-
return fields.size();
1013+
switch (rti->getRecordKind()) {
1014+
case swift::reflection::RecordKind::ThickFunction:
1015+
// There are two fields, `function` and `context`, but they're not exposed
1016+
// by lldb.
1017+
return 0;
1018+
case swift::reflection::RecordKind::OpaqueExistential:
1019+
// `OpaqueExistential` is documented as:
1020+
// An existential is a three-word buffer followed by value metadata...
1021+
// The buffer is exposed as children named `payload_data_{0,1,2}`, and
1022+
// the number of fields are increased to match.
1023+
return rti->getNumFields() + 3;
1024+
default:
1025+
return rti->getNumFields();
1026+
}
1027+
}
1028+
if (auto *eti = llvm::dyn_cast_or_null<swift::reflection::EnumTypeInfo>(ti)) {
1029+
return eti->getNumPayloadCases();
10151030
}
10161031
// FIXME: Implement more cases.
10171032
return {};

lldb/test/API/lang/swift/implementation_only_imports/library_resilient/TestLibraryResilient.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def cleanup():
8282
# This test is deliberately checking what the user will see, rather than
8383
# the structure provided by the Python API, in order to test the recovery.
8484
self.expect("fr var", substrs=[
85-
"(SomeLibrary.ContainsTwoInts) container = (other = 10)",
85+
"(SomeLibrary.ContainsTwoInts) container = {", "other = 10",
8686
"(Int) simple = 1"])
8787
self.expect("e container", substrs=["(SomeLibrary.ContainsTwoInts)", "other = 10"])
8888
self.expect("e container.wrapped", error=True, substrs=["value of type 'ContainsTwoInts' has no member 'wrapped'"])

0 commit comments

Comments
 (0)