| |
| // RUN: %empty-directory(%t) |
| // -- Convert <i32 0x...> constants to decimal constants that LLVM will print |
| // RUN: %{python} %utils/chex.py < %s > %t/keypaths.sil |
| // RUN: %target-swift-frontend -module-name keypaths -emit-ir %s | %FileCheck %t/keypaths.sil --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-os |
| |
| sil_stage canonical |
| import Swift |
| |
| public struct S: Hashable { |
| public var x: Int |
| public let y: String |
| public var z: C |
| public var reabstracted: () -> () |
| |
| public func hash(into hasher: inout Hasher) |
| public static func ==(_: S, _: S) -> Bool |
| } |
| public class C: Hashable { |
| public final var x: Int |
| public final let y: String |
| public final var z: S |
| public var w: Int { get set } |
| |
| public init() |
| |
| public func hash(into hasher: inout Hasher) |
| public static func ==(_: C, _: C) -> Bool |
| } |
| |
| public struct G<T> { |
| public var x: T { get set } |
| public subscript<U: Hashable>(x: U) -> T { get set } |
| } |
| |
| public class C1: C { } |
| public class C2: C1 { |
| public var reabstracted: () -> () |
| } |
| |
| sil_vtable C {} |
| sil_vtable C1 {} |
| sil_vtable C2 {} |
| |
| // CHECK: %TSi = type <{ [[WORD:i.*]] }> |
| |
| // -- %a: S.x |
| // CHECK: [[KP_A:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic 8keypaths1SV" |
| // CHECK-SAME: @"symbolic Si |
| // -- instantiable in-line, size 4 |
| // CHECK-SAME: <i32 0x8000_0004>, |
| // -- offset of S.x, mutable |
| // CHECK-SAME: <i32 0x0180_0000> }> |
| |
| // -- %b: S.y |
| // CHECK: [[KP_B:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic 8keypaths1SV |
| // CHECK-SAME: @"symbolic SS |
| // -- instantiable in-line, size 4 |
| // CHECK-SAME: <i32 0x8000_0004>, |
| // -- offset of S.y, immutable |
| // CHECK-32-SAME: <i32 0x0100_0004> }> |
| // CHECK-64-SAME: <i32 0x0100_0008> }> |
| |
| // -- %c: S.z |
| // CHECK: [[KP_C:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic 8keypaths1SV |
| // CHECK-SAME: @"symbolic 8keypaths1CC |
| // -- instantiable in-line, size 4 |
| // CHECK-SAME: <i32 0x8000_0004>, |
| // -- offset of S.z, mutable |
| // CHECK-32-SAME: <i32 0x0180_0010> }> |
| // CHECK-64-SAME: <i32 0x0180_0018> }> |
| |
| // -- %d: C.x |
| // CHECK: [[KP_D:@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 |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: @"symbolic |
| // -- instantiable in-line, size 4 |
| // CHECK-SAME: <i32 0x8000_0004>, |
| // -- 0x0300_0000 (class) + immutable + offset of C.y |
| // CHECK-32-SAME: <i32 0x0300_000c> }> |
| // CHECK-64-SAME: <i32 0x0300_0018> }> |
| |
| // -- %f: C.z |
| // CHECK: [[KP_F:@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.z |
| // CHECK-32-SAME: <i32 0x0380_0018> }> |
| // CHECK-64-SAME: <i32 0x0380_0028> }> |
| |
| // -- %g: S.z.x |
| // CHECK: [[KP_G:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: @"symbolic |
| // -- instantiable in-line, size 12 |
| // CHECK-SAME: <i32 0x8000_000c>, |
| // -- offset of S.z |
| // CHECK-32-SAME: <i32 0x0180_0010>, |
| // CHECK-64-SAME: <i32 0x0180_0018>, |
| // CHECK: @"symbolic |
| // -- 0x0300_0000 (class) + offset of C.x |
| // CHECK-32-SAME: <i32 0x0380_0008> }> |
| // CHECK-64-SAME: <i32 0x0380_0010> }> |
| |
| // -- %h: C.z.x |
| // CHECK: [[KP_H:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: <i32 0x8000_000c>, |
| // -- 0x0300_0000 (class) + offset of C.z |
| // CHECK-32-SAME: <i32 0x0380_0018>, |
| // CHECK-64-SAME: <i32 0x0380_0028>, |
| // CHECK: @"symbolic |
| // -- offset of S.x |
| // CHECK-SAME: <i32 0x0180_0000> }> |
| |
| // -- %k: computed |
| // CHECK: [[KP_K:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: @"symbolic |
| // -- instantiable in-line, size 12 |
| // CHECK-SAME: <i32 0x8000_000c>, |
| // -- computed, get-only, identified by (indirected) function pointer, no args |
| // CHECK-SAME: <i32 0x0200_0002>, |
| // CHECK-SAME: @got.k_id |
| // CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* @k_get |
| |
| // -- %l: computed |
| // CHECK: [[KP_L:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: @"symbolic |
| // -- instantiable in-line, size 16 |
| // CHECK-SAME: <i32 0x8000_0010>, |
| // -- computed, settable, nonmutating, identified by indirect pointer, no args |
| // CHECK-SAME: <i32 0x0240_0002>, |
| // CHECK-SAME: @"got.$s8keypaths1CC1wSivgTq" |
| // CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_get |
| // CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set |
| |
| // -- %m: computed |
| // CHECK: [[KP_M:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: [[WORD]]* @keypath_once |
| // CHECK-SAME: @"symbolic |
| // CHECK-SAME: @"symbolic |
| // -- instantiable in-line, size 16 |
| // CHECK-SAME: <i32 0x8000_0010>, |
| // -- computed, settable, nonmutating, identified by property offset, no args |
| // CHECK-SAME: <i32 0x02e0_0000>, |
| // CHECK-SAME: [[WORD]] |
| // CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_get |
| // CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_set |
| |
| // -- %m2: reabstracted |
| // Note: the contents here aren't interesting. The test triggered infinite |
| // looping in the compiler at one point. |
| // CHECK: [[KP_M:@keypath.*]] = private global <{ {{.*}} }> <{ |
| |
| // -- %i: Gen<A>.x |
| // CHECK: [[KP_I:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: i32 0 |
| // CHECK-SAME: @"generic environment l" |
| // CHECK-SAME: @"symbolic 8keypaths3GenVyxxG" |
| // CHECK-SAME: @"symbolic x" |
| // -- size 8 |
| // CHECK-SAME: i32 8, |
| // -- struct with runtime-resolved offset, mutable |
| // CHECK-SAME: <i32 0x01fffffe>, |
| // CHECK-32-SAME: i32 16 }> |
| // CHECK-64-SAME: i32 32 }> |
| |
| // -- %j: Gen<A>.y |
| // CHECK: [[KP_J:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ |
| // CHECK-SAME: i32 0 |
| // CHECK-SAME: @"generic environment l" |
| // CHECK-SAME: @"symbolic 8keypaths3GenVyxxG" |
| // CHECK-SAME: @"symbolic x" |
| // -- size 8 |
| // CHECK-SAME: i32 8, |
| // -- struct with runtime-resolved offset |
| // CHECK-SAME: <i32 0x01fffffe>, |
| // CHECK-32-SAME: i32 20 }> |
| // CHECK-64-SAME: i32 36 }> |
| |
| // CHECK-LABEL: @"generic environment SHRzSHR_r0_l" = linkonce_odr hidden constant |
| // CHECK-SAME: i32 8193, i16 2, i8 -128, i8 -128, i32 128 |
| |
| // -- %t |
| // CHECK: [[KP_T:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ {{.*}} i32 1, {{.*}} @"got.$s8keypaths1GV1xxvpMV" |
| // CHECK-SAME: @"symbolic x" |
| // -- computed get-only property, identified by indirect pointer |
| // CHECK-SAME: <i32 0x0208_0002> |
| |
| // -- %u |
| // CHECK: [[KP_U:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ {{.*}} i32 3, {{.*}} @"got.$s8keypaths1GVyxqd__cSHRd__luipMV" |
| // CHECK-SAME: @"symbolic q_" |
| // CHECK-SAME: @"symbolic x" |
| // CHECK-SAME: @"keypath_get_witness_table |
| // -- computed get-only property, identified by indirect pointer |
| // CHECK-SAME: <i32 0x0208_0002> |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @stored_property_fixed_offsets() |
| sil @stored_property_fixed_offsets : $@convention(thin) () -> () { |
| entry: |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_A]] to i8*), i8* undef) |
| %a = keypath $KeyPath<S, Int>, (root $S; stored_property #S.x : $Int) |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_B]] to i8*), i8* undef) |
| %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_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) |
| %f = keypath $KeyPath<C, S>, (root $C; stored_property #C.z : $S) |
| |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_G]] to i8*), i8* undef) |
| %g = keypath $KeyPath<S, Int>, (root $S; stored_property #S.z : $C; stored_property #C.x : $Int) |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_H]] to i8*), i8* undef) |
| %h = keypath $KeyPath<C, Int>, (root $C; stored_property #C.z : $S; stored_property #S.x : $Int) |
| |
| %k = keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int) |
| %l = keypath $KeyPath<C, Int>, (root $C; settable_property $Int, id #C.w!getter.1, getter @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) |
| %m = keypath $KeyPath<S, () -> ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed () -> @out (), setter @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout S) -> ()) |
| %m2 = keypath $KeyPath<C2, () -> ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed () -> @out (), setter @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout C2) -> ()) |
| |
| return undef : $() |
| } |
| |
| sil @k_id : $@convention(thin) () -> () |
| sil @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int { |
| bb0(%0 : @trivial $*Int, %1 : @trivial $*S): |
| unreachable |
| } |
| |
| sil @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int { |
| bb0(%0 : @trivial $*Int, %1 : @trivial $*C): |
| unreachable |
| } |
| |
| sil @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () { |
| bb0(%0 : @trivial $*Int, %1 : @trivial $*C): |
| unreachable |
| } |
| |
| sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed () -> @out () { |
| bb0(%0 : @trivial $*@callee_guaranteed () -> @out (), %1 : @trivial $*S): |
| unreachable |
| } |
| |
| sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout S) -> () { |
| bb0(%0 : @trivial $*@callee_guaranteed () -> @out (), %1 : @trivial $*S): |
| unreachable |
| } |
| |
| sil @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed () -> @out () |
| sil @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout C2) -> () |
| |
| struct Gen<T, U> { |
| var x: T |
| var y: U |
| } |
| |
| struct Foo<T> { |
| var foo: T |
| } |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @stored_property_generics(%swift.type* %T, %swift.type* %U) |
| sil @stored_property_generics : $@convention(thin) <T, U> () -> () { |
| entry: |
| // CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to |
| // CHECK: store %swift.type* %T, %swift.type** [[PTR]] |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_I]] to i8*), i8* [[ARGS]]) |
| %i = keypath $KeyPath<Gen<T,T>, T>, <A> (root $Gen<A, A>; stored_property #Gen.x : $A) <T> |
| |
| // CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to |
| // CHECK: store %swift.type* %U, %swift.type** [[PTR]] |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_J]] to i8*), i8* [[ARGS]]) |
| %j = keypath $KeyPath<Gen<U,U>, U>, <A> (root $Gen<A, A>; stored_property #Gen.y : $A) <U> |
| |
| // CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to |
| // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8keypaths3FooVMa"([[WORD]] 0, %swift.type* %T) |
| // CHECK: [[FOO_T:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 |
| // CHECK: store %swift.type* [[FOO_T]], %swift.type** [[PTR]] |
| // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_I]] to i8*), i8* [[ARGS]]) |
| %i2 = keypath $KeyPath<Gen<Foo<T>,Foo<T>>, Foo<T>>, <A> (root $Gen<A, A>; stored_property #Gen.x : $A) <Foo<T>> |
| |
| return undef : $() |
| } |
| |
| // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @computed_property_generics |
| sil @computed_property_generics : $@convention(thin) <T, U> () -> () { |
| entry: |
| %n = keypath $WritableKeyPath<T, U>, <UUU, TTT> (root $TTT; settable_property $UUU, id @n_get : $@convention(thin) <UU, TT> (@in_guaranteed TT) -> @out UU, getter @n_get : $@convention(thin) <UU, TT> (@in_guaranteed TT) -> @out UU, setter @n_set : $@convention(thin) <UU, TT> (@in_guaranteed UU, @in_guaranteed TT) -> ()) <U, T> |
| |
| return undef : $() |
| } |
| |
| sil @n_get : $@convention(thin) <UU, TT> (@in_guaranteed TT) -> @out UU |
| sil @n_set : $@convention(thin) <UU, TT> (@in_guaranteed UU, @in_guaranteed TT) -> () |
| |
| sil @computed_property_indices : $@convention(thin) (C, S, C, S, C, S) -> () { |
| entry(%0 : @unowned $C, %1 : @unowned $S, %2 : @unowned $C, %3 : @unowned $S, %4 : @unowned $C, %5 : @unowned $S): |
| %o = keypath $WritableKeyPath<S, C>, ( |
| root $S; |
| settable_property $C, |
| id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, |
| getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, |
| setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), |
| indices [%$0 : $C : $C], |
| indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int |
| ) (%0) |
| %p = keypath $WritableKeyPath<S, C>, ( |
| root $S; |
| settable_property $C, |
| id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, |
| getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, |
| setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), |
| indices [%$0 : $S : $S, %$1 : $C : $C], |
| indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int |
| ) (%1, %2) |
| %r = keypath $WritableKeyPath<S, S>, ( |
| root $S; |
| settable_property $C, |
| id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, |
| getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, |
| setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), |
| indices [%$0 : $S : $S, %$1 : $C : $C], |
| indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int; |
| settable_property $S, |
| id @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S, |
| getter @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S, |
| setter @r_set : $@convention(thin) (@in_guaranteed S, @in_guaranteed C, UnsafeRawPointer) -> (), |
| indices [%$2 : $S : $S], |
| indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int |
| ) (%3, %4, %5) |
| |
| return undef : $() |
| } |
| |
| sil @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C |
| sil @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> () |
| sil @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool |
| sil @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int |
| |
| sil @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S |
| sil @r_set : $@convention(thin) (@in_guaranteed S, @in_guaranteed C, UnsafeRawPointer) -> () |
| |
| sil @generic_computed_property_indices : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B) -> () { |
| entry(%0 : @trivial $*A, %1 : @trivial $*B, %2 : @trivial $*A, %3 : @trivial $*B, %4 : @trivial $*A, %5 : @trivial $*B): |
| %s = keypath $WritableKeyPath<A, B>, <X: Hashable, Y: Hashable> ( |
| root $X; |
| settable_property $Y, |
| id @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, UnsafeRawPointer) -> @out U, |
| getter @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, UnsafeRawPointer) -> @out U, |
| setter @s_set : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), |
| indices [%$0 : $X : $*X], |
| indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int |
| ) <A, B> (%0) |
| %t = keypath $WritableKeyPath<A, B>, <X: Hashable, Y: Hashable> ( |
| root $X; |
| settable_property $Y, |
| id @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, UnsafeRawPointer) -> @out U, |
| getter @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, UnsafeRawPointer) -> @out U, |
| setter @s_set : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), |
| indices [%$0 : $Y : $*Y, %$1 : $X : $*X], |
| indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int |
| ) <A, B> (%1, %2) |
| %v = keypath $WritableKeyPath<A, A>, <X: Hashable, Y: Hashable> ( |
| root $X; |
| settable_property $Y, |
| id @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, UnsafeRawPointer) -> @out U, |
| getter @s_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, UnsafeRawPointer) -> @out U, |
| setter @s_set : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), |
| indices [%$0 : $Y : $*Y, %$1 : $X : $*X], |
| indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int; |
| settable_property $X, |
| id @v_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed U, UnsafeRawPointer) -> @out T, |
| getter @v_get : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed U, UnsafeRawPointer) -> @out T, |
| setter @v_set : $@convention(thin) <T: Hashable, U: Hashable> (@in_guaranteed T, @in_guaranteed U, UnsafeRawPointer) -> (), |
| indices [%$2 : $Y : $*Y], |
| indices_equals @s_equals : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @s_hash : $@convention(thin) <T: Hashable, U: Hashable> (UnsafeRawPointer) -> Int |
| ) <A, B> (%3, %4, %5) |
| |
| return undef : $() |
| } |
| |
| sil @generic_external : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B) -> () { |
| entry(%0 : @trivial $*A, %1 : @trivial $*B, %2 : @trivial $*A, %3 : @trivial $*B, %4 : @trivial $*A, %5 : @trivial $*B): |
| %t = keypath $KeyPath<G<B>, B>, <Z> ( |
| root $G<Z>; |
| gettable_property $Z, |
| id @g_x_get : $@convention(thin) <Z> (@in_guaranteed G<Z>) -> @out Z, |
| getter @g_x_get : $@convention(thin) <Z> (@in_guaranteed G<Z>) -> @out Z, |
| external #G.x<Z> |
| ) <B> |
| |
| %u = keypath $KeyPath<G<A>, A>, <X: Hashable, Y: Hashable> ( |
| root $G<Y>; |
| gettable_property $Y, |
| id @g_subscript_get : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed G<B>, UnsafeRawPointer) -> @out B, |
| getter @g_subscript_get : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed G<B>, UnsafeRawPointer) -> @out B, |
| indices [%$0 : $X : $*X], |
| indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, |
| indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int, |
| external #G.subscript<Y, X> |
| ) <B, A> (%1) |
| |
| return undef : $() |
| } |
| |
| sil @identity : $@convention(thin) <T> () -> () { |
| entry: |
| %v = keypath $WritableKeyPath<T, T>, <A> (root $A; objc "self") <T> |
| %w = keypath $WritableKeyPath<Int, Int>, (root $Int; objc "self") |
| |
| return undef : $() |
| } |
| |
| sil @s_get : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed A, UnsafeRawPointer) -> @out B |
| sil @s_set : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed B, @in_guaranteed A, UnsafeRawPointer) -> () |
| sil @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool |
| sil @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int |
| |
| sil @v_get : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed B, UnsafeRawPointer) -> @out A |
| sil @v_set : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed A, @in_guaranteed B, UnsafeRawPointer) -> () |
| |
| sil @g_x_get : $@convention(thin) <Z> (@in_guaranteed G<Z>) -> @out Z |
| sil @g_subscript_get : $@convention(thin) <A: Hashable, B: Hashable> (@in_guaranteed G<B>, UnsafeRawPointer) -> @out B |