Skip to content

Commit 52cc0c6

Browse files
committed
Factor out SwiftLanguageRuntimeImpl::ForEachSuperClassTypeInfo()
1 parent bdca7d8 commit 52cc0c6

File tree

2 files changed

+90
-61
lines changed

2 files changed

+90
-61
lines changed

lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteAST(
858858
llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteMirrors(
859859
CompilerType instance_type, ValueObject *instance, ConstString member_name,
860860
Status *error) {
861+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
862+
"using remote mirrors");
861863
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
862864
instance_type.GetTypeSystem());
863865
if (!ts) {
@@ -866,72 +868,53 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemote
866868
return {};
867869
}
868870

869-
// Try remote mirrors.
870-
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
871-
"[GetMemberVariableOffsetRemoteMirrors] using remote mirrors");
872-
if (const swift::reflection::TypeInfo *type_info = GetTypeInfo(
873-
instance_type,
874-
instance ? instance->GetExecutionContextRef().GetFrameSP().get()
875-
: nullptr)) {
876-
auto record_type_info =
877-
llvm::dyn_cast<swift::reflection::RecordTypeInfo>(type_info);
878-
if (record_type_info) {
879-
// Handle tuples.
880-
LLDB_LOGF(
881-
GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
882-
"[GetMemberVariableOffsetRemoteMirrors] using record type info");
883-
if (record_type_info->getRecordKind() ==
884-
swift::reflection::RecordKind::Tuple) {
885-
unsigned tuple_idx;
886-
if (member_name.GetStringRef().getAsInteger(10, tuple_idx) ||
887-
tuple_idx >= record_type_info->getNumFields()) {
888-
if (error)
889-
error->SetErrorString("tuple index out of bounds");
890-
return {};
891-
}
892-
return record_type_info->getFields()[tuple_idx].Offset;
893-
}
894-
895-
// Handle other record types.
896-
for (auto &field : record_type_info->getFields()) {
897-
if (ConstString(field.Name) == member_name)
898-
return field.Offset;
899-
}
900-
}
901-
}
902-
903-
lldb::addr_t pointer = instance->GetPointerValue();
904-
auto *reflection_ctx = GetReflectionContext();
905-
if (!reflection_ctx)
906-
return {};
907-
908-
auto find_field =
909-
[&](const swift::reflection::TypeInfo *ti) -> llvm::Optional<uint64_t> {
910-
auto class_type_info =
911-
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti);
912-
if (class_type_info) {
913-
for (auto &field : class_type_info->getFields()) {
914-
if (ConstString(field.Name) == member_name)
915-
return field.Offset;
871+
// Try the static type metadata.
872+
auto frame = instance ? instance->GetExecutionContextRef().GetFrameSP().get()
873+
: nullptr;
874+
if (auto *ti = llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(
875+
GetTypeInfo(instance_type, frame))) {
876+
auto fields = ti->getFields();
877+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
878+
"using record type info");
879+
880+
// Handle tuples.
881+
if (ti->getRecordKind() == swift::reflection::RecordKind::Tuple) {
882+
unsigned tuple_idx;
883+
if (member_name.GetStringRef().getAsInteger(10, tuple_idx) ||
884+
tuple_idx >= ti->getNumFields()) {
885+
if (error)
886+
error->SetErrorString("tuple index out of bounds");
887+
return {};
916888
}
889+
return fields[tuple_idx].Offset;
917890
}
918-
return {};
919-
};
920-
921-
LLDBTypeInfoProvider provider(*this, *ts);
922-
auto md_ptr = reflection_ctx->readMetadataFromInstance(pointer);
923-
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
924-
"[GetMemberVariableOffsetRemoteMirrors] using instance type info");
925-
while (md_ptr && *md_ptr) {
926-
if (auto offset =
927-
find_field(reflection_ctx->getMetadataTypeInfo(*md_ptr, &provider)))
928-
return offset;
929891

930-
// Continue with the base class.
931-
md_ptr = reflection_ctx->readSuperClassFromClassMetadata(*md_ptr);
892+
// Handle other record types.
893+
for (auto &field : fields)
894+
if (StringRef(field.Name) == member_name.GetStringRef())
895+
return field.Offset;
932896
}
933897

934-
return {};
898+
// Try the instance type metadata.
899+
bool did_log = false;
900+
llvm::Optional<uint64_t> result;
901+
if (instance)
902+
ForEachSuperClassTypeInfo(
903+
*instance, [&](const swift::reflection::RecordTypeInfo &ti) -> bool {
904+
if (!did_log) {
905+
did_log = true;
906+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
907+
"using instance type info");
908+
}
909+
for (auto &field : ti.getFields())
910+
if (StringRef(field.Name) == member_name.GetStringRef()) {
911+
result = field.Offset;
912+
return true;
913+
}
914+
return false;
915+
});
916+
917+
return result;
935918
}
936919

937920

@@ -994,6 +977,44 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffset(
994977
}
995978
return offset;
996979
}
980+
981+
bool SwiftLanguageRuntimeImpl::ForEachSuperClassTypeInfo(
982+
ValueObject &instance,
983+
std::function<bool(const swift::reflection::RecordTypeInfo &rti)> fn) {
984+
lldb::addr_t pointer = instance.GetPointerValue();
985+
auto *reflection_ctx = GetReflectionContext();
986+
if (!reflection_ctx)
987+
return false;
988+
989+
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
990+
instance.GetCompilerType().GetTypeSystem());
991+
if (!ts)
992+
return false;
993+
994+
LLDBTypeInfoProvider provider(*this, *ts);
995+
auto md_ptr = reflection_ctx->readMetadataFromInstance(pointer);
996+
if (!md_ptr)
997+
return false;
998+
999+
// Class object.
1000+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
1001+
"found RecordTypeInfo for instance");
1002+
while (md_ptr && *md_ptr) {
1003+
auto *ti = reflection_ctx->getMetadataTypeInfo(*md_ptr, &provider);
1004+
if (auto *class_type_info =
1005+
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti)) {
1006+
if (fn(*class_type_info))
1007+
return true;
1008+
}
1009+
1010+
// Continue with the base class.
1011+
md_ptr = reflection_ctx->readSuperClassFromClassMetadata(*md_ptr);
1012+
}
1013+
return false;
1014+
}
1015+
1016+
1017+
9971018
bool SwiftLanguageRuntime::IsSelf(Variable &variable) {
9981019
// A variable is self if its name if "self", and it's either a
9991020
// function argument or a local variable and it's scope is a

lldb/source/Target/SwiftLanguageRuntimeImpl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ class SwiftLanguageRuntimeImpl {
162162
const swift::reflection::TypeRef *GetTypeRef(CompilerType type,
163163
Module *module = nullptr);
164164

165+
/// If \p instance points to a Swift object, retrieve its
166+
/// RecordTypeInfo pass it to the callback \p fn. Repeat the process
167+
/// with all superclasses. If \p fn returns \p true, early exit and
168+
/// return \ptrue. Otherwise return \p false.
169+
bool ForEachSuperClassTypeInfo(
170+
ValueObject &instance,
171+
std::function<bool(const swift::reflection::RecordTypeInfo &rti)> fn);
172+
165173
// Classes that inherit from SwiftLanguageRuntime can see and modify these
166174
Value::ValueType GetValueType(Value::ValueType static_value_type,
167175
CompilerType static_type,

0 commit comments

Comments
 (0)