blob: e2fe978156bfc5ef5c12b373d1da41bd3da20504 [file] [log] [blame]
// RUN: rm -rf %t && mkdir %t
// RUN: %build-irgen-test-overlays
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir | FileCheck %s
// REQUIRES: CPU=x86_64
// REQUIRES: objc_interop
// CHECK: [[SGIZMO:%C12objc_dealloc10SwiftGizmo]] = type
// CHECK: [[GIZMO:%CSo5Gizmo]] = type opaque
sil_stage raw
import Builtin
import Swift
import gizmo
class X { }
sil_vtable X {}
sil @_TFC12objc_dealloc1XD : $@convention(method) (X) -> ()
func onDestruct() { }
class SwiftGizmo : Gizmo {
var x : X
override init()
deinit
}
sil_vtable SwiftGizmo {}
sil @_TFC12objc_dealloc10SwiftGizmoD : $@convention(method) (SwiftGizmo) -> ()
sil @_TF12objc_dealloc10onDestructFT_T_ : $@convention(thin) () -> () {
bb0:
%0 = tuple ()
%1 = tuple () // user: %2
return %1 : $() // id: %2
}
sil @_TFC12objc_dealloc10SwiftGizmod : $@convention(thin) (@owned SwiftGizmo) -> @owned Builtin.NativeObject {
bb0(%0 : $SwiftGizmo):
// function_ref objc_dealloc.onDestruct () -> ()
%1 = function_ref @_TF12objc_dealloc10onDestructFT_T_ : $@convention(thin) () -> () // user: %2
%2 = apply %1() : $@convention(thin) () -> ()
%3 = ref_element_addr %0 : $SwiftGizmo, #SwiftGizmo.x // user: %4
destroy_addr %3 : $*X // id: %4
%5 = unchecked_ref_cast %0 : $SwiftGizmo to $Builtin.NativeObject // user: %6
return %5 : $Builtin.NativeObject // id: %6
}
sil @_TToFC12objc_dealloc10SwiftGizmog1xC12objc_dealloc1X : $@convention(objc_method) (SwiftGizmo) -> @autoreleased X {
bb0(%0 : $SwiftGizmo):
%1 = ref_element_addr %0 : $SwiftGizmo, #SwiftGizmo.x // user: %2
%2 = load %1 : $*X // users: %4, %3
strong_retain %2 : $X // id: %3
return %2 : $X // id: %4
}
sil @_TToFC12objc_dealloc10SwiftGizmos1xC12objc_dealloc1X : $@convention(objc_method) (X, SwiftGizmo) -> () {
bb0(%0 : $X, %1 : $SwiftGizmo):
strong_retain %0 : $X // id: %2
strong_retain %1 : $SwiftGizmo // id: %3
%4 = ref_element_addr %1 : $SwiftGizmo, #SwiftGizmo.x // user: %5
assign %0 to %4 : $*X // id: %5
strong_release %1 : $SwiftGizmo // id: %6
%7 = tuple () // user: %8
return %7 : $() // id: %8
}
// CHECK: define internal void @_TToFC12objc_dealloc10SwiftGizmoD([[OPAQUE:%.*]]*, i8*) unnamed_addr
sil @_TToFC12objc_dealloc10SwiftGizmoD : $@convention(objc_method) (SwiftGizmo) -> () {
bb0(%0 : $SwiftGizmo):
// CHECK-NEXT: entry
// CHECK-NEXT: [[OBJC_SUPER:%[a-zA-Z0-9_]+]] = alloca %objc_super, align 8
// CHECK: [[SGIZMOVAL:%[a-zA-Z0-9]+]] = bitcast [[OPAQUE]]* %0 to [[SGIZMO]]*
// Call to onDestruct()
// CHECK: call void @_TF12objc_dealloc10onDestructFT_T_()
// function_ref objc_dealloc.onDestruct () -> ()
%1 = function_ref @_TF12objc_dealloc10onDestructFT_T_ : $@convention(thin) () -> () // user: %2
%2 = apply %1() : $@convention(thin) () -> ()
// Destroy instance variables
// FIXME: This should move to .cxx_destruct
// CHECK: [[XOFFSET:%[a-zA-Z0-9]+]] = load i64, i64* @_TWvdvC12objc_dealloc10SwiftGizmo1xCS_1X, align 8
// CHECK-NEXT: bitcast
// CHECK-NEXT: [[IVAR_ADDR:%[a-zA-Z0-9]+]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[XOFFSET]]
// CHECK-NEXT: [[XADDR:%[.a-zA-Z0-9]+]] = bitcast i8* [[IVAR_ADDR]] to %C12objc_dealloc1X**
// CHECK-NEXT: [[X:%[a-zA-Z0-9]+]] = load %C12objc_dealloc1X*, %C12objc_dealloc1X** [[XADDR]], align 8
// CHECK-NEXT: call void bitcast (void (%swift.refcounted*)* @rt_swift_release to void (%C12objc_dealloc1X*)*)(%C12objc_dealloc1X* [[X]])
%3 = ref_element_addr %0 : $SwiftGizmo, #SwiftGizmo.x // user: %4
destroy_addr %3 : $*X // id: %4
// Call super -dealloc.
// CHECK: [[SUPER:%[a-zA-Z0-9]+]] = bitcast [[SGIZMO]]* [[SGIZMOVAL]] to [[GIZMO]]*
// CHECK-NEXT: [[SUPER_OBJ:%[a-zA-Z0-9]+]] = bitcast [[GIZMO]]* [[SUPER]] to %objc_object*
// CHECK-NEXT: [[T0:%.*]] = call %swift.type* @_TMaC12objc_dealloc10SwiftGizmo()
// CHECK-NEXT: [[T1:%.*]] = bitcast %swift.type* [[T0]] to %objc_class*
// CHECK-NEXT: [[OBJC_SUPER_RECEIVER:%[a-zA-Z0-9]+]] = getelementptr %objc_super, %objc_super* [[OBJC_SUPER]], i32 0, i32 0
// CHECK-NEXT: store %objc_object* [[SUPER_OBJ]], %objc_object** [[OBJC_SUPER_RECEIVER]], align 8
// CHECK-NEXT: [[OBJC_SUPER_CLASS:%[a-zA-Z0-9]+]] = getelementptr %objc_super, %objc_super* [[OBJC_SUPER]], i32 0, i32 1
// CHECK-NEXT: store %objc_class* [[T1]], %objc_class** [[OBJC_SUPER_CLASS]], align 8
// CHECK-NEXT: [[DEALLOC_SEL:%[a-zA-Z0-9]+]] = load i8*, i8** @"\01L_selector(dealloc)", align 8
// CHECK-NEXT: call void bitcast (void ()* @objc_msgSendSuper2 to void (%objc_super*, i8*)*)(%objc_super* [[OBJC_SUPER]], i8* [[DEALLOC_SEL]])
%5 = super_method %0 : $SwiftGizmo, #Gizmo.deinit!deallocator.foreign : (Gizmo) -> () -> (), $@convention(objc_method) (Gizmo) -> () // user: %7
%6 = upcast %0 : $SwiftGizmo to $Gizmo // user: %7
%7 = apply %5(%6) : $@convention(objc_method) (Gizmo) -> ()
// CHECK-NEXT: ret void
%8 = tuple () // user: %9
return %8 : $() // id: %9
}
// @objc ObjectiveC.SwiftGizmo.__ivar_destroyer
sil @_TToFC12objc_dealloc10SwiftGizmoE : $@convention(objc_method) (SwiftGizmo) -> () {
bb0(%0 : $SwiftGizmo):
%3 = tuple ()
return %3 : $() // id: %4
}
sil @_TToFC12objc_dealloc10SwiftGizmocfT_S0_ : $@convention(objc_method) (@owned SwiftGizmo) -> @owned SwiftGizmo {
bb0(%0 : $SwiftGizmo):
return %0 : $SwiftGizmo
}
sil @_TToFC12objc_dealloc10SwiftGizmocfT7bellsOnSi_GSQS0__ : $@convention(objc_method) (Int, @owned SwiftGizmo) -> @owned SwiftGizmo! {
bb0(%0 : $Int, %1 : $SwiftGizmo):
unreachable
}