@@ -1196,6 +1196,29 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1196
1196
}
1197
1197
1198
1198
// Objects.
1199
+ switch (rti->getReferenceKind ()) {
1200
+ case swift::reflection::ReferenceKind::Weak:
1201
+ case swift::reflection::ReferenceKind::Unowned:
1202
+ case swift::reflection::ReferenceKind::Unmanaged:
1203
+ // Weak references are implicitly Optionals, so report the one
1204
+ // child of Optional here.
1205
+ if (idx != 0 )
1206
+ break ; // Maybe assert that type is not an Optional?
1207
+ child_name = " some" ;
1208
+ child_byte_size = ts->GetPointerByteSize ();
1209
+ child_byte_offset = 0 ;
1210
+ child_bitfield_bit_size = 0 ;
1211
+ child_bitfield_bit_offset = 0 ;
1212
+ child_is_base_class = false ;
1213
+ child_is_deref_of_parent = false ;
1214
+ language_flags = 0 ;
1215
+ if (CompilerType optional = GetWeakReferent (*ts, type))
1216
+ return optional;
1217
+ break ;
1218
+ default :
1219
+ break ;
1220
+ }
1221
+
1199
1222
// Try the instance type metadata.
1200
1223
if (!valobj)
1201
1224
return {};
@@ -1215,61 +1238,58 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1215
1238
instance_type.GetTypeSystem ().dyn_cast_or_null <TypeSystemSwift>();
1216
1239
if (!instance_ts)
1217
1240
return {};
1218
-
1219
1241
// LLDBTypeInfoProvider needs to be kept alive while supers gets accessed.
1220
1242
llvm::SmallVector<SuperClassType, 2 > supers;
1221
- LLDBTypeInfoProvider tip (*this , *instance_ts);
1222
- reflection_ctx->ForEachSuperClassType (
1223
- &tip, ts->GetDescriptorFinder (), pointer,
1224
- [&](SuperClassType sc) -> bool {
1225
- // If the typeref is invalid, we don't want to process it (for
1226
- // example, this could be an artifical ObjC class).
1227
- if (!sc.get_typeref ())
1228
- return false ;
1243
+ auto superclass_finder = [&](SuperClassType sc) -> bool {
1244
+ // If the typeref is invalid, we don't want to process it (for
1245
+ // example, this could be an artifical ObjC class).
1246
+ if (!sc.get_typeref ())
1247
+ return false ;
1229
1248
1230
- if (!found_start) {
1231
- // The ValueObject always points to the same class instance,
1232
- // even when querying base classes. Drop base classes until we
1233
- // reach the requested type.
1234
- if (auto *tr = sc.get_typeref ()) {
1235
- NodePointer base_class = tr->getDemangling (dem);
1236
- if (TypeSystemSwiftTypeRef::GetBaseName (base_class) != type_name)
1237
- return false ;
1238
- found_start = true ;
1239
- }
1240
- }
1241
- supers.push_back (sc);
1242
- return supers.size () >= 2 ;
1243
- }) ;
1249
+ if (!found_start) {
1250
+ // The ValueObject always points to the same class instance,
1251
+ // even when querying base classes. Drop base classes until we
1252
+ // reach the requested type.
1253
+ if (auto *tr = sc.get_typeref ()) {
1254
+ NodePointer base_class = tr->getDemangling (dem);
1255
+ if (TypeSystemSwiftTypeRef::GetBaseName (base_class) != type_name)
1256
+ return false ;
1257
+ found_start = true ;
1258
+ }
1259
+ }
1260
+ supers.push_back (sc);
1261
+ return supers.size () >= 2 ;
1262
+ } ;
1244
1263
1245
- if (supers.size () == 0 ) {
1264
+ LLDBTypeInfoProvider tip (*this , *instance_ts);
1265
+ // Try out the instance pointer based super class traversal first, as its
1266
+ // usually faster.
1267
+ reflection_ctx->ForEachSuperClassType (&tip, ts->GetDescriptorFinder (),
1268
+ pointer, superclass_finder);
1269
+
1270
+ if (supers.empty ())
1271
+ // If the pointer based super class traversal failed (this may happen
1272
+ // when metadata is not present in the binary, for example: embedded
1273
+ // Swift), try the typeref based one next.
1274
+ reflection_ctx->ForEachSuperClassType (&tip, ts->GetDescriptorFinder (), tr,
1275
+ superclass_finder);
1276
+
1277
+ if (supers.empty ()) {
1246
1278
LLDB_LOG (GetLog (LLDBLog::Types),
1247
1279
" Couldn't find the type metadata for {0} in instance" ,
1248
1280
type.GetTypeName ());
1249
- return {};
1250
- }
1251
1281
1252
- switch (rti->getReferenceKind ()) {
1253
- case swift::reflection::ReferenceKind::Weak:
1254
- case swift::reflection::ReferenceKind::Unowned:
1255
- case swift::reflection::ReferenceKind::Unmanaged:
1256
- // Weak references are implicitly Optionals, so report the one
1257
- // child of Optional here.
1258
- if (idx != 0 )
1259
- break ; // Maybe assert that type is not an Optional?
1260
- child_name = " some" ;
1261
- child_byte_size = ts->GetPointerByteSize ();
1262
- child_byte_offset = 0 ;
1263
- child_bitfield_bit_size = 0 ;
1264
- child_bitfield_bit_offset = 0 ;
1265
- child_is_base_class = false ;
1266
- child_is_deref_of_parent = false ;
1267
- language_flags = 0 ;
1268
- if (CompilerType optional = GetWeakReferent (*ts, type))
1269
- return optional;
1270
- break ;
1271
- default :
1272
- break ;
1282
+ auto *cti = reflection_ctx->GetClassInstanceTypeInfo (
1283
+ tr, &tip, ts->GetDescriptorFinder ());
1284
+ if (auto *rti =
1285
+ llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(cti)) {
1286
+ auto fields = rti->getFields ();
1287
+ if (idx < fields.size ()) {
1288
+ llvm::Optional<TypeSystemSwift::TupleElement> tuple;
1289
+ return get_from_field_info (fields[idx], tuple, true );
1290
+ }
1291
+ }
1292
+ return {};
1273
1293
}
1274
1294
1275
1295
// Handle the artificial base class fields.
@@ -1722,6 +1742,14 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class(
1722
1742
1723
1743
const auto *typeref = reflection_ctx->ReadTypeFromInstance (
1724
1744
instance_ptr, ts.GetDescriptorFinder (), true );
1745
+
1746
+ // If we couldn't find the typeref from the instance, the best we can do is
1747
+ // use the static type. This is a valid use case when the binary doesn't
1748
+ // contain any metadata (for example, embedded Swift).
1749
+ if (!typeref)
1750
+ typeref = reflection_ctx->GetTypeRefOrNull (class_type.GetMangledTypeName (),
1751
+ ts.GetDescriptorFinder ());
1752
+
1725
1753
if (!typeref) {
1726
1754
LLDB_LOGF (log,
1727
1755
" could not read typeref for type: %s (instance_ptr = 0x%" PRIx64
0 commit comments