Merge pull request #21615 from DougGregor/runtime-demangle-generic-objc-class-5.0
[5.0] [Runtime] Correctly match demangle tree for generic Objective-C classes.
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index 569e8d7..00b8a20 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -837,6 +837,15 @@
// ObjC-ness and resilience of the class hierarchy, there might be a few
// different ways we need to go about this.
if (loweredBaseTy.getClassOrBoundGenericClass()) {
+
+ // Use the property's class type to determine the field access.
+ auto propertyBaseDecl = property->getDeclContext()->getSelfClassDecl();
+ auto currentBaseTy =
+ loweredBaseTy.getASTType()->getSuperclassForDecl(propertyBaseDecl);
+ assert(currentBaseTy->getClassOrBoundGenericClass() == propertyBaseDecl);
+ loweredBaseTy =
+ IGM.getLoweredType(AbstractionPattern::getOpaque(), currentBaseTy);
+
switch (getClassFieldAccess(IGM, loweredBaseTy, property)) {
case FieldAccess::ConstantDirect: {
// Known constant fixed offset.
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index e79ad5b..6e37c05 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -87,6 +87,17 @@
// CHECK-32-SAME: <i32 0x0380_0008> }>
// CHECK-64-SAME: <i32 0x0380_0010> }>
+// -- %d1: C1.x
+// CHECK: [[KP_D1:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
+// -- instantiable in-line, size 4
+// CHECK-SAME: <i32 0x8000_0004>,
+// -- 0x0300_0000 (class) + mutable + offset of C.x
+// CHECK-32-SAME: <i32 0x0380_0008> }>
+// CHECK-64-SAME: <i32 0x0380_0010> }>
+
// -- %e: C.y
// CHECK: [[KP_E:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: [[WORD]]* @keypath_once
@@ -232,9 +243,10 @@
%b = keypath $KeyPath<S, String>, (root $S; stored_property #S.y : $String)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_C]] to i8*), i8* undef)
%c = keypath $KeyPath<S, C>, (root $S; stored_property #S.z : $C)
-
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_D]] to i8*), i8* undef)
%d = keypath $KeyPath<C, Int>, (root $C; stored_property #C.x : $Int)
+ // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_D1]] to i8*), i8* undef)
+ %d1 = keypath $KeyPath<C1, Int>, (root $C1; stored_property #C.x : $Int)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_E]] to i8*), i8* undef)
%e = keypath $KeyPath<C, String>, (root $C; stored_property #C.y : $String)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_F]] to i8*), i8* undef)