Skip to content

Commit d7cfd65

Browse files
authored
Merge pull request #2271 from apple/lldb-Implement-TypeSystemSwiftTypeRef-GetIndexOfChildMemberWithName-next
[lldb] Implement TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName
2 parents 7723f5d + 04993ef commit d7cfd65

23 files changed

+253
-55
lines changed

lldb/include/lldb/Symbol/CompilerType.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class CompilerType {
323323

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

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

339340
size_t GetNumTemplateArguments() const;

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ class TypeSystem : public PluginInterface {
354354
// member member names in "clang_type" only, not descendants.
355355
virtual uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
356356
const char *name,
357+
ExecutionContext *exe_ctx,
357358
bool omit_empty_base_classes) = 0;
358359

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

370372
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type);

lldb/include/lldb/Target/SwiftLanguageRuntime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ class SwiftLanguageRuntime : public LanguageRuntime {
256256
llvm::Optional<unsigned> GetNumChildren(CompilerType type,
257257
ValueObject *valobj);
258258

259+
llvm::Optional<size_t> GetIndexOfChildMemberWithName(
260+
CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
261+
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes);
262+
259263
/// Ask Remote Mirrors about a child of a composite type.
260264
CompilerType GetChildCompilerTypeAtIndex(
261265
CompilerType type, size_t idx, bool transparent_pointers,

lldb/source/Core/ValueObject.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,8 @@ lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
593593

594594
size_t ValueObject::GetIndexOfChildWithName(ConstString name) {
595595
bool omit_empty_base_classes = true;
596-
return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
596+
ExecutionContext exe_ctx(GetExecutionContextRef());
597+
return GetCompilerType().GetIndexOfChildWithName(name.GetCString(), &exe_ctx,
597598
omit_empty_base_classes);
598599
}
599600

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

616+
ExecutionContext exe_ctx(GetExecutionContextRef());
615617
const size_t num_child_indexes =
616618
GetCompilerType().GetIndexOfChildMemberWithName(
617-
name.GetCString(), omit_empty_base_classes, child_indexes);
619+
name.GetCString(), &exe_ctx, omit_empty_base_classes, child_indexes);
618620
if (num_child_indexes == 0)
619621
return nullptr;
620622

lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
158158
return UINT32_MAX;
159159

160160
const bool omit_empty_base_classes = false;
161-
return m_block_struct_type.GetIndexOfChildWithName(name.AsCString(),
162-
omit_empty_base_classes);
161+
return m_block_struct_type.GetIndexOfChildWithName(
162+
name.AsCString(), nullptr, omit_empty_base_classes);
163163
}
164164

165165
private:

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6467,7 +6467,8 @@ static uint32_t GetIndexForRecordChild(const clang::RecordDecl *record_decl,
64676467

64686468
size_t TypeSystemClang::GetIndexOfChildMemberWithName(
64696469
lldb::opaque_compiler_type_t type, const char *name,
6470-
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
6470+
ExecutionContext *exe_ctx, bool omit_empty_base_classes,
6471+
std::vector<uint32_t> &child_indexes) {
64716472
if (type && name && name[0]) {
64726473
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
64736474
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
@@ -6495,7 +6496,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
64956496
CompilerType field_type = GetType(field->getType());
64966497
child_indexes.push_back(child_idx);
64976498
if (field_type.GetIndexOfChildMemberWithName(
6498-
name, omit_empty_base_classes, child_indexes))
6499+
name, exe_ctx, omit_empty_base_classes, child_indexes))
64996500
return child_indexes.size();
65006501
child_indexes.pop_back();
65016502

@@ -6606,7 +6607,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
66066607
GetType(getASTContext().getObjCInterfaceType(
66076608
superclass_interface_decl));
66086609
if (superclass_clang_type.GetIndexOfChildMemberWithName(
6609-
name, omit_empty_base_classes, child_indexes)) {
6610+
name, exe_ctx, omit_empty_base_classes, child_indexes)) {
66106611
// We did find an ivar in a superclass so just return the
66116612
// results!
66126613
return child_indexes.size();
@@ -6626,7 +6627,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
66266627
llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
66276628
->getPointeeType());
66286629
return objc_object_clang_type.GetIndexOfChildMemberWithName(
6629-
name, omit_empty_base_classes, child_indexes);
6630+
name, exe_ctx, omit_empty_base_classes, child_indexes);
66306631
} break;
66316632

66326633
case clang::Type::ConstantArray: {
@@ -6678,7 +6679,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
66786679

66796680
if (pointee_clang_type.IsAggregateType()) {
66806681
return pointee_clang_type.GetIndexOfChildMemberWithName(
6681-
name, omit_empty_base_classes, child_indexes);
6682+
name, exe_ctx, omit_empty_base_classes, child_indexes);
66826683
}
66836684
} break;
66846685

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

66886689
if (pointee_clang_type.IsAggregateType()) {
66896690
return pointee_clang_type.GetIndexOfChildMemberWithName(
6690-
name, omit_empty_base_classes, child_indexes);
6691+
name, exe_ctx, omit_empty_base_classes, child_indexes);
66916692
}
66926693
} break;
66936694

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

6705-
uint32_t
6706-
TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
6707-
const char *name,
6708-
bool omit_empty_base_classes) {
6706+
uint32_t TypeSystemClang::GetIndexOfChildWithName(
6707+
lldb::opaque_compiler_type_t type, const char *name,
6708+
ExecutionContext *exe_ctx, bool omit_empty_base_classes) {
67096709
if (type && name && name[0]) {
67106710
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
67116711

@@ -6807,7 +6807,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
68076807
llvm::cast<clang::ObjCObjectPointerType>(qual_type.getTypePtr())
68086808
->getPointeeType());
68096809
return pointee_clang_type.GetIndexOfChildWithName(
6810-
name, omit_empty_base_classes);
6810+
name, exe_ctx, omit_empty_base_classes);
68116811
} break;
68126812

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

68596859
if (pointee_type.IsAggregateType()) {
6860-
return pointee_type.GetIndexOfChildWithName(name,
6860+
return pointee_type.GetIndexOfChildWithName(name, exe_ctx,
68616861
omit_empty_base_classes);
68626862
}
68636863
} break;
@@ -6868,7 +6868,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
68686868
CompilerType pointee_type = GetType(pointer_type->getPointeeType());
68696869

68706870
if (pointee_type.IsAggregateType()) {
6871-
return pointee_type.GetIndexOfChildWithName(name,
6871+
return pointee_type.GetIndexOfChildWithName(name, exe_ctx,
68726872
omit_empty_base_classes);
68736873
} else {
68746874
// if (parent_name)

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ class TypeSystemClang : public TypeSystem {
811811
// Lookup a child given a name. This function will match base class names and
812812
// member member names in "clang_type" only, not descendants.
813813
uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
814-
const char *name,
814+
const char *name, ExecutionContext *exe_ctx,
815815
bool omit_empty_base_classes) override;
816816

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

828829
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7226,8 +7226,8 @@ CompilerType SwiftASTContext::GetChildCompilerTypeAtIndex(
72267226
// second index 1 is the child index for "m_b" within class A.
72277227

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

72337233
if (type && name && name[0]) {
@@ -7249,7 +7249,7 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
72497249
case swift::TypeKind::UnownedStorage:
72507250
case swift::TypeKind::WeakStorage:
72517251
return ToCompilerType(swift_can_type->getReferenceStorageReferent())
7252-
.GetIndexOfChildMemberWithName(name, omit_empty_base_classes,
7252+
.GetIndexOfChildMemberWithName(name, exe_ctx, omit_empty_base_classes,
72537253
child_indexes);
72547254
case swift::TypeKind::GenericTypeParam:
72557255
case swift::TypeKind::DependentMember:
@@ -7330,7 +7330,7 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
73307330
CompilerType superclass_type =
73317331
ToCompilerType(superclass_swift_type.getPointer());
73327332
if (superclass_type.GetIndexOfChildMemberWithName(
7333-
name, omit_empty_base_classes, child_indexes))
7333+
name, exe_ctx, omit_empty_base_classes, child_indexes))
73347334
return child_indexes.size();
73357335

73367336
// We didn't find a stored property matching "name" in our
@@ -7376,7 +7376,7 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
73767376

73777377
if (pointee_clang_type.IsAggregateType()) {
73787378
return pointee_clang_type.GetIndexOfChildMemberWithName(
7379-
name, omit_empty_base_classes, child_indexes);
7379+
name, exe_ctx, omit_empty_base_classes, child_indexes);
73807380
}
73817381
} break;
73827382
case swift::TypeKind::UnboundGeneric:

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,8 @@ class SwiftASTContext : public TypeSystemSwift {
608608
// name, not just the first.
609609
size_t
610610
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
611-
const char *name, bool omit_empty_base_classes,
611+
const char *name, ExecutionContext *exe_ctx,
612+
bool omit_empty_base_classes,
612613
std::vector<uint32_t> &child_indexes) override;
613614

614615
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,11 @@ bool TypeSystemSwift::ShouldTreatScalarValueAsAddress(
102102
.AnySet(eTypeInstanceIsPointer | eTypeIsReference);
103103
}
104104

105-
uint32_t
106-
TypeSystemSwift::GetIndexOfChildWithName(opaque_compiler_type_t type,
107-
const char *name,
108-
bool omit_empty_base_classes) {
105+
uint32_t TypeSystemSwift::GetIndexOfChildWithName(
106+
opaque_compiler_type_t type, const char *name, ExecutionContext *exe_ctx,
107+
bool omit_empty_base_classes) {
109108
std::vector<uint32_t> child_indexes;
110109
size_t num_child_indexes = GetIndexOfChildMemberWithName(
111-
type, name, omit_empty_base_classes, child_indexes);
110+
type, name, exe_ctx, omit_empty_base_classes, child_indexes);
112111
return num_child_indexes == 1 ? child_indexes.front() : UINT32_MAX;
113112
}

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ class TypeSystemSwift : public TypeSystem {
246246
/// Lookup a child given a name. This function will match base class names
247247
/// and member names in \p type only, not descendants.
248248
uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
249-
const char *name,
249+
const char *name, ExecutionContext *exe_ctx,
250250
bool omit_empty_base_classes) override;
251251

252252
/// \}

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
#include "clang/APINotes/APINotesManager.h"
3636
#include "clang/APINotes/APINotesReader.h"
3737

38+
#include <algorithm>
39+
#include <sstream>
40+
3841
using namespace lldb;
3942
using namespace lldb_private;
4043

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

23262329
#ifndef NDEBUG
23272330
std::string ast_child_name;
@@ -2362,11 +2365,70 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
23622365
}
23632366

23642367
size_t TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName(
2365-
opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes,
2366-
std::vector<uint32_t> &child_indexes) {
2368+
opaque_compiler_type_t type, const char *name, ExecutionContext *exe_ctx,
2369+
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
2370+
if (auto *exe_scope = exe_ctx->GetBestExecutionContextScope())
2371+
if (auto *runtime =
2372+
SwiftLanguageRuntime::Get(exe_scope->CalculateProcess()))
2373+
if (auto index_size = runtime->GetIndexOfChildMemberWithName(
2374+
GetCanonicalType(type), name, exe_ctx, omit_empty_base_classes,
2375+
child_indexes)) {
2376+
#ifndef NDEBUG
2377+
// This block is a custom VALIDATE_AND_RETURN implementation to support
2378+
// checking the return value, plus the by-ref `child_indexes`.
2379+
if (!m_swift_ast_context)
2380+
return *index_size;
2381+
auto ast_type = ReconstructType(type);
2382+
if (!ast_type)
2383+
return *index_size;
2384+
std::vector<uint32_t> ast_child_indexes;
2385+
auto ast_index_size = m_swift_ast_context->GetIndexOfChildMemberWithName(
2386+
ast_type, name, exe_ctx, omit_empty_base_classes,
2387+
ast_child_indexes);
2388+
// The runtime has more info than the AST. No useful validation can be
2389+
// done.
2390+
if (*index_size > ast_index_size)
2391+
return *index_size;
2392+
2393+
auto fail = [&]() {
2394+
auto join = [](const auto &v) {
2395+
std::ostringstream buf;
2396+
buf << "{";
2397+
for (const auto &item : v)
2398+
buf << item << ",";
2399+
buf.seekp(-1, std::ios_base::end);
2400+
buf << "}";
2401+
return buf.str();
2402+
};
2403+
llvm::dbgs() << join(child_indexes)
2404+
<< " != " << join(ast_child_indexes) << "\n";
2405+
llvm::dbgs() << "failing type was " << (const char *)type
2406+
<< ", member was " << name << "\n";
2407+
assert(false &&
2408+
"TypeSystemSwiftTypeRef diverges from SwiftASTContext");
2409+
};
2410+
if (*index_size != ast_index_size)
2411+
fail();
2412+
for (unsigned i = 0; i < *index_size; ++i)
2413+
if (child_indexes[i] < ast_child_indexes[i])
2414+
// When the runtime may know know about more children. When this
2415+
// happens, indexes will be larger. But if an index is smaller, that
2416+
// means the runtime has dropped info somehow.
2417+
fail();
2418+
#endif
2419+
return *index_size;
2420+
}
2421+
2422+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
2423+
"Using SwiftASTContext::GetIndexOfChildMemberWithName fallback for "
2424+
"type %s",
2425+
AsMangledName(type));
2426+
23672427
return m_swift_ast_context->GetIndexOfChildMemberWithName(
2368-
ReconstructType(type), name, omit_empty_base_classes, child_indexes);
2428+
ReconstructType(type), name, exe_ctx, omit_empty_base_classes,
2429+
child_indexes);
23692430
}
2431+
23702432
size_t
23712433
TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type) {
23722434
return m_swift_ast_context->GetNumTemplateArguments(ReconstructType(type));

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
165165
ValueObject *valobj, uint64_t &language_flags) override;
166166
size_t
167167
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
168-
const char *name, bool omit_empty_base_classes,
168+
const char *name, ExecutionContext *exe_ctx,
169+
bool omit_empty_base_classes,
169170
std::vector<uint32_t> &child_indexes) override;
170171
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
171172
CompilerType GetTypeForFormatters(lldb::opaque_compiler_type_t type) override;

lldb/source/Symbol/CompilerType.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,11 +654,11 @@ CompilerType CompilerType::GetChildCompilerTypeAtIndex(
654654
// index 1 is the child index for "m_b" within class A
655655

656656
size_t CompilerType::GetIndexOfChildMemberWithName(
657-
const char *name, bool omit_empty_base_classes,
657+
const char *name, ExecutionContext *exe_ctx, bool omit_empty_base_classes,
658658
std::vector<uint32_t> &child_indexes) const {
659659
if (IsValid() && name && name[0]) {
660660
return m_type_system->GetIndexOfChildMemberWithName(
661-
m_type, name, omit_empty_base_classes, child_indexes);
661+
m_type, name, exe_ctx, omit_empty_base_classes, child_indexes);
662662
}
663663
return 0;
664664
}
@@ -714,9 +714,10 @@ bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
714714

715715
uint32_t
716716
CompilerType::GetIndexOfChildWithName(const char *name,
717+
ExecutionContext *exe_ctx,
717718
bool omit_empty_base_classes) const {
718719
if (IsValid() && name && name[0]) {
719-
return m_type_system->GetIndexOfChildWithName(m_type, name,
720+
return m_type_system->GetIndexOfChildWithName(m_type, name, exe_ctx,
720721
omit_empty_base_classes);
721722
}
722723
return UINT32_MAX;

0 commit comments

Comments
 (0)