Skip to content

[lldb] Implement TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName #2271

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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f86df1d
thread exe_ctx through GetIndexOfChild(Member)?WithName
kastiglione Dec 17, 2020
b5cd727
call newly stubbed SwiftLanguageRuntime::GetIndexOfChildMemberWithName
kastiglione Dec 17, 2020
3d4afb7
use StringRef and MutableArrayRef in new API
kastiglione Dec 17, 2020
f2e3c5b
revert MutableArrayRef back to vector
kastiglione Dec 17, 2020
226a76f
implement most of GetIndexOfChildMemberWithName
kastiglione Dec 18, 2020
85a8207
in GetChildCompilerTypeAtIndex, switch fallback() to impl()
kastiglione Dec 18, 2020
ec6ea5a
rework GetIndexOfChildMemberWithName validation
kastiglione Dec 18, 2020
284128c
first changes to tests now that these private members are visible
kastiglione Dec 18, 2020
ff52481
take base class into account when calculating member index
kastiglione Dec 18, 2020
1078f4b
use <3 instead of <=2 - for consistency
kastiglione Dec 18, 2020
dfdfbf4
dereference weak types
kastiglione Dec 18, 2020
c71a93c
traverse class hierarchy
kastiglione Dec 18, 2020
91c6166
fix superclass iteration
kastiglione Dec 18, 2020
8900a31
return 0 not None for ThickFunction
kastiglione Dec 18, 2020
87110d0
handle ExistentialMetatype in SwiftLanguageRuntimeImpl
kastiglione Dec 18, 2020
e15cc2a
update TestLibraryIndirect.py
kastiglione Dec 19, 2020
2ca06dd
comment: LLDB can find it through type metadata
kastiglione Dec 19, 2020
74c46e1
use `T v(...)` style initialization
kastiglione Dec 19, 2020
9a39bd7
update No.swiftmodule.swift
kastiglione Dec 19, 2020
69aa747
reenable TestSwiftFoundationTypeNotification.py
kastiglione Dec 19, 2020
04993ef
add superclass to child_indexes
kastiglione Dec 19, 2020
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
5 changes: 3 additions & 2 deletions lldb/include/lldb/Symbol/CompilerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ class CompilerType {

/// Lookup a child given a name. This function will match base class names and
/// member member names in "clang_type" only, not descendants.
uint32_t GetIndexOfChildWithName(const char *name,
uint32_t GetIndexOfChildWithName(const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes) const;

/// Lookup a child member given a name. This function will match member names
Expand All @@ -333,7 +333,8 @@ class CompilerType {
/// vector<vector<uint32_t>>
/// so we catch all names that match a given child name, not just the first.
size_t
GetIndexOfChildMemberWithName(const char *name, bool omit_empty_base_classes,
GetIndexOfChildMemberWithName(const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) const;

size_t GetNumTemplateArguments() const;
Expand Down
4 changes: 3 additions & 1 deletion lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ class TypeSystem : public PluginInterface {
// member member names in "clang_type" only, not descendants.
virtual uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
const char *name,
ExecutionContext *exe_ctx,
bool omit_empty_base_classes) = 0;

// Lookup a child member given a name. This function will match member names
Expand All @@ -364,7 +365,8 @@ class TypeSystem : public PluginInterface {
// so we catch all names that match a given child name, not just the first.
virtual size_t
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
const char *name, bool omit_empty_base_classes,
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) = 0;

virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type);
Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Target/SwiftLanguageRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ class SwiftLanguageRuntime : public LanguageRuntime {
llvm::Optional<unsigned> GetNumChildren(CompilerType type,
ValueObject *valobj);

llvm::Optional<size_t> GetIndexOfChildMemberWithName(
CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes);

/// Ask Remote Mirrors about a child of a composite type.
CompilerType GetChildCompilerTypeAtIndex(
CompilerType type, size_t idx, bool transparent_pointers,
Expand Down
6 changes: 4 additions & 2 deletions lldb/source/Core/ValueObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,8 @@ lldb::ValueObjectSP ValueObject::GetChildAtNamePath(

size_t ValueObject::GetIndexOfChildWithName(ConstString name) {
bool omit_empty_base_classes = true;
return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
ExecutionContext exe_ctx(GetExecutionContextRef());
return GetCompilerType().GetIndexOfChildWithName(name.GetCString(), &exe_ctx,
omit_empty_base_classes);
}

Expand All @@ -612,9 +613,10 @@ ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name,
if (!GetCompilerType().IsValid())
return ValueObjectSP();

ExecutionContext exe_ctx(GetExecutionContextRef());
const size_t num_child_indexes =
GetCompilerType().GetIndexOfChildMemberWithName(
name.GetCString(), omit_empty_base_classes, child_indexes);
name.GetCString(), &exe_ctx, omit_empty_base_classes, child_indexes);
if (num_child_indexes == 0)
return nullptr;

Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
return UINT32_MAX;

const bool omit_empty_base_classes = false;
return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
omit_empty_base_classes);
return m_block_struct_type.GetIndexOfChildWithName(
name.AsCString(), nullptr, omit_empty_base_classes);
}

private:
Expand Down
26 changes: 13 additions & 13 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6467,7 +6467,8 @@ static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,

size_t TypeSystemClang::GetIndexOfChildMemberWithName(
lldb::opaque_compiler_type_t type, const char *name,
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
ExecutionContext *exe_ctx, bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) {
if (type && name && name[0]) {
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
Expand Down Expand Up @@ -6495,7 +6496,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
CompilerType field_type = GetType(field->getType());
child_indexes.push_back(child_idx);
if (field_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes))
name, exe_ctx, omit_empty_base_classes, child_indexes))
return child_indexes.size();
child_indexes.pop_back();

Expand Down Expand Up @@ -6606,7 +6607,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
GetType(getASTContext().getObjCInterfaceType(
superclass_interface_decl));
if (superclass_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes)) {
name, exe_ctx, omit_empty_base_classes, child_indexes)) {
// We did find an ivar in a superclass so just return the
// results!
return child_indexes.size();
Expand All @@ -6626,7 +6627,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
->getPointeeType());
return objc_object_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes);
name, exe_ctx, omit_empty_base_classes, child_indexes);
} break;

case clang::Type::ConstantArray: {
Expand Down Expand Up @@ -6678,7 +6679,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(

if (pointee_clang_type.IsAggregateType()) {
return pointee_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes);
name, exe_ctx, omit_empty_base_classes, child_indexes);
}
} break;

Expand All @@ -6687,7 +6688,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(

if (pointee_clang_type.IsAggregateType()) {
return pointee_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes);
name, exe_ctx, omit_empty_base_classes, child_indexes);
}
} break;

Expand All @@ -6702,10 +6703,9 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
// doesn't descend into the children, but only looks one level deep and name
// matches can include base class names.

uint32_t
TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
const char *name,
bool omit_empty_base_classes) {
uint32_t TypeSystemClang::GetIndexOfChildWithName(
lldb::opaque_compiler_type_t type, const char *name,
ExecutionContext *exe_ctx, bool omit_empty_base_classes) {
if (type && name && name[0]) {
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));

Expand Down Expand Up @@ -6807,7 +6807,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
->getPointeeType());
return pointee_clang_type.GetIndexOfChildWithName(
name, omit_empty_base_classes);
name, exe_ctx, omit_empty_base_classes);
} break;

case clang::Type::ConstantArray: {
Expand Down Expand Up @@ -6857,7 +6857,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
CompilerType pointee_type = GetType(reference_type->getPointeeType());

if (pointee_type.IsAggregateType()) {
return pointee_type.GetIndexOfChildWithName(name,
return pointee_type.GetIndexOfChildWithName(name, exe_ctx,
omit_empty_base_classes);
}
} break;
Expand All @@ -6868,7 +6868,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
CompilerType pointee_type = GetType(pointer_type->getPointeeType());

if (pointee_type.IsAggregateType()) {
return pointee_type.GetIndexOfChildWithName(name,
return pointee_type.GetIndexOfChildWithName(name, exe_ctx,
omit_empty_base_classes);
} else {
// if (parent_name)
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ class TypeSystemClang : public TypeSystem {
// Lookup a child given a name. This function will match base class names and
// member member names in "clang_type" only, not descendants.
uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
const char *name,
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes) override;

// Lookup a child member given a name. This function will match member names
Expand All @@ -822,7 +822,8 @@ class TypeSystemClang : public TypeSystem {
// so we catch all names that match a given child name, not just the first.
size_t
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
const char *name, bool omit_empty_base_classes,
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;

size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
Expand Down
10 changes: 5 additions & 5 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7203,8 +7203,8 @@ CompilerType SwiftASTContext::GetChildCompilerTypeAtIndex(
// second index 1 is the child index for "m_b" within class A.

size_t SwiftASTContext::GetIndexOfChildMemberWithName(
opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) {
opaque_compiler_type_t type, const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
VALID_OR_RETURN(0);

if (type && name && name[0]) {
Expand All @@ -7226,7 +7226,7 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
case swift::TypeKind::UnownedStorage:
case swift::TypeKind::WeakStorage:
return ToCompilerType(swift_can_type->getReferenceStorageReferent())
.GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
.GetIndexOfChildMemberWithName(name, exe_ctx, omit_empty_base_classes,
child_indexes);
case swift::TypeKind::GenericTypeParam:
case swift::TypeKind::DependentMember:
Expand Down Expand Up @@ -7307,7 +7307,7 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
CompilerType superclass_type =
ToCompilerType(superclass_swift_type.getPointer());
if (superclass_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes))
name, exe_ctx, omit_empty_base_classes, child_indexes))
return child_indexes.size();

// We didn't find a stored property matching "name" in our
Expand Down Expand Up @@ -7353,7 +7353,7 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(

if (pointee_clang_type.IsAggregateType()) {
return pointee_clang_type.GetIndexOfChildMemberWithName(
name, omit_empty_base_classes, child_indexes);
name, exe_ctx, omit_empty_base_classes, child_indexes);
}
} break;
case swift::TypeKind::UnboundGeneric:
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,8 @@ class SwiftASTContext : public TypeSystemSwift {
// name, not just the first.
size_t
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
const char *name, bool omit_empty_base_classes,
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;

size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
Expand Down
9 changes: 4 additions & 5 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,11 @@ bool TypeSystemSwift::ShouldTreatScalarValueAsAddress(
.AnySet(eTypeInstanceIsPointer | eTypeIsReference);
}

uint32_t
TypeSystemSwift::GetIndexOfChildWithName(opaque_compiler_type_t type,
const char *name,
bool omit_empty_base_classes) {
uint32_t TypeSystemSwift::GetIndexOfChildWithName(
opaque_compiler_type_t type, const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes) {
std::vector<uint32_t> child_indexes;
size_t num_child_indexes = GetIndexOfChildMemberWithName(
type, name, omit_empty_base_classes, child_indexes);
type, name, exe_ctx, omit_empty_base_classes, child_indexes);
return num_child_indexes == 1 ? child_indexes.front() : UINT32_MAX;
}
2 changes: 1 addition & 1 deletion lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class TypeSystemSwift : public TypeSystem {
/// Lookup a child given a name. This function will match base class names
/// and member names in \p type only, not descendants.
uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
const char *name,
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes) override;

/// \}
Expand Down
70 changes: 66 additions & 4 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
#include "clang/APINotes/APINotesManager.h"
#include "clang/APINotes/APINotesReader.h"

#include <algorithm>
#include <sstream>

using namespace lldb;
using namespace lldb_private;

Expand Down Expand Up @@ -2321,7 +2324,7 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
if (m_swift_ast_context->GetNumChildren(ReconstructType(type),
omit_empty_base_classes, exe_ctx) <
runtime->GetNumChildren({this, type}, valobj).getValueOr(0))
return fallback();
return impl();

#ifndef NDEBUG
std::string ast_child_name;
Expand Down Expand Up @@ -2362,11 +2365,70 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
}

size_t TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName(
opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) {
opaque_compiler_type_t type, const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
if (auto *exe_scope = exe_ctx->GetBestExecutionContextScope())
if (auto *runtime =
SwiftLanguageRuntime::Get(exe_scope->CalculateProcess()))
if (auto index_size = runtime->GetIndexOfChildMemberWithName(
GetCanonicalType(type), name, exe_ctx, omit_empty_base_classes,
child_indexes)) {
#ifndef NDEBUG
// This block is a custom VALIDATE_AND_RETURN implementation to support
// checking the return value, plus the by-ref `child_indexes`.
if (!m_swift_ast_context)
return *index_size;
auto ast_type = ReconstructType(type);
if (!ast_type)
return *index_size;
std::vector<uint32_t> ast_child_indexes;
auto ast_index_size = m_swift_ast_context->GetIndexOfChildMemberWithName(
ast_type, name, exe_ctx, omit_empty_base_classes,
ast_child_indexes);
// The runtime has more info than the AST. No useful validation can be
// done.
if (*index_size > ast_index_size)
return *index_size;

auto fail = [&]() {
auto join = [](const auto &v) {
std::ostringstream buf;
buf << "{";
for (const auto &item : v)
buf << item << ",";
buf.seekp(-1, std::ios_base::end);
buf << "}";
return buf.str();
};
llvm::dbgs() << join(child_indexes)
<< " != " << join(ast_child_indexes) << "\n";
llvm::dbgs() << "failing type was " << (const char *)type
<< ", member was " << name << "\n";
assert(false &&
"TypeSystemSwiftTypeRef diverges from SwiftASTContext");
};
if (*index_size != ast_index_size)
fail();
for (unsigned i = 0; i < *index_size; ++i)
if (child_indexes[i] < ast_child_indexes[i])
// When the runtime may know know about more children. When this
// happens, indexes will be larger. But if an index is smaller, that
// means the runtime has dropped info somehow.
fail();
#endif
return *index_size;
}

LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
"Using SwiftASTContext::GetIndexOfChildMemberWithName fallback for "
"type %s",
AsMangledName(type));

return m_swift_ast_context->GetIndexOfChildMemberWithName(
ReconstructType(type), name, omit_empty_base_classes, child_indexes);
ReconstructType(type), name, exe_ctx, omit_empty_base_classes,
child_indexes);
}

size_t
TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type) {
return m_swift_ast_context->GetNumTemplateArguments(ReconstructType(type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
ValueObject *valobj, uint64_t &language_flags) override;
size_t
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
const char *name, bool omit_empty_base_classes,
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
CompilerType GetTypeForFormatters(lldb::opaque_compiler_type_t type) override;
Expand Down
7 changes: 4 additions & 3 deletions lldb/source/Symbol/CompilerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,11 +654,11 @@ CompilerType CompilerType::GetChildCompilerTypeAtIndex(
// index 1 is the child index for "m_b" within class A

size_t CompilerType::GetIndexOfChildMemberWithName(
const char *name, bool omit_empty_base_classes,
const char *name, ExecutionContext *exe_ctx, bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) const {
if (IsValid() && name && name[0]) {
return m_type_system->GetIndexOfChildMemberWithName(
m_type, name, omit_empty_base_classes, child_indexes);
m_type, name, exe_ctx, omit_empty_base_classes, child_indexes);
}
return 0;
}
Expand Down Expand Up @@ -714,9 +714,10 @@ bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {

uint32_t
CompilerType::GetIndexOfChildWithName(const char *name,
ExecutionContext *exe_ctx,
bool omit_empty_base_classes) const {
if (IsValid() && name && name[0]) {
return m_type_system->GetIndexOfChildWithName(m_type, name,
return m_type_system->GetIndexOfChildWithName(m_type, name, exe_ctx,
omit_empty_base_classes);
}
return UINT32_MAX;
Expand Down
Loading