blob: b700add5f88641779438a87394ad2eaec1bc41fd [file] [log] [blame]
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s --check-prefix=CHECK --check-prefix=ONONE
// R/UN: %target-swift-frontend -O -disable-llvm-optzns -emit-ir %s | %FileCheck %s --check-prefix=CHECK --check-prefix=ONONE
@_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(%swift.type* %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(%swift.type* [[INSTANTIATED_TYPE]], %swift.type* [[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(%swift.type* [[INSTANTIATED_TYPE]], %swift.type* [[INSTANTIATED_TYPE]])
useMetadata(PrivateNonfinal<Int, String, V>.self)
}
// CHECK-LABEL: define {{.*}}15PrivateNonfinal{{.*}}cfC
// CHECK: call {{.*}}@swift_allocObject(%swift.type* %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> {
@inline(never)
final func borts() {
useMetadata(PrivateNonfinalSubclass.self)
}
// CHECK-LABEL: define {{.*}}PrivateNonfinalSubclass{{.*}}cfC
// CHECK: call {{.*}}@swift_allocObject(%swift.type* %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-LABEL: define {{.*}}FinalPrivateNonfinalSubclass{{.*}}burts
@inline(never)
final func burts() {
// CHECK: [[TYPE_GEP:%.*]] = getelementptr {{.*}} %0
// CHECK: [[TYPE:%.*]] = load {{.*}} [[TYPE_GEP]]
// CHECK: call {{.*}} @useMetadata(%swift.type* [[TYPE]], %swift.type* [[TYPE]])
useMetadata(FinalPrivateNonfinalSubclass<U>.self)
// CHECK: [[INSTANTIATED_TYPE:%.*]] = call {{.*}} @__swift_instantiateConcreteTypeFromMangledName{{.*}}({{.*}}FinalPrivateNonfinalSubclass
// CHECK: call {{.*}} @useMetadata(%swift.type* [[INSTANTIATED_TYPE]], %swift.type* [[INSTANTIATED_TYPE]])
useMetadata(FinalPrivateNonfinalSubclass<Int>.self)
}
// CHECK-LABEL: define {{.*}}FinalPrivateNonfinalSubclass{{.*}}cfC"
// CHECK: call {{.*}}@swift_allocObject(%swift.type* %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_GEP:%.*]] = getelementptr {{.*}} %0
// CHECK: [[TYPE:%.*]] = load {{.*}} [[TYPE_GEP]]
// CHECK: call {{.*}} @useMetadata(%swift.type* [[TYPE]], %swift.type* [[TYPE]])
useMetadata(PrivateFinal<T, U, V>.self)
// CHECK: [[INSTANTIATED_TYPE:%.*]] = call {{.*}} @__swift_instantiateConcreteTypeFromMangledName{{.*}}({{.*}}PrivateFinal
// CHECK: call {{.*}} @useMetadata(%swift.type* [[INSTANTIATED_TYPE]], %swift.type* [[INSTANTIATED_TYPE]])
useMetadata(PrivateFinal<Int, String, Float>.self)
}
// CHECK-LABEL: define {{.*}}PrivateFinal{{.*}}cfC"
// CHECK: call {{.*}}@swift_allocObject(%swift.type* %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()
}