| // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -emit-ir | %FileCheck %s |
| |
| // REQUIRES: CPU=i386 || CPU=x86_64 |
| // XFAIL: linux |
| |
| import Swift |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc void @archetype_metatype_cast |
| // CHECK: %0 = call %swift.type* @swift_dynamicCastMetatype(%swift.type* %T, %swift.type* %U) |
| // CHECK: %1 = icmp ne %swift.type* %0, null |
| sil @archetype_metatype_cast : $@convention(thin) <T, U> () -> () { |
| entry: |
| %0 = metatype $@thick T.Type |
| checked_cast_br %0 : $@thick T.Type to $@thick U.Type, yes, no |
| yes(%1 : $@thick U.Type): |
| br end |
| |
| no: |
| br end |
| |
| end: |
| return undef : $() |
| } |
| |
| protocol P {} |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc void @existential_archetype_metatype_cast(%swift.type*, i8**, %swift.type* %T) |
| // CHECK: [[T0:%.*]] = call %swift.type* @swift_dynamicCastMetatype(%swift.type* %0, %swift.type* %T) |
| // CHECK: [[T1:%.*]] = icmp ne %swift.type* [[T0]], null |
| sil @existential_archetype_metatype_cast : $@convention(thin) <T> (@thick P.Type) -> () { |
| entry(%0 : $@thick P.Type): |
| checked_cast_br %0 : $@thick P.Type to $@thick T.Type, yes, no |
| yes(%1 : $@thick T.Type): |
| br end |
| |
| no: |
| br end |
| |
| end: |
| return undef : $() |
| } |
| |
| class SomeClass {} |
| sil_vtable SomeClass {} |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc %objc_object* @metatype_object_conversion(%objc_class*) {{.*}} { |
| // CHECK: %1 = bitcast %objc_class* %0 to %objc_object* |
| // CHECK: ret %objc_object* %1 |
| // CHECK: } |
| sil @metatype_object_conversion : $@convention(thin) (@objc_metatype SomeClass.Type) -> @owned AnyObject { |
| entry(%m : $@objc_metatype SomeClass.Type): |
| %o = objc_metatype_to_object %m : $@objc_metatype SomeClass.Type to $AnyObject |
| return %o : $AnyObject |
| } |
| |
| protocol SomeClassProtocol : class {} |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc %objc_object* @existential_metatype_object_conversion(%objc_class*, i8**) {{.*}} { |
| // CHECK: [[T0:%.*]] = bitcast %objc_class* %0 to %objc_object* |
| // CHECK: ret %objc_object* [[T0]] |
| // CHECK: } |
| sil @existential_metatype_object_conversion : $@convention(thin) (@objc_metatype SomeClassProtocol.Type) -> @owned AnyObject { |
| entry(%m : $@objc_metatype SomeClassProtocol.Type): |
| %o = objc_existential_metatype_to_object %m : $@objc_metatype SomeClassProtocol.Type to $AnyObject |
| return %o : $AnyObject |
| } |
| |
| class OtherClass : SomeClass {} |
| sil_vtable OtherClass {} |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc void @value_metatype_cast(%T14metatype_casts9SomeClassC*) |
| // CHECK: [[T0:%.*]] = bitcast %T14metatype_casts9SomeClassC* %0 to %swift.type** |
| // CHECK: [[T1:%.*]] = load %swift.type*, %swift.type** [[T0]] |
| // CHECK: [[T2:%.*]] = icmp eq %swift.type* [[T1]], {{.*}} @_T014metatype_casts10OtherClassCMf |
| sil @value_metatype_cast : $@convention(thin) (SomeClass) -> () { |
| entry(%0 : $SomeClass): |
| %1 = value_metatype $@thick SomeClass.Type, %0 : $SomeClass |
| checked_cast_br [exact] %1 : $@thick SomeClass.Type to $@thick OtherClass.Type, yes, no |
| |
| yes(%2 : $@thick OtherClass.Type): |
| br end |
| |
| no: |
| br end |
| |
| end: |
| return undef : $() |
| } |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @checked_cast_to_anyobject_type |
| // CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to i8* |
| // CHECK: [[CAST:%.*]] = call { i8* } @dynamic_cast_existential_0_class_unconditional(i8* [[T0]], %swift.type* %0) |
| // CHECK: [[RESULT0:%.*]] = extractvalue { i8* } [[CAST]], 0 |
| // CHECK: [[RESULT:%.*]] = bitcast i8* [[RESULT0]] to %swift.type* |
| // CHECK: ret %swift.type* [[RESULT]] |
| sil @checked_cast_to_anyobject_type : $@convention(thin) (@thick Any.Type) -> @thick AnyObject.Type { |
| entry(%0 : $@thick Any.Type): |
| %2 = unconditional_checked_cast %0 : $@thick Any.Type to $@thick AnyObject.Type |
| return %2 : $@thick AnyObject.Type |
| } |
| |
| // Trivial case -- we know the source is a class metatype, so there's nothing |
| // to check. |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @checked_cast_class_to_anyobject_type |
| // CHECK: [[METATYPE:%.*]] = call %swift.type* @_T014metatype_casts9SomeClassCMa() |
| // CHECK: ret %swift.type* [[METATYPE]] |
| sil @checked_cast_class_to_anyobject_type : $@convention(thin) () -> @thick AnyObject.Type { |
| entry: |
| %1 = metatype $@thick SomeClass.Type |
| %2 = unconditional_checked_cast %1 : $@thick SomeClass.Type to $@thick AnyObject.Type |
| return %2 : $@thick AnyObject.Type |
| } |