Skip to content

Commit 5db02e5

Browse files
authored
Merge pull request #2200 from apple/lldb-Wire-up-TypeSystemSwiftTypeRef-GetNumChildren
[lldb] Wire-up TypeSystemSwiftTypeRef::GetNumChildren
2 parents 2ad40e2 + a5d4945 commit 5db02e5

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

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

lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp

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