// RUN: %target-sil-opt -sil-print-types -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) (@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) (@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) (@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) (@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 { 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) (@in_guaranteed WeakBox) -> @owned Optional { bb0(%instance : @guaranteed $WeakBox): %weak_optional = struct_extract %instance : $WeakBox, #WeakBox.t %strong_optional = strong_copy_weak_value %weak_optional : $@sil_weak Optional return %strong_optional : $Optional } // 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) (@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 at , 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) (@owned Optional) -> @out WeakBox { bb0(%value : @owned $Optional): %weak_value = weak_copy_value %value : $Optional destroy_value %value : $Optional %retval = struct $WeakBox (%weak_value : $@sil_weak Optional) return %retval : $WeakBox }