-
Notifications
You must be signed in to change notification settings - Fork 344
[lldb] Add ReferenceTypeInfo support to SwiftLanguageRuntimeImpl::GetNumChildren #2218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
af7c46a
da1254e
3ff1e49
5967cbc
3c4c00b
a76bd63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -997,6 +997,38 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffset( | |
return offset; | ||
} | ||
|
||
static CompilerType GetWeakReferent(TypeSystemSwiftTypeRef &ts, | ||
CompilerType type) { | ||
using namespace swift::Demangle; | ||
Demangler dem; | ||
auto mangled = type.GetMangledTypeName().GetStringRef(); | ||
NodePointer n = dem.demangleSymbol(mangled); | ||
if (!n || n->getKind() != Node::Kind::Global || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || n->getKind() != Node::Kind::TypeMangling || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || | ||
(n->getKind() != Node::Kind::Weak && | ||
n->getKind() != Node::Kind::Unowned && | ||
n->getKind() != Node::Kind::Unmanaged) || | ||
!n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren()) | ||
return {}; | ||
// FIXME: We only need to canonicalize this node, not the entire type. | ||
n = ts.CanonicalizeSugar(dem, n->getFirstChild()); | ||
if (!n || n->getKind() != Node::Kind::SugaredOptional || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
return ts.RemangleAsType(dem, n); | ||
} | ||
|
||
llvm::Optional<unsigned> | ||
SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type, | ||
ValueObject *valobj) { | ||
|
@@ -1008,7 +1040,8 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type, | |
// Try the static type metadata. | ||
auto frame = | ||
valobj ? valobj->GetExecutionContextRef().GetFrameSP().get() : nullptr; | ||
auto *ti = GetTypeInfo(type, frame); | ||
const swift::reflection::TypeRef *tr = nullptr; | ||
auto *ti = GetTypeInfo(type, frame, &tr); | ||
// Structs and Tuples. | ||
if (auto *rti = | ||
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti)) { | ||
|
@@ -1030,6 +1063,41 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type, | |
if (auto *eti = llvm::dyn_cast_or_null<swift::reflection::EnumTypeInfo>(ti)) { | ||
return eti->getNumPayloadCases(); | ||
} | ||
// Objects. | ||
if (auto *rti = | ||
llvm::dyn_cast_or_null<swift::reflection::ReferenceTypeInfo>(ti)) { | ||
|
||
switch (rti->getReferenceKind()) { | ||
case swift::reflection::ReferenceKind::Weak: | ||
case swift::reflection::ReferenceKind::Unowned: | ||
case swift::reflection::ReferenceKind::Unmanaged: | ||
// Weak references are implicitly Optionals, so report the one | ||
// child of Optional here. | ||
if (GetWeakReferent(*ts, type)) | ||
return 1; | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
if (!tr) | ||
return {}; | ||
|
||
auto *reflection_ctx = GetReflectionContext(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would this fit nicely into one case in the switch above, or are there many different kinds for which this path makes sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good question, I'm not sure yet. Once this PR is working, I'll compare the paths then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think? There are a couple distinct conditions in each case that don't make sense to the other case, and so combing the two doesn't feel like a no-brainer to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was just thinking of writing this as
but that's purely cosmetic and not important at all... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, I had misunderstood. I will make that change in a follow up. |
||
auto &builder = reflection_ctx->getBuilder(); | ||
auto tc = swift::reflection::TypeConverter(builder); | ||
LLDBTypeInfoProvider tip(*this, *ts); | ||
auto *cti = tc.getClassInstanceTypeInfo(tr, 0, &tip); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a todo to figure out if other values should be used instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tests pass, and no There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. |
||
if (auto *rti = | ||
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(cti)) { | ||
// The superclass, if any, is an extra child. | ||
if (builder.lookupSuperclass(tr)) | ||
return rti->getNumFields() + 1; | ||
return rti->getNumFields(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be a recursive case or will there only ever be a record type underneath a class? (Well, probably). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently it's only ever a RecordTypeInfo: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could factor out a helper function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll soon be implementing I have a question, by "calls itself" do you mean recursive like in your top comment? If so, can you elaborate on what needs to be recursive? |
||
} | ||
|
||
return {}; | ||
} | ||
// FIXME: Implement more cases. | ||
return {}; | ||
} | ||
|
@@ -1064,38 +1132,6 @@ static llvm::StringRef GetBaseName(swift::Demangle::NodePointer node) { | |
} | ||
} | ||
|
||
static CompilerType GetWeakReferent(TypeSystemSwiftTypeRef &ts, | ||
CompilerType type) { | ||
using namespace swift::Demangle; | ||
Demangler dem; | ||
auto mangled = type.GetMangledTypeName().GetStringRef(); | ||
NodePointer n = dem.demangleSymbol(mangled); | ||
if (!n || n->getKind() != Node::Kind::Global || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || n->getKind() != Node::Kind::TypeMangling || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || | ||
(n->getKind() != Node::Kind::Weak && | ||
n->getKind() != Node::Kind::Unowned && | ||
n->getKind() != Node::Kind::Unmanaged) || | ||
!n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren()) | ||
return {}; | ||
// FIXME: We only need to canonicalize this node, not the entire type. | ||
n = ts.CanonicalizeSugar(dem, n->getFirstChild()); | ||
if (!n || n->getKind() != Node::Kind::SugaredOptional || !n->hasChildren()) | ||
return {}; | ||
n = n->getFirstChild(); | ||
return ts.RemangleAsType(dem, n); | ||
} | ||
|
||
static CompilerType | ||
GetTypeFromTypeRef(TypeSystemSwiftTypeRef &ts, | ||
const swift::reflection::TypeRef *type_ref) { | ||
|
@@ -2510,9 +2546,9 @@ SwiftLanguageRuntimeImpl::GetTypeRef(CompilerType type, | |
return type_ref; | ||
} | ||
|
||
const swift::reflection::TypeInfo * | ||
SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type, | ||
ExecutionContextScope *exe_scope) { | ||
const swift::reflection::TypeInfo *SwiftLanguageRuntimeImpl::GetTypeInfo( | ||
CompilerType type, ExecutionContextScope *exe_scope, | ||
swift::reflection::TypeRef const **out_tr) { | ||
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwift>(type.GetTypeSystem()); | ||
if (!ts) | ||
return nullptr; | ||
|
@@ -2543,6 +2579,9 @@ SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type, | |
if (!type_ref) | ||
return nullptr; | ||
|
||
if (out_tr) | ||
*out_tr = type_ref; | ||
|
||
auto *reflection_ctx = GetReflectionContext(); | ||
if (!reflection_ctx) | ||
return nullptr; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,7 +78,8 @@ class SwiftLanguageRuntimeImpl { | |
|
||
/// Ask Remote Mirrors for the type info about a Swift type. | ||
const swift::reflection::TypeInfo * | ||
GetTypeInfo(CompilerType type, ExecutionContextScope *exe_scope); | ||
GetTypeInfo(CompilerType type, ExecutionContextScope *exe_scope, | ||
swift::reflection::TypeRef const **out_tr = nullptr); | ||
Comment on lines
+81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added an out parameter to return the typeref. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be cleaner to factor out a function
and call that directly where we need the type_ref? If it isn't, then returning either a |
||
|
||
llvm::Optional<const swift::reflection::TypeInfo *> | ||
lookupClangTypeInfo(CompilerType clang_type); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this whole function was moved up and nothing more.