mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Also, add a third [serializable] state for functions whose bodies we *can* serialize, but only do so if they're referenced from another serialized function. This will be used for bodies synthesized for imported definitions, such as init(rawValue:), etc, and various thunks, but for now this change is NFC.
109 lines
4.8 KiB
Swift
109 lines
4.8 KiB
Swift
// RUN: %target-swift-frontend -emit-silgen -emit-verbose-sil %s | %FileCheck %s
|
|
|
|
// CHECK-LABEL: @_specialize(exported: false, kind: full, where T == Int, U == Float)
|
|
// CHECK-NEXT: func specializeThis<T, U>(_ t: T, u: U)
|
|
@_specialize(where T == Int, U == Float)
|
|
func specializeThis<T, U>(_ t: T, u: U) {}
|
|
|
|
public protocol PP {
|
|
associatedtype PElt
|
|
}
|
|
public protocol QQ {
|
|
associatedtype QElt
|
|
}
|
|
|
|
public struct RR : PP {
|
|
public typealias PElt = Float
|
|
}
|
|
public struct SS : QQ {
|
|
public typealias QElt = Int
|
|
}
|
|
|
|
public struct GG<T : PP> {}
|
|
|
|
// CHECK-LABEL: public class CC<T> where T : PP {
|
|
// CHECK-NEXT: @_specialize(exported: false, kind: full, where T == RR, U == SS)
|
|
// CHECK-NEXT: @inline(never) public func foo<U>(_ u: U, g: GG<T>) -> (U, GG<T>) where U : QQ
|
|
public class CC<T : PP> {
|
|
@inline(never)
|
|
@_specialize(where T == RR, U == SS)
|
|
public func foo<U : QQ>(_ u: U, g: GG<T>) -> (U, GG<T>) {
|
|
return (u, g)
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [_specialize exported: false, kind: full, where T == Int, U == Float] @_T015specialize_attr0A4Thisyx_q_1utr0_lF : $@convention(thin) <T, U> (@in T, @in U) -> () {
|
|
|
|
// CHECK-LABEL: sil [noinline] [_specialize exported: false, kind: full, where T == RR, U == SS] @_T015specialize_attr2CCC3fooqd___AA2GGVyxGtqd___AG1gtAA2QQRd__lF : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Test user-specialized subscript accessors.
|
|
|
|
public protocol TestSubscriptable {
|
|
associatedtype Element
|
|
subscript(i: Int) -> Element { get set }
|
|
}
|
|
|
|
public class ASubscriptable<Element> : TestSubscriptable {
|
|
var storage: UnsafeMutablePointer<Element>
|
|
|
|
init(capacity: Int) {
|
|
storage = UnsafeMutablePointer<Element>.allocate(capacity: capacity)
|
|
}
|
|
|
|
public subscript(i: Int) -> Element {
|
|
@_specialize(where Element == Int)
|
|
get {
|
|
return storage[i]
|
|
}
|
|
@_specialize(where Element == Int)
|
|
set(rhs) {
|
|
storage[i] = rhs
|
|
}
|
|
}
|
|
}
|
|
|
|
// ASubscriptable.subscript.getter with _specialize
|
|
// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_T015specialize_attr14ASubscriptableC9subscriptxSicfg : $@convention(method) <Element> (Int, @guaranteed ASubscriptable<Element>) -> @out Element {
|
|
|
|
// ASubscriptable.subscript.setter with _specialize
|
|
// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_T015specialize_attr14ASubscriptableC9subscriptxSicfs : $@convention(method) <Element> (@in Element, Int, @guaranteed ASubscriptable<Element>) -> () {
|
|
|
|
// ASubscriptable.subscript.materializeForSet with no attribute
|
|
// CHECK-LABEL: sil [transparent] [serialized] @_T015specialize_attr14ASubscriptableC9subscriptxSicfm : $@convention(method) <Element> (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, Int, @guaranteed ASubscriptable<Element>) -> (Builtin.RawPointer, Optional<Builtin.RawPointer>) {
|
|
|
|
public class Addressable<Element> : TestSubscriptable {
|
|
var storage: UnsafeMutablePointer<Element>
|
|
|
|
init(capacity: Int) {
|
|
storage = UnsafeMutablePointer<Element>.allocate(capacity: capacity)
|
|
}
|
|
|
|
public subscript(i: Int) -> Element {
|
|
@_specialize(where Element == Int)
|
|
unsafeAddress {
|
|
return UnsafePointer<Element>(storage + i)
|
|
}
|
|
@_specialize(where Element == Int)
|
|
unsafeMutableAddress {
|
|
return UnsafeMutablePointer<Element>(storage + i)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Addressable.subscript.getter with no attribute
|
|
// CHECK-LABEL: sil [transparent] [serialized] @_T015specialize_attr11AddressableC9subscriptxSicfg : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> @out Element {
|
|
|
|
// Addressable.subscript.unsafeAddressor with _specialize
|
|
// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_T015specialize_attr11AddressableC9subscriptxSicflu : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> UnsafePointer<Element> {
|
|
|
|
// Addressable.subscript.setter with no attribute
|
|
// CHECK-LABEL: sil [transparent] [serialized] @_T015specialize_attr11AddressableC9subscriptxSicfs : $@convention(method) <Element> (@in Element, Int, @guaranteed Addressable<Element>) -> () {
|
|
|
|
// Addressable.subscript.unsafeMutableAddressor with _specialize
|
|
// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_T015specialize_attr11AddressableC9subscriptxSicfau : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> UnsafeMutablePointer<Element> {
|
|
|
|
// Addressable.subscript.materializeForSet with no attribute
|
|
// CHECK-LABEL: sil [transparent] [serialized] @_T015specialize_attr11AddressableC9subscriptxSicfm : $@convention(method) <Element> (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, Int, @guaranteed Addressable<Element>) -> (Builtin.RawPointer, Optional<Builtin.RawPointer>) {
|
|
|