Skip to content

Commit 4a0987a

Browse files
authored
Merge pull request #2317 from apple/lldb-Implement-TypeSystemSwiftTypeRef-GetNumFields
[lldb] Implement TypeSystemSwiftTypeRef::GetNumFields
2 parents d171818 + 76a3c02 commit 4a0987a

14 files changed

+124
-12
lines changed

lldb/include/lldb/Symbol/CompilerType.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ class CompilerType {
290290
std::function<bool(const CompilerType &integer_type, ConstString name,
291291
const llvm::APSInt &value)> const &callback) const;
292292

293-
uint32_t GetNumFields() const;
293+
uint32_t GetNumFields(ExecutionContext *exe_ctx = nullptr) const;
294294

295295
CompilerType GetFieldAtIndex(size_t idx, std::string &name,
296296
uint64_t *bit_offset_ptr,

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ class TypeSystem : public PluginInterface {
320320
ConstString name,
321321
const llvm::APSInt &value)> const &callback) {}
322322

323-
virtual uint32_t GetNumFields(lldb::opaque_compiler_type_t type) = 0;
323+
virtual uint32_t GetNumFields(lldb::opaque_compiler_type_t type,
324+
ExecutionContext *exe_ctx = nullptr) = 0;
324325

325326
virtual CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type,
326327
size_t idx, std::string &name,

lldb/include/lldb/Target/SwiftLanguageRuntime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ class SwiftLanguageRuntime : public LanguageRuntime {
270270
bool &child_is_deref_of_parent, ValueObject *valobj,
271271
uint64_t &language_flags);
272272

273+
/// Ask Remote Mirrors about the fields of a composite type.
274+
llvm::Optional<unsigned> GetNumFields(CompilerType type,
275+
ExecutionContext *exe_ctx);
276+
273277
/// Ask Remote Mirrors for the size of a Swift type.
274278
llvm::Optional<uint64_t> GetBitSize(CompilerType type,
275279
ExecutionContextScope *exe_scope);

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,8 @@ SwiftLanguage::GetHardcodedSynthetics() {
789789
is_imported = true;
790790
}
791791

792-
if (is_imported && type.GetNumFields() == 0)
792+
ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
793+
if (is_imported && type.GetNumFields(&exe_ctx) == 0)
793794
return true;
794795
if (valobj.IsBaseClass() && type.IsRuntimeGeneratedType()) {
795796
auto parent(valobj.GetParent());

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5416,7 +5416,8 @@ void TypeSystemClang::ForEachEnumerator(
54165416

54175417
#pragma mark Aggregate Types
54185418

5419-
uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type) {
5419+
uint32_t TypeSystemClang::GetNumFields(lldb::opaque_compiler_type_t type,
5420+
ExecutionContext *exe_ctx) {
54205421
if (!type)
54215422
return 0;
54225423

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,8 @@ class TypeSystemClang : public TypeSystem {
788788
ConstString name,
789789
const llvm::APSInt &value)> const &callback) override;
790790

791-
uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;
791+
uint32_t GetNumFields(lldb::opaque_compiler_type_t type,
792+
ExecutionContext *exe_ctx = nullptr) override;
792793

793794
CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
794795
std::string &name, uint64_t *bit_offset_ptr,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6384,7 +6384,8 @@ SwiftASTContext::GetNumDirectBaseClasses(opaque_compiler_type_t opaque_type) {
63846384
return 0;
63856385
}
63866386

6387-
uint32_t SwiftASTContext::GetNumFields(opaque_compiler_type_t type) {
6387+
uint32_t SwiftASTContext::GetNumFields(opaque_compiler_type_t type,
6388+
ExecutionContext *exe_ctx) {
63886389
VALID_OR_RETURN(0);
63896390

63906391
if (!type)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,8 @@ class SwiftASTContext : public TypeSystemSwift {
586586
bool omit_empty_base_classes,
587587
const ExecutionContext *exe_ctx) override;
588588

589-
uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;
589+
uint32_t GetNumFields(lldb::opaque_compiler_type_t type,
590+
ExecutionContext *exe_ctx = nullptr) override;
590591

591592
CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
592593
std::string &name, uint64_t *bit_offset_ptr,

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,9 +2231,31 @@ TypeSystemSwiftTypeRef::GetNumChildren(opaque_compiler_type_t type,
22312231
ReconstructType(type), omit_empty_base_classes, exe_ctx);
22322232
}
22332233

2234-
uint32_t TypeSystemSwiftTypeRef::GetNumFields(opaque_compiler_type_t type) {
2235-
return m_swift_ast_context->GetNumFields(ReconstructType(type));
2234+
uint32_t TypeSystemSwiftTypeRef::GetNumFields(opaque_compiler_type_t type,
2235+
ExecutionContext *exe_ctx) {
2236+
if (exe_ctx)
2237+
if (auto *runtime = SwiftLanguageRuntime::Get(exe_ctx->GetProcessSP()))
2238+
if (auto num_fields =
2239+
runtime->GetNumFields(GetCanonicalType(type), exe_ctx))
2240+
// Use a lambda to intercept & unwrap the `Optional` return value from
2241+
// `SwiftLanguageRuntime::GetNumFields`.
2242+
return [&] {
2243+
auto impl = [&]() -> llvm::Optional<uint32_t> {
2244+
if (!type)
2245+
return 0;
2246+
return num_fields;
2247+
};
2248+
VALIDATE_AND_RETURN(impl, GetNumFields, type,
2249+
(ReconstructType(type), exe_ctx));
2250+
}().getValue();
2251+
2252+
LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES),
2253+
"Using SwiftASTContext::GetNumFields fallback for type %s",
2254+
AsMangledName(type));
2255+
2256+
return m_swift_ast_context->GetNumFields(ReconstructType(type), exe_ctx);
22362257
}
2258+
22372259
CompilerType TypeSystemSwiftTypeRef::GetFieldAtIndex(
22382260
opaque_compiler_type_t type, size_t idx, std::string &name,
22392261
uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
152152
uint32_t GetNumChildren(lldb::opaque_compiler_type_t type,
153153
bool omit_empty_base_classes,
154154
const ExecutionContext *exe_ctx) override;
155-
uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;
155+
uint32_t GetNumFields(lldb::opaque_compiler_type_t type,
156+
ExecutionContext *exe_ctx = nullptr) override;
156157
CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
157158
std::string &name, uint64_t *bit_offset_ptr,
158159
uint32_t *bitfield_bit_size_ptr,

lldb/source/Symbol/CompilerType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,10 @@ void CompilerType::ForEachEnumerator(
538538
return m_type_system->ForEachEnumerator(m_type, callback);
539539
}
540540

541-
uint32_t CompilerType::GetNumFields() const {
541+
uint32_t CompilerType::GetNumFields(ExecutionContext *exe_ctx) const {
542542
if (!IsValid())
543543
return 0;
544-
return m_type_system->GetNumFields(m_type);
544+
return m_type_system->GetNumFields(m_type, exe_ctx);
545545
}
546546

547547
CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,

lldb/source/Target/SwiftLanguageRuntime.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ class SwiftLanguageRuntimeStub {
278278
return {};
279279
}
280280

281+
llvm::Optional<unsigned> GetNumFields(CompilerType type,
282+
ExecutionContext *exe_ctx) {
283+
STUB_LOG();
284+
return {};
285+
}
286+
281287
bool GetObjectDescription(Stream &str, ValueObject &object) {
282288
STUB_LOG();
283289
return false;
@@ -2185,6 +2191,12 @@ CompilerType SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
21852191
language_flags);
21862192
}
21872193

2194+
llvm::Optional<unsigned>
2195+
SwiftLanguageRuntime::GetNumFields(CompilerType type,
2196+
ExecutionContext *exe_ctx) {
2197+
FORWARD(GetNumFields, type, exe_ctx);
2198+
}
2199+
21882200
bool SwiftLanguageRuntime::GetObjectDescription(Stream &str,
21892201
ValueObject &object) {
21902202
FORWARD(GetObjectDescription, str, object);

lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,70 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
10931093
return {};
10941094
}
10951095

1096+
llvm::Optional<unsigned>
1097+
SwiftLanguageRuntimeImpl::GetNumFields(CompilerType type,
1098+
ExecutionContext *exe_ctx) {
1099+
auto *ts =
1100+
llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(type.GetTypeSystem());
1101+
if (!ts)
1102+
return {};
1103+
1104+
using namespace swift::reflection;
1105+
// Try the static type metadata.
1106+
const TypeRef *tr = nullptr;
1107+
auto *ti = GetTypeInfo(type, exe_ctx->GetFramePtr(), &tr);
1108+
// Structs and Tuples.
1109+
switch (ti->getKind()) {
1110+
case TypeInfoKind::Record: {
1111+
// Structs and Tuples.
1112+
auto *rti = llvm::cast<RecordTypeInfo>(ti);
1113+
switch (rti->getRecordKind()) {
1114+
case RecordKind::ExistentialMetatype:
1115+
case RecordKind::ThickFunction:
1116+
// There are two fields, `function` and `context`, but they're not exposed
1117+
// by lldb.
1118+
return 0;
1119+
case RecordKind::OpaqueExistential:
1120+
// `OpaqueExistential` is documented as:
1121+
// An existential is a three-word buffer followed by value metadata...
1122+
// The buffer is exposed as fields named `payload_data_{0,1,2}`, and
1123+
// the number of fields are increased to match.
1124+
return rti->getNumFields() + 3;
1125+
default:
1126+
return rti->getNumFields();
1127+
}
1128+
}
1129+
case TypeInfoKind::Enum: {
1130+
auto *eti = llvm::cast<EnumTypeInfo>(ti);
1131+
return eti->getNumPayloadCases();
1132+
}
1133+
case TypeInfoKind::Reference: {
1134+
// Objects.
1135+
auto *rti = llvm::cast<ReferenceTypeInfo>(ti);
1136+
switch (rti->getReferenceKind()) {
1137+
case ReferenceKind::Weak:
1138+
case ReferenceKind::Unowned:
1139+
case ReferenceKind::Unmanaged:
1140+
if (auto referent = GetWeakReferent(*ts, type))
1141+
return referent.GetNumFields(exe_ctx);
1142+
return 0;
1143+
case ReferenceKind::Strong:
1144+
TypeConverter tc(GetReflectionContext()->getBuilder());
1145+
LLDBTypeInfoProvider tip(*this, *ts);
1146+
auto *cti = tc.getClassInstanceTypeInfo(tr, 0, &tip);
1147+
if (auto *rti = llvm::dyn_cast_or_null<RecordTypeInfo>(cti)) {
1148+
return rti->getNumFields();
1149+
}
1150+
1151+
return {};
1152+
}
1153+
}
1154+
default:
1155+
// FIXME: Implement more cases.
1156+
return {};
1157+
}
1158+
}
1159+
10961160
/// Return the base name of the topmost nominal type.
10971161
static llvm::StringRef GetBaseName(swift::Demangle::NodePointer node) {
10981162
if (!node)

lldb/source/Target/SwiftLanguageRuntimeImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ class SwiftLanguageRuntimeImpl {
120120
llvm::Optional<unsigned> GetNumChildren(CompilerType type,
121121
ValueObject *valobj);
122122

123+
llvm::Optional<unsigned> GetNumFields(CompilerType type,
124+
ExecutionContext *exe_ctx);
125+
123126
llvm::Optional<size_t> GetIndexOfChildMemberWithName(
124127
CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
125128
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes);

0 commit comments

Comments
 (0)