blob: 94c79d3c41835c1daec2edb0dfb84547d2321252 [file] [log] [blame]
// RUN: %target-swift-frontend %s -emit-ir | %FileCheck %s
// REQUIRES: CPU=x86_64
sil_stage canonical
protocol P {
func concrete_method()
static func concrete_static_method()
func generic_method<Z>(x: Z)
}
struct Foo: P {
func concrete_method()
static func concrete_static_method()
func generic_method<Z>(x: Z)
}
class Bar<T, U, V>: P {
func concrete_method()
static func concrete_static_method()
func generic_method<Z>(x: Z)
}
sil_vtable Bar {}
sil @$s19sil_witness_methods3BarCfD : $@convention(method) <T, U, V> (Bar<T, U, V>) -> ()
struct X {}
struct Y {}
struct Z {}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @concrete_type_concrete_method_witness(%T19sil_witness_methods3FooV* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
sil @concrete_type_concrete_method_witness : $@convention(witness_method: P) (@in Foo) -> @thick Foo.Type {
entry(%x : $*Foo):
%m = metatype $@thick Foo.Type
return %m : $@thick Foo.Type
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @generic_type_concrete_method_witness(%T19sil_witness_methods3BarC** noalias nocapture swiftself dereferenceable({{.*}}), %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 10
// CHECK: %T = load %swift.type*, %swift.type** [[T1]], align 8
// CHECK: [[U0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// CHECK: [[U1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[U0]], i64 11
// CHECK: %U = load %swift.type*, %swift.type** [[U1]], align 8
// CHECK: [[V0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// CHECK: [[V1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[V0]], i64 12
// CHECK: %V = load %swift.type*, %swift.type** [[V1]], align 8
sil @generic_type_concrete_method_witness : $@convention(witness_method: P) <T, U, V> (@in Bar<T, U, V>) -> @thick Bar<T, U, V>.Type {
entry(%x : $*Bar<T, U, V>):
%t = metatype $@thick T.Type
%u = metatype $@thick U.Type
%v = metatype $@thick V.Type
%m = metatype $@thick Bar<T, U, V>.Type
return %m : $@thick Bar<T, U, V>.Type
}
// TODO: %Self Type arg is redundant for static method witness
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @concrete_type_concrete_static_method_witness(%swift.type* swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
sil @concrete_type_concrete_static_method_witness : $@convention(witness_method: P) (@thick Foo.Type) -> @thick Foo.Type {
entry(%x : $@thick Foo.Type):
%m = metatype $@thick Foo.Type
return %m : $@thick Foo.Type
}
// The use of %0 or %Self here is irrelevant.
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @generic_type_concrete_static_method_witness(%swift.type* swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 10
// CHECK: %T = load %swift.type*, %swift.type** [[T1]], align 8
// CHECK: [[U0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// CHECK: [[U1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[U0]], i64 11
// CHECK: %U = load %swift.type*, %swift.type** [[U1]], align 8
// CHECK: [[V0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// CHECK: [[V1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[V0]], i64 12
// CHECK: %V = load %swift.type*, %swift.type** [[V1]], align 8
sil @generic_type_concrete_static_method_witness : $@convention(witness_method: P) <T, U, V> (@thick Bar<T, U, V>.Type) -> @thick Bar<T, U, V>.Type {
entry(%x : $@thick Bar<T, U, V>.Type):
%t = metatype $@thick T.Type
%u = metatype $@thick U.Type
%v = metatype $@thick V.Type
%m = metatype $@thick Bar<T, U, V>.Type
return %m : $@thick Bar<T, U, V>.Type
}
// TODO: %Self Type arg is redundant for class method witness
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @concrete_type_generic_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %T19sil_witness_methods3FooV* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
sil @concrete_type_generic_method_witness : $@convention(witness_method: P) <Z> (@in Z, @in Foo) -> @thick Foo.Type {
entry(%z : $*Z, %x : $*Foo):
%m = metatype $@thick Foo.Type
return %m : $@thick Foo.Type
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @generic_type_generic_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %T19sil_witness_methods3BarC{{.*}}** noalias nocapture swiftself dereferenceable(8), %swift.type* %Self, i8** %SelfWitnessTable)
sil @generic_type_generic_method_witness : $@convention(witness_method: P) <T, U, V, Z> (@in Z, @in Bar<T, U, V>) -> @thick Bar<T, U, V>.Type {
entry(%z : $*Z, %x : $*Bar<T, U, V>):
%t = metatype $@thick T.Type
%u = metatype $@thick U.Type
%v = metatype $@thick V.Type
%m = metatype $@thick Bar<T, U, V>.Type
return %m : $@thick Bar<T, U, V>.Type
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @concrete_type_generic_static_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %swift.type* swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
sil @concrete_type_generic_static_method_witness : $@convention(witness_method: P) <Z> (@in Z, @thick Foo.Type) -> @thick Foo.Type {
entry(%z : $*Z, %x : $@thick Foo.Type):
%m = metatype $@thick Foo.Type
return %m : $@thick Foo.Type
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @generic_type_generic_static_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %swift.type* swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
sil @generic_type_generic_static_method_witness : $@convention(witness_method: P) <T, U, V, Z> (@in Z, @thick Bar<T, U, V>.Type) -> @thick Bar<T, U, V>.Type {
entry(%z : $*Z, %x : $@thick Bar<T, U, V>.Type):
%t = metatype $@thick T.Type
%u = metatype $@thick U.Type
%v = metatype $@thick V.Type
%m = metatype $@thick Bar<T, U, V>.Type
return %m : $@thick Bar<T, U, V>.Type
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @call_concrete_witness() {{.*}} {
// CHECK: call swiftcc %swift.type* @concrete_type_concrete_method_witness(%T19sil_witness_methods3FooV* {{.*}}, %swift.type* {{.*}} @"$s19sil_witness_methods3FooVMf", {{.*}})
sil @call_concrete_witness : $(Foo) -> () {
entry(%x : $Foo):
%m = alloc_stack $Foo
store %x to %m : $*Foo
%w = function_ref @concrete_type_concrete_method_witness : $@convention(witness_method: P) (@in Foo) -> @thick Foo.Type
%z = apply %w(%m) : $@convention(witness_method: P) (@in Foo) -> @thick Foo.Type
dealloc_stack %m : $*Foo
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @call_concrete_static_witness() {{.*}} {
// CHECK: call swiftcc %swift.type* @concrete_type_concrete_static_method_witness(%swift.type* {{.*}} @"$s19sil_witness_methods3FooVMf", {{.*}} %swift.type* {{.*}} @"$s19sil_witness_methods3FooVMf", {{.*}})
sil @call_concrete_static_witness : $() -> () {
entry:
%m = metatype $@thick Foo.Type
%w = function_ref @concrete_type_concrete_static_method_witness : $@convention(witness_method: P) (@thick Foo.Type) -> @thick Foo.Type
%z = apply %w(%m) : $@convention(witness_method: P) (@thick Foo.Type) -> @thick Foo.Type
return undef : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @partial_apply_concrete_witness() {{.*}} {
// CHECK: [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject({{.*}})
// CHECK: [[LAYOUT:%.*]] = bitcast %swift.refcounted* [[CONTEXT]] to <{ %swift.refcounted, i8* }>*
// CHECK: [[WTABLE:%.*]] = getelementptr inbounds <{ %swift.refcounted, i8* }>, <{ %swift.refcounted, i8* }>* [[LAYOUT]], i32 0, i32 1
// CHECK: store i8* bitcast (i8** @"$s19sil_witness_methods3BarCyxq_q0_GAA1PAAWP" to i8*), i8** [[WTABLE]]
// CHECK: [[RESULT:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast (%swift.type* (%T19sil_witness_methods3BarCyAA3FooVA2EG**, %swift.refcounted*)* @"$s36generic_type_concrete_method_witnessTA" to i8*), %swift.refcounted* undef }, %swift.refcounted* [[CONTEXT]], 1
// CHECK: ret { i8*, %swift.refcounted* } [[RESULT]]
sil @partial_apply_concrete_witness : $() -> @callee_owned (@in Bar<Foo, Foo, Foo>) -> @thick Bar<Foo, Foo, Foo>.Type {
entry:
%w = function_ref @generic_type_concrete_method_witness : $@convention(witness_method: P) <T, U, V> (@in Bar<T, U, V>) -> @thick Bar<T, U, V>.Type
%z = partial_apply %w<Foo, Foo, Foo>() : $@convention(witness_method: P) <T, U, V> (@in Bar<T, U, V>) -> @thick Bar<T, U, V>.Type
return %z : $@callee_owned (@in Bar<Foo, Foo, Foo>) -> @thick Bar<Foo, Foo, Foo>.Type
}