| |
| // RUN: %target-sil-opt %s | %target-sil-opt | %FileCheck %s |
| |
| sil_stage canonical |
| |
| import Swift |
| |
| struct S: Hashable { |
| var x: Int |
| let y: String |
| var z: C |
| |
| func hash(into hasher: inout Hasher) |
| 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 |
| } |
| |
| func hash(into hasher: inout Hasher) |
| 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 |
| |
| subscript<U: Hashable>(ro _: U) -> T { get } |
| } |
| |
| struct T { |
| var x: (Int, Int) |
| var y: (a: Int, b: Int, c: Int) |
| let z: (Int, Int) |
| let w: (Int, C) |
| } |
| |
| // CHECK-LABEL: sil shared @stored_properties |
| sil shared @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 @stored_properties_generic |
| sil shared @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 : $() |
| } |
| |
| // CHECK-LABEL: sil shared @tuple_elements |
| sil shared @tuple_elements : $@convention(thin) () -> () { |
| entry: |
| // CHECK: keypath $WritableKeyPath<T, Int>, (root $T; stored_property #T.x : $(Int, Int); tuple_element #0 : $Int) |
| %a = keypath $WritableKeyPath<T, Int>, (root $T; stored_property #T.x : $(Int, Int); tuple_element #0 : $Int) |
| // CHECK: keypath $WritableKeyPath<T, Int>, (root $T; stored_property #T.y : $(a: Int, b: Int, c: Int); tuple_element #2 : $Int) |
| %b = keypath $WritableKeyPath<T, Int>, (root $T; stored_property #T.y : $(a: Int, b: Int, c: Int); tuple_element #2 : $Int) |
| // CHECK: keypath $KeyPath<T, Int>, (root $T; stored_property #T.z : $(Int, Int); tuple_element #1 : $Int) |
| %c = keypath $KeyPath<T, Int>, (root $T; stored_property #T.z : $(Int, Int); tuple_element #1 : $Int) |
| // CHECK: keypath $ReferenceWritableKeyPath<T, C>, (root $T; stored_property #T.w : $(Int, C); tuple_element #1 : $C) |
| %d = keypath $ReferenceWritableKeyPath<T, C>, (root $T; stored_property #T.w : $(Int, C); tuple_element #1 : $C) |
| |
| 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 @computed_properties |
| sil shared @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 @computed_properties_generic |
| sil shared @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 @tuple_generic |
| sil shared @ tuple_generic : $@convention(thin) <T, U> () -> () { |
| entry: |
| // CHECK: keypath $WritableKeyPath<(T, U), T>, <τ_0_0, τ_0_1> (root $(τ_0_0, τ_0_1); tuple_element #0 : $τ_0_0) <T, U> |
| %a = keypath $WritableKeyPath<(T, U), T>, <τ_0_0, τ_0_1> (root $(τ_0_0, τ_0_1); tuple_element #0 : $τ_0_0) <T, U> |
| // CHECK: keypath $WritableKeyPath<(T, U), U>, <τ_0_0, τ_0_1> (root $(τ_0_0, τ_0_1); tuple_element #1 : $τ_0_1) <T, U> |
| %b = keypath $WritableKeyPath<(T, U), U>, <τ_0_0, τ_0_1> (root $(τ_0_0, τ_0_1); tuple_element #1 : $τ_0_1) <T, U> |
| |
| return undef : $() |
| } |
| |
| // CHECK-LABEL: sil @optional |
| sil @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 @indexes |
| sil @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 @external |
| sil @external : $@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>) -> (), external #Gen.x<τ_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>) -> (), external #Gen.x<G, H, I>) <D, E, F> |
| |
| return undef : $() |
| } |
| |
| sil @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in_guaranteed External<T>, UnsafeRawPointer) -> @out T |
| sil @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool |
| sil @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int |
| |
| // CHECK-LABEL: sil_property #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0) |
| sil_property #External.ro <T> (stored_property #External.ro : $T) |
| |
| // CHECK-LABEL: sil_property #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) |
| sil_property #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) |