1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
// RUN: %target-swift-frontend -enable-objc-interop %s -emit-ir | %FileCheck --check-prefixes=CHECK,CHECK-objc %s
// RUN: %target-swift-frontend -disable-objc-interop %s -emit-ir | %FileCheck --check-prefixes=CHECK,CHECK-native %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 ptr @concrete_type_concrete_method_witness(ptr noalias nocapture swiftself %0, ptr %Self, ptr %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 ptr @generic_type_concrete_method_witness(ptr noalias nocapture swiftself dereferenceable({{.*}}) %0, ptr %Self, ptr %SelfWitnessTable)
// CHECK-objc: [[T1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 10
// CHECK-native: [[T1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 7
// CHECK: %T = load ptr, ptr [[T1]], align 8
// CHECK-objc: [[U1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 11
// CHECK-native: [[U1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 8
// CHECK: %U = load ptr, ptr [[U1]], align 8
// CHECK-objc: [[V1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 12
// CHECK-native: [[V1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 9
// CHECK: %V = load ptr, ptr [[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 ptr @concrete_type_concrete_static_method_witness(ptr swiftself %0, ptr %Self, ptr %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 ptr @generic_type_concrete_static_method_witness(ptr swiftself %0, ptr %Self, ptr %SelfWitnessTable)
// CHECK-objc: [[T1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 10
// CHECK-native: [[T1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 7
// CHECK: %T = load ptr, ptr [[T1]], align 8
// CHECK-objc: [[U1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 11
// CHECK-native: [[U1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 8
// CHECK: %U = load ptr, ptr [[U1]], align 8
// CHECK-objc: [[V1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 12
// CHECK-native: [[V1:%.*]] = getelementptr inbounds ptr, ptr %Self, i64 9
// CHECK: %V = load ptr, ptr [[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 ptr @concrete_type_generic_method_witness(ptr noalias %0, ptr %Z, ptr noalias nocapture swiftself %1, ptr %Self, ptr %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 ptr @generic_type_generic_method_witness(ptr noalias %0, ptr %Z, ptr noalias nocapture swiftself dereferenceable(8) %1, ptr %Self, ptr %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 ptr @concrete_type_generic_static_method_witness(ptr noalias %0, ptr %Z, ptr swiftself %1, ptr %Self, ptr %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 ptr @generic_type_generic_static_method_witness(ptr noalias %0, ptr %Z, ptr swiftself %1, ptr %Self, ptr %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 ptr @concrete_type_concrete_method_witness(ptr {{.*}}, ptr {{.*}} @"$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 ptr @concrete_type_concrete_static_method_witness(ptr {{.*}} @"$s19sil_witness_methods3FooVMf", {{.*}} ptr {{.*}} @"$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 { ptr, ptr } @partial_apply_concrete_witness() {{.*}} {
// CHECK: [[CONTEXT:%.*]] = call noalias ptr @swift_allocObject({{.*}})
// CHECK: [[WTABLE:%.*]] = getelementptr inbounds <{ %swift.refcounted, ptr }>, ptr [[CONTEXT]], i32 0, i32 1
// CHECK: store ptr @"$s19sil_witness_methods3BarCyxq_q0_GAA1PAAWP", ptr [[WTABLE]]
// CHECK: [[RESULT:%.*]] = insertvalue { ptr, ptr } { ptr @"$s36generic_type_concrete_method_witnessTA", ptr undef }, ptr [[CONTEXT]], 1
// CHECK: ret { ptr, ptr } [[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
}
|