@@ -1142,10 +1142,99 @@ GetTypeFromTypeRef(TypeSystemSwiftTypeRef &ts,
1142
1142
return ts.RemangleAsType (dem, node);
1143
1143
}
1144
1144
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
+
1145
1167
llvm::Optional<size_t > SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName (
1146
1168
CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
1147
1169
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
+ }
1149
1238
}
1150
1239
1151
1240
CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex (
0 commit comments