Skip to content

Factor out ForEachSuperClassTypeInfo (NFC) #1822

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

Merged
merged 2 commits into from
Sep 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/include/lldb/Target/SwiftLanguageRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
/// \param instance_type
llvm::Optional<uint64_t> GetMemberVariableOffset(CompilerType instance_type,
ValueObject *instance,
ConstString member_name,
llvm::StringRef member_name,
Status *error = nullptr);

/// Ask Remote Mirrors for the size of a Swift type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ NativeHashedStorageHandler::NativeHashedStorageHandler(
if (llvm::isa<::swift::TupleType>(swift_type)) {
Status error;
llvm::Optional<uint64_t> result = runtime->GetMemberVariableOffset(
{swift_ast, swift_type}, nativeStorage_sp.get(), ConstString("1"),
{swift_ast, swift_type}, nativeStorage_sp.get(), "1",
&error);
if (result)
m_key_stride_padded = result.getValue();
Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6851,8 +6851,8 @@ static llvm::Optional<uint64_t> GetInstanceVariableOffset_Metadata(
}

Status error;
llvm::Optional<uint64_t> offset = runtime->GetMemberVariableOffset(
type, valobj, ConstString(ivar_name), &error);
llvm::Optional<uint64_t> offset =
runtime->GetMemberVariableOffset(type, valobj, ivar_name, &error);
if (offset)
LOG_PRINTF(LIBLLDB_LOG_TYPES, "for %s: %llu", ivar_name.str().c_str(),
*offset);
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Target/SwiftLanguageRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class SwiftLanguageRuntimeStub {

llvm::Optional<uint64_t> GetMemberVariableOffset(CompilerType instance_type,
ValueObject *instance,
ConstString member_name,
llvm::StringRef member_name,
Status *error) {
STUB_LOG();
return {};
Expand Down Expand Up @@ -2083,8 +2083,8 @@ bool SwiftLanguageRuntime::IsStoredInlineInBuffer(CompilerType type) {
}

llvm::Optional<uint64_t> SwiftLanguageRuntime::GetMemberVariableOffset(
CompilerType instance_type, ValueObject *instance, ConstString member_name,
Status *error) {
CompilerType instance_type, ValueObject *instance,
llvm::StringRef member_name, Status *error) {
FORWARD(GetMemberVariableOffset, instance_type, instance, member_name, error);
}

Expand Down
168 changes: 94 additions & 74 deletions lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ SwiftLanguageRuntimeImpl::emplaceClangTypeInfo(
llvm::Optional<uint64_t>
SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteAST(
CompilerType instance_type, ValueObject *instance,
ConstString member_name) {
llvm::StringRef member_name) {
auto *scratch_ctx =
llvm::cast<SwiftASTContext>(instance_type.GetTypeSystem());
if (scratch_ctx->HasFatalErrors())
Expand All @@ -777,7 +777,7 @@ SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteAST(
GetCanonicalSwiftType(instance_type).getPointer();

// Perform the cache lookup.
MemberID key{swift_type, member_name.GetCString()};
MemberID key{swift_type, ConstString(member_name).GetCString()};
auto it = m_member_offsets.find(key);
if (it != m_member_offsets.end())
return it->second;
Expand Down Expand Up @@ -818,7 +818,7 @@ SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteAST(
bound.GetTypeName().AsCString());

swift_type = GetCanonicalSwiftType(bound).getPointer();
MemberID key{swift_type, member_name.GetCString()};
MemberID key{swift_type, ConstString(member_name).GetCString()};
auto it = m_member_offsets.find(key);
if (it != m_member_offsets.end())
return it->second;
Expand All @@ -834,15 +834,15 @@ SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteAST(

// Use RemoteAST to determine the member offset.
if (safe_to_use_remote_ast) {
swift::remoteAST::Result<uint64_t> result = remote_ast->getOffsetOfMember(
swift_type, optmeta, member_name.GetStringRef());
swift::remoteAST::Result<uint64_t> result =
remote_ast->getOffsetOfMember(swift_type, optmeta, member_name);
if (result) {
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[MemberVariableOffsetResolver] offset discovered = %" PRIu64,
(uint64_t)result.getValue());

// Cache this result.
MemberID key{swift_type, member_name.GetCString()};
MemberID key{swift_type, ConstString(member_name).GetCString()};
m_member_offsets.insert({key, result.getValue()});
return result.getValue();
}
Expand All @@ -856,8 +856,10 @@ SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteAST(
}

llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemoteMirrors(
CompilerType instance_type, ValueObject *instance, ConstString member_name,
CompilerType instance_type, ValueObject *instance, llvm::StringRef member_name,
Status *error) {
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"using remote mirrors");
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
instance_type.GetTypeSystem());
if (!ts) {
Expand All @@ -866,86 +868,66 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffsetRemote
return {};
}

// Try remote mirrors.
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[GetMemberVariableOffsetRemoteMirrors] using remote mirrors");
if (const swift::reflection::TypeInfo *type_info = GetTypeInfo(
instance_type,
instance ? instance->GetExecutionContextRef().GetFrameSP().get()
: nullptr)) {
auto record_type_info =
llvm::dyn_cast<swift::reflection::RecordTypeInfo>(type_info);
if (record_type_info) {
// Handle tuples.
LLDB_LOGF(
GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[GetMemberVariableOffsetRemoteMirrors] using record type info");
if (record_type_info->getRecordKind() ==
swift::reflection::RecordKind::Tuple) {
unsigned tuple_idx;
if (member_name.GetStringRef().getAsInteger(10, tuple_idx) ||
tuple_idx >= record_type_info->getNumFields()) {
if (error)
error->SetErrorString("tuple index out of bounds");
return {};
}
return record_type_info->getFields()[tuple_idx].Offset;
}

// Handle other record types.
for (auto &field : record_type_info->getFields()) {
if (ConstString(field.Name) == member_name)
return field.Offset;
// Try the static type metadata.
auto frame = instance ? instance->GetExecutionContextRef().GetFrameSP().get()
: nullptr;
if (auto *ti = llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(
GetTypeInfo(instance_type, frame))) {
auto fields = ti->getFields();
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"using record type info");

// Handle tuples.
if (ti->getRecordKind() == swift::reflection::RecordKind::Tuple) {
unsigned tuple_idx;
if (member_name.getAsInteger(10, tuple_idx) ||
tuple_idx >= ti->getNumFields()) {
if (error)
error->SetErrorString("tuple index out of bounds");
return {};
}
return fields[tuple_idx].Offset;
}
}

lldb::addr_t pointer = instance->GetPointerValue();
auto *reflection_ctx = GetReflectionContext();
if (!reflection_ctx)
return {};

auto find_field =
[&](const swift::reflection::TypeInfo *ti) -> llvm::Optional<uint64_t> {
auto class_type_info =
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti);
if (class_type_info) {
for (auto &field : class_type_info->getFields()) {
if (ConstString(field.Name) == member_name)
return field.Offset;
}
}
return {};
};

LLDBTypeInfoProvider provider(*this, *ts);
auto md_ptr = reflection_ctx->readMetadataFromInstance(pointer);
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[GetMemberVariableOffsetRemoteMirrors] using instance type info");
while (md_ptr && *md_ptr) {
if (auto offset =
find_field(reflection_ctx->getMetadataTypeInfo(*md_ptr, &provider)))
return offset;

// Continue with the base class.
md_ptr = reflection_ctx->readSuperClassFromClassMetadata(*md_ptr);
// Handle other record types.
for (auto &field : fields)
if (StringRef(field.Name) == member_name)
return field.Offset;
}

return {};
// Try the instance type metadata.
bool did_log = false;
llvm::Optional<uint64_t> result;
if (instance)
ForEachSuperClassTypeInfo(
*instance, [&](const swift::reflection::RecordTypeInfo &ti) -> bool {
if (!did_log) {
did_log = true;
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"using instance type info");
}
for (auto &field : ti.getFields())
if (StringRef(field.Name) == member_name) {
result = field.Offset;
return true;
}
return false;
});

return result;
}


llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffset(
CompilerType instance_type, ValueObject *instance, ConstString member_name,
Status *error) {
CompilerType instance_type, ValueObject *instance,
llvm::StringRef member_name, Status *error) {
llvm::Optional<uint64_t> offset;

if (!instance_type.IsValid())
return {};

LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[GetMemberVariableOffset] asked to resolve offset for member %s",
member_name.AsCString());
member_name.str().c_str());

// Using the module context for RemoteAST is cheaper bit only safe
// when there is no dynamic type resolution involved.
Expand Down Expand Up @@ -984,16 +966,54 @@ llvm::Optional<uint64_t> SwiftLanguageRuntimeImpl::GetMemberVariableOffset(
if (offset) {
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[GetMemberVariableOffset] offset of %s is %d",
member_name.AsCString(), *offset);
member_name.str().c_str(), *offset);
} else {
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"[GetMemberVariableOffset] failed for %s",
member_name.AsCString());
member_name.str().c_str());
if (error)
error->SetErrorStringWithFormat("could not resolve member offset");
}
return offset;
}

bool SwiftLanguageRuntimeImpl::ForEachSuperClassTypeInfo(
ValueObject &instance,
std::function<bool(const swift::reflection::RecordTypeInfo &rti)> fn) {
lldb::addr_t pointer = instance.GetPointerValue();
auto *reflection_ctx = GetReflectionContext();
if (!reflection_ctx)
return false;

auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
instance.GetCompilerType().GetTypeSystem());
if (!ts)
return false;

LLDBTypeInfoProvider provider(*this, *ts);
auto md_ptr = reflection_ctx->readMetadataFromInstance(pointer);
if (!md_ptr)
return false;

// Class object.
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"found RecordTypeInfo for instance");
while (md_ptr && *md_ptr) {
auto *ti = reflection_ctx->getMetadataTypeInfo(*md_ptr, &provider);
if (auto *class_type_info =
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti)) {
if (fn(*class_type_info))
return true;
}

// Continue with the base class.
md_ptr = reflection_ctx->readSuperClassFromClassMetadata(*md_ptr);
}
return false;
}



bool SwiftLanguageRuntime::IsSelf(Variable &variable) {
// A variable is self if its name if "self", and it's either a
// function argument or a local variable and it's scope is a
Expand Down
19 changes: 13 additions & 6 deletions lldb/source/Target/SwiftLanguageRuntimeImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,13 @@ class SwiftLanguageRuntimeImpl {
llvm::Optional<uint64_t>
GetMemberVariableOffsetRemoteAST(CompilerType instance_type,
ValueObject *instance,
ConstString member_name);
llvm::Optional<uint64_t>
GetMemberVariableOffsetRemoteMirrors(CompilerType instance_type,
ValueObject *instance,
ConstString member_name, Status *error);
llvm::StringRef member_name);
llvm::Optional<uint64_t> GetMemberVariableOffsetRemoteMirrors(
CompilerType instance_type, ValueObject *instance,
llvm::StringRef member_name, Status *error);
llvm::Optional<uint64_t> GetMemberVariableOffset(CompilerType instance_type,
ValueObject *instance,
ConstString member_name,
llvm::StringRef member_name,
Status *error);

/// Like \p BindGenericTypeParameters but for TypeSystemSwiftTypeRef.
Expand Down Expand Up @@ -162,6 +161,14 @@ class SwiftLanguageRuntimeImpl {
const swift::reflection::TypeRef *GetTypeRef(CompilerType type,
Module *module = nullptr);

/// If \p instance points to a Swift object, retrieve its
/// RecordTypeInfo pass it to the callback \p fn. Repeat the process
/// with all superclasses. If \p fn returns \p true, early exit and
/// return \ptrue. Otherwise return \p false.
bool ForEachSuperClassTypeInfo(
ValueObject &instance,
std::function<bool(const swift::reflection::RecordTypeInfo &rti)> fn);

// Classes that inherit from SwiftLanguageRuntime can see and modify these
Value::ValueType GetValueType(Value::ValueType static_value_type,
CompilerType static_type,
Expand Down