Skip to content

Commit a72a24c

Browse files
authored
Merge pull request #2218 from apple/lldb-Add-ReferenceTypeInfo-support-to-SwiftLanguageRuntimeImpl-GetNumChildren
[lldb] Add ReferenceTypeInfo support to SwiftLanguageRuntimeImpl::GetNumChildren
2 parents bcb4baf + a76bd63 commit a72a24c

File tree

3 files changed

+81
-40
lines changed

3 files changed

+81
-40
lines changed

lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,38 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffset(
997997
return offset;
998998
}
999999

1000+
static CompilerType GetWeakReferent(TypeSystemSwiftTypeRef &ts,
1001+
CompilerType type) {
1002+
using namespace swift::Demangle;
1003+
Demangler dem;
1004+
auto mangled = type.GetMangledTypeName().GetStringRef();
1005+
NodePointer n = dem.demangleSymbol(mangled);
1006+
if (!n || n->getKind() != Node::Kind::Global || !n->hasChildren())
1007+
return {};
1008+
n = n->getFirstChild();
1009+
if (!n || n->getKind() != Node::Kind::TypeMangling || !n->hasChildren())
1010+
return {};
1011+
n = n->getFirstChild();
1012+
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren())
1013+
return {};
1014+
n = n->getFirstChild();
1015+
if (!n ||
1016+
(n->getKind() != Node::Kind::Weak &&
1017+
n->getKind() != Node::Kind::Unowned &&
1018+
n->getKind() != Node::Kind::Unmanaged) ||
1019+
!n->hasChildren())
1020+
return {};
1021+
n = n->getFirstChild();
1022+
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren())
1023+
return {};
1024+
// FIXME: We only need to canonicalize this node, not the entire type.
1025+
n = ts.CanonicalizeSugar(dem, n->getFirstChild());
1026+
if (!n || n->getKind() != Node::Kind::SugaredOptional || !n->hasChildren())
1027+
return {};
1028+
n = n->getFirstChild();
1029+
return ts.RemangleAsType(dem, n);
1030+
}
1031+
10001032
llvm::Optional<unsigned>
10011033
SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
10021034
ValueObject *valobj) {
@@ -1008,7 +1040,8 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
10081040
// Try the static type metadata.
10091041
auto frame =
10101042
valobj ? valobj->GetExecutionContextRef().GetFrameSP().get() : nullptr;
1011-
auto *ti = GetTypeInfo(type, frame);
1043+
const swift::reflection::TypeRef *tr = nullptr;
1044+
auto *ti = GetTypeInfo(type, frame, &tr);
10121045
// Structs and Tuples.
10131046
if (auto *rti =
10141047
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti)) {
@@ -1030,6 +1063,41 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
10301063
if (auto *eti = llvm::dyn_cast_or_null<swift::reflection::EnumTypeInfo>(ti)) {
10311064
return eti->getNumPayloadCases();
10321065
}
1066+
// Objects.
1067+
if (auto *rti =
1068+
llvm::dyn_cast_or_null<swift::reflection::ReferenceTypeInfo>(ti)) {
1069+
1070+
switch (rti->getReferenceKind()) {
1071+
case swift::reflection::ReferenceKind::Weak:
1072+
case swift::reflection::ReferenceKind::Unowned:
1073+
case swift::reflection::ReferenceKind::Unmanaged:
1074+
// Weak references are implicitly Optionals, so report the one
1075+
// child of Optional here.
1076+
if (GetWeakReferent(*ts, type))
1077+
return 1;
1078+
break;
1079+
default:
1080+
break;
1081+
}
1082+
1083+
if (!tr)
1084+
return {};
1085+
1086+
auto *reflection_ctx = GetReflectionContext();
1087+
auto &builder = reflection_ctx->getBuilder();
1088+
auto tc = swift::reflection::TypeConverter(builder);
1089+
LLDBTypeInfoProvider tip(*this, *ts);
1090+
auto *cti = tc.getClassInstanceTypeInfo(tr, 0, &tip);
1091+
if (auto *rti =
1092+
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(cti)) {
1093+
// The superclass, if any, is an extra child.
1094+
if (builder.lookupSuperclass(tr))
1095+
return rti->getNumFields() + 1;
1096+
return rti->getNumFields();
1097+
}
1098+
1099+
return {};
1100+
}
10331101
// FIXME: Implement more cases.
10341102
return {};
10351103
}
@@ -1064,38 +1132,6 @@ static llvm::StringRef GetBaseName(swift::Demangle::NodePointer node) {
10641132
}
10651133
}
10661134

1067-
static CompilerType GetWeakReferent(TypeSystemSwiftTypeRef &ts,
1068-
CompilerType type) {
1069-
using namespace swift::Demangle;
1070-
Demangler dem;
1071-
auto mangled = type.GetMangledTypeName().GetStringRef();
1072-
NodePointer n = dem.demangleSymbol(mangled);
1073-
if (!n || n->getKind() != Node::Kind::Global || !n->hasChildren())
1074-
return {};
1075-
n = n->getFirstChild();
1076-
if (!n || n->getKind() != Node::Kind::TypeMangling || !n->hasChildren())
1077-
return {};
1078-
n = n->getFirstChild();
1079-
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren())
1080-
return {};
1081-
n = n->getFirstChild();
1082-
if (!n ||
1083-
(n->getKind() != Node::Kind::Weak &&
1084-
n->getKind() != Node::Kind::Unowned &&
1085-
n->getKind() != Node::Kind::Unmanaged) ||
1086-
!n->hasChildren())
1087-
return {};
1088-
n = n->getFirstChild();
1089-
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren())
1090-
return {};
1091-
// FIXME: We only need to canonicalize this node, not the entire type.
1092-
n = ts.CanonicalizeSugar(dem, n->getFirstChild());
1093-
if (!n || n->getKind() != Node::Kind::SugaredOptional || !n->hasChildren())
1094-
return {};
1095-
n = n->getFirstChild();
1096-
return ts.RemangleAsType(dem, n);
1097-
}
1098-
10991135
static CompilerType
11001136
GetTypeFromTypeRef(TypeSystemSwiftTypeRef &ts,
11011137
const swift::reflection::TypeRef *type_ref) {
@@ -2510,9 +2546,9 @@ SwiftLanguageRuntimeImpl::GetTypeRef(CompilerType type,
25102546
return type_ref;
25112547
}
25122548

2513-
const swift::reflection::TypeInfo *
2514-
SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type,
2515-
ExecutionContextScope *exe_scope) {
2549+
const swift::reflection::TypeInfo *SwiftLanguageRuntimeImpl::GetTypeInfo(
2550+
CompilerType type, ExecutionContextScope *exe_scope,
2551+
swift::reflection::TypeRef const **out_tr) {
25162552
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwift>(type.GetTypeSystem());
25172553
if (!ts)
25182554
return nullptr;
@@ -2543,6 +2579,9 @@ SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type,
25432579
if (!type_ref)
25442580
return nullptr;
25452581

2582+
if (out_tr)
2583+
*out_tr = type_ref;
2584+
25462585
auto *reflection_ctx = GetReflectionContext();
25472586
if (!reflection_ctx)
25482587
return nullptr;

lldb/source/Target/SwiftLanguageRuntimeImpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ class SwiftLanguageRuntimeImpl {
7878

7979
/// Ask Remote Mirrors for the type info about a Swift type.
8080
const swift::reflection::TypeInfo *
81-
GetTypeInfo(CompilerType type, ExecutionContextScope *exe_scope);
81+
GetTypeInfo(CompilerType type, ExecutionContextScope *exe_scope,
82+
swift::reflection::TypeRef const **out_tr = nullptr);
8283

8384
llvm::Optional<const swift::reflection::TypeInfo *>
8485
lookupClangTypeInfo(CompilerType clang_type);

lldb/test/API/lang/swift/implementation_only_imports/library_indirect/TestLibraryIndirect.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,10 @@ def cleanup():
114114
# This test is deliberately checking what the user will see, rather than
115115
# the structure provided by the Python API, in order to test the recovery.
116116
self.expect("fr var", substrs=[
117-
"(SomeLibrary.ContainsTwoInts) container = (wrapped = 0x",
118-
", other = 10)",
117+
"(SomeLibrary.ContainsTwoInts) container = {",
118+
"wrapped = 0x",
119+
"other = 10",
119120
"(Int) simple = 1"])
120-
self.expect("e container", substrs=["(SomeLibrary.ContainsTwoInts)", "(wrapped = 0x", ", other = 10"])
121+
self.expect("e container", substrs=["(SomeLibrary.ContainsTwoInts)", "wrapped = 0x", "other = 10"])
121122
self.expect("e container.wrapped", substrs=["(SomeLibrary.BoxedTwoInts)", "0x", "{}"])
122123
self.expect("e container.wrapped.value", error=True, substrs=["value of type 'BoxedTwoInts' has no member 'value'"])

0 commit comments

Comments
 (0)