blob: eeb4a31b10af39a07afd202ec23605fddc0d37b3 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -cse | FileCheck %s
// REQUIRES: objc_interop
import Builtin
import Swift
import Foundation
@objc(XX) protocol XX {
}
// CHECK-LABEL: sil @cse_objc_protocol
// CHECK: objc_protocol #XX : $Protocol
// CHECK-NOT: objc_protocol
// CHECK: tuple (%0 : $Protocol, %0 : $Protocol)
// CHECK: return
sil @cse_objc_protocol : $@convention(thin) () -> @owned (Protocol, Protocol) {
bb0:
%0 = objc_protocol #XX : $Protocol
%1 = objc_protocol #XX : $Protocol
%2 = tuple (%0: $Protocol, %1: $Protocol)
return %2 : $(Protocol, Protocol)
}
@objc protocol Walkable {
func walk()
}
class Bar : NSObject, Walkable {
override init()
func walk()
deinit
}
func trytowalk(f: Walkable)
// test.Bar.init (test.Bar.Type)() -> test.Bar
sil hidden @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar {
bb0(%0 : $Bar):
%1 = alloc_stack $Bar, let, name "sf" // users: %2, %6, %9, %10
store %0 to %1 : $*Bar // id: %2
%3 = upcast %0 : $Bar to $NSObject // user: %7
%4 = super_method [volatile] %0 : $Bar, #NSObject.init!initializer.1.foreign : (NSObject.Type) -> () -> NSObject , $@convention(objc_method) (@owned NSObject) -> @owned NSObject // user: %7
%7 = apply %4(%3) : $@convention(objc_method) (@owned NSObject) -> @owned NSObject // user: %8
%8 = unchecked_ref_cast %7 : $NSObject to $Bar // users: %9, %11
store %8 to %1 : $*Bar // id: %9
dealloc_stack %1 : $*Bar // id: %10
return %8 : $Bar // id: %11
}
// test.Bar.__allocating_init (test.Bar.Type)() -> test.Bar
sil hidden @_TFC4test3BarCfMS0_FT_S0_ : $@convention(thin) (@thick Bar.Type) -> @owned Bar {
bb0(%0 : $@thick Bar.Type):
%1 = alloc_ref [objc] $Bar // user: %3
// function_ref test.Bar.init (test.Bar.Type)() -> test.Bar
%2 = function_ref @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar // user: %3
%3 = apply %2(%1) : $@convention(method) (@owned Bar) -> @owned Bar // user: %4
return %3 : $Bar // id: %4
}
// @objc test.Bar.init (test.Bar.Type)() -> test.Bar
sil hidden @_TToFC4test3BarcfMS0_FT_S0_ : $@convention(objc_method) (@owned Bar) -> @owned Bar {
bb0(%0 : $Bar):
// function_ref test.Bar.init (test.Bar.Type)() -> test.Bar
%1 = function_ref @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar // user: %2
%2 = apply %1(%0) : $@convention(method) (@owned Bar) -> @owned Bar // user: %3
return %2 : $Bar // id: %3
}
// test.Bar.walk (test.Bar)() -> ()
sil hidden @_TFC4test3Bar4walkfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () {
bb0(%0 : $Bar):
debug_value %0 : $Bar, let, name "self" // id: %1
%2 = tuple () // user: %3
return %2 : $() // id: %3
}
// @objc test.Bar.walk (test.Bar)() -> ()
sil hidden @_TToFC4test3Bar4walkfS0_FT_T_ : $@convention(objc_method) (Bar) -> () {
bb0(%0 : $Bar):
strong_retain %0 : $Bar // id: %1
// function_ref test.Bar.walk (test.Bar)() -> ()
%2 = function_ref @_TFC4test3Bar4walkfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () // user: %3
%3 = apply %2(%0) : $@convention(method) (@guaranteed Bar) -> () // user: %5
strong_release %0 : $Bar // id: %4
return %3 : $() // id: %5
}
// test.Bar.__deallocating_deinit
sil hidden @_TFC4test3BarD : $@convention(method) (@owned Bar) -> () {
bb0(%0 : $Bar):
debug_value %0 : $Bar, let, name "self" // id: %1
%2 = super_method %0 : $Bar, #NSObject.deinit!deallocator.foreign : (NSObject) -> () -> () , $@convention(objc_method) (NSObject) -> () // user: %4
%3 = upcast %0 : $Bar to $NSObject // user: %4
%4 = apply %2(%3) : $@convention(objc_method) (NSObject) -> ()
%5 = tuple () // user: %6
return %5 : $() // id: %6
}
// CHECK-LABEL: _TF4test9trytowalkFPS_8Walkable_T_
// CHECK: bb0(%0 : $Walkable):
// CHECK-NEXT: open_existential_ref
// CHECK-NEXT: witness_method
// CHECK-NEXT: apply
// CHECK-NEXT: witness_method
// CHECK-NEXT: apply
// CHECK-NEXT: strong_release
// CHECK-NEXT: tuple
// CHECK-NEXT: return
// test.trytowalk (test.Walkable) -> ()
sil hidden @_TF4test9trytowalkFPS_8Walkable_T_ : $@convention(thin) (@owned Walkable) -> () {
bb0(%0 : $Walkable):
%2 = open_existential_ref %0 : $Walkable to $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable // users: %3, %4
%3 = witness_method [volatile] $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable, #Walkable.walk!1.foreign, %2 : $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () // user: %4
%4 = apply %3<@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable>(%2) : $@convention(objc_method) _0_0 where τ_0_0 : Walkable> _0_0) -> ()
%5 = witness_method [volatile] $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable, #Walkable.walk!1.foreign, %2 : $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () // user: %6
%6 = apply %5<@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable>(%2) : $@convention(objc_method) _0_0 where τ_0_0 : Walkable> _0_0) -> ()
strong_release %0 : $Walkable // id: %8
%9 = tuple () // user: %10
return %9 : $() // id: %10
}
// Check that the open_existential_ref is CSEed not only in instructions, but also in the types
// of BB arguments. The type of BB2 argument should use the same opened existential as the
// one opened in the entry block.
// CHECK-LABEL: sil @cse_open_existential_in_bbarg : $@convention(thin) (@owned AnyObject) -> ()
// CHECK: open_existential_ref %0 : $AnyObject to $[[OPENED:@opened\(.*\) AnyObject]]
// CHECK: bb1(%{{[0-9]*}} : $@convention(objc_method) ([[OPENED]]) -> @autoreleased Optional<NSString>):
// CHECK-NOT: open_existential_ref
// CHECK: bb2(%{{[0-9]*}} : $@convention(objc_method) ([[OPENED]]) -> @autoreleased Optional<NSString>):
// CHECK-NOT: open_existential_ref
// CHECK: return
sil @cse_open_existential_in_bbarg : $@convention(thin) (@owned AnyObject) -> () {
bb0(%0 : $AnyObject):
%1 = open_existential_ref %0 : $AnyObject to $@opened("CCEAC0E2-4BB2-11E6-86F8-B8E856428C60") AnyObject
dynamic_method_br %1 : $@opened("CCEAC0E2-4BB2-11E6-86F8-B8E856428C60") AnyObject, #NSProxy.description!getter.1.foreign, bb1, bb3
bb1(%3 : $@convention(objc_method) (@opened("CCEAC0E2-4BB2-11E6-86F8-B8E856428C60") AnyObject) -> @autoreleased Optional<NSString>):
strong_retain %1 : $@opened("CCEAC0E2-4BB2-11E6-86F8-B8E856428C60") AnyObject
%5 = partial_apply %3(%1) : $@convention(objc_method) (@opened("CCEAC0E2-4BB2-11E6-86F8-B8E856428C60") AnyObject) -> @autoreleased Optional<NSString>
%6 = apply %5() : $@callee_owned () -> @owned Optional<NSString>
%7 = open_existential_ref %0 : $AnyObject to $@opened("CCEDAF1E-4BB2-11E6-86F8-B8E856428C60") AnyObject
dynamic_method_br %7 : $@opened("CCEDAF1E-4BB2-11E6-86F8-B8E856428C60") AnyObject, #NSProxy.description!getter.1.foreign, bb2, bb3
bb2(%9 : $@convention(objc_method) (@opened("CCEDAF1E-4BB2-11E6-86F8-B8E856428C60") AnyObject) -> @autoreleased Optional<NSString>):
strong_retain %7 : $@opened("CCEDAF1E-4BB2-11E6-86F8-B8E856428C60") AnyObject
%10 = partial_apply %9(%7) : $@convention(objc_method) (@opened("CCEDAF1E-4BB2-11E6-86F8-B8E856428C60") AnyObject) -> @autoreleased Optional<NSString>
%11 = apply %10() : $@callee_owned () -> @owned Optional<NSString>
br bb3
bb3:
strong_release %0 : $AnyObject
%13 = tuple ()
return %13 : $()
}
sil_vtable Bar {
#Bar.init!initializer.1: _TFC4test3BarcfMS0_FT_S0_ // test.Bar.init (test.Bar.Type)() -> test.Bar
#Bar.walk!1: _TFC4test3Bar4walkfS0_FT_T_ // test.Bar.walk (test.Bar)() -> ()
#Bar.deinit!deallocator: _TFC4test3BarD // test.Bar.__deallocating_deinit
}