mirror of
https://github.com/apple/swift.git
synced 2026-06-27 12:25:55 +02:00
16484c9be5
rdar://34222540
202 lines
15 KiB
Plaintext
202 lines
15 KiB
Plaintext
// REQUIRES: plus_zero_runtime
|
|
|
|
// First parse this and then emit a *.sib. Then read in the *.sib, then recreate
|
|
// RUN: %empty-directory(%t)
|
|
// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name boxes
|
|
// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.2.sib -module-name boxes
|
|
// RUN: %target-sil-opt %t/tmp.2.sib -module-name boxes | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Swift
|
|
|
|
struct S: Hashable {
|
|
var x: Int
|
|
let y: String
|
|
var z: C
|
|
|
|
var hashValue: Int { get }
|
|
static func ==(x: S, y: S) -> Bool
|
|
}
|
|
class C: Hashable {
|
|
final var x: Int
|
|
final let y: String
|
|
final var z: S
|
|
|
|
init()
|
|
var overridable: Int {
|
|
get set
|
|
}
|
|
|
|
var hashValue: Int { get }
|
|
static func ==(x: C, y: C) -> Bool
|
|
}
|
|
|
|
protocol P {}
|
|
protocol Q {}
|
|
protocol R {}
|
|
|
|
struct Gen<A: P, B: Q, C: R> {
|
|
var x: A
|
|
let y: B
|
|
var z: C
|
|
}
|
|
|
|
public struct External<T> {
|
|
var ro: T { get }
|
|
|
|
subscript<U: Hashable>(ro _: U) -> T { get }
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @stored_properties
|
|
sil shared [serialized] @stored_properties : $@convention(thin) () -> () {
|
|
entry:
|
|
// CHECK: keypath $WritableKeyPath<S, Int>, (root $S; stored_property #S.x : $Int)
|
|
%a = keypath $WritableKeyPath<S, Int>, (root $S; stored_property #S.x : $Int)
|
|
// CHECK: keypath $ReferenceWritableKeyPath<C, Int>, (root $C; stored_property #C.x : $Int)
|
|
%b = keypath $ReferenceWritableKeyPath<C, Int>, (root $C; stored_property #C.x : $Int)
|
|
// CHECK: keypath $KeyPath<S, String>, (root $S; stored_property #S.y : $String)
|
|
%c = keypath $KeyPath<S, String>, (root $S; stored_property #S.y : $String)
|
|
// CHECK: keypath $ReferenceWritableKeyPath<S, Int>, (root $S; stored_property #S.z : $C; stored_property #C.x : $Int)
|
|
%d = keypath $ReferenceWritableKeyPath<S, Int>, (root $S; stored_property #S.z : $C; stored_property #C.x : $Int)
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @stored_properties_generic
|
|
sil shared [serialized] @stored_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> () {
|
|
entry:
|
|
// CHECK: keypath $WritableKeyPath<Gen<D, E, F>, D>, <τ_0_0, τ_0_1, τ_0_2 where {{.*}}> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; stored_property #Gen.x : $τ_0_0) <D, E, F>
|
|
%a = keypath $WritableKeyPath<Gen<D,E,F>, D>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; stored_property #Gen.x : $G) <D, E, F>
|
|
// CHECK: keypath $KeyPath<Gen<D, E, F>, E>, <τ_0_0, τ_0_1, τ_0_2 where {{.*}}> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; stored_property #Gen.y : $τ_0_1) <D, E, F>
|
|
%b = keypath $KeyPath<Gen<D,E,F>, E>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; stored_property #Gen.y : $H) <D, E, F>
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
sil @id_a : $@convention(thin) () -> ()
|
|
sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int
|
|
sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()
|
|
sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int
|
|
sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()
|
|
sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed (@in_guaranteed S) -> @out S) -> @out @callee_guaranteed (@in_guaranteed C) -> @out C
|
|
sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed (@in_guaranteed C) -> @out C, @in_guaranteed @callee_guaranteed (@in_guaranteed S) -> @out S) -> ()
|
|
sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int
|
|
sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> ()
|
|
sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool
|
|
sil @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int
|
|
sil @get_gen_int_subs : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (@in_guaranteed A, UnsafeRawPointer) -> @out C
|
|
sil @set_gen_int_subs : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> ()
|
|
sil @gen_subs_eq : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
|
|
sil @gen_subs_hash : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (UnsafeRawPointer) -> Int
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @computed_properties
|
|
sil shared [serialized] @computed_properties : $@convention(thin) () -> () {
|
|
entry:
|
|
// CHECK: keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int)
|
|
%a = keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int)
|
|
// CHECK: keypath $WritableKeyPath<S, Int>, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ())
|
|
%b = keypath $WritableKeyPath<S, Int>, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ())
|
|
// CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed (@in_guaranteed S) -> @out S) -> @out @callee_guaranteed (@in_guaranteed C) -> @out C, setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed (@in_guaranteed C) -> @out C, @in_guaranteed @callee_guaranteed (@in_guaranteed S) -> @out S) -> ())
|
|
%c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed (@in_guaranteed S) -> @out S) -> @out @callee_guaranteed (@in_guaranteed C) -> @out C, setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed (@in_guaranteed C) -> @out C, @in_guaranteed @callee_guaranteed (@in_guaranteed S) -> @out S) -> ())
|
|
// CHECK: keypath $WritableKeyPath<C, Int>, (root $C; settable_property $Int, id #C.overridable!getter.1 : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ())
|
|
%d = keypath $WritableKeyPath<C, Int>, (root $C; settable_property $Int, id #C.overridable!getter.1 : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ())
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
sil @get_gen_a : $@convention(thin) <X1: P, Y1: Q, Z1: R> (@in_guaranteed Gen<X1, Y1, Z1>) -> @out X1
|
|
sil @set_gen_a : $@convention(thin) <X2: P, Y2: Q, Z2: R> (@in_guaranteed X2, @in_guaranteed Gen<X2, Y2, Z2>) -> ()
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @computed_properties_generic
|
|
sil shared [serialized] @computed_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> () {
|
|
entry:
|
|
// CHECK: keypath $KeyPath<Gen<D, E, F>, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) <D, E, F>
|
|
%a = keypath $KeyPath<Gen<D, E, F>, D>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <X3: P, Y3: Q, Z3: R> (@in_guaranteed Gen<X3, Y3, Z3>) -> @out X3, setter @set_gen_a : $@convention(thin) <X4: P, Y4: Q, Z4: R> (@in_guaranteed X4, @in_guaranteed Gen<X4, Y4, Z4>) -> ()) <D, E, F>
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @optional
|
|
sil shared [serialized] @optional : $@convention(thin) () -> () {
|
|
entry:
|
|
// CHECK: keypath $KeyPath<Optional<Int>, Optional<Int>>, (root $Optional<Int>; optional_chain : $Int; optional_wrap : $Optional<Int>)
|
|
%a = keypath $KeyPath<Optional<Int>, Optional<Int>>, (root $Optional<Int>; optional_chain : $Int; optional_wrap : $Optional<Int>)
|
|
// CHECK: keypath $KeyPath<Optional<Int>, Int>, (root $Optional<Int>; optional_force : $Int)
|
|
%b = keypath $KeyPath<Optional<Int>, Int>, (root $Optional<Int>; optional_force : $Int)
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @indexes
|
|
sil shared [serialized] @indexes : $@convention(thin) (S, C) -> () {
|
|
// CHECK: bb0([[S:%.*]] : $S, [[C:%.*]] : $C):
|
|
entry(%s : $S, %c : $C):
|
|
// CHECK: keypath $KeyPath<S, Int>, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) ([[S]], [[C]])
|
|
%a = keypath $KeyPath<S, Int>, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%s, %c)
|
|
// CHECK: [[T:%.*]] = alloc_stack
|
|
%t = alloc_stack $S
|
|
// CHECK: [[D:%.*]] = alloc_stack
|
|
%d = alloc_stack $C
|
|
// CHECK: keypath $KeyPath<S, Int>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, UnsafeRawPointer) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer) -> Int) <S, C, Int> ([[T]], [[D]])
|
|
%b = keypath $KeyPath<S, Int>, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (@in_guaranteed A, UnsafeRawPointer) -> @out C, setter @set_gen_int_subs : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (UnsafeRawPointer) -> Int) <S, C, Int> (%t, %d)
|
|
|
|
dealloc_stack %d : $*C
|
|
dealloc_stack %t : $*S
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [serialized] @external
|
|
sil shared [serialized] @external : $@convention(thin) <A, B: Hashable> (@in_guaranteed B) -> () {
|
|
entry(%z : $*B):
|
|
// CHECK: %1 = keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.ro<Int> : $Int)
|
|
%a = keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.ro<Int> : $Int)
|
|
|
|
// CHECK: %2 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1, τ_0_2> (root $External<τ_0_2>; external #External.ro<τ_0_2> : $τ_0_2) <A, A, A>
|
|
%b = keypath $KeyPath<External<A>, A>, <C, D, E> (root $External<E>; external #External.ro <E> : $E) <A, A, A>
|
|
|
|
// CHECK: %3 = keypath $KeyPath<External<Int>, Int>, <τ_0_0> (root $External<τ_0_0>; external #External.ro<τ_0_0> : $τ_0_0) <Int>
|
|
%c = keypath $KeyPath<External<Int>, Int>, <F> (root $External<F>; external #External.ro <F> : $F) <Int>
|
|
|
|
// CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1) <B, A> (%0)
|
|
%d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (root $External<H>; external #External.subscript <H, G> [%$0 : $G : $*G] : $H) <B, A> (%z)
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
sil [serialized] @serialize_all : $@convention(thin) () -> () {
|
|
entry:
|
|
%0 = function_ref @stored_properties : $@convention(thin) () -> ()
|
|
%1 = function_ref @stored_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> ()
|
|
%2 = function_ref @computed_properties : $@convention(thin) () -> ()
|
|
%3 = function_ref @computed_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> ()
|
|
%4 = function_ref @optional : $@convention(thin) () -> ()
|
|
%5 = function_ref @indexes : $@convention(thin) (S, C) -> ()
|
|
%6 = function_ref @external : $@convention(thin) <A, B: Hashable> (@in_guaranteed B) -> ()
|
|
|
|
unreachable
|
|
}
|
|
|
|
sil [serialized] @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in_guaranteed External<T>, UnsafeRawPointer) -> @out T
|
|
sil [serialized] @equals_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
|
|
sil [serialized] @hash_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer) -> Int
|
|
|
|
// CHECK-LABEL: sil_property [serialized] #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0)
|
|
sil_property [serialized] #External.ro <T> (stored_property #External.ro : $T)
|
|
|
|
// CHECK-LABEL: sil_property [serialized] #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0,
|
|
// CHECK-SAME: id @id_a : $@convention(thin) () -> (),
|
|
// CHECK-SAME: getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0,
|
|
// CHECK-SAME: indices [%$0 : $τ_1_0 : $*τ_1_0],
|
|
// CHECK-SAME: indices_equals @equals_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
|
|
// CHECK-SAME: indices_hash @hash_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (UnsafeRawPointer) -> Int)
|
|
sil_property [serialized] #External.subscript <T><U: Hashable> (gettable_property $T,
|
|
id @id_a : $@convention(thin) () -> (),
|
|
getter @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in_guaranteed External<T>, UnsafeRawPointer) -> @out T,
|
|
indices [%$0 : $U : $*U],
|
|
indices_equals @equals_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
|
|
indices_hash @hash_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer) -> Int)
|
|
|
|
|