mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
For now, always use indirect convention for types with packs. This is motivated by the fact that getting from/setting to a pack currently requires addresses which aren't materialized for tuples. In the fullness of time, these values should be direct in opaque values mode, but for now it can be postponed.
152 lines
6.1 KiB
Plaintext
152 lines
6.1 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-opaque-values -enable-sil-verify-all -emit-sorted-sil %s | %FileCheck %s
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
sil_stage raw
|
|
|
|
protocol Foo {
|
|
func foo()
|
|
}
|
|
|
|
struct S : Foo {
|
|
func foo()
|
|
init()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @initDeinitExistentialValue : $@convention(thin) <T> (@in T) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $T):
|
|
// CHECK: [[IE:%.*]] = init_existential_value [[ARG]] : $T, $T, $Any
|
|
// CHECK: deinit_existential_value [[IE]] : $Any
|
|
// CHECK-LABEL: } // end sil function 'initDeinitExistentialValue'
|
|
sil @initDeinitExistentialValue : $@convention(thin) <T> (@in T) -> () {
|
|
bb0(%0 : $T):
|
|
%i = init_existential_value %0 : $T, $T, $Any
|
|
deinit_existential_value %i : $Any
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @openExistentialBoxValue : $@convention(thin) (@in any Error) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $any Error):
|
|
// CHECK: open_existential_box_value [[ARG]] : $any Error to $@opened("{{.*}}", any Error) Self
|
|
// CHECK-LABEL: } // end sil function 'openExistentialBoxValue'
|
|
sil @openExistentialBoxValue : $@convention(thin) (@in Error) -> () {
|
|
bb0(%0 : $Error):
|
|
%o = open_existential_box_value %0 : $Error to $@opened("2E9EACA6-FD59-11E6-B016-685B3593C495", Error) Self
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @openExistentialValue : $@convention(thin) (@in any Foo) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $any Foo):
|
|
// CHECK: open_existential_value [[ARG]] : $any Foo to $@opened("2E9EACA6-FD59-11E6-B016-685B3593C496", any Foo) Self
|
|
// CHECK-LABEL: } // end sil function 'openExistentialValue'
|
|
sil @openExistentialValue : $@convention(thin) (@in Foo) -> () {
|
|
bb0(%0 : $Foo):
|
|
%o = open_existential_value %0 : $Foo to $@opened("2E9EACA6-FD59-11E6-B016-685B3593C496", Foo) Self
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// Test @callee_guaranteed parsing.
|
|
// ----
|
|
|
|
sil @dummy : $@convention(thin) (Builtin.Int64) -> ()
|
|
|
|
// SILFunctionType.getCalleeConvention requires all ParameterConventions to fit
|
|
// inside SILFunctionTypeBits. The only way to test this is with @callee_guaranteed.
|
|
// CHECK-LABEL: sil hidden @parse_callee_guaranteed : $@convention(thin) () -> @callee_guaranteed () -> () {
|
|
sil hidden @parse_callee_guaranteed : $@convention(thin) () -> @callee_guaranteed () -> () {
|
|
entry:
|
|
%f = function_ref @dummy : $@convention(thin) (Builtin.Int64) -> ()
|
|
%z = integer_literal $Builtin.Int64, 0
|
|
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] {{.*}} $@convention(thin) (Builtin.Int64) -> ()
|
|
%g = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
|
|
// CHECK: return [[PA]] : $@callee_guaranteed () -> ()
|
|
return %g : $@callee_guaranteed () -> ()
|
|
}
|
|
// CHECK-LABEL: } // end sil function 'parse_callee_guaranteed'
|
|
|
|
// Test @in/@out parsing.
|
|
// ----
|
|
//
|
|
// CHECK-LABEL: sil hidden @parse_identity : $@convention(thin) <T> (@in T) -> @out T {
|
|
// CHECK: bb0(%0 : $T):
|
|
// CHECK: return %0 : $T
|
|
// CHECK-LABEL: } // end sil function 'parse_identity'
|
|
sil hidden @parse_identity : $@convention(thin) <T> (@in T) -> @out T {
|
|
bb0(%0 : $T):
|
|
return %0 : $T
|
|
}
|
|
|
|
// Test @in_guaranteed parsing.
|
|
// ----
|
|
|
|
sil @doWithS : $@convention(method) (S) -> ()
|
|
|
|
// CHECK-LABEL: sil hidden [transparent] [thunk] @parse_mutating : $@convention(witness_method: Foo) (@in_guaranteed S) -> () {
|
|
sil hidden [transparent] [thunk] @parse_mutating : $@convention(witness_method: Foo) (@in_guaranteed S) -> () {
|
|
// CHECK: bb0(%0 : $S):
|
|
bb0(%0 : $S):
|
|
%f = function_ref @doWithS : $@convention(method) (S) -> ()
|
|
// CHECK: apply %{{.*}}(%0) : $@convention(method) (S) -> ()
|
|
%a = apply %f(%0) : $@convention(method) (S) -> ()
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
// CHECK-LABEL: } // end sil function 'parse_mutating'
|
|
|
|
struct WeakBox<T : AnyObject> {
|
|
weak var t: T?
|
|
}
|
|
|
|
// Test strong_copy_weak_value parsing.
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_strong_copy_weak_value : {{.*}} {
|
|
// CHECK: bb0([[INSTANCE:%[^,]+]] :
|
|
// CHECK: [[WEAK_OPTIONAL:%[^,]+]] = struct_extract [[INSTANCE]]
|
|
// CHECK: strong_copy_weak_value [[WEAK_OPTIONAL]]
|
|
// CHECK-LABEL: } // end sil function 'test_strong_copy_weak_value'
|
|
sil [ossa] @test_strong_copy_weak_value : $@convention(thin) <T where T : AnyObject> (@in_guaranteed WeakBox<T>) -> @owned Optional<T> {
|
|
bb0(%instance : @guaranteed $WeakBox<T>):
|
|
%weak_optional = struct_extract %instance : $WeakBox<T>, #WeakBox.t
|
|
%strong_optional = strong_copy_weak_value %weak_optional : $@sil_weak Optional<T>
|
|
return %strong_optional : $Optional<T>
|
|
}
|
|
|
|
// Test tuple_pack_extract parsing.
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_tuple_pack_extract : {{.*}} {
|
|
// CHECK: bb0([[TUPLE_ADDR:%[^,]+]] :
|
|
// CHECK: [[TUPLE:%[^,]+]] = load_borrow [[TUPLE_ADDR]]
|
|
// CHECK: [[ZERO:%[^,]+]] = integer_literal
|
|
// CHECK: [[INDEX:%[^,]+]] = dynamic_pack_index [[ZERO]]
|
|
// CHECK: [[ELT:%[^,]+]] = tuple_pack_extract [[INDEX]] of [[TUPLE]]
|
|
// CHECK-LABEL: } // end sil function 'test_tuple_pack_extract'
|
|
sil [ossa] @test_tuple_pack_extract : $@convention(thin) <each T> (@in_guaranteed (repeat each T)) -> () {
|
|
entry(%tuple_addr : $*(repeat each T)):
|
|
%tuple = load_borrow %tuple_addr : $*(repeat each T)
|
|
%zero = integer_literal $Builtin.Word, 0
|
|
%index = dynamic_pack_index %zero of $Pack{repeat each T}
|
|
%opened = open_pack_element %index of <each U_1> at <Pack{repeat each T}>, shape $U_1, uuid "00000000-0000-0000-0000-000000000000"
|
|
%elt = tuple_pack_extract %index of %tuple : $(repeat each T) as $@pack_element("00000000-0000-0000-0000-000000000000") U_1
|
|
end_borrow %tuple : $(repeat each T)
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// Test weak_copy_value parsing.
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_weak_copy_value_1 : {{.*}} {
|
|
// CHECK: bb0([[VALUE:%[^,]+]] :
|
|
// CHECK: weak_copy_value [[VALUE]]
|
|
// CHECK-LABEL: } // end sil function 'test_weak_copy_value_1'
|
|
sil [ossa] @test_weak_copy_value_1 : $@convention(thin) <T where T : AnyObject> (@owned Optional<T>) -> @out WeakBox<T> {
|
|
bb0(%value : @owned $Optional<T>):
|
|
%weak_value = weak_copy_value %value : $Optional<T>
|
|
destroy_value %value : $Optional<T>
|
|
%retval = struct $WeakBox<T> (%weak_value : $@sil_weak Optional<T>)
|
|
return %retval : $WeakBox<T>
|
|
}
|