blob: 47476d7e616377ab40411590ff66be5ace88278d [file] [log] [blame]
// 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: () -> ()
}
public struct T {
public var a: (Int, String)
public let b: (f: String, g: Int)
}
public struct TG<T, U, V> {
public var a: (T, U, V)
}
typealias TGA<T, U> = (a: T, b: U)
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> }>
// -- %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
// 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.|__imp_}}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.|__imp_}}$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 <{ {{.*}} }> <{
// -- %t0: T.a.0
// CHECK: [[KP_T0:@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 T.a, mutable
// CHECK-SAME: <i32 0x0180_0000>,
// CHECK: @"symbolic
// -- tuple element #0 of T.a
// CHECK-SAME: <i32 0x0180_0000> }>
// -- %t1: T.b.g
// CHECK: [[KP_T1:@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 T.b
// CHECK-32-SAME: <i32 0x0100_0010>,
// CHECK-64-SAME: <i32 0x0100_0018>,
// CHECK: @"symbolic
// -- tuple element #1 of T.b
// CHECK-32-SAME: <i32 0x0180_000c> }>
// CHECK-64-SAME: <i32 0x0180_0010> }>
// -- %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 }>
// -- %tg0: TG<T,U,V>.a.0
// CHECK: [[KP_TG0:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: @"generic environment r1_l"
// CHECK-SAME: @"symbolic
// CHECK-SAME: @"symbolic
// -- struct with runtime-resolved offset, mutable
// CHECK-SAME: <i32 0x01ff_fffe>,
// -- offset of TG.a
// CHECK-32-SAME: i32 20
// CHECK-64-SAME: i32 40
// CHECK-SAME: @"symbolic
// -- tuple element with compile-time known offset, mutable
// -- tuple element #0 of TG.a
// CHECK-SAME: <i32 0x0180_0000> }>
// -- %tg1: TG<T,U,V>.a.2
// CHECK: [[KP_TG1:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: @"generic environment r1_l"
// CHECK-SAME: @"symbolic
// CHECK-SAME: @"symbolic
// -- struct with runtime-resolved offset, mutable
// CHECK-SAME: <i32 0x01ff_fffe>,
// -- offset of TG.a
// CHECK-32-SAME: i32 20
// CHECK-64-SAME: i32 40
// CHECK-SAME: @"symbolic
// -- tuple element with runtime-resolved offset, mutable
// CHECK-SAME: <i32 0x01ff_fffe>,
// -- tuple element #2 of TG.a
// CHECK-32-SAME: i32 32 }>
// CHECK-64-SAME: i32 64 }>
// -- %tg2: TGA<T,U>.1
// CHECK: [[KP_TG2:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
// CHECK-SAME: @"generic environment r0_l"
// CHECK-SAME: @"symbolic
// CHECK-SAME: @"symbolic
// -- tuple element with runtime-resolved offset, mutable
// CHECK-SAME: <i32 0x01ff_fffe>,
// -- tuple element #1 of TGA
// CHECK-32-SAME: i32 24 }>
// CHECK-64-SAME: i32 48 }>
// CHECK-LABEL: @"generic environment SHRzSHR_r0_l" = linkonce_odr hidden constant
// CHECK-SAME: i32 8193, i16 2, i8 -128, i8 -128, i32 128
// 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_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)
%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) -> ())
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_T0]] to i8*), i8* undef)
%t0 = keypath $KeyPath<T, Int>, (root $T; stored_property #T.a : $(Int, String); tuple_element #0 : $Int)
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_T1]] to i8*), i8* undef)
%t1 = keypath $KeyPath<T, Int>, (root $T; stored_property #T.b : $(f: String, g: Int); tuple_element #1 : $Int)
return undef : $()
}
sil @k_id : $@convention(thin) () -> ()
sil @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int {
bb0(%0 : $*Int, %1 : $*S):
unreachable
}
sil @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int {
bb0(%0 : $*Int, %1 : $*C):
unreachable
}
sil @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () {
bb0(%0 : $*Int, %1 : $*C):
unreachable
}
sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed () -> @out () {
bb0(%0 : $*@callee_guaranteed () -> @out (), %1 : $*S):
unreachable
}
sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout S) -> () {
bb0(%0 : $*@callee_guaranteed () -> @out (), %1 : $*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 @tuple_generics(%swift.type* %T, %swift.type* %U, %swift.type* %V)
sil @tuple_generics : $@convention(thin) <T, U, V> () -> () {
entry:
// CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to
// CHECK: store %swift.type* %T, %swift.type** [[PTR]]
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_TG0]] to i8*), i8* [[ARGS]])
%tg0 = keypath $KeyPath<TG<T,U,V>, T>, <A,B,C> (root $TG<A,B,C>; stored_property #TG.a : $(A,B,C); tuple_element #0 : $A) <T,U,V>
// CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to
// CHECK: store %swift.type* %T, %swift.type** [[PTR]]
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_TG1]] to i8*), i8* [[ARGS]])
%tg1 = keypath $KeyPath<TG<T,U,V>, V>, <A,B,C> (root $TG<A,B,C>; stored_property #TG.a : $(A,B,C); tuple_element #2 : $C) <T,U,V>
// CHECK: [[PTR:%.*]] = bitcast i8* [[ARGS:%.*]] to
// CHECK: store %swift.type* %T, %swift.type** [[PTR]]
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_TG2]] to i8*), i8* [[ARGS]])
%tg2 = keypath $KeyPath<TGA<T,U>, U>, <A,B> (root $TGA<A,B>; tuple_element #1 : $B) <T,U>
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 : $C, %1 : $S, %2 : $C, %3 : $S, %4 : $C, %5 : $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 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*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 @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) -> ()