|
| 1 | +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine | %FileCheck %s |
| 2 | + |
| 3 | +// REQUIRES: objc_interop |
| 4 | + |
| 5 | +sil_stage canonical |
| 6 | + |
| 7 | +import Builtin |
| 8 | +import Swift |
| 9 | +import SwiftShims |
| 10 | + |
| 11 | +import Foundation |
| 12 | + |
| 13 | +@objc(XX) protocol X { |
| 14 | +} |
| 15 | + |
| 16 | +class XImpl : X { |
| 17 | + @objc deinit |
| 18 | + init() |
| 19 | +} |
| 20 | + |
| 21 | +// (thick_to_objc_metatype (metatype @thick)) -> (metatype @objc_metatype) |
| 22 | +// |
| 23 | +// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype36test_thick_to_objc_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @owned AnyObject |
| 24 | +// CHECK-NOT: metatype $@thick |
| 25 | +// CHECK-NOT: {{thick_to_objc_metatype }} |
| 26 | +// CHECK: metatype $@objc_metatype |
| 27 | +// CHECK: return |
| 28 | +// peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_metatype () -> Swift.AnyObject |
| 29 | +sil @_TF31peephole_thick_to_objc_metatype36test_thick_to_objc_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @owned AnyObject { |
| 30 | +bb0: |
| 31 | + %0 = metatype $@thick XImpl.Type // users: %1, %2 |
| 32 | + %2 = thick_to_objc_metatype %0 : $@thick XImpl.Type to $@objc_metatype XImpl.Type // user: %3 |
| 33 | + %3 = objc_metatype_to_object %2 : $@objc_metatype XImpl.Type to $AnyObject // user: %4 |
| 34 | + return %3 : $AnyObject // id: %4 |
| 35 | +} |
| 36 | + |
| 37 | +// (thick_to_objc_metatype (existential_metatype @thick)) -> (existential_metatype @objc_metatype) |
| 38 | +// |
| 39 | +// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype48test_thick_to_objc_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @owned AnyObject |
| 40 | +// CHECK-NOT: existential_metatype $@thick |
| 41 | +// CHECK-NOT: {{thick_to_objc_metatype }} |
| 42 | +// CHECK: existential_metatype $@objc_metatype |
| 43 | +// CHECK: return |
| 44 | +// peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_existential_metatype (peephole_thick_to_objc_metatype.X) -> Swift.AnyObject |
| 45 | +sil @_TF31peephole_thick_to_objc_metatype48test_thick_to_objc_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @owned AnyObject { |
| 46 | +bb0(%0 : $X): |
| 47 | + debug_value %0 : $X, let, name "o" // id: %1 |
| 48 | + %2 = existential_metatype $@thick X.Type, %0 : $X // user: %3 |
| 49 | + %3 = thick_to_objc_metatype %2 : $@thick X.Type to $@objc_metatype X.Type // user: %4 |
| 50 | + %4 = objc_existential_metatype_to_object %3 : $@objc_metatype X.Type to $AnyObject // users: %5, %7 |
| 51 | + debug_value %4 : $AnyObject, let, name "Ty" // id: %5 |
| 52 | + strong_release %0 : $X // id: %6 |
| 53 | + return %4 : $AnyObject // id: %7 |
| 54 | +} |
| 55 | + |
| 56 | +// (thick_to_objc_metatype (value_metatype @thick)) -> (value_metatype @objc_metatype) |
| 57 | +// |
| 58 | +// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype42test_thick_to_objc_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) <T where T : AnyObject> (@owned T) -> @owned An |
| 59 | +// CHECK-NOT: value_metatype $@thick |
| 60 | +// CHECK-NOT: {{thick_to_objc_metatype }} |
| 61 | +// CHECK: value_metatype $@objc_metatype |
| 62 | +// CHECK: return |
| 63 | +// peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_value_metatype <A : Swift.AnyObject>(A) -> Swift.AnyObject |
| 64 | +sil @_TF31peephole_thick_to_objc_metatype42test_thick_to_objc_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) <T where T : AnyObject> (@owned T) -> @owned AnyObject { |
| 65 | +bb0(%0 : $T): |
| 66 | + debug_value %0 : $T, let, name "o" // id: %1 |
| 67 | + %2 = value_metatype $@thick T.Type, %0 : $T // user: %3 |
| 68 | + %3 = thick_to_objc_metatype %2 : $@thick T.Type to $@objc_metatype T.Type // user: %4 |
| 69 | + %4 = objc_metatype_to_object %3 : $@objc_metatype T.Type to $AnyObject // users: %5, %7 |
| 70 | + debug_value %4 : $AnyObject, let, name "Ty" // id: %5 |
| 71 | + strong_release %0 : $T // id: %6 |
| 72 | + return %4 : $AnyObject // id: %7 |
| 73 | +} |
| 74 | + |
| 75 | +// (objc_to_thick_metatype (metatype @objc_metatype)) -> (metatype @thick) |
| 76 | +// |
| 77 | +// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype36test_objc_to_thick_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @thick XImpl.Type |
| 78 | +// CHECK-NOT: metatype $@objc_metatype |
| 79 | +// CHECK-NOT: {{objc_to_thick_metatype }} |
| 80 | +// CHECK: metatype $@thick |
| 81 | +// CHECK: return |
| 82 | +sil @_TF31peephole_thick_to_objc_metatype36test_objc_to_thick_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @thick XImpl.Type { |
| 83 | +bb0: |
| 84 | + %0 = metatype $@objc_metatype XImpl.Type // users: %1, %2 |
| 85 | + %2 = objc_to_thick_metatype %0 : $@objc_metatype XImpl.Type to $@thick XImpl.Type |
| 86 | + return %2 : $@thick XImpl.Type |
| 87 | +} |
| 88 | + |
| 89 | +// (objc_to_objc_metatype (existential_metatype @objc_metatype)) -> (existential_metatype @thick) |
| 90 | +// |
| 91 | +// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype48test_objc_to_thick_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @thick X.Type |
| 92 | +// CHECK-NOT: existential_metatype $@objc_metatype |
| 93 | +// CHECK-NOT: {{objc_to_thick_metatype }} |
| 94 | +// CHECK: existential_metatype $@thick |
| 95 | +// CHECK: return |
| 96 | +sil @_TF31peephole_thick_to_objc_metatype48test_objc_to_thick_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @thick X.Type { |
| 97 | +bb0(%0 : $X): |
| 98 | + debug_value %0 : $X, let, name "o" // id: %1 |
| 99 | + %2 = existential_metatype $@objc_metatype X.Type, %0 : $X // user: %3 |
| 100 | + %3 = objc_to_thick_metatype %2 : $@objc_metatype X.Type to $@thick X.Type // user: %4 |
| 101 | + strong_release %0 : $X |
| 102 | + return %3 : $@thick X.Type |
| 103 | +} |
| 104 | + |
| 105 | +// (objc_to_thick_metatype (value_metatype @objc_metatype)) -> (value_metatype @thick) |
| 106 | +// |
| 107 | +// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype42test_objc_to_thick_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) <T where T : AnyObject> (@owned T) -> @thick T.Type |
| 108 | +// CHECK-NOT: value_metatype $@objc_metatype |
| 109 | +// CHECK-NOT: {{objc_to_thick_metatype }} |
| 110 | +// CHECK: value_metatype $@thick |
| 111 | +// CHECK: return |
| 112 | +sil @_TF31peephole_thick_to_objc_metatype42test_objc_to_thick_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) <T where T : AnyObject> (@owned T) -> @thick T.Type { |
| 113 | +bb0(%0 : $T): |
| 114 | + debug_value %0 : $T, let, name "o" // id: %1 |
| 115 | + %2 = value_metatype $@objc_metatype T.Type, %0 : $T // user: %3 |
| 116 | + %3 = objc_to_thick_metatype %2 : $@objc_metatype T.Type to $@thick T.Type // user: %4 |
| 117 | + strong_release %0 : $T |
| 118 | + return %3 : $@thick T.Type |
| 119 | +} |
| 120 | + |
| 121 | +// CHECK-LABEL: sil @$test_peephole_objc_to_thick_to_objc : |
| 122 | +// CHECK: [[T:%.*]] = apply |
| 123 | +// CHECK-NOT: objc_to_thick_metatype |
| 124 | +// CHECK-NOT: thick_to_objc_metatype |
| 125 | +// CHECK: enum $Optional<@objc_metatype AnyObject.Type>, #Optional.some!enumelt, [[T]] : $@objc_metatype AnyObject.Type |
| 126 | +// CHECK: } // end sil function '$test_peephole_objc_to_thick_to_objc' |
| 127 | + |
| 128 | +sil @$test_peephole_objc_to_thick_to_objc : $@convention(thin) (@guaranteed NSObject) -> Optional<UnsafeMutablePointer<OpaquePointer>> { |
| 129 | +// %0 "obj" // users: %3, %2, %1 |
| 130 | +bb0(%0 : $NSObject): |
| 131 | + debug_value %0 : $NSObject, let, name "obj", argno 1 // id: %1 |
| 132 | + %2 = objc_method %0 : $NSObject, #NSObject.classForCoder!getter.foreign : (NSObject) -> () -> AnyObject.Type, $@convention(objc_method) (NSObject) -> @objc_metatype AnyObject.Type // user: %3 |
| 133 | + %3 = apply %2(%0) : $@convention(objc_method) (NSObject) -> @objc_metatype AnyObject.Type // user: %4 |
| 134 | + %4 = objc_to_thick_metatype %3 : $@objc_metatype AnyObject.Type to $@thick AnyObject.Type // users: %6, %5 |
| 135 | + debug_value %4 : $@thick AnyObject.Type, let, name "c" // id: %5 |
| 136 | + %6 = thick_to_objc_metatype %4 : $@thick AnyObject.Type to $@objc_metatype AnyObject.Type // user: %7 |
| 137 | + %7 = enum $Optional<@objc_metatype AnyObject.Type>, #Optional.some!enumelt, %6 : $@objc_metatype AnyObject.Type // user: %10 |
| 138 | + %8 = enum $Optional<UnsafeMutablePointer<UInt32>>, #Optional.none!enumelt // user: %10 |
| 139 | + // function_ref class_copyMethodList |
| 140 | + %9 = function_ref @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> // user: %10 |
| 141 | + %10 = apply %9(%7, %8) : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> // users: %12, %11 |
| 142 | + debug_value %10 : $Optional<UnsafeMutablePointer<OpaquePointer>>, let, name "l" // id: %11 |
| 143 | + return %10 : $Optional<UnsafeMutablePointer<OpaquePointer>> // id: %12 |
| 144 | +} |
| 145 | + |
| 146 | +// CHECK-LABEL: sil @$test_peephole_thick_to_objc_to_thick : |
| 147 | +// CHECK: [[T:%.*]] = apply |
| 148 | +// CHECK-NOT: thick_to_objc_metatype |
| 149 | +// CHECK-NOT: objc_to_thick_metatype |
| 150 | +// CHECK: return [[T]] |
| 151 | +// CHECK: } // end sil function '$test_peephole_thick_to_objc_to_thick' |
| 152 | + |
| 153 | +sil @$test_peephole_thick_to_objc_to_thick : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type { |
| 154 | +bb0(%0 : $AnyObject): |
| 155 | + %func = function_ref @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type |
| 156 | + %res = apply %func(%0) : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type |
| 157 | + %objctype = thick_to_objc_metatype %res : $@thick AnyObject.Type to $@objc_metatype AnyObject.Type |
| 158 | + %thicktype = objc_to_thick_metatype %objctype : $@objc_metatype AnyObject.Type to $@thick AnyObject.Type |
| 159 | + return %thicktype : $@thick AnyObject.Type |
| 160 | +} |
| 161 | + |
| 162 | +// class_copyMethodList |
| 163 | +sil [serializable] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> |
| 164 | +sil [serializable] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type |
0 commit comments