blob: 6c0182dbd3b0abc3f8e1290e8cf61998ddec32a8 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine | %FileCheck %s
// REQUIRES: objc_interop
sil_stage canonical
import Builtin
import Swift
import SwiftShims
import Foundation
@objc(XX) protocol X {
}
class XImpl : X {
@objc deinit
init()
}
// (thick_to_objc_metatype (metatype @thick)) -> (metatype @objc_metatype)
//
// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype36test_thick_to_objc_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @owned AnyObject
// CHECK-NOT: metatype $@thick
// CHECK-NOT: {{thick_to_objc_metatype }}
// CHECK: metatype $@objc_metatype
// CHECK: return
// peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_metatype () -> Swift.AnyObject
sil @_TF31peephole_thick_to_objc_metatype36test_thick_to_objc_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @owned AnyObject {
bb0:
%0 = metatype $@thick XImpl.Type // users: %1, %2
%2 = thick_to_objc_metatype %0 : $@thick XImpl.Type to $@objc_metatype XImpl.Type // user: %3
%3 = objc_metatype_to_object %2 : $@objc_metatype XImpl.Type to $AnyObject // user: %4
return %3 : $AnyObject // id: %4
}
// (thick_to_objc_metatype (existential_metatype @thick)) -> (existential_metatype @objc_metatype)
//
// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype48test_thick_to_objc_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @owned AnyObject
// CHECK-NOT: existential_metatype $@thick
// CHECK-NOT: {{thick_to_objc_metatype }}
// CHECK: existential_metatype $@objc_metatype
// CHECK: return
// peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_existential_metatype (peephole_thick_to_objc_metatype.X) -> Swift.AnyObject
sil @_TF31peephole_thick_to_objc_metatype48test_thick_to_objc_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @owned AnyObject {
bb0(%0 : $X):
debug_value %0 : $X, let, name "o" // id: %1
%2 = existential_metatype $@thick X.Type, %0 : $X // user: %3
%3 = thick_to_objc_metatype %2 : $@thick X.Type to $@objc_metatype X.Type // user: %4
%4 = objc_existential_metatype_to_object %3 : $@objc_metatype X.Type to $AnyObject // users: %5, %7
debug_value %4 : $AnyObject, let, name "Ty" // id: %5
strong_release %0 : $X // id: %6
return %4 : $AnyObject // id: %7
}
// (thick_to_objc_metatype (value_metatype @thick)) -> (value_metatype @objc_metatype)
//
// 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
// CHECK-NOT: value_metatype $@thick
// CHECK-NOT: {{thick_to_objc_metatype }}
// CHECK: value_metatype $@objc_metatype
// CHECK: return
// peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_value_metatype <A : Swift.AnyObject>(A) -> Swift.AnyObject
sil @_TF31peephole_thick_to_objc_metatype42test_thick_to_objc_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) <T where T : AnyObject> (@owned T) -> @owned AnyObject {
bb0(%0 : $T):
debug_value %0 : $T, let, name "o" // id: %1
%2 = value_metatype $@thick T.Type, %0 : $T // user: %3
%3 = thick_to_objc_metatype %2 : $@thick T.Type to $@objc_metatype T.Type // user: %4
%4 = objc_metatype_to_object %3 : $@objc_metatype T.Type to $AnyObject // users: %5, %7
debug_value %4 : $AnyObject, let, name "Ty" // id: %5
strong_release %0 : $T // id: %6
return %4 : $AnyObject // id: %7
}
// (objc_to_thick_metatype (metatype @objc_metatype)) -> (metatype @thick)
//
// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype36test_objc_to_thick_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @thick XImpl.Type
// CHECK-NOT: metatype $@objc_metatype
// CHECK-NOT: {{objc_to_thick_metatype }}
// CHECK: metatype $@thick
// CHECK: return
sil @_TF31peephole_thick_to_objc_metatype36test_objc_to_thick_metatype_metatypeFT_Ps9AnyObject_ : $@convention(thin) () -> @thick XImpl.Type {
bb0:
%0 = metatype $@objc_metatype XImpl.Type // users: %1, %2
%2 = objc_to_thick_metatype %0 : $@objc_metatype XImpl.Type to $@thick XImpl.Type
return %2 : $@thick XImpl.Type
}
// (objc_to_objc_metatype (existential_metatype @objc_metatype)) -> (existential_metatype @thick)
//
// CHECK-LABEL: sil @_TF31peephole_thick_to_objc_metatype48test_objc_to_thick_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @thick X.Type
// CHECK-NOT: existential_metatype $@objc_metatype
// CHECK-NOT: {{objc_to_thick_metatype }}
// CHECK: existential_metatype $@thick
// CHECK: return
sil @_TF31peephole_thick_to_objc_metatype48test_objc_to_thick_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @thick X.Type {
bb0(%0 : $X):
debug_value %0 : $X, let, name "o" // id: %1
%2 = existential_metatype $@objc_metatype X.Type, %0 : $X // user: %3
%3 = objc_to_thick_metatype %2 : $@objc_metatype X.Type to $@thick X.Type // user: %4
strong_release %0 : $X
return %3 : $@thick X.Type
}
// (objc_to_thick_metatype (value_metatype @objc_metatype)) -> (value_metatype @thick)
//
// 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
// CHECK-NOT: value_metatype $@objc_metatype
// CHECK-NOT: {{objc_to_thick_metatype }}
// CHECK: value_metatype $@thick
// CHECK: return
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 {
bb0(%0 : $T):
debug_value %0 : $T, let, name "o" // id: %1
%2 = value_metatype $@objc_metatype T.Type, %0 : $T // user: %3
%3 = objc_to_thick_metatype %2 : $@objc_metatype T.Type to $@thick T.Type // user: %4
strong_release %0 : $T
return %3 : $@thick T.Type
}
// CHECK-LABEL: sil @$test_peephole_objc_to_thick_to_objc :
// CHECK: [[T:%.*]] = apply
// CHECK-NOT: objc_to_thick_metatype
// CHECK-NOT: thick_to_objc_metatype
// CHECK: enum $Optional<@objc_metatype AnyObject.Type>, #Optional.some!enumelt, [[T]] : $@objc_metatype AnyObject.Type
// CHECK: } // end sil function '$test_peephole_objc_to_thick_to_objc'
sil @$test_peephole_objc_to_thick_to_objc : $@convention(thin) (@guaranteed NSObject) -> Optional<UnsafeMutablePointer<OpaquePointer>> {
// %0 "obj" // users: %3, %2, %1
bb0(%0 : $NSObject):
debug_value %0 : $NSObject, let, name "obj", argno 1 // id: %1
%2 = objc_method %0 : $NSObject, #NSObject.classForCoder!getter.foreign : (NSObject) -> () -> AnyObject.Type, $@convention(objc_method) (NSObject) -> @objc_metatype AnyObject.Type // user: %3
%3 = apply %2(%0) : $@convention(objc_method) (NSObject) -> @objc_metatype AnyObject.Type // user: %4
%4 = objc_to_thick_metatype %3 : $@objc_metatype AnyObject.Type to $@thick AnyObject.Type // users: %6, %5
debug_value %4 : $@thick AnyObject.Type, let, name "c" // id: %5
%6 = thick_to_objc_metatype %4 : $@thick AnyObject.Type to $@objc_metatype AnyObject.Type // user: %7
%7 = enum $Optional<@objc_metatype AnyObject.Type>, #Optional.some!enumelt, %6 : $@objc_metatype AnyObject.Type // user: %10
%8 = enum $Optional<UnsafeMutablePointer<UInt32>>, #Optional.none!enumelt // user: %10
// function_ref class_copyMethodList
%9 = function_ref @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> // user: %10
%10 = apply %9(%7, %8) : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> // users: %12, %11
debug_value %10 : $Optional<UnsafeMutablePointer<OpaquePointer>>, let, name "l" // id: %11
return %10 : $Optional<UnsafeMutablePointer<OpaquePointer>> // id: %12
}
// CHECK-LABEL: sil @$test_peephole_thick_to_objc_to_thick :
// CHECK: [[T:%.*]] = apply
// CHECK-NOT: thick_to_objc_metatype
// CHECK-NOT: objc_to_thick_metatype
// CHECK: return [[T]]
// CHECK: } // end sil function '$test_peephole_thick_to_objc_to_thick'
sil @$test_peephole_thick_to_objc_to_thick : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type {
bb0(%0 : $AnyObject):
%func = function_ref @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type
%res = apply %func(%0) : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type
%objctype = thick_to_objc_metatype %res : $@thick AnyObject.Type to $@objc_metatype AnyObject.Type
%thicktype = objc_to_thick_metatype %objctype : $@objc_metatype AnyObject.Type to $@thick AnyObject.Type
return %thicktype : $@thick AnyObject.Type
}
// class_copyMethodList
sil [serializable] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>>
sil [serializable] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type