// RUN: rm -rf %t // RUN: mkdir %t // RUN: %target-swift-frontend -emit-module -enable-resilience -I %t -module-name resilient_struct -o %t %S/../Inputs/resilient_struct.swift // RUN: %target-swift-frontend -emit-module -enable-resilience -I %t -module-name resilient_class -o %t %S/../Inputs/resilient_class.swift // RUN: %target-swift-frontend -use-native-super-method -enable-resilience -parse-sil -parse-as-library -emit-ir -I %t %s | FileCheck %s sil_stage canonical import Builtin import Swift import SwiftShims import resilient_class public class ChildToResilientParent : ResilientOutsideParent { public override func method() public override class func classMethod() deinit override init() } public class ChildToFixedParent : OutsideParent { public override func method() public override class func classMethod() deinit override init() } public extension ResilientOutsideChild { public func callSuperMethod() public class func callSuperClassMethod() } // resilient_class.ResilientOutsideParent.method () -> () sil @_TFC15resilient_class22ResilientOutsideParent6methodfT_T_ : $@convention(method) (@guaranteed ResilientOutsideParent) -> () // static resilient_class.ResilientOutsideParent.classMethod () -> () sil @_TZFC15resilient_class22ResilientOutsideParent11classMethodfT_T_ : $@convention(thin) (@thick ResilientOutsideParent.Type) -> () // super.ChildToResilientParent.method () -> () sil @_TFC5super22ChildToResilientParent6methodfT_T_ : $@convention(method) (@guaranteed ChildToResilientParent) -> () { // %0 bb0(%0 : $ChildToResilientParent): debug_value %0 : $ChildToResilientParent, let, name "self", argno 1 strong_retain %0 : $ChildToResilientParent %3 = upcast %0 : $ChildToResilientParent to $ResilientOutsideParent %4 = super_method %0 : $ChildToResilientParent, #ResilientOutsideParent.method!1 : ResilientOutsideParent -> () -> () , $@convention(method) (@guaranteed ResilientOutsideParent) -> () %5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> () strong_release %3 : $ResilientOutsideParent %7 = tuple () return %7 : $() } // ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly. // CHECK-LABEL: define void @_TFC5super22ChildToResilientParent6methodfT_T_(%C5super22ChildToResilientParent*) // CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class22ResilientOutsideParent() // CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%C15resilient_class22ResilientOutsideParent*)** // CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[OPAQUE_SUPER_METADATA]] // CHECK: [[FN_PTR:%[0-9]+]] = load void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[VTABLE_SLOT]] // CHECK: call void // static super.ChildToResilientParent.classMethod () -> () sil @_TZFC5super22ChildToResilientParent11classMethodfT_T_ : $@convention(thin) (@thick ChildToResilientParent.Type) -> () { bb0(%0 : $@thick ChildToResilientParent.Type): debug_value %0 : $@thick ChildToResilientParent.Type, let, name "self", argno 1 %2 = upcast %0 : $@thick ChildToResilientParent.Type to $@thick ResilientOutsideParent.Type %3 = super_method %0 : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod!1 : ResilientOutsideParent.Type -> () -> () , $@convention(thin) (@thick ResilientOutsideParent.Type) -> () %4 = apply %3(%2) : $@convention(thin) (@thick ResilientOutsideParent.Type) -> () %5 = tuple () return %5 : $() } // ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly. // CHECK-LABEL: define void @_TZFC5super22ChildToResilientParent11classMethodfT_T_(%swift.type*) // CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class22ResilientOutsideParent() // CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%swift.type*)** // CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[OPAQUE_SUPER_METADATA]] // CHECK: [[FN_PTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[VTABLE_SLOT]] // CHECK: call void // resilient_class.OutsideParent.method () -> () sil @_TFC15resilient_class13OutsideParent6methodfT_T_ : $@convention(method) (@guaranteed OutsideParent) -> () // static resilient_class.OutsideParent.classMethod () -> () sil @_TZFC15resilient_class13OutsideParent11classMethodfT_T_ : $@convention(thin) (@thick OutsideParent.Type) -> () // super.ChildToFixedParent.method () -> () sil @_TFC5super18ChildToFixedParent6methodfT_T_ : $@convention(method) (@guaranteed ChildToFixedParent) -> () { // %0 bb0(%0 : $ChildToFixedParent): debug_value %0 : $ChildToFixedParent, let, name "self", argno 1 strong_retain %0 : $ChildToFixedParent %3 = upcast %0 : $ChildToFixedParent to $OutsideParent %4 = super_method %0 : $ChildToFixedParent, #OutsideParent.method!1 : OutsideParent -> () -> () , $@convention(method) (@guaranteed OutsideParent) -> () %5 = apply %4(%3) : $@convention(method) (@guaranteed OutsideParent) -> () strong_release %3 : $OutsideParent %7 = tuple () return %7 : $() } // CHECK-LABEL: define void @_TFC5super18ChildToFixedParent6methodfT_T_(%C5super18ChildToFixedParent*) // CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class13OutsideParent() // CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%C15resilient_class13OutsideParent*)** // CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C15resilient_class13OutsideParent*)*, void (%C15resilient_class13OutsideParent*)** [[OPAQUE_SUPER_METADATA]] // CHECK: [[FN_PTR:%[0-9]+]] = load void (%C15resilient_class13OutsideParent*)*, void (%C15resilient_class13OutsideParent*)** [[VTABLE_SLOT]] // CHECK: call void // static super.ChildToFixedParent.classMethod () -> () sil @_TZFC5super18ChildToFixedParent11classMethodfT_T_ : $@convention(thin) (@thick ChildToFixedParent.Type) -> () { // %0 bb0(%0 : $@thick ChildToFixedParent.Type): debug_value %0 : $@thick ChildToFixedParent.Type, let, name "self", argno 1 %2 = upcast %0 : $@thick ChildToFixedParent.Type to $@thick OutsideParent.Type %3 = super_method %0 : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod!1 : OutsideParent.Type -> () -> () , $@convention(thin) (@thick OutsideParent.Type) -> () %4 = apply %3(%2) : $@convention(thin) (@thick OutsideParent.Type) -> () %5 = tuple () return %5 : $() } // ChildToFixedParent is in our resilience domain - load super metadata directly. // CHECK-LABEL: define void @_TZFC5super18ChildToFixedParent11classMethodfT_T_(%swift.type*) // CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class13OutsideParent() // CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%swift.type*)** // CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[OPAQUE_SUPER_METADATA]] // CHECK: [[FN_PTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[VTABLE_SLOT]] // CHECK: call void // ext.super.resilient_class.ResilientOutsideChild.callSuperMethod () -> () sil @_TFE5superC15resilient_class21ResilientOutsideChild15callSuperMethodfT_T_ : $@convention(method) (@guaranteed ResilientOutsideChild) -> () { // %0 bb0(%0 : $ResilientOutsideChild): debug_value %0 : $ResilientOutsideChild, let, name "self", argno 1 strong_retain %0 : $ResilientOutsideChild %3 = upcast %0 : $ResilientOutsideChild to $ResilientOutsideParent %4 = super_method %0 : $ResilientOutsideChild, #ResilientOutsideParent.method!1 : ResilientOutsideParent -> () -> () , $@convention(method) (@guaranteed ResilientOutsideParent) -> () %5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> () strong_release %3 : $ResilientOutsideParent %7 = tuple () return %7 : $() } // Extending a resilient class - load super metadata indirectly. // CHECK-LABEL: define void @_TFE5superC15resilient_class21ResilientOutsideChild15callSuperMethodfT_T_(%C15resilient_class21ResilientOutsideChild*) // CHECK: [[METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class21ResilientOutsideChild() // CHECK: [[OPAQUE_METADATA:%[0-9]+]] = bitcast %swift.type* [[METADATA]] to %swift.type** // CHECK: [[SUPER_METADATA_PTR:%[0-9]+]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1 // CHECK: [[SUPER_METADATA:%[0-9]+]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]] // CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%C15resilient_class22ResilientOutsideParent*)** // CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[OPAQUE_SUPER_METADATA]] // CHECK: [[FN_PTR:%[0-9]+]] = load void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[VTABLE_SLOT]] // CHECK: call void // static ext.super.resilient_class.ResilientOutsideChild.callSuperClassMethod () -> () sil @_TZFE5superC15resilient_class21ResilientOutsideChild20callSuperClassMethodfT_T_ : $@convention(thin) (@thick ResilientOutsideChild.Type) -> () { // %0 bb0(%0 : $@thick ResilientOutsideChild.Type): debug_value %0 : $@thick ResilientOutsideChild.Type, let, name "self", argno 1 %2 = upcast %0 : $@thick ResilientOutsideChild.Type to $@thick ResilientOutsideParent.Type %3 = super_method %0 : $@thick ResilientOutsideChild.Type, #ResilientOutsideParent.classMethod!1 : ResilientOutsideParent.Type -> () -> () , $@convention(thin) (@thick ResilientOutsideParent.Type) -> () %4 = apply %3(%2) : $@convention(thin) (@thick ResilientOutsideParent.Type) -> () %5 = tuple () return %5 : $() } // Extending a resilient class - load super metadata indirectly. // CHECK-LABEL: define void @_TZFE5superC15resilient_class21ResilientOutsideChild20callSuperClassMethodfT_T_(%swift.type*) // CHECK: [[METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class21ResilientOutsideChild() // CHECK: [[OPAQUE_METADATA:%[0-9]+]] = bitcast %swift.type* [[METADATA]] to %swift.type** // CHECK: [[SUPER_METADATA_PTR:%[0-9]+]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1 // CHECK: [[SUPER_METADATA:%[0-9]+]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]] // CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%swift.type*)** // CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[OPAQUE_SUPER_METADATA]] // CHECK: [[FN_PTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[VTABLE_SLOT]] // CHECK: call void sil_vtable ChildToResilientParent { #ResilientOutsideParent.method!1: _TFC5super22ChildToResilientParent6methodfT_T_ // super.ChildToResilientParent.method () -> () #ResilientOutsideParent.classMethod!1: _TZFC5super22ChildToResilientParent11classMethodfT_T_ // static super.ChildToResilientParent.classMethod () -> () } sil_vtable ChildToFixedParent { #OutsideParent.method!1: _TFC5super18ChildToFixedParent6methodfT_T_ // super.ChildToFixedParent.method () -> () #OutsideParent.classMethod!1: _TZFC5super18ChildToFixedParent11classMethodfT_T_ // static super.ChildToFixedParent.classMethod () -> () }