// RUN: %target-swift-frontend -emit-ir %s | FileCheck %s // REQUIRES: CPU=x86_64 // REQUIRES: objc_interop import Builtin import Swift // CHECK: [[REF:%swift.refcounted]] = type // CHECK: [[TYPE:%swift.type]] = type // CHECK: [[OBJCCLASS:%objc_class]] = type // CHECK: [[OPAQUE:%swift.opaque]] = type opaque // CHECK: [[C_CLASS:%C5class1C]] = type // CHECK: [[OBJCOBJ:%objc_object]] = type class C {} sil_vtable C {} // : include _Tt prefix here // CHECK: [[C_NAME:@.*]] = private unnamed_addr constant [13 x i8] c"_TtC5class1C\00" // CHECK: @_DATA__TtC5class1C = private constant {{.*}} { // \ CHECK: i32 128, // \ CHECK: i32 16, // \ CHECK: i32 16, // \ CHECK: i32 0, // \ CHECK: i8* null, // \ CHECK: i8* getelementptr inbounds ([13 x i8], [13 x i8]* [[C_NAME]], i64 0, i64 0), // \ CHECK: i8* null, // \ CHECK: i8* null, // \ CHECK: i8* null, // \ CHECK: i8* null, // \ CHECK: i8* null // \ CHECK: } // CHECK: @_TMfC5class1C = internal global <{ {{.*}} }> <{ // \ CHECK: void ([[C_CLASS]]*)* @_TFC5class1CD, // \ CHECK: i8** @_TWVBo, // \ CHECK: i64 ptrtoint ([[OBJCCLASS]]* @_TMmC5class1C to i64), // \ CHECK: [[OBJCCLASS]]* @"OBJC_CLASS_$_SwiftObject", // \ CHECK: [[OPAQUE]]* @_objc_empty_cache, // \ CHECK: [[OPAQUE]]* null, // \ CHECK: i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC5class1C to i64), i64 1) // \ CHECK: }> // Destroying destructor // CHECK: define{{( protected)?}} [[REF]]* @_TFC5class1Cd([[C_CLASS]]*) {{.*}} { // CHECK-NEXT: entry: // CHECK-NEXT: [[OBJ_PTR:%[a-zA-Z0-9]+]] = bitcast [[C_CLASS]]* %0 to [[REF]]* // CHECK-NEXT: ret [[REF]]* [[OBJ_PTR]] sil @_TFC5class1Cd : $@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{{( protected)?}} void @_TFC5class1CD([[C_CLASS]]*) sil @_TFC5class1CD : $@convention(method) (@owned C) -> () { bb0(%0 : $C): // CHECK-NEXT: entry // CHECK-NEXT: [[SELF:%[a-zA-Z0-9]+]] = call [[REF]]* @_TFC5class1Cd([[C_CLASS]]* %0) // CHECK-NEXT: [[SELF_OBJ:%[a-zA-Z0-9]+]] = bitcast [[REF]]* [[SELF]] to [[C_CLASS]]* %1 = function_ref @_TFC5class1Cd : $@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{{( protected)?}} [[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{{( protected)?}} [[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{{( protected)?}} %C5class1C* @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 i32* // CHECK: [[ALIGN32:%.*]] = load i32, i32* [[T1]], align 4 // CHECK: [[ALIGN:%.*]] = zext i32 [[ALIGN32]] to i64 // CHECK: [[RESULT:%[0-9]+]] = call noalias %swift.refcounted* @rt_swift_allocObject(%swift.type* %0, i64 [[SIZE]], i64 [[ALIGN]]) %1 = alloc_ref_dynamic %0 : $@thick C.Type, $C return %1 : $C } // CHECK-LABEL: define{{( protected)?}} %C5class1C* @autorelease(%C5class1C*) {{.*}} { // CHECK: %1 = bitcast %C5class1C* %0 to %objc_object* // CHECK: call %objc_object* @objc_autorelease(%objc_object* %1) // CHECK: ret %C5class1C* %0 sil @autorelease : $@convention(thin) (@owned C) -> C { entry(%c : $C): autorelease_value %c : $C return %c : $C } // CHECK-LABEL: define{{( protected)?}} i64 @autorelease_optional(i64) {{.*}} { // CHECK: %1 = inttoptr i64 %0 to %objc_object* // CHECK: call %objc_object* @objc_autorelease(%objc_object* %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(thin) (@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 #RequiredBase.init!allocator.1: alloc_RequiredBase } // rdar://problem/19902523 protocol ClassConstraint: class {} class ClassConstraintConformance: ClassConstraint {} sil_vtable ClassConstraintConformance {} class ClassConstrainedGenericField { var field: T init() } sil_vtable ClassConstrainedGenericField {} sil @fixed_class_generic_field : $@convention(thin) (@owned ClassConstrainedGenericField) -> @owned ClassConstraintConformance { entry(%x : $ClassConstrainedGenericField): %a = ref_element_addr %x : $ClassConstrainedGenericField, #ClassConstrainedGenericField.field %b = load %a : $*ClassConstraintConformance return %b : $ClassConstraintConformance } // CHECK-LABEL: define{{( protected)?}} %C5class26ClassConstraintConformance* @fixed_class_generic_field(%C5class28ClassConstrainedGenericField*) // CHECK: [[FIELD_ADDR_GENERIC:%.*]] = getelementptr inbounds %C5class28ClassConstrainedGenericField, %C5class28ClassConstrainedGenericField* %0, i32 0, i32 1 // CHECK: [[FIELD_ADDR_CONCRETE:%.*]] = bitcast %objc_object** [[FIELD_ADDR_GENERIC]] to %C5class26ClassConstraintConformance** // CHECK: load %C5class26ClassConstraintConformance*, %C5class26ClassConstraintConformance** [[FIELD_ADDR_CONCRETE]]