Skip to content

Commit c5e226b

Browse files
committed
[Runtime] Use CF superclass metadata in runtime lookups.
When searching the superclasses at runtime, e.g., to find a suitable protocol conformance record, also consider the superclasses of CF types, which were recorded in the metadata but otherwise unused.
1 parent cae1c8c commit c5e226b

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3085,9 +3085,17 @@ bool _swift_isClassOrObjCExistentialType(const Metadata *value,
30853085

30863086
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
30873087
const Metadata *swift::_swift_class_getSuperclass(const Metadata *theClass) {
3088-
if (const ClassMetadata *classType = theClass->getClassObject())
3088+
if (const ClassMetadata *classType = theClass->getClassObject()) {
30893089
if (classHasSuperclass(classType))
30903090
return getMetadataForClass(classType->Superclass);
3091+
}
3092+
3093+
if (const ForeignClassMetadata *foreignClassType
3094+
= dyn_cast<ForeignClassMetadata>(theClass)) {
3095+
if (const Metadata *superclass = foreignClassType->Superclass)
3096+
return superclass;
3097+
}
3098+
30913099
return nullptr;
30923100
}
30933101

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -463,12 +463,10 @@ searchInConformanceCache(const Metadata *type,
463463
}
464464
}
465465

466-
// If the type is a class, try its superclass.
467-
if (const ClassMetadata *classType = type->getClassObject()) {
468-
if (classHasSuperclass(classType)) {
469-
type = getMetadataForClass(classType->Superclass);
470-
goto recur;
471-
}
466+
// If there is a superclass, look there.
467+
if (auto superclass = _swift_class_getSuperclass(type)) {
468+
type = superclass;
469+
goto recur;
472470
}
473471

474472
// We did not find an up-to-date cache entry.
@@ -506,12 +504,10 @@ bool isRelatedType(const Metadata *type, const void *candidate,
506504
return true;
507505
}
508506

509-
// If the type is a class, try its superclass.
510-
if (const ClassMetadata *classType = type->getClassObject()) {
511-
if (classHasSuperclass(classType)) {
512-
type = getMetadataForClass(classType->Superclass);
513-
continue;
514-
}
507+
// If there is a superclass, look there.
508+
if (auto superclass = _swift_class_getSuperclass(type)) {
509+
type = superclass;
510+
continue;
515511
}
516512

517513
break;

test/Runtime/demangleToMetadataObjC.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,10 @@ DemangleToMetadataTests.test("members of runtime-only Objective-C classes") {
9191
_typeByMangledName("So17OS_dispatch_queueC8DispatchE10AttributesV")!)
9292
}
9393

94+
DemangleToMetadataTests.test("runtime conformance lookup via foreign superclasses") {
95+
expectEqual(Set<CFMutableString>.self,
96+
_typeByMangledName("ShySo18CFMutableStringRefaG")!)
97+
}
98+
9499
runAllTests()
95100

0 commit comments

Comments
 (0)