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
|
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s --check-prefix=CHECK --check-prefix=ONONE
// RUN: %target-swift-frontend -O -disable-llvm-optzns -Xllvm -sil-disable-pass=FunctionSignatureOpts -emit-ir %s | %FileCheck %s --check-prefix=CHECK --check-prefix=O
@_silgen_name("useMetadata")
func useMetadata<T>(_: T.Type)
// TODO: Although this is not explicitly final, class hierarchy analysis
// should figure out that it's effectively final because it has no
// subclasses.
private class PrivateEffectivelyFinal<T, U, V> {
final func butts() {
useMetadata(PrivateEffectivelyFinal<T, U, V>.self)
useMetadata(PrivateEffectivelyFinal<Int, String, V>.self)
}
// CHECK-LABEL: define {{.*}}PrivateEffectivelyFinal{{.*}}cfC
// CHECK: call {{.*}}@swift_allocObject(ptr %0
}
// The class is not final and has subclasses, so we can only peephole
// metadata requests in limited circumstances.
private class PrivateNonfinal<T, U, V> {
// The designated init allocating entry point is always overridden
// by subclasses, so it can use the self metadata it was passed.
// Methods in general on nonfinal classes cannot use the self metadata as
// is.
// CHECK-LABEL: define {{.*}}15PrivateNonfinal{{.*}}buttsyyF{{.*}}"
@inline(never)
final func butts() {
// CHECK: [[INSTANTIATED_TYPE_RESPONSE:%.*]] = call {{.*}} @{{.*}}15PrivateNonfinal{{.*}}Ma
// CHECK-NEXT: [[INSTANTIATED_TYPE:%.*]] = extractvalue {{.*}} [[INSTANTIATED_TYPE_RESPONSE]]
// CHECK-NEXT: call {{.*}} @useMetadata(ptr [[INSTANTIATED_TYPE]], ptr [[INSTANTIATED_TYPE]])
useMetadata(PrivateNonfinal<T, U, V>.self)
// CHECK: [[INSTANTIATED_TYPE_RESPONSE:%.*]] = call {{.*}} @{{.*}}15PrivateNonfinal{{.*}}Ma
// CHECK-NEXT: [[INSTANTIATED_TYPE:%.*]] = extractvalue {{.*}} [[INSTANTIATED_TYPE_RESPONSE]]
// CHECK-NEXT: call {{.*}} @useMetadata(ptr [[INSTANTIATED_TYPE]], ptr [[INSTANTIATED_TYPE]])
useMetadata(PrivateNonfinal<Int, String, V>.self)
}
// CHECK-LABEL: define {{.*}}15PrivateNonfinal{{.*}}cfC
// CHECK: call {{.*}}@swift_allocObject(ptr %0
}
// TODO: Although this is not explicitly final, class hierarchy analysis
// should figure out that it's effectively final because it has no
// subclasses.
private class PrivateNonfinalSubclass: PrivateNonfinal<Int, String, Float> {
// CHECK-O-LABEL: define {{.*}}PrivateNonfinalSubclass{{.*}}cfC
// CHECK-O: call {{.*}}@swift_allocObject(ptr %0
@inline(never)
final func borts() {
useMetadata(PrivateNonfinalSubclass.self)
}
// CHECK-ONONE-LABEL: define {{.*}}PrivateNonfinalSubclass{{.*}}cfC
// CHECK-ONONE: call {{.*}}@swift_allocObject(ptr %0
}
final private class FinalPrivateNonfinalSubclass<U>: PrivateNonfinal<U, String, Float> {
// The class is final, so we can always form metadata for
// FinalPrivateNonfinalSubclass<U> from the self argument.
// CHECK-O-LABEL: define {{.*}}FinalPrivateNonfinalSubclass{{.*}}cfC"
// CHECK-O: call {{.*}}@swift_allocObject(ptr %0
// CHECK-LABEL: define {{.*}}FinalPrivateNonfinalSubclass{{.*}}burts
@inline(never)
final func burts() {
// CHECK: [[TYPE:%.*]] = load {{.*}} %0
// CHECK: call {{.*}} @useMetadata(ptr [[TYPE]], ptr [[TYPE]])
useMetadata(FinalPrivateNonfinalSubclass<U>.self)
// CHECK: [[INSTANTIATED_TYPE:%.*]] = call {{.*}} @__swift_instantiateConcreteTypeFromMangledName{{.*}}({{.*}}FinalPrivateNonfinalSubclass
// CHECK: call {{.*}} @useMetadata(ptr [[INSTANTIATED_TYPE]], ptr [[INSTANTIATED_TYPE]])
useMetadata(FinalPrivateNonfinalSubclass<Int>.self)
}
// CHECK-ONONE-LABEL: define {{.*}}FinalPrivateNonfinalSubclass{{.*}}cfC"
// CHECK-ONONE: call {{.*}}@swift_allocObject(ptr %0
}
// CHECK-O-LABEL: define {{.*}}FinalPrivateNonfinalSubclass{{.*}}cfC"
// CHECK-O: call {{.*}}@swift_allocObject(ptr %0
final private class PrivateFinal<T, U, V> {
// The class is final, so we can always form metadata for
// PrivateFinal<T, U, V> from the self argument.
// CHECK-LABEL: define {{.*}}PrivateFinal{{.*}}butts
func butts() {
// CHECK: [[TYPE:%.*]] = load {{.*}} %0
// CHECK: call {{.*}} @useMetadata(ptr [[TYPE]], ptr [[TYPE]])
useMetadata(PrivateFinal<T, U, V>.self)
// CHECK: [[INSTANTIATED_TYPE:%.*]] = call {{.*}} @__swift_instantiateConcreteTypeFromMangledName{{.*}}({{.*}}PrivateFinal
// CHECK: call {{.*}} @useMetadata(ptr [[INSTANTIATED_TYPE]], ptr [[INSTANTIATED_TYPE]])
useMetadata(PrivateFinal<Int, String, Float>.self)
}
// CHECK-LABEL: define {{.*}}PrivateFinal{{.*}}cfC"
// CHECK: call {{.*}}@swift_allocObject(ptr %0
}
public func useStuff<T, U, V>(_: T, _: U, _: V) {
PrivateEffectivelyFinal<T, U, V>().butts()
PrivateNonfinal<T, U, V>().butts()
PrivateNonfinalSubclass().borts()
FinalPrivateNonfinalSubclass<U>().burts()
PrivateFinal<T, U, V>().butts()
}
|