Files
swift-mirror/test/SILGen/dynamic.swift
Erik Eckstein 789646a15b Demangling: Make demangled names more readable and further reduce the size of the simplified demangled names
The goal here is to make the short demangling as short and readable as possible, also at the cost of omitting some information.
The assumption is that whenever the short demangling is displayed, there is a way for the user to also get the full demangled name if needed.

*) omit <where ...> because it does not give useful information anyway

Deserializer.deserialize<A where ...> () throws -> [A]
--> Deserializer.deserialize<A> () throws -> [A]

*) for multiple specialized functions only emit a single “specialized”

specialized specialized Constructible.create(A.Element) -> Constructible<A>
--> specialized Constructible.create(A.Element) -> Constructible<A>

*) Don’t print function argument types:

foo(Int, Double, named: Int)
--> foo(_:_:named:)

This is a trade-off, because it can lead to ambiguity if there are overloads with different types.

*) make contexts of closures, local functions, etc. more readable by using “<a> in <b>” syntax
This is also done for the full and not only for the simplified demangling.

Renderer.(renderInlines([Inline]) -> String).(closure #1)
--> closure #1 in Renderer.renderInlines

*) change spacing, so that it matches our coding style:

foo <A> (x : A)
--> foo<A>(x: A)
2017-04-13 08:43:28 -07:00

523 lines
26 KiB
Swift

// RUN: rm -rf %t && mkdir -p %t
// RUN: %build-silgen-test-overlays
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -Xllvm -sil-full-demangle -primary-file %s %S/Inputs/dynamic_other.swift -emit-silgen | %FileCheck %s
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -Xllvm -sil-full-demangle -primary-file %s %S/Inputs/dynamic_other.swift -emit-sil -verify
// REQUIRES: objc_interop
import Foundation
import gizmo
class Foo: Proto {
// Not objc or dynamic, so only a vtable entry
init(native: Int) {}
func nativeMethod() {}
var nativeProp: Int = 0
subscript(native native: Int) -> Int {
get { return native }
set {}
}
// @objc, so it has an ObjC entry point but can also be dispatched
// by vtable
@objc init(objc: Int) {}
@objc func objcMethod() {}
@objc var objcProp: Int = 0
@objc subscript(objc objc: AnyObject) -> Int {
get { return 0 }
set {}
}
// dynamic, so it has only an ObjC entry point
dynamic init(dynamic: Int) {}
dynamic func dynamicMethod() {}
dynamic var dynamicProp: Int = 0
dynamic subscript(dynamic dynamic: Int) -> Int {
get { return dynamic }
set {}
}
func overriddenByDynamic() {}
@NSManaged var managedProp: Int
}
protocol Proto {
func nativeMethod()
var nativeProp: Int { get set }
subscript(native native: Int) -> Int { get set }
func objcMethod()
var objcProp: Int { get set }
subscript(objc objc: AnyObject) -> Int { get set }
func dynamicMethod()
var dynamicProp: Int { get set }
subscript(dynamic dynamic: Int) -> Int { get set }
}
// ObjC entry points for @objc and dynamic entry points
// normal and @objc initializing ctors can be statically dispatched
// CHECK-LABEL: sil hidden @_T07dynamic3FooC{{.*}}tcfC
// CHECK: function_ref @_T07dynamic3FooC{{.*}}tcfc
// CHECK-LABEL: sil hidden @_T07dynamic3FooC{{.*}}tcfC
// CHECK: function_ref @_T07dynamic3FooC{{.*}}tcfc
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3{{[_0-9a-zA-Z]*}}fcTo
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3FooC10objcMethod{{[_0-9a-zA-Z]*}}FTo
// CHECK-LABEL: sil hidden [transparent] [thunk] @_T07dynamic3FooC8objcPropSifgTo
// CHECK-LABEL: sil hidden [transparent] [thunk] @_T07dynamic3FooC8objcPropSifsTo
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3FooC9subscriptSis9AnyObject_p4objc_tcfgTo
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3FooC9subscriptSis9AnyObject_p4objc_tcfsTo
// TODO: dynamic initializing ctor must be objc dispatched
// CHECK-LABEL: sil hidden @_T07dynamic3{{[_0-9a-zA-Z]*}}fC
// CHECK: function_ref @_T07dynamic3{{[_0-9a-zA-Z]*}}fcTD
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] @_T07dynamic3{{[_0-9a-zA-Z]*}}fcTD
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.init!initializer.1.foreign :
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3{{[_0-9a-zA-Z]*}}fcTo
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3FooC0A6Method{{[_0-9a-zA-Z]*}}FTo
// CHECK-LABEL: sil hidden [transparent] [thunk] @_T07dynamic3FooC0A4PropSifgTo
// CHECK-LABEL: sil hidden [transparent] [thunk] @_T07dynamic3FooC0A4PropSifsTo
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3FooC9subscriptS2iAA_tcfgTo
// CHECK-LABEL: sil hidden [thunk] @_T07dynamic3FooC9subscriptS2iAA_tcfsTo
// Protocol witnesses use best appropriate dispatch
// Native witnesses use vtable dispatch:
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP12nativeMethod{{[_0-9a-zA-Z]*}}FTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.nativeMethod!1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP10nativePropSifgTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.nativeProp!getter.1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP10nativePropSifsTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.nativeProp!setter.1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP9subscriptS2i6native_tcfgTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!getter.1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP9subscriptS2i6native_tcfsTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!setter.1 :
// @objc witnesses use vtable dispatch:
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP10objcMethod{{[_0-9a-zA-Z]*}}FTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.objcMethod!1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP8objcPropSifgTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.objcProp!getter.1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP8objcPropSifsTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.objcProp!setter.1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP9subscriptSis9AnyObject_p4objc_tcfgTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!getter.1 :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP9subscriptSis9AnyObject_p4objc_tcfsTW
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!setter.1 :
// Dynamic witnesses use objc dispatch:
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP0A6Method{{[_0-9a-zA-Z]*}}FTW
// CHECK: function_ref @_T07dynamic3FooC0A6Method{{[_0-9a-zA-Z]*}}FTD
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] @_T07dynamic3FooC0A6Method{{[_0-9a-zA-Z]*}}FTD
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.dynamicMethod!1.foreign :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP0A4PropSifgTW
// CHECK: function_ref @_T07dynamic3FooC0A4PropSifgTD
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] @_T07dynamic3FooC0A4PropSifgTD
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.dynamicProp!getter.1.foreign :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP0A4PropSifsTW
// CHECK: function_ref @_T07dynamic3FooC0A4PropSifsTD
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] @_T07dynamic3FooC0A4PropSifsTD
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.dynamicProp!setter.1.foreign :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP9subscriptS2iAA_tcfgTW
// CHECK: function_ref @_T07dynamic3FooC9subscriptS2iAA_tcfgTD
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] @_T07dynamic3FooC9subscriptS2iAA_tcfgTD
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.subscript!getter.1.foreign :
// CHECK-LABEL: sil private [transparent] [thunk] @_T07dynamic3FooCAA5ProtoA2aDP9subscriptS2iAA_tcfsTW
// CHECK: function_ref @_T07dynamic3FooC9subscriptS2iAA_tcfsTD
// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] @_T07dynamic3FooC9subscriptS2iAA_tcfsTD
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.subscript!setter.1.foreign :
// Superclass dispatch
class Subclass: Foo {
// Native and objc methods can directly reference super members
override init(native: Int) {
super.init(native: native)
}
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC{{[_0-9a-zA-Z]*}}fC
// CHECK: function_ref @_T07dynamic8SubclassC{{[_0-9a-zA-Z]*}}fc
override func nativeMethod() {
super.nativeMethod()
}
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC12nativeMethod{{[_0-9a-zA-Z]*}}F
// CHECK: function_ref @_T07dynamic3FooC12nativeMethodyyF : $@convention(method) (@guaranteed Foo) -> ()
override var nativeProp: Int {
get { return super.nativeProp }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC10nativePropSifg
// CHECK: function_ref @_T07dynamic3FooC10nativePropSifg : $@convention(method) (@guaranteed Foo) -> Int
set { super.nativeProp = newValue }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC10nativePropSifs
// CHECK: function_ref @_T07dynamic3FooC10nativePropSifs : $@convention(method) (Int, @guaranteed Foo) -> ()
}
override subscript(native native: Int) -> Int {
get { return super[native: native] }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC9subscriptS2i6native_tcfg
// CHECK: function_ref @_T07dynamic3FooC9subscriptS2i6native_tcfg : $@convention(method) (Int, @guaranteed Foo) -> Int
set { super[native: native] = newValue }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC9subscriptS2i6native_tcfs
// CHECK: function_ref @_T07dynamic3FooC9subscriptS2i6native_tcfs : $@convention(method) (Int, Int, @guaranteed Foo) -> ()
}
override init(objc: Int) {
super.init(objc: objc)
}
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassCACSi4objc_tcfc
// CHECK: function_ref @_T07dynamic3FooCACSi4objc_tcfc : $@convention(method) (Int, @owned Foo) -> @owned Foo
override func objcMethod() {
super.objcMethod()
}
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC10objcMethod{{[_0-9a-zA-Z]*}}F
// CHECK: function_ref @_T07dynamic3FooC10objcMethodyyF : $@convention(method) (@guaranteed Foo) -> ()
override var objcProp: Int {
get { return super.objcProp }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC8objcPropSifg
// CHECK: function_ref @_T07dynamic3FooC8objcPropSifg : $@convention(method) (@guaranteed Foo) -> Int
set { super.objcProp = newValue }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC8objcPropSifs
// CHECK: function_ref @_T07dynamic3FooC8objcPropSifs : $@convention(method) (Int, @guaranteed Foo) -> ()
}
override subscript(objc objc: AnyObject) -> Int {
get { return super[objc: objc] }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC9subscriptSis9AnyObject_p4objc_tcfg
// CHECK: function_ref @_T07dynamic3FooC9subscriptSis9AnyObject_p4objc_tcfg : $@convention(method) (@owned AnyObject, @guaranteed Foo) -> Int
set { super[objc: objc] = newValue }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC9subscriptSis9AnyObject_p4objc_tcfs
// CHECK: function_ref @_T07dynamic3FooC9subscriptSis9AnyObject_p4objc_tcfs : $@convention(method) (Int, @owned AnyObject, @guaranteed Foo) -> ()
}
// Dynamic methods are super-dispatched by objc_msgSend
override init(dynamic: Int) {
super.init(dynamic: dynamic)
}
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC{{[_0-9a-zA-Z]*}}fc
// CHECK: super_method [volatile] {{%.*}} : $Subclass, #Foo.init!initializer.1.foreign :
override func dynamicMethod() {
super.dynamicMethod()
}
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC0A6Method{{[_0-9a-zA-Z]*}}F
// CHECK: super_method [volatile] {{%.*}} : $Subclass, #Foo.dynamicMethod!1.foreign :
override var dynamicProp: Int {
get { return super.dynamicProp }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC0A4PropSifg
// CHECK: super_method [volatile] {{%.*}} : $Subclass, #Foo.dynamicProp!getter.1.foreign :
set { super.dynamicProp = newValue }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC0A4PropSifs
// CHECK: super_method [volatile] {{%.*}} : $Subclass, #Foo.dynamicProp!setter.1.foreign :
}
override subscript(dynamic dynamic: Int) -> Int {
get { return super[dynamic: dynamic] }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC9subscriptS2iAA_tcfg
// CHECK: super_method [volatile] {{%.*}} : $Subclass, #Foo.subscript!getter.1.foreign :
set { super[dynamic: dynamic] = newValue }
// CHECK-LABEL: sil hidden @_T07dynamic8SubclassC9subscriptS2iAA_tcfs
// CHECK: super_method [volatile] {{%.*}} : $Subclass, #Foo.subscript!setter.1.foreign :
}
dynamic override func overriddenByDynamic() {}
}
// CHECK-LABEL: sil hidden @_T07dynamic20nativeMethodDispatchyyF : $@convention(thin) () -> ()
func nativeMethodDispatch() {
// CHECK: function_ref @_T07dynamic3{{[_0-9a-zA-Z]*}}fC
let c = Foo(native: 0)
// CHECK: class_method {{%.*}} : $Foo, #Foo.nativeMethod!1 :
c.nativeMethod()
// CHECK: class_method {{%.*}} : $Foo, #Foo.nativeProp!getter.1 :
let x = c.nativeProp
// CHECK: class_method {{%.*}} : $Foo, #Foo.nativeProp!setter.1 :
c.nativeProp = x
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!getter.1 :
let y = c[native: 0]
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!setter.1 :
c[native: 0] = y
}
// CHECK-LABEL: sil hidden @_T07dynamic18objcMethodDispatchyyF : $@convention(thin) () -> ()
func objcMethodDispatch() {
// CHECK: function_ref @_T07dynamic3{{[_0-9a-zA-Z]*}}fC
let c = Foo(objc: 0)
// CHECK: class_method {{%.*}} : $Foo, #Foo.objcMethod!1 :
c.objcMethod()
// CHECK: class_method {{%.*}} : $Foo, #Foo.objcProp!getter.1 :
let x = c.objcProp
// CHECK: class_method {{%.*}} : $Foo, #Foo.objcProp!setter.1 :
c.objcProp = x
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!getter.1 :
let y = c[objc: 0 as NSNumber]
// CHECK: class_method {{%.*}} : $Foo, #Foo.subscript!setter.1 :
c[objc: 0 as NSNumber] = y
}
// CHECK-LABEL: sil hidden @_T07dynamic0A14MethodDispatchyyF : $@convention(thin) () -> ()
func dynamicMethodDispatch() {
// CHECK: function_ref @_T07dynamic3{{[_0-9a-zA-Z]*}}fC
let c = Foo(dynamic: 0)
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.dynamicMethod!1.foreign
c.dynamicMethod()
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.dynamicProp!getter.1.foreign
let x = c.dynamicProp
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.dynamicProp!setter.1.foreign
c.dynamicProp = x
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.subscript!getter.1.foreign
let y = c[dynamic: 0]
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.subscript!setter.1.foreign
c[dynamic: 0] = y
}
// CHECK-LABEL: sil hidden @_T07dynamic15managedDispatchyAA3FooCF
func managedDispatch(_ c: Foo) {
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.managedProp!getter.1.foreign
let x = c.managedProp
// CHECK: class_method [volatile] {{%.*}} : $Foo, #Foo.managedProp!setter.1.foreign
c.managedProp = x
}
// CHECK-LABEL: sil hidden @_T07dynamic21foreignMethodDispatchyyF
func foreignMethodDispatch() {
// CHECK: function_ref @_T0So9GuisemeauC{{[_0-9a-zA-Z]*}}fC
let g = Guisemeau()!
// CHECK: class_method [volatile] {{%.*}} : $Gizmo, #Gizmo.frob!1.foreign
g.frob()
// CHECK: class_method [volatile] {{%.*}} : $Gizmo, #Gizmo.count!getter.1.foreign
let x = g.count
// CHECK: class_method [volatile] {{%.*}} : $Gizmo, #Gizmo.count!setter.1.foreign
g.count = x
// CHECK: class_method [volatile] {{%.*}} : $Guisemeau, #Guisemeau.subscript!getter.1.foreign
let y: Any! = g[0]
// CHECK: class_method [volatile] {{%.*}} : $Guisemeau, #Guisemeau.subscript!setter.1.foreign
g[0] = y
// CHECK: class_method [volatile] {{%.*}} : $NSObject, #NSObject.description!getter.1.foreign
_ = g.description
}
extension Gizmo {
// CHECK-LABEL: sil hidden @_T0So5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fc
// CHECK: class_method [volatile] {{%.*}} : $Gizmo, #Gizmo.init!initializer.1.foreign
convenience init(convenienceInExtension: Int) {
self.init(bellsOn: convenienceInExtension)
}
// CHECK-LABEL: sil hidden @_T0So5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fC
// CHECK: class_method [volatile] {{%.*}} : $@thick Gizmo.Type, #Gizmo.init!allocator.1.foreign
convenience init(foreignClassFactory x: Int) {
self.init(stuff: x)
}
// CHECK-LABEL: sil hidden @_T0So5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fC
// CHECK: class_method [volatile] {{%.*}} : $@thick Gizmo.Type, #Gizmo.init!allocator.1.foreign
convenience init(foreignClassExactFactory x: Int) {
self.init(exactlyStuff: x)
}
@objc func foreignObjCExtension() { }
dynamic func foreignDynamicExtension() { }
}
// CHECK-LABEL: sil hidden @_T07dynamic24foreignExtensionDispatchySo5GizmoCF
// CHECK: bb0([[ARG:%.*]] : $Gizmo):
func foreignExtensionDispatch(_ g: Gizmo) {
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK: class_method [volatile] [[BORROWED_ARG]] : $Gizmo, #Gizmo.foreignObjCExtension!1.foreign : (Gizmo)
g.foreignObjCExtension()
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK: class_method [volatile] [[BORROWED_ARG]] : $Gizmo, #Gizmo.foreignDynamicExtension!1.foreign
g.foreignDynamicExtension()
}
// CHECK-LABEL: sil hidden @_T07dynamic33nativeMethodDispatchFromOtherFileyyF : $@convention(thin) () -> ()
func nativeMethodDispatchFromOtherFile() {
// CHECK: function_ref @_T07dynamic13FromOtherFile{{[_0-9a-zA-Z]*}}fC
let c = FromOtherFile(native: 0)
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.nativeMethod!1 :
c.nativeMethod()
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.nativeProp!getter.1 :
let x = c.nativeProp
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.nativeProp!setter.1 :
c.nativeProp = x
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.subscript!getter.1 :
let y = c[native: 0]
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.subscript!setter.1 :
c[native: 0] = y
}
// CHECK-LABEL: sil hidden @_T07dynamic31objcMethodDispatchFromOtherFileyyF : $@convention(thin) () -> ()
func objcMethodDispatchFromOtherFile() {
// CHECK: function_ref @_T07dynamic13FromOtherFile{{[_0-9a-zA-Z]*}}fC
let c = FromOtherFile(objc: 0)
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.objcMethod!1 :
c.objcMethod()
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.objcProp!getter.1 :
let x = c.objcProp
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.objcProp!setter.1 :
c.objcProp = x
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.subscript!getter.1 :
let y = c[objc: 0]
// CHECK: class_method {{%.*}} : $FromOtherFile, #FromOtherFile.subscript!setter.1 :
c[objc: 0] = y
}
// CHECK-LABEL: sil hidden @_T07dynamic0A27MethodDispatchFromOtherFileyyF : $@convention(thin) () -> ()
func dynamicMethodDispatchFromOtherFile() {
// CHECK: function_ref @_T07dynamic13FromOtherFile{{[_0-9a-zA-Z]*}}fC
let c = FromOtherFile(dynamic: 0)
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.dynamicMethod!1.foreign
c.dynamicMethod()
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.dynamicProp!getter.1.foreign
let x = c.dynamicProp
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.dynamicProp!setter.1.foreign
c.dynamicProp = x
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.subscript!getter.1.foreign
let y = c[dynamic: 0]
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.subscript!setter.1.foreign
c[dynamic: 0] = y
}
// CHECK-LABEL: sil hidden @_T07dynamic28managedDispatchFromOtherFileyAA0deF0CF
func managedDispatchFromOtherFile(_ c: FromOtherFile) {
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.managedProp!getter.1.foreign
let x = c.managedProp
// CHECK: class_method [volatile] {{%.*}} : $FromOtherFile, #FromOtherFile.managedProp!setter.1.foreign
c.managedProp = x
}
// CHECK-LABEL: sil hidden @_T07dynamic0A16ExtensionMethodsyAA13ObjCOtherFileCF
func dynamicExtensionMethods(_ obj: ObjCOtherFile) {
// CHECK: class_method [volatile] {{%.*}} : $ObjCOtherFile, #ObjCOtherFile.extensionMethod!1.foreign
obj.extensionMethod()
// CHECK: class_method [volatile] {{%.*}} : $ObjCOtherFile, #ObjCOtherFile.extensionProp!getter.1.foreign
_ = obj.extensionProp
// CHECK: class_method [volatile] {{%.*}} : $@thick ObjCOtherFile.Type, #ObjCOtherFile.extensionClassProp!getter.1.foreign
// CHECK-NEXT: thick_to_objc_metatype {{%.*}} : $@thick ObjCOtherFile.Type to $@objc_metatype ObjCOtherFile.Type
_ = type(of: obj).extensionClassProp
// CHECK: class_method [volatile] {{%.*}} : $ObjCOtherFile, #ObjCOtherFile.dynExtensionMethod!1.foreign
obj.dynExtensionMethod()
// CHECK: class_method [volatile] {{%.*}} : $ObjCOtherFile, #ObjCOtherFile.dynExtensionProp!getter.1.foreign
_ = obj.dynExtensionProp
// CHECK: class_method [volatile] {{%.*}} : $@thick ObjCOtherFile.Type, #ObjCOtherFile.dynExtensionClassProp!getter.1.foreign
// CHECK-NEXT: thick_to_objc_metatype {{%.*}} : $@thick ObjCOtherFile.Type to $@objc_metatype ObjCOtherFile.Type
_ = type(of: obj).dynExtensionClassProp
}
public class Base {
dynamic var x: Bool { return false }
}
public class Sub : Base {
// CHECK-LABEL: sil hidden @_T07dynamic3SubC1xSbfg : $@convention(method) (@guaranteed Sub) -> Bool {
// CHECK: bb0([[SELF:%.*]] : $Sub):
// CHECK: [[AUTOCLOSURE:%.*]] = function_ref @_T07dynamic3SubC1xSbfgSbyKXKfu_ : $@convention(thin) (@owned Sub) -> (Bool, @error Error)
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: = partial_apply [[AUTOCLOSURE]]([[SELF_COPY]])
// CHECK: return {{%.*}} : $Bool
// CHECK: } // end sil function '_T07dynamic3SubC1xSbfg'
// CHECK-LABEL: sil private [transparent] @_T07dynamic3SubC1xSbfgSbyKXKfu_ : $@convention(thin) (@owned Sub) -> (Bool, @error Error) {
// CHECK: bb0([[VALUE:%.*]] : $Sub):
// CHECK: [[BORROWED_VALUE:%.*]] = begin_borrow [[VALUE]]
// CHECK: [[VALUE_COPY:%.*]] = copy_value [[BORROWED_VALUE]]
// CHECK: [[CASTED_VALUE_COPY:%.*]] = upcast [[VALUE_COPY]]
// CHECK: [[SUPER:%.*]] = super_method [volatile] [[VALUE_COPY]] : $Sub, #Base.x!getter.1.foreign : (Base) -> () -> Bool, $@convention(objc_method) (Base) -> ObjCBool
// CHECK: = apply [[SUPER]]([[CASTED_VALUE_COPY]])
// CHECK: destroy_value [[VALUE_COPY]]
// CHECK: end_borrow [[BORROWED_VALUE]] from [[VALUE]]
// CHECK: destroy_value [[VALUE]]
// CHECK: } // end sil function '_T07dynamic3SubC1xSbfgSbyKXKfu_'
override var x: Bool { return false || super.x }
}
public class BaseExt : NSObject {}
extension BaseExt {
@objc public var count: Int {
return 0
}
}
public class SubExt : BaseExt {
public override var count: Int {
return 1
}
}
public class GenericBase<T> {
public func method(_: T) {}
}
public class ConcreteDerived : GenericBase<Int> {
public override dynamic func method(_: Int) {}
}
// The dynamic override has a different calling convention than the base,
// so after re-abstracting the signature we must dispatch to the dynamic
// thunk.
// CHECK-LABEL: sil private @_T07dynamic15ConcreteDerivedC6methodySiFAA11GenericBaseCADyxFTV : $@convention(method) (@in Int, @guaranteed ConcreteDerived) -> ()
// CHECK: bb0(%0 : $*Int, %1 : $ConcreteDerived):
// CHECK-NEXT: [[VALUE:%.*]] = load [trivial] %0 : $*Int
// CHECK: [[DYNAMIC_THUNK:%.*]] = function_ref @_T07dynamic15ConcreteDerivedC6methodySiFTD : $@convention(method) (Int, @guaranteed ConcreteDerived) -> ()
// CHECK-NEXT: apply [[DYNAMIC_THUNK]]([[VALUE]], %1) : $@convention(method) (Int, @guaranteed ConcreteDerived) -> ()
// CHECK: return
// Vtable contains entries for native and @objc methods, but not dynamic ones
// CHECK-LABEL: sil_vtable Foo {
// CHECK-NEXT: #Foo.init!initializer.1: {{.*}} : _T07dynamic3FooCACSi6native_tcfc
// CHECK-NEXT: #Foo.nativeMethod!1: {{.*}} : _T07dynamic3FooC12nativeMethodyyF
// CHECK-NEXT: #Foo.nativeProp!getter.1: {{.*}} : _T07dynamic3FooC10nativePropSifg // dynamic.Foo.nativeProp.getter : Swift.Int
// CHECK-NEXT: #Foo.nativeProp!setter.1: {{.*}} : _T07dynamic3FooC10nativePropSifs // dynamic.Foo.nativeProp.setter : Swift.Int
// CHECK-NEXT: #Foo.nativeProp!materializeForSet.1
// CHECK-NEXT: #Foo.subscript!getter.1: {{.*}} : _T07dynamic3FooC9subscriptS2i6native_tcfg // dynamic.Foo.subscript.getter : (native: Swift.Int) -> Swift.Int
// CHECK-NEXT: #Foo.subscript!setter.1: {{.*}} : _T07dynamic3FooC9subscriptS2i6native_tcfs // dynamic.Foo.subscript.setter : (native: Swift.Int) -> Swift.Int
// CHECK-NEXT: #Foo.subscript!materializeForSet.1
// CHECK-NEXT: #Foo.init!initializer.1: {{.*}} : _T07dynamic3FooCACSi4objc_tcfc
// CHECK-NEXT: #Foo.objcMethod!1: {{.*}} : _T07dynamic3FooC10objcMethodyyF
// CHECK-NEXT: #Foo.objcProp!getter.1: {{.*}} : _T07dynamic3FooC8objcPropSifg // dynamic.Foo.objcProp.getter : Swift.Int
// CHECK-NEXT: #Foo.objcProp!setter.1: {{.*}} : _T07dynamic3FooC8objcPropSifs // dynamic.Foo.objcProp.setter : Swift.Int
// CHECK-NEXT: #Foo.objcProp!materializeForSet.1
// CHECK-NEXT: #Foo.subscript!getter.1: {{.*}} : _T07dynamic3FooC9subscriptSis9AnyObject_p4objc_tcfg // dynamic.Foo.subscript.getter : (objc: Swift.AnyObject) -> Swift.Int
// CHECK-NEXT: #Foo.subscript!setter.1: {{.*}} : _T07dynamic3FooC9subscriptSis9AnyObject_p4objc_tcfs // dynamic.Foo.subscript.setter : (objc: Swift.AnyObject) -> Swift.Int
// CHECK-NEXT: #Foo.subscript!materializeForSet
// CHECK-NEXT: #Foo.overriddenByDynamic!1: {{.*}} : _T07dynamic3FooC19overriddenByDynamic{{[_0-9a-zA-Z]*}}
// CHECK-NEXT: #Foo.deinit!deallocator: {{.*}}
// CHECK-NEXT: }
// Vtable uses a dynamic thunk for dynamic overrides
// CHECK-LABEL: sil_vtable Subclass {
// CHECK: #Foo.overriddenByDynamic!1: {{.*}} : public _T07dynamic8SubclassC19overriddenByDynamic{{[_0-9a-zA-Z]*}}FTD
// CHECK: }
// No vtable entry for override of @objc extension property
// CHECK-LABEL: sil_vtable SubExt {
// CHECK-NEXT: #BaseExt.init!initializer.1: (BaseExt.Type) -> () -> BaseExt : _T07dynamic6SubExtCACycfc // dynamic.SubExt.init() -> dynamic.SubExt
// CHECK-NEXT: #SubExt.deinit!deallocator: _T07dynamic6SubExtCfD // dynamic.SubExt.__deallocating_deinit
// CHECK-NEXT: }
// Dynamic thunk + vtable re-abstraction
// CHECK-LABEL: sil_vtable ConcreteDerived {
// CHECK-NEXT: #GenericBase.method!1: <T> (GenericBase<T>) -> (T) -> () : public _T07dynamic15ConcreteDerivedC6methodySiFAA11GenericBaseCADyxFTV // vtable thunk for dynamic.GenericBase.method(A) -> () dispatching to dynamic.ConcreteDerived.method(Swift.Int) -> ()
// CHECK-NEXT: #GenericBase.init!initializer.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : _T07dynamic15ConcreteDerivedCACycfc // dynamic.ConcreteDerived.init() -> dynamic.ConcreteDerived
// CHECK-NEXT: #ConcreteDerived.deinit!deallocator: _T07dynamic15ConcreteDerivedCfD // dynamic.ConcreteDerived.__deallocating_deinit
// CHECK-NEXT: }