1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
// RUN: %target-swift-emit-silgen -module-name objc_extensions -sdk %S/Inputs/ -I %S/Inputs -enable-source-import %s | %FileCheck %s
// REQUIRES: objc_interop
import Foundation
import objc_extensions_helper
class Sub : Base {}
// CHECK-LABEL: sil hidden [ossa] @$s15objc_extensions20testOverridePropertyyyAA3SubCF
func testOverrideProperty(_ obj: Sub) {
// CHECK: bb0([[ARG:%.*]] : @guaranteed $Sub):
// CHECK: = objc_method [[ARG]] : $Sub, #Sub.prop!setter.foreign : (Sub) -> (String?) -> ()
obj.prop = "abc"
} // CHECK: } // end sil function '$s15objc_extensions20testOverridePropertyyyAA3SubCF'
testOverrideProperty(Sub())
extension Sub {
@objc override var prop: String! {
didSet(oldValue) {
// Ignore it, but explicitly specify 'oldValue' because this test
// checks that its correctly fetched.
}
// Make sure that we are generating the @objc thunk and are calling the actual method.
//
// CHECK-LABEL: sil private [thunk] [ossa] @$s15objc_extensions3SubC4propSSSgvgTo : $@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 @$s15objc_extensions3SubC4propSSSgvg : $@convention(method) (@guaranteed Sub) -> @owned Optional<String>
// CHECK: apply [[GETTER_FUNC]]([[BORROWED_SELF_COPY]])
// CHECK: end_borrow [[BORROWED_SELF_COPY]]
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: } // end sil function '$s15objc_extensions3SubC4propSSSgvgTo'
// Then check the body of the getter calls the super_method.
// CHECK-LABEL: sil hidden [ossa] @$s15objc_extensions3SubC4propSSSgvg : $@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.foreign
// CHECK: [[RESULT:%.*]] = apply [[SUPER_METHOD]]([[BORROWED_SELF_COPY_CAST]])
// CHECK: bb3(
// CHECK: end_borrow [[BORROWED_SELF_COPY_CAST]]
// CHECK: destroy_value [[SELF_COPY_CAST]]
// CHECK: } // end sil function '$s15objc_extensions3SubC4propSSSgvg'
// Then check the setter @objc thunk.
//
// CHECK-LABEL: sil private [thunk] [ossa] @$s15objc_extensions3SubC4propSSSgvsTo : $@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: [[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 @$s15objc_extensions3SubC4propSSSgvs : $@convention(method) (@owned Optional<String>, @guaranteed Sub) -> ()
// CHECK: apply [[NORMAL_FUNC]]([[BRIDGED_NEW_VALUE]], [[BORROWED_SELF_COPY]])
// CHECK: end_borrow [[BORROWED_SELF_COPY]]
// CHECK: destroy_value [[SELF_COPY]]
// CHECK: } // end sil function '$s15objc_extensions3SubC4propSSSgvsTo'
// Then check the body of the actually setter value and make sure that we
// call the didSet function.
// CHECK-LABEL: sil hidden [ossa] @$s15objc_extensions3SubC4propSSSgvs : $@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.foreign : (Base) -> () -> String?, $@convention(objc_method) (Base) -> @autoreleased Optional<NSString>
// CHECK: [[OLD_NSSTRING:%.*]] = apply [[GET_SUPER_METHOD]]([[BORROWED_UPCAST_SELF_COPY]])
// CHECK: bb3([[OLD_NSSTRING_BRIDGED:%.*]] : @owned $Optional<String>):
// CHECK: [[MOVED_OLD_NSSTRING_BRIDGED:%.*]] = move_value [var_decl] [[OLD_NSSTRING_BRIDGED]]
// 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: [[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: [[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.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]]
// This is an identity cast that should be eliminated by SILGen peepholes.
// CHECK: [[BORROWED_OLD_NSSTRING_BRIDGED:%.*]] = begin_borrow [[MOVED_OLD_NSSTRING_BRIDGED]]
// CHECK: [[DIDSET_NOTIFIER:%.*]] = function_ref @$s15objc_extensions3SubC4propSSSgvW : $@convention(method) (@guaranteed Optional<String>, @guaranteed Sub) -> ()
// CHECK: apply [[DIDSET_NOTIFIER]]([[BORROWED_OLD_NSSTRING_BRIDGED]], [[SELF]])
// CHECK: end_borrow [[BORROWED_OLD_NSSTRING_BRIDGED]]
// CHECK: destroy_value [[MOVED_OLD_NSSTRING_BRIDGED]]
// CHECK: destroy_value [[NEW_VALUE]]
// CHECK: } // end sil function '$s15objc_extensions3SubC4propSSSgvs'
}
@objc func foo() {
}
@objc override func objCBaseMethod() {}
}
// CHECK-LABEL: sil private [ossa] @$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_ : $@convention(thin) (@guaranteed Sub) -> @owned @callee_guaranteed () -> ()
// CHECK: function_ref @$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_yycfu0_ : $@convention(thin) (@guaranteed Sub) -> ()
// CHECK: } // end sil function '$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_'
// CHECK-LABEL: sil private [ossa] @$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_yycfu0_ : $@convention(thin) (@guaranteed Sub) -> ()
// CHECK: objc_method %0 : $Sub, #Sub.foo!foreign : (Sub) -> () -> (), $@convention(objc_method) (Sub) -> ()
// CHECK: } // end sil function '$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_yycfu0_'
func testCurry(_ x: Sub) {
_ = x.foo
}
extension Sub {
@objc var otherProp: String {
get { return "hello" }
set { }
}
}
class SubSub : Sub {
// CHECK-LABEL: sil hidden [ossa] @$s15objc_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!foreign : (Sub) -> () -> (), $@convention(objc_method) (Sub) -> ()
// CHECK: end_borrow [[BORROWED_UPCAST_SELF_COPY]]
// CHECK: } // end sil function '$s15objc_extensions03SubC0C14objCBaseMethodyyF'
override func objCBaseMethod() {
super.objCBaseMethod()
}
}
extension SubSub {
// CHECK-LABEL: sil hidden [ossa] @$s15objc_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.foreign
// CHECK: end_borrow [[BORROWED_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.foreign
// CHECK: end_borrow [[BORROWED_UPCAST_SELF_COPY_2]]
// CHECK: } // end sil function '$s15objc_extensions03SubC0C9otherPropSSvs'
@objc override var otherProp: String {
didSet(oldValue) {
// Ignore it.
}
}
}
// https://github.com/apple/swift/issues/43637
extension Base {
fileprivate static var x = 1
}
// CHECK-LABEL: sil hidden [ossa] @$s15objc_extensions19testStaticVarAccessyyF
func testStaticVarAccess() {
// CHECK: [[F:%.*]] = function_ref @$sSo4BaseC15objc_extensionsE1x33_1F05E59585E0BB585FCA206FBFF1A92DLLSivau
// CHECK: [[PTR:%.*]] = apply [[F]]()
// CHECK: [[ADDR:%.*]] = pointer_to_address [[PTR]]
_ = Base.x
}
extension PettableContainer {
// CHECK-LABEL: sil private [thunk] [ossa] @$sSo17PettableContainerC15objc_extensionsE7extractxyFTo : $@convention(objc_method) @pseudogeneric <T where T : Pettable> (PettableContainer<T>) -> @autoreleased T
@objc public func extract() -> T { fatalError() }
// CHECK-LABEL: sil private [thunk] [ossa] @$sSo17PettableContainerC15objc_extensionsE8extract2xSgyFTo : $@convention(objc_method) @pseudogeneric <T where T : Pettable> (PettableContainer<T>) -> @autoreleased Optional<T>
@objc public func extract2() -> T? { fatalError() }
}
|