Skip to content

Commit d0a8d14

Browse files
committed
implement most of GetIndexOfChildMemberWithName
1 parent 7b8951c commit d0a8d14

File tree

1 file changed

+90
-1
lines changed

1 file changed

+90
-1
lines changed

lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,10 +1142,99 @@ GetTypeFromTypeRef(TypeSystemSwiftTypeRef &ts,
11421142
return ts.RemangleAsType(dem, node);
11431143
}
11441144

1145+
static llvm::Optional<size_t>
1146+
findFieldWithName(const std::vector<swift::reflection::FieldInfo> &fields,
1147+
llvm::StringRef name, std::vector<uint32_t> &child_indexes,
1148+
uint32_t offset = 0) {
1149+
uint32_t index = 0;
1150+
auto it = std::find_if(fields.begin(), fields.end(), [&](const auto &field) {
1151+
// A nonnull TypeRef is required for enum cases, where it represents cases
1152+
// that have a payload. In other types it will be true anyway.
1153+
if (field.TR == nullptr)
1154+
return false;
1155+
if (name != field.Name) {
1156+
++index;
1157+
return false;
1158+
}
1159+
return true;
1160+
});
1161+
if (it == fields.end())
1162+
return {};
1163+
child_indexes.push_back(offset + index);
1164+
return child_indexes.size();
1165+
}
1166+
11451167
llvm::Optional<size_t> SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
11461168
CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
11471169
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
1148-
return {};
1170+
auto *ts =
1171+
llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(type.GetTypeSystem());
1172+
if (!ts)
1173+
return {};
1174+
1175+
using namespace swift::reflection;
1176+
// Try the static type metadata.
1177+
const TypeRef *tr = nullptr;
1178+
auto *ti = GetTypeInfo(type, exe_ctx->GetFramePtr(), &tr);
1179+
switch (ti->getKind()) {
1180+
case TypeInfoKind::Record: {
1181+
// Structs and Tuples.
1182+
auto *rti = llvm::cast<RecordTypeInfo>(ti);
1183+
switch (rti->getRecordKind()) {
1184+
case RecordKind::ThickFunction:
1185+
// There are two fields, `function` and `context`, but they're not exposed
1186+
// by lldb.
1187+
return {};
1188+
case RecordKind::OpaqueExistential:
1189+
// `OpaqueExistential` is documented as:
1190+
// An existential is a three-word buffer followed by value metadata...
1191+
// The buffer is exposed as children named `payload_data_{0,1,2}`, and
1192+
// the number of fields are increased to match.
1193+
if (name.startswith("payload_data_")) {
1194+
uint32_t index;
1195+
if (name.take_back().getAsInteger(10, index) && index <= 2) {
1196+
child_indexes.push_back(index);
1197+
return child_indexes.size();
1198+
}
1199+
}
1200+
return findFieldWithName(rti->getFields(), name, child_indexes, 3);
1201+
default:
1202+
return findFieldWithName(rti->getFields(), name, child_indexes);
1203+
}
1204+
}
1205+
case TypeInfoKind::Enum: {
1206+
auto *eti = llvm::cast<EnumTypeInfo>(ti);
1207+
return findFieldWithName(eti->getCases(), name, child_indexes);
1208+
}
1209+
case TypeInfoKind::Reference: {
1210+
// Objects.
1211+
auto *rti = llvm::cast<ReferenceTypeInfo>(ti);
1212+
switch (rti->getReferenceKind()) {
1213+
case ReferenceKind::Weak:
1214+
case ReferenceKind::Unowned:
1215+
case ReferenceKind::Unmanaged:
1216+
// TODO: Dereference
1217+
return {};
1218+
case ReferenceKind::Strong: {
1219+
auto *reflection_ctx = GetReflectionContext();
1220+
auto &builder = reflection_ctx->getBuilder();
1221+
auto tc = TypeConverter(builder);
1222+
auto tip = LLDBTypeInfoProvider(*this, *ts);
1223+
auto *cti = tc.getClassInstanceTypeInfo(tr, 0, &tip);
1224+
if (auto *rti = llvm::cast_or_null<RecordTypeInfo>(cti)) {
1225+
if (auto size =
1226+
findFieldWithName(rti->getFields(), name, child_indexes))
1227+
return size;
1228+
// TODO: handle base classes.
1229+
}
1230+
return {};
1231+
}
1232+
}
1233+
}
1234+
default:
1235+
// FIXME: Implement more cases.
1236+
return {};
1237+
}
11491238
}
11501239

11511240
CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(

0 commit comments

Comments
 (0)