Skip to content

Commit af106f3

Browse files
authored
Merge pull request #2224 from apple/lldb-Add-ReferenceTypeInfo-support-to-SwiftLanguageRuntimeImpl-GetNumChildren-next
[lldb] Add ReferenceTypeInfo support to SwiftLanguageRuntimeImpl::GetNumChildren
2 parents 34546e4 + 9a26ceb commit af106f3

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
@@ -995,6 +995,38 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffset(
995995
return offset;
996996
}
997997

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

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

2511-
const swift::reflection::TypeInfo *
2512-
SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type,
2513-
ExecutionContextScope *exe_scope) {
2547+
const swift::reflection::TypeInfo *SwiftLanguageRuntimeImpl::GetTypeInfo(
2548+
CompilerType type, ExecutionContextScope *exe_scope,
2549+
swift::reflection::TypeRef const **out_tr) {
25142550
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwift>(type.GetTypeSystem());
25152551
if (!ts)
25162552
return nullptr;
@@ -2541,6 +2577,9 @@ SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type,
25412577
if (!type_ref)
25422578
return nullptr;
25432579

2580+
if (out_tr)
2581+
*out_tr = type_ref;
2582+
25442583
auto *reflection_ctx = GetReflectionContext();
25452584
if (!reflection_ctx)
25462585
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
@@ -112,9 +112,10 @@ def cleanup():
112112
# This test is deliberately checking what the user will see, rather than
113113
# the structure provided by the Python API, in order to test the recovery.
114114
self.expect("fr var", substrs=[
115-
"(SomeLibrary.ContainsTwoInts) container = (wrapped = 0x",
116-
", other = 10)",
115+
"(SomeLibrary.ContainsTwoInts) container = {",
116+
"wrapped = 0x",
117+
"other = 10",
117118
"(Int) simple = 1"])
118-
self.expect("e container", substrs=["(SomeLibrary.ContainsTwoInts)", "(wrapped = 0x", ", other = 10"])
119+
self.expect("e container", substrs=["(SomeLibrary.ContainsTwoInts)", "wrapped = 0x", "other = 10"])
119120
self.expect("e container.wrapped", substrs=["(SomeLibrary.BoxedTwoInts)", "0x", "{}"])
120121
self.expect("e container.wrapped.value", error=True, substrs=["value of type 'BoxedTwoInts' has no member 'value'"])

0 commit comments

Comments
 (0)