mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
189 lines
10 KiB
Swift
189 lines
10 KiB
Swift
// RUN: %target-swift-frontend -enable-sil-ownership -emit-silgen -sdk %S/Inputs/ -I %S/Inputs -enable-source-import %s | %FileCheck %s
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
import objc_extensions_helper
|
|
|
|
class Sub : Base {}
|
|
|
|
extension Sub {
|
|
override var prop: String! {
|
|
didSet {
|
|
// Ignore it.
|
|
}
|
|
|
|
// Make sure that we are generating the @objc thunk and are calling the actual method.
|
|
//
|
|
// CHECK-LABEL: sil hidden [thunk] @_T015objc_extensions3SubC4propSQySSGvgTo : $@convention(objc_method) (Sub) -> @autoreleased Optional<NSString> {
|
|
// CHECK: bb0([[SELF:%.*]] : @unowned $Sub):
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
|
|
// CHECK: [[GETTER_FUNC:%.*]] = function_ref @_T015objc_extensions3SubC4propSQySSGvg : $@convention(method) (@guaranteed Sub) -> @owned Optional<String>
|
|
// CHECK: apply [[GETTER_FUNC]]([[BORROWED_SELF_COPY]])
|
|
// CHECK: end_borrow [[BORROWED_SELF_COPY]] from [[SELF_COPY]]
|
|
// CHECK: destroy_value [[SELF_COPY]]
|
|
// CHECK: } // end sil function '_T015objc_extensions3SubC4propSQySSGvgTo'
|
|
|
|
// Then check the body of the getter calls the super_method.
|
|
// CHECK-LABEL: sil hidden @_T015objc_extensions3SubC4propSQySSGvg : $@convention(method) (@guaranteed Sub) -> @owned Optional<String> {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $Sub):
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[SELF_COPY_CAST:%.*]] = upcast [[SELF_COPY]] : $Sub to $Base
|
|
// CHECK: [[BORROWED_SELF_COPY_CAST:%.*]] = begin_borrow [[SELF_COPY_CAST]]
|
|
// CHECK: [[CAST_BACK:%.*]] = unchecked_ref_cast [[BORROWED_SELF_COPY_CAST]] : $Base to $Sub
|
|
// CHECK: [[SUPER_METHOD:%.*]] = objc_super_method [[CAST_BACK]] : $Sub, #Base.prop!getter.1.foreign
|
|
// CHECK: end_borrow [[BORROWED_SELF_COPY_CAST]]
|
|
// CHECK: [[RESULT:%.*]] = apply [[SUPER_METHOD]]([[SELF_COPY_CAST]])
|
|
// CHECK: bb3(
|
|
// CHECK: destroy_value [[SELF_COPY_CAST]]
|
|
// CHECK: } // end sil function '_T015objc_extensions3SubC4propSQySSGvg'
|
|
|
|
// Then check the setter @objc thunk.
|
|
//
|
|
// CHECK-LABEL: sil hidden [thunk] @_T015objc_extensions3SubC4propSQySSGvsTo : $@convention(objc_method) (Optional<NSString>, Sub) -> () {
|
|
// CHECK: bb0([[NEW_VALUE:%.*]] : @unowned $Optional<NSString>, [[SELF:%.*]] : @unowned $Sub):
|
|
// CHECK: [[NEW_VALUE_COPY:%.*]] = copy_value [[NEW_VALUE]]
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] : $Sub
|
|
// CHECK: switch_enum [[NEW_VALUE_COPY]] : $Optional<NSString>, case #Optional.some!enumelt.1: [[SUCC_BB:bb[0-9]+]], case #Optional.none!enumelt: [[FAIL_BB:bb[0-9]+]]
|
|
// CHECK: [[SUCC_BB]]([[STR:%.*]] : @owned $NSString):
|
|
// CHECK: [[FAIL_BB]]:
|
|
// CHECK: bb3([[BRIDGED_NEW_VALUE:%.*]] : @owned $Optional<String>):
|
|
// CHECK: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
|
|
// CHECK: [[NORMAL_FUNC:%.*]] = function_ref @_T015objc_extensions3SubC4propSQySSGvs : $@convention(method) (@owned Optional<String>, @guaranteed Sub) -> ()
|
|
// CHECK: apply [[NORMAL_FUNC]]([[BRIDGED_NEW_VALUE]], [[BORROWED_SELF_COPY]])
|
|
// CHECK: end_borrow [[BORROWED_SELF_COPY]] from [[SELF_COPY]]
|
|
// CHECK: destroy_value [[SELF_COPY]]
|
|
// CHECK: } // end sil function '_T015objc_extensions3SubC4propSQySSGvsTo'
|
|
|
|
// Then check the body of the actually setter value and make sure that we
|
|
// call the didSet function.
|
|
// CHECK-LABEL: sil hidden @_T015objc_extensions3SubC4propSQySSGvs : $@convention(method) (@owned Optional<String>, @guaranteed Sub) -> () {
|
|
|
|
// First we get the old value.
|
|
// CHECK: bb0([[NEW_VALUE:%.*]] : @owned $Optional<String>, [[SELF:%.*]] : @guaranteed $Sub):
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[UPCAST_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $Sub to $Base
|
|
// CHECK: [[BORROWED_UPCAST_SELF_COPY:%.*]] = begin_borrow [[UPCAST_SELF_COPY]]
|
|
// CHECK: [[CAST_BACK:%.*]] = unchecked_ref_cast [[BORROWED_UPCAST_SELF_COPY]] : $Base to $Sub
|
|
// CHECK: [[GET_SUPER_METHOD:%.*]] = objc_super_method [[CAST_BACK]] : $Sub, #Base.prop!getter.1.foreign : (Base) -> () -> String!, $@convention(objc_method) (Base) -> @autoreleased Optional<NSString>
|
|
// CHECK: end_borrow [[BORROWED_UPCAST_SELF_COPY]] from [[UPCAST_SELF_COPY]]
|
|
// CHECK: [[OLD_NSSTRING:%.*]] = apply [[GET_SUPER_METHOD]]([[UPCAST_SELF_COPY]])
|
|
|
|
// CHECK: bb3([[OLD_NSSTRING_BRIDGED:%.*]] : @owned $Optional<String>):
|
|
// This next line is completely not needed. But we are emitting it now.
|
|
// CHECK: destroy_value [[UPCAST_SELF_COPY]]
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[UPCAST_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $Sub to $Base
|
|
// CHECK: [[BORROWED_NEW_VALUE:%.*]] = begin_borrow [[NEW_VALUE]]
|
|
// CHECK: [[NEW_VALUE_COPY:%.*]] = copy_value [[BORROWED_NEW_VALUE]]
|
|
// CHECK: switch_enum [[NEW_VALUE_COPY]] : $Optional<String>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: bb4([[OLD_STRING:%.*]] : @owned $String):
|
|
// CHECK: bb6([[BRIDGED_NEW_STRING:%.*]] : @owned $Optional<NSString>):
|
|
// CHECK: end_borrow [[BORROWED_NEW_VALUE]]
|
|
// CHECK: [[BORROWED_UPCAST_SELF:%.*]] = begin_borrow [[UPCAST_SELF_COPY]] : $Base
|
|
// CHECK: [[SUPERREF_DOWNCAST:%.*]] = unchecked_ref_cast [[BORROWED_UPCAST_SELF]] : $Base to $Sub
|
|
// CHECK: [[SET_SUPER_METHOD:%.*]] = objc_super_method [[SUPERREF_DOWNCAST]] : $Sub, #Base.prop!setter.1.foreign : (Base) -> (String!) -> (), $@convention(objc_method) (Optional<NSString>, Base) -> ()
|
|
// CHECK: apply [[SET_SUPER_METHOD]]([[BRIDGED_NEW_STRING]], [[UPCAST_SELF_COPY]])
|
|
// CHECK: destroy_value [[BRIDGED_NEW_STRING]]
|
|
// CHECK: destroy_value [[UPCAST_SELF_COPY]]
|
|
// CHECK: [[BORROWED_OLD_NSSTRING_BRIDGED:%.*]] = begin_borrow [[OLD_NSSTRING_BRIDGED]]
|
|
// CHECK: [[COPIED_OLD_NSSTRING_BRIDGED:%.*]] = copy_value [[BORROWED_OLD_NSSTRING_BRIDGED]]
|
|
// CHECK: end_borrow [[BORROWED_OLD_NSSTRING_BRIDGED]] from [[OLD_NSSTRING_BRIDGED]]
|
|
// This is an identity cast that should be eliminated by SILGen peepholes.
|
|
// CHECK: [[DIDSET_NOTIFIER:%.*]] = function_ref @_T015objc_extensions3SubC4propSQySSGvW : $@convention(method) (@owned Optional<String>, @guaranteed Sub) -> ()
|
|
// CHECK: apply [[DIDSET_NOTIFIER]]([[COPIED_OLD_NSSTRING_BRIDGED]], [[SELF]])
|
|
// CHECK: destroy_value [[OLD_NSSTRING_BRIDGED]]
|
|
// CHECK: destroy_value [[NEW_VALUE]]
|
|
// CHECK: } // end sil function '_T015objc_extensions3SubC4propSQySSGvs'
|
|
|
|
}
|
|
|
|
func foo() {
|
|
}
|
|
|
|
override func objCBaseMethod() {}
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden @_T015objc_extensions20testOverridePropertyyyAA3SubCF
|
|
func testOverrideProperty(_ obj: Sub) {
|
|
// CHECK: bb0([[ARG:%.*]] : @owned $Sub):
|
|
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
|
|
// CHECK: = objc_method [[BORROWED_ARG]] : $Sub, #Sub.prop!setter.1.foreign : (Sub) -> (String!) -> ()
|
|
obj.prop = "abc"
|
|
} // CHECK: } // end sil function '_T015objc_extensions20testOverridePropertyyyAA3SubCF'
|
|
|
|
testOverrideProperty(Sub())
|
|
|
|
// CHECK-LABEL: sil shared [thunk] @_T015objc_extensions3SubC3fooyyFTc
|
|
// CHECK: function_ref @_T015objc_extensions3SubC3fooyyFTD
|
|
// CHECK: } // end sil function '_T015objc_extensions3SubC3fooyyFTc'
|
|
// CHECK: sil shared [transparent] [serializable] [thunk] @_T015objc_extensions3SubC3fooyyFTD
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $Sub):
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: objc_method [[SELF_COPY]] : $Sub, #Sub.foo!1.foreign
|
|
// CHECK: } // end sil function '_T015objc_extensions3SubC3fooyyFTD'
|
|
func testCurry(_ x: Sub) {
|
|
_ = x.foo
|
|
}
|
|
|
|
extension Sub {
|
|
var otherProp: String {
|
|
get { return "hello" }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
class SubSub : Sub {
|
|
// CHECK-LABEL: sil hidden @_T015objc_extensions03SubC0C14objCBaseMethodyyF :
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $SubSub):
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[UPCAST_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $SubSub to $Sub
|
|
// CHECK: [[BORROWED_UPCAST_SELF_COPY:%.*]] = begin_borrow [[UPCAST_SELF_COPY]]
|
|
// CHECK: [[DOWNCAST:%.*]] = unchecked_ref_cast [[BORROWED_UPCAST_SELF_COPY]] : $Sub to $SubSub
|
|
// CHECK: objc_super_method [[DOWNCAST]] : $SubSub, #Sub.objCBaseMethod!1.foreign : (Sub) -> () -> (), $@convention(objc_method) (Sub) -> ()
|
|
// CHECK: end_borrow [[BORROWED_UPCAST_SELF_COPY]] from [[UPCAST_SELF_COPY]]
|
|
// CHECK: } // end sil function '_T015objc_extensions03SubC0C14objCBaseMethodyyF'
|
|
override func objCBaseMethod() {
|
|
super.objCBaseMethod()
|
|
}
|
|
}
|
|
|
|
extension SubSub {
|
|
// CHECK-LABEL: sil hidden @_T015objc_extensions03SubC0C9otherPropSSvs
|
|
// CHECK: bb0([[NEW_VALUE:%.*]] : @owned $String, [[SELF:%.*]] : @guaranteed $SubSub):
|
|
// CHECK: [[SELF_COPY_1:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[UPCAST_SELF_COPY_1:%.*]] = upcast [[SELF_COPY_1]] : $SubSub to $Sub
|
|
// CHECK: [[BORROWED_UPCAST_SELF_COPY_1:%.*]] = begin_borrow [[UPCAST_SELF_COPY_1]]
|
|
// CHECK: [[DOWNCAST_BORROWED_UPCAST_SELF_COPY_1:%.*]] = unchecked_ref_cast [[BORROWED_UPCAST_SELF_COPY_1]] : $Sub to $SubSub
|
|
// CHECK: = objc_super_method [[DOWNCAST_BORROWED_UPCAST_SELF_COPY_1]] : $SubSub, #Sub.otherProp!getter.1.foreign
|
|
// CHECK: end_borrow [[BORROWED_UPCAST_SELF_COPY_1]] from [[UPCAST_SELF_COPY_1]]
|
|
|
|
// CHECK: [[SELF_COPY_2:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[UPCAST_SELF_COPY_2:%.*]] = upcast [[SELF_COPY_2]] : $SubSub to $Sub
|
|
// CHECK: [[BORROWED_UPCAST_SELF_COPY_2:%.*]] = begin_borrow [[UPCAST_SELF_COPY_2]]
|
|
// CHECK: [[DOWNCAST_BORROWED_UPCAST_SELF_COPY_2:%.*]] = unchecked_ref_cast [[BORROWED_UPCAST_SELF_COPY_2]] : $Sub to $SubSub
|
|
// CHECK: = objc_super_method [[DOWNCAST_BORROWED_UPCAST_SELF_COPY_2]] : $SubSub, #Sub.otherProp!setter.1.foreign
|
|
// CHECK: end_borrow [[BORROWED_UPCAST_SELF_COPY_2]] from [[UPCAST_SELF_COPY_2]]
|
|
// CHECK: } // end sil function '_T015objc_extensions03SubC0C9otherPropSSvs'
|
|
override var otherProp: String {
|
|
didSet {
|
|
// Ignore it.
|
|
}
|
|
}
|
|
}
|
|
|
|
// SR-1025
|
|
extension Base {
|
|
fileprivate static var x = 1
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden @_T015objc_extensions19testStaticVarAccessyyF
|
|
func testStaticVarAccess() {
|
|
// CHECK: [[F:%.*]] = function_ref @_T0So4BaseC15objc_extensionsE1x33_1F05E59585E0BB585FCA206FBFF1A92DLLSivau
|
|
// CHECK: [[PTR:%.*]] = apply [[F]]()
|
|
// CHECK: [[ADDR:%.*]] = pointer_to_address [[PTR]]
|
|
_ = Base.x
|
|
}
|