mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
277 lines
11 KiB
Plaintext
277 lines
11 KiB
Plaintext
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
|
|
// TODO: 32-bit support
|
|
// REQUIRES: PTRSIZE=64
|
|
|
|
sil_stage canonical
|
|
import Swift
|
|
|
|
struct S {
|
|
var x: Int
|
|
let y: String
|
|
var z: C
|
|
var reabstracted: () -> ()
|
|
}
|
|
class C {
|
|
final var x: Int
|
|
final let y: String
|
|
final var z: S
|
|
var w: Int { get set }
|
|
|
|
init()
|
|
}
|
|
|
|
sil_vtable C {}
|
|
|
|
// CHECK: %TSi = type <{ [[WORD:i.*]] }>
|
|
|
|
// -- %a: S.x
|
|
// CHECK: [[KP_A:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0018 - instantiable in-line, size 4
|
|
// CHECK-SAME: i32 -2147483644,
|
|
// -- offset of S.x
|
|
// CHECK-SAME: i32 0 }>
|
|
|
|
// -- %b: S.y
|
|
// CHECK: [[KP_B:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0018 - instantiable in-line, size 4
|
|
// CHECK-SAME: i32 -2147483644,
|
|
// -- offset of S.y
|
|
// CHECK-32-SAME: i32 4 }>
|
|
// CHECK-64-SAME: i32 8 }>
|
|
|
|
// -- %c: S.z
|
|
// CHECK: [[KP_C:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0018 - instantiable in-line, size 4
|
|
// CHECK-SAME: i32 -2147483644,
|
|
// -- offset of S.z
|
|
// CHECK-32-SAME: i32 16 }>
|
|
// CHECK-64-SAME: i32 32 }>
|
|
|
|
// -- %d: C.x
|
|
// CHECK: [[KP_D:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0018 - instantiable in-line, size 4
|
|
// CHECK-SAME: i32 -2147483644,
|
|
// -- 0x4000_0000 (class) + offset of C.x
|
|
// CHECK-32-SAME: i32 1073741832 }>
|
|
// CHECK-64-SAME: i32 1073741840 }>
|
|
|
|
// -- %e: C.y
|
|
// CHECK: [[KP_E:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0018 - instantiable in-line, size 4
|
|
// CHECK-SAME: i32 -2147483644,
|
|
// -- 0x4000_0000 (class) + offset of C.y
|
|
// CHECK-32-SAME: i32 1073741836 }>
|
|
// CHECK-64-SAME: i32 1073741848 }>
|
|
|
|
// -- %f: C.z
|
|
// CHECK: [[KP_F:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0018 - instantiable in-line, size 4
|
|
// CHECK-SAME: i32 -2147483644,
|
|
// -- 0x4000_0000 (class) + offset of C.z
|
|
// CHECK-32-SAME: i32 1073741848 }>
|
|
// CHECK-64-SAME: i32 1073741872 }>
|
|
|
|
// -- %g: S.z.x
|
|
// CHECK: [[KP_G:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0010 - instantiable in-line, size 12
|
|
// CHECK-32-SAME: i32 -2147483636,
|
|
// -- 0x8000_0018 - instantiable in-line, size 16
|
|
// CHECK-64-SAME: i32 -2147483632,
|
|
// -- offset of S.z
|
|
// CHECK-32-SAME: i32 16,
|
|
// CHECK-64-SAME: i32 32,
|
|
// CHECK: %swift.type* (i8*)*
|
|
// -- 0x4000_0000 (class) + offset of C.x
|
|
// CHECK-32-SAME: i32 1073741832 }>
|
|
// CHECK-64-SAME: i32 1073741840 }>
|
|
|
|
// -- %h: C.z.x
|
|
// CHECK: [[KP_H:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0010 - instantiable in-line, size 12
|
|
// CHECK-32-SAME: i32 -2147483636,
|
|
// -- 0x8000_0018 - instantiable in-line, size 16
|
|
// CHECK-64-SAME: i32 -2147483632,
|
|
// -- 0x4000_0000 (class) + offset of C.z
|
|
// CHECK-32-SAME: i32 1073741848,
|
|
// CHECK-64-SAME: i32 1073741872,
|
|
// CHECK: %swift.type* (i8*)*
|
|
// -- offset of S.x
|
|
// CHECK-SAME: i32 0 }>
|
|
|
|
// -- %k: computed
|
|
// CHECK: [[KP_K:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_0014 - instantiable in-line, size 20
|
|
// CHECK-64-SAME: i32 -2147483628,
|
|
// -- 0x8000_000c - instantiable in-line, size 12
|
|
// CHECK-32-SAME: i32 -2147483640,
|
|
// -- 0x2000_0000 - computed, get-only, identified by function pointer, no args
|
|
// CHECK-SAME: i32 536870912,
|
|
// CHECK-SAME: void ()* @k_id,
|
|
// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* @k_get }>
|
|
|
|
// -- %l: computed
|
|
// CHECK: [[KP_L:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_001c - instantiable in-line, size 28
|
|
// CHECK-64-SAME: i32 -2147483620,
|
|
// -- 0x8000_0010 - instantiable in-line, size 16
|
|
// CHECK-32-SAME: i32 -2147483636,
|
|
// -- 0x2a00_0000 - computed, settable, nonmutating, identified by vtable, no args
|
|
// CHECK-SAME: i32 704643072,
|
|
// CHECK-SAME: [[WORD]]
|
|
// 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]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// CHECK-SAME: %swift.type* (i8*)*
|
|
// -- 0x8000_001c - instantiable in-line, size 28
|
|
// CHECK-64-SAME: i32 -2147483620,
|
|
// -- 0x8000_0010 - instantiable in-line, size 16
|
|
// CHECK-32-SAME: i32 -2147483636,
|
|
// -- 0x3c00_0000 - computed, settable, nonmutating, identified by property offset, no args
|
|
// CHECK-SAME: i32 1006632960,
|
|
// CHECK-SAME: [[WORD]]
|
|
// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_get,
|
|
// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_set }>
|
|
|
|
|
|
// -- %i: Gen<A>.x
|
|
// CHECK: [[KP_I:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)* [[I_GET_GEN_A_A:@[a-z_.0-9]+]],
|
|
// CHECK-SAME: %swift.type* (i8*)* [[I_GET_A:@[a-z_.0-9]+]],
|
|
// -- size 8
|
|
// CHECK-SAME: i32 8,
|
|
// -- 0x1ffffffe - struct with runtime-resolved offset
|
|
// CHECK-SAME: i32 536870910,
|
|
// CHECK-32-SAME: i32 12 }>
|
|
// CHECK-64-SAME: i32 24 }>
|
|
|
|
// -- %j: Gen<A>.y
|
|
// CHECK: [[KP_J:@keypath.*]] = private global <{ {{.*}} }> <{
|
|
// CHECK-SAME: [[WORD]] 0,
|
|
// CHECK-SAME: %swift.type* (i8*)* [[J_GET_GEN_A_A:@[a-z_.0-9]+]],
|
|
// CHECK-SAME: %swift.type* (i8*)* [[J_GET_A:@[a-z_.0-9]+]],
|
|
// -- size 8
|
|
// CHECK-SAME: i32 8,
|
|
// -- 0x1ffffffe - struct with runtime-resolved offset
|
|
// CHECK-SAME: i32 536870910,
|
|
// CHECK-32-SAME: i32 16 }>
|
|
// CHECK-64-SAME: i32 32 }>
|
|
|
|
// CHECK-LABEL: define{{( 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 S) -> @out Int)
|
|
%l = keypath $KeyPath<C, Int>, (root $C; settable_property $Int, id #C.w!getter.1, getter @l_get : $@convention(thin) (@in C) -> @out Int, setter @l_set : $@convention(thin) (@in Int, @in C) -> ())
|
|
%m = keypath $KeyPath<S, () -> ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in S) -> @out @callee_owned (@in ()) -> @out (), setter @m_set : $@convention(thin) (@in @callee_owned (@in ()) -> @out (), @inout S) -> ())
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
sil @k_id : $@convention(thin) () -> ()
|
|
sil @k_get : $@convention(thin) (@in S) -> @out Int
|
|
|
|
sil @l_get : $@convention(thin) (@in C) -> @out Int
|
|
sil @l_set : $@convention(thin) (@in Int, @in C) -> ()
|
|
|
|
sil @m_get : $@convention(thin) (@in S) -> @out @callee_owned (@in ()) -> @out ()
|
|
sil @m_set : $@convention(thin) (@in @callee_owned (@in ()) -> @out (), @inout S) -> ()
|
|
|
|
struct Gen<T, U> {
|
|
var x: T
|
|
var y: U
|
|
}
|
|
|
|
struct Foo<T> {
|
|
var foo: T
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} swiftcc void @stored_property_generics(%swift.type* %T, %swift.type* %U)
|
|
sil @stored_property_generics : $@convention(thin) <T, U> () -> () {
|
|
entry:
|
|
// CHECK: [[PTR:%.*]] = bitcast [1 x %swift.type*]* [[ARGS:%.*]] to
|
|
// CHECK: store %swift.type* %T, %swift.type** [[PTR]]
|
|
// CHECK: [[ARGS_I8:%.*]] = bitcast [1 x %swift.type*]* [[ARGS]] to
|
|
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_I]] to i8*), i8* [[ARGS_I8]])
|
|
%i = keypath $KeyPath<Gen<T,T>, T>, <A> (root $Gen<A, A>; stored_property #Gen.x : $A) <T>
|
|
|
|
// CHECK: [[PTR:%.*]] = bitcast [1 x %swift.type*]* [[ARGS:%.*]] to
|
|
// CHECK: store %swift.type* %U, %swift.type** [[PTR]]
|
|
// CHECK: [[ARGS_I8:%.*]] = bitcast [1 x %swift.type*]* [[ARGS]] to
|
|
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_J]] to i8*), i8* [[ARGS_I8]])
|
|
%j = keypath $KeyPath<Gen<U,U>, U>, <A> (root $Gen<A, A>; stored_property #Gen.y : $A) <U>
|
|
|
|
// CHECK: [[PTR:%.*]] = bitcast [1 x %swift.type*]* [[ARGS:%.*]] to
|
|
// CHECK: [[FOO_T:%.*]] = call %swift.type* @_T08keypaths3FooVMa(%swift.type* %T)
|
|
// CHECK: store %swift.type* [[FOO_T]], %swift.type** [[PTR]]
|
|
// CHECK: [[ARGS_I8:%.*]] = bitcast [1 x %swift.type*]* [[ARGS]] to
|
|
// CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_I]] to i8*), i8* [[ARGS_I8]])
|
|
%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: define private %swift.type* [[I_GET_GEN_A_A]](i8*)
|
|
// CHECK: [[BUF:%.*]] = bitcast i8* %0
|
|
// CHECK: [[A:%.*]] = load %swift.type*, %swift.type** [[BUF]]
|
|
// CHECK: [[GEN:%.*]] = call %swift.type* @_T08keypaths3GenVMa(%swift.type* [[A]], %swift.type* [[A]])
|
|
// CHECK: ret %swift.type* [[GEN]]
|
|
|
|
|
|
// CHECK: define private %swift.type* [[I_GET_A]](i8*)
|
|
// CHECK: [[BUF:%.*]] = bitcast i8* %0
|
|
// CHECK: [[A:%.*]] = load %swift.type*, %swift.type** [[BUF]]
|
|
// CHECK: ret %swift.type* [[A]]
|