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
|
// RUN: %target-swift-frontend -emit-ir -o - -primary-file %s | %FileCheck %s
// REQUIRES: CPU=x86_64
sil_stage canonical
import Builtin
import Swift
import SwiftShims
public protocol Kindable {
var kind: Int { get }
}
extension Int : Kindable {
public var kind: Int { get }
}
extension Float : Kindable {
public var kind: Int { get }
}
// CHECK: @"$sSi21existential_metatypes8KindableAAWP" = external{{( dllimport)?}} global ptr, align 8
// CHECK: @"$sSf21existential_metatypes8KindableAAWP" = external{{( dllimport)?}} global ptr, align 8
sil @int_kind_getter : $@convention(method) (Int) -> Int {
bb0(%0 : $Int):
%2 = integer_literal $Builtin.Int64, 0
%3 = struct $Int (%2 : $Builtin.Int64)
return %3 : $Int
}
sil [transparent] [thunk] @int_kind_getter_witness : $@convention(witness_method: Kindable) (@in_guaranteed Int) -> Int {
bb0(%0 : $*Int):
%1 = load %0 : $*Int
%2 = function_ref @int_kind_getter : $@convention(method) (Int) -> Int
%3 = apply %2(%1) : $@convention(method) (Int) -> Int
return %3 : $Int
}
sil @float_kind_getter : $@convention(method) (Float) -> Int {
bb0(%0 : $Float):
%2 = integer_literal $Builtin.Int64, 1
%3 = struct $Int (%2 : $Builtin.Int64)
return %3 : $Int
}
sil [transparent] [thunk] @float_kind_getter_witness : $@convention(witness_method: Kindable) (@in_guaranteed Float) -> Int {
bb0(%0 : $*Float):
%1 = load %0 : $*Float
%2 = function_ref @float_kind_getter : $@convention(method) (Float) -> Int
%3 = apply %2(%1) : $@convention(method) (Float) -> Int
return %3 : $Int
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test0()
sil @test0 : $@convention(thin) () -> () {
bb0:
// CHECK: [[V:%.*]] = alloca { ptr, ptr }, align 8
// CHECK-NEXT: llvm.lifetime.start
%0 = alloc_stack $@thick Kindable.Type, var, name "v"
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { ptr, ptr }, ptr [[V]], i32 0, i32 0
// CHECK-NEXT: store ptr @"$sSiN", ptr [[T0]], align 8
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { ptr, ptr }, ptr [[V]], i32 0, i32 1
%1 = metatype $@thin Int.Type
%2 = metatype $@thick Int.Type
%3 = init_existential_metatype %2 : $@thick Int.Type, $@thick Kindable.Type
// CHECK-NEXT: store ptr @"$sSi21existential_metatypes8KindableAAWP", ptr [[T0]], align 8
store %3 to %0 : $*@thick Kindable.Type
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { ptr, ptr }, ptr [[V]], i32 0, i32 0
// CHECK-NEXT: store ptr @"$sSfN", ptr [[T0]], align 8
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { ptr, ptr }, ptr [[V]], i32 0, i32 1
%5 = metatype $@thin Float.Type
%6 = metatype $@thick Float.Type
%7 = init_existential_metatype %6 : $@thick Float.Type, $@thick Kindable.Type
// CHECK-NEXT: store ptr @"$sSf21existential_metatypes8KindableAAWP", ptr [[T0]], align 8
store %7 to %0 : $*@thick Kindable.Type
%9 = tuple ()
// CHECK-NEXT: llvm.lifetime.end
dealloc_stack %0 : $*@thick Kindable.Type
// CHECK-NEXT: ret void
return %9 : $()
}
sil @use : $@convention(thin) (@thick Kindable.Type) -> () {
bb0(%0 : $@thick Kindable.Type):
%2 = tuple ()
return %2 : $()
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test1(i64 %0, i64 %1)
sil @test1 : $@convention(thin) (Optional<@thick Kindable.Type>) -> () {
bb0(%0 : $Optional<@thick Kindable.Type>):
// CHECK: [[TYPE:%.*]] = inttoptr i64 %0 to ptr
// CHECK: [[WITNESS:%.*]] = inttoptr i64 %1 to ptr
switch_enum %0 : $Optional<@thick Kindable.Type>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1(%3 : $@thick Kindable.Type):
%5 = function_ref @use : $@convention(thin) (@thick Kindable.Type) -> ()
%6 = apply %5(%3) : $@convention(thin) (@thick Kindable.Type) -> ()
br bb3
bb2:
br bb3
bb3:
%9 = tuple ()
return %9 : $()
}
sil_witness_table public_external Int: Kindable module existential_metatypes {
method #Kindable.kind!getter: @int_kind_getter_witness
}
sil_witness_table public_external Float: Kindable module existential_metatypes {
method #Kindable.kind!getter: @float_kind_getter_witness
}
|