@@ -815,6 +815,10 @@ SwiftLanguageRuntime::GetNumChildren(CompilerType type,
815
815
return llvm::createStringError (" could not typeref for " +
816
816
type.GetMangledTypeName ().GetString ());
817
817
818
+ // Indirect enums.
819
+ if (type.GetTypeInfo () & lldb::eTypeIsEnumeration)
820
+ return 1 ;
821
+
818
822
// Existentials.
819
823
if (size_t n = GetExistentialSyntheticChildren (ts, tr, ti).size ())
820
824
return n;
@@ -1029,6 +1033,8 @@ SwiftLanguageRuntime::GetIndexOfChildMemberWithName(
1029
1033
auto ts = type.GetTypeSystem ().dyn_cast_or_null <TypeSystemSwiftTypeRef>();
1030
1034
if (!ts)
1031
1035
return {SwiftLanguageRuntime::eError, {}};
1036
+ if (!exe_ctx)
1037
+ return {SwiftLanguageRuntime::eError, {}};
1032
1038
1033
1039
using namespace swift ::reflection;
1034
1040
// Try the static type metadata.
@@ -1086,6 +1092,29 @@ SwiftLanguageRuntime::GetIndexOfChildMemberWithName(
1086
1092
exe_ctx, omit_empty_base_classes,
1087
1093
child_indexes);
1088
1094
case ReferenceKind::Strong: {
1095
+ // Indirect enums.
1096
+ if (type.GetTypeInfo () & lldb::eTypeIsEnumeration) {
1097
+ const swift::reflection::TypeRef *tr = nullptr ;
1098
+ auto ti_or_err = GetSwiftRuntimeTypeInfo (
1099
+ type, exe_ctx->GetBestExecutionContextScope (), &tr);
1100
+ if (!ti_or_err) {
1101
+ LLDB_LOG_ERROR (GetLog (LLDBLog::Types), ti_or_err.takeError (),
1102
+ " Could not get enum type info: {0}" );
1103
+ return {SwiftLanguageRuntime::eError, {}};
1104
+ }
1105
+ auto *eti = llvm::dyn_cast<EnumTypeInfo>(&*ti_or_err);
1106
+ if (!eti) {
1107
+ // This is probably a generic single-payload enum.
1108
+ // Let's pretend we found it.
1109
+ LLDB_LOG (GetLog (LLDBLog::Types),
1110
+ " Presuming generic single-payload enum." );
1111
+ child_indexes.push_back (0 );
1112
+ return {SwiftLanguageRuntime::eFound, child_indexes.size ()};
1113
+ }
1114
+ return findFieldWithName (eti->getCases (), tr, name, true ,
1115
+ child_indexes);
1116
+ }
1117
+
1089
1118
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext ();
1090
1119
if (!reflection_ctx)
1091
1120
return {SwiftLanguageRuntime::eError, {}};
@@ -1197,6 +1226,47 @@ llvm::Expected<CompilerType> SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
1197
1226
return pack_element_type;
1198
1227
}
1199
1228
1229
+ auto get_from_indirect_enum = [&]() -> llvm::Expected<CompilerType> {
1230
+ ThreadSafeReflectionContext reflection_ctx = GetReflectionContext ();
1231
+ if (!reflection_ctx)
1232
+ return llvm::createStringError (" no reflection context" );
1233
+ // The indirect enum field should point to a closure context.
1234
+ LLDBTypeInfoProvider tip (*this , &exe_ctx);
1235
+ lldb::addr_t instance = ::MaskMaybeBridgedPointer (GetProcess (), pointer);
1236
+ auto ti_or_err = reflection_ctx->GetTypeInfoFromInstance (
1237
+ instance, &tip, ts->GetDescriptorFinder ());
1238
+ if (!ti_or_err) {
1239
+ llvm::consumeError (ti_or_err.takeError ());
1240
+ return CompilerType ();
1241
+ }
1242
+ auto *ti = &*ti_or_err;
1243
+ if (auto *rti = llvm::dyn_cast<swift::reflection::RecordTypeInfo>(ti)) {
1244
+ switch (rti->getRecordKind ()) {
1245
+ case swift::reflection::RecordKind::ClosureContext: {
1246
+ auto &field = rti->getFields ()[0 ];
1247
+ auto *type_ref = field.TR ;
1248
+ language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
1249
+ child_byte_offset = field.Offset ;
1250
+ child_byte_size = field.TI .getSize ();
1251
+ return GetTypeFromTypeRef (*ts, type_ref);
1252
+ }
1253
+ case swift::reflection::RecordKind::Tuple: {
1254
+ std::vector<TypeSystemSwift::TupleElement> elts;
1255
+ for (auto &field : rti->getFields ())
1256
+ elts.emplace_back (ConstString (), GetTypeFromTypeRef (*ts, field.TR ));
1257
+ return ts->CreateTupleType (elts);
1258
+ }
1259
+ default :
1260
+ return llvm::createStringError (
1261
+ " unexpected kind of indirect record enum" );
1262
+ }
1263
+ }
1264
+ language_flags |= TypeSystemSwift::LanguageFlags::eIsIndirectEnumCase;
1265
+ child_byte_offset = 0 ;
1266
+ child_byte_size = ti->getSize ();
1267
+ return ts->GetBuiltinRawPointerType ();
1268
+ };
1269
+
1200
1270
// The actual conversion from the FieldInfo record.
1201
1271
auto get_from_field_info =
1202
1272
[&](const swift::reflection::FieldInfo &field,
@@ -1225,27 +1295,16 @@ llvm::Expected<CompilerType> SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
1225
1295
CompilerType result;
1226
1296
if (tuple)
1227
1297
result = tuple->element_type ;
1228
- else if (is_indirect_enum) {
1229
- ThreadSafeReflectionContext reflection_ctx = GetReflectionContext ();
1230
- if (!reflection_ctx)
1231
- return llvm::createStringError (" no reflection context" );
1232
- // The indirect enum field should point to a closure context.
1233
- LLDBTypeInfoProvider tip (*this , &exe_ctx);
1234
- lldb::addr_t instance = ::MaskMaybeBridgedPointer (GetProcess (), pointer);
1235
- auto ti_or_err = reflection_ctx->GetTypeInfoFromInstance (
1236
- instance, &tip, ts->GetDescriptorFinder ());
1237
- if (!ti_or_err)
1238
- return ti_or_err.takeError ();
1239
- auto *ti = &*ti_or_err;
1240
- auto *rti = llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti);
1241
- if (rti->getFields ().size () < 1 )
1242
- return llvm::createStringError (" no fields in indirect enum" );
1243
- auto &field = rti->getFields ()[0 ];
1244
- auto *type_ref = field.TR ;
1245
- result = GetTypeFromTypeRef (*ts, type_ref);
1246
- child_byte_offset = field.Offset ;
1247
- } else
1298
+ else {
1299
+ if (is_indirect_enum) {
1300
+ auto type_or_err = get_from_indirect_enum ();
1301
+ // Only if this couldn't be resolved as an instance pointer, carry on.
1302
+ if (!type_or_err || *type_or_err)
1303
+ return type_or_err;
1304
+ }
1248
1305
result = GetTypeFromTypeRef (*ts, field.TR );
1306
+ }
1307
+
1249
1308
// Bug-for-bug compatibility. See comment in
1250
1309
// SwiftASTContext::GetBitSize().
1251
1310
if (result.IsFunctionType ())
@@ -1395,6 +1454,10 @@ llvm::Expected<CompilerType> SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
1395
1454
if (!reflection_ctx)
1396
1455
return llvm::createStringError (" no reflection context" );
1397
1456
1457
+ // Indirect enums.
1458
+ if (type.GetTypeInfo () & lldb::eTypeIsEnumeration)
1459
+ return get_from_indirect_enum ();
1460
+
1398
1461
CompilerType instance_type = valobj->GetCompilerType ();
1399
1462
auto instance_ts =
1400
1463
instance_type.GetTypeSystem ().dyn_cast_or_null <TypeSystemSwift>();
0 commit comments