mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Recent Swift uses 2 as the is-Swift bit when running on newer versions, and 1 on older versions. Since it's difficult or impossible to know what we'll be running on at build time, make the selection at runtime.
171 lines
7.6 KiB
Plaintext
171 lines
7.6 KiB
Plaintext
// RUN: %target-swift-frontend -enable-objc-interop -emit-ir %s | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-%target-import-type
|
|
|
|
// REQUIRES: CPU=x86_64
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
// CHECK-DAG: [[REF:%swift.refcounted]] = type
|
|
// CHECK-DAG: [[TYPE:%swift.type]] = type
|
|
// CHECK-DAG: [[OBJCCLASS:%objc_class]] = type
|
|
// CHECK-DAG: [[OPAQUE:%swift.opaque]] = type opaque
|
|
// CHECK-DAG: [[C_CLASS:%T5class1CC]] = type
|
|
// CHECK-DAG: [[OBJCOBJ:%objc_object]] = type
|
|
|
|
class C {}
|
|
sil_vtable C {}
|
|
|
|
// <rdar://14812566>: include _Tt prefix here
|
|
// CHECK: [[C_NAME:@.*]] = private unnamed_addr constant [13 x i8] c"_TtC5class1C\00"
|
|
|
|
// CHECK: @_DATA__TtC5class1C = private constant {{.*}} {
|
|
// CHECK-SAME: i32 128,
|
|
// CHECK-SAME: i32 16,
|
|
// CHECK-SAME: i32 16,
|
|
// CHECK-SAME: i32 0,
|
|
// CHECK-SAME: i8* null,
|
|
// CHECK-SAME: i8* getelementptr inbounds ([13 x i8], [13 x i8]* [[C_NAME]], i64 0, i64 0),
|
|
// CHECK-SAME: i8* null,
|
|
// CHECK-SAME: i8* null,
|
|
// CHECK-SAME: i8* null,
|
|
// CHECK-SAME: i8* null,
|
|
// CHECK-SAME: i8* null
|
|
// CHECK-SAME: }
|
|
|
|
// CHECK: @"$s5class1CCMf" = internal global <{ {{.*}} }> <{
|
|
// CHECK-SAME: void ([[C_CLASS]]*)* @"$s5class1CCfD",
|
|
// CHECK-DIRECT-SAME: i8** @"$sBoWV",
|
|
// CHECK-INDIRECT-SAME: i8** null,
|
|
// CHECK-SAME: i64 ptrtoint ([[OBJCCLASS]]* @"$s5class1CCMm" to i64),
|
|
// CHECK-DIRECT-SAME: [[OBJCCLASS]]* @"OBJC_CLASS_$_{{(_TtCs12_)?}}SwiftObject",
|
|
// CHECK-INDIRECT-SAME: %swift.type* null,
|
|
// CHECK-SAME: [[OPAQUE]]* @_objc_empty_cache,
|
|
// CHECK-SAME: [[OPAQUE]]* null,
|
|
// CHECK-SAME: i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC5class1C to i64), i64 [[IS_SWIFT_BIT:1|2]])
|
|
// CHECK-SAME: }>
|
|
|
|
// Destroying destructor
|
|
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc [[REF]]* @"$s5class1CCfd"([[C_CLASS]]* swiftself) {{.*}} {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[OBJ_PTR:%[a-zA-Z0-9]+]] = bitcast [[C_CLASS]]* %0 to [[REF]]*
|
|
// CHECK-NEXT: ret [[REF]]* [[OBJ_PTR]]
|
|
sil @$s5class1CCfd : $@convention(method) (@owned C) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : $C):
|
|
%1 = unchecked_ref_cast %0 : $C to $Builtin.NativeObject // user: %2
|
|
return %1 : $Builtin.NativeObject // id: %2
|
|
}
|
|
|
|
// Deallocating destructor
|
|
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s5class1CCfD"([[C_CLASS]]* swiftself)
|
|
sil @$s5class1CCfD : $@convention(method) (@owned C) -> () {
|
|
bb0(%0 : $C):
|
|
// CHECK-NEXT: entry
|
|
// CHECK-NEXT: [[SELF:%[a-zA-Z0-9]+]] = call swiftcc [[REF]]* @"$s5class1CCfd"([[C_CLASS]]* swiftself %0)
|
|
// CHECK-NEXT: [[SELF_OBJ:%[a-zA-Z0-9]+]] = bitcast [[REF]]* [[SELF]] to [[C_CLASS]]*
|
|
%1 = function_ref @$s5class1CCfd : $@convention(method) (@owned C) -> @owned Builtin.NativeObject // user: %2
|
|
%2 = apply %1(%0) : $@convention(method) (@owned C) -> @owned Builtin.NativeObject // user: %3
|
|
%3 = unchecked_ref_cast %2 : $Builtin.NativeObject to $C // user: %4
|
|
// CHECK-NEXT: [[SELF:%[a-zA-Z0-9]+]] = bitcast [[C_CLASS]]* [[SELF_OBJ]] to [[REF]]*
|
|
// CHECK-NEXT: call void @swift_deallocClassInstance([[REF]]* [[SELF]], i64 16, i64 7)
|
|
dealloc_ref %3 : $C // id: %4
|
|
// CHECK-NEXT: ret void
|
|
%5 = tuple () // user: %6
|
|
return %5 : $() // id: %6
|
|
}
|
|
|
|
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc [[REF]]* @unchecked_ref_cast_cast([[C_CLASS]]*)
|
|
// CHECK: bitcast [[C_CLASS]]* {{%.*}} to [[REF]]*
|
|
sil @unchecked_ref_cast_cast : $@convention(thin) (C) -> Builtin.NativeObject {
|
|
entry(%c : $C):
|
|
%r = unchecked_ref_cast %c : $C to $Builtin.NativeObject
|
|
return %r : $Builtin.NativeObject
|
|
}
|
|
|
|
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc [[OBJCOBJ]]* @ref_to_objc_pointer_cast([[C_CLASS]]*)
|
|
// CHECK: bitcast [[C_CLASS]]* %0 to [[OBJCOBJ]]*
|
|
sil @ref_to_objc_pointer_cast : $@convention(thin) (C) -> Builtin.UnknownObject {
|
|
entry(%c : $C):
|
|
%r = unchecked_ref_cast %c : $C to $Builtin.UnknownObject
|
|
return %r : $Builtin.UnknownObject
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %T5class1CC* @alloc_ref_dynamic(%swift.type*)
|
|
sil @alloc_ref_dynamic : $@convention(thin) (@thick C.Type) -> @owned C {
|
|
bb0(%0 : $@thick C.Type):
|
|
// CHECK: [[META_PTR:%[0-9]+]] = bitcast %swift.type* %0 to i8*
|
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[META_PTR]], i32 48
|
|
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
|
|
// CHECK: [[SIZE32:%.*]] = load i32, i32* [[T1]], align 8
|
|
// CHECK: [[SIZE:%.*]] = zext i32 [[SIZE32]] to i64
|
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[META_PTR]], i32 52
|
|
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i16*
|
|
// CHECK: [[ALIGN16:%.*]] = load i16, i16* [[T1]], align 4
|
|
// CHECK: [[ALIGN:%.*]] = zext i16 [[ALIGN16]] to i64
|
|
// CHECK: [[RESULT:%[0-9]+]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* %0, i64 [[SIZE]], i64 [[ALIGN]])
|
|
%1 = alloc_ref_dynamic %0 : $@thick C.Type, $C
|
|
return %1 : $C
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %T5class1CC* @autorelease(%T5class1CC*) {{.*}} {
|
|
// CHECK: %1 = bitcast %T5class1CC* %0 to i8*
|
|
// CHECK: call i8* @llvm.objc.autorelease(i8* %1)
|
|
// CHECK: ret %T5class1CC* %0
|
|
sil @autorelease : $@convention(thin) (@owned C) -> C {
|
|
entry(%c : $C):
|
|
autorelease_value %c : $C
|
|
return %c : $C
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @autorelease_optional(i64) {{.*}} {
|
|
// CHECK: %1 = inttoptr i64 %0 to i8*
|
|
// CHECK: call i8* @llvm.objc.autorelease(i8* %1)
|
|
// CHECK: ret i64 %0
|
|
sil @autorelease_optional : $@convention(thin) (@owned C?) -> C? {
|
|
entry(%c : $C?):
|
|
autorelease_value %c : $C?
|
|
return %c : $C?
|
|
}
|
|
|
|
// rdar://problem/19514920
|
|
|
|
class NonRequiredBase {}
|
|
class RequiredBase: NonRequiredBase {
|
|
required override init()
|
|
}
|
|
|
|
sil public_external @init_NonRequiredBase : $@convention(method) (@owned NonRequiredBase) -> @owned NonRequiredBase
|
|
sil public_external @alloc_RequiredBase : $@convention(method) (@thick RequiredBase.Type) -> @owned RequiredBase
|
|
sil public_external @init_RequiredBase : $@convention(method) (@owned RequiredBase) -> @owned RequiredBase
|
|
|
|
sil_vtable NonRequiredBase {
|
|
#NonRequiredBase.init!initializer.1: @init_NonRequiredBase
|
|
}
|
|
|
|
sil_vtable RequiredBase {
|
|
#NonRequiredBase.init!initializer.1: @init_RequiredBase [override]
|
|
#RequiredBase.init!allocator.1: @alloc_RequiredBase
|
|
}
|
|
|
|
// rdar://problem/19902523
|
|
|
|
protocol ClassConstraint: class {}
|
|
class ClassConstraintConformance: ClassConstraint {}
|
|
sil_vtable ClassConstraintConformance {}
|
|
|
|
class ClassConstrainedGenericField<T: ClassConstraint> {
|
|
var field: T
|
|
init()
|
|
}
|
|
sil_vtable ClassConstrainedGenericField {}
|
|
|
|
sil @fixed_class_generic_field : $@convention(thin) (@owned ClassConstrainedGenericField<ClassConstraintConformance>) -> @owned ClassConstraintConformance {
|
|
entry(%x : $ClassConstrainedGenericField<ClassConstraintConformance>):
|
|
%a = ref_element_addr %x : $ClassConstrainedGenericField<ClassConstraintConformance>, #ClassConstrainedGenericField.field
|
|
%b = load %a : $*ClassConstraintConformance
|
|
return %b : $ClassConstraintConformance
|
|
}
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %T5class26ClassConstraintConformanceC* @fixed_class_generic_field(%T5class28ClassConstrainedGenericFieldCyAA0B21ConstraintConformanceCG*)
|
|
// CHECK: [[FIELD_ADDR_GENERIC:%.*]] = getelementptr inbounds %T5class28ClassConstrainedGenericFieldCyAA0B21ConstraintConformanceCG, %T5class28ClassConstrainedGenericFieldCyAA0B21ConstraintConformanceCG* %0, i32 0, i32 1
|
|
// CHECK: load %T5class26ClassConstraintConformanceC*, %T5class26ClassConstraintConformanceC** [[FIELD_ADDR_GENERIC]]
|
|
|