mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Now that all the machinery is in place, the ClassMetadataBuilder can (more accurately) query the ClassLayout instead of trying to re-derive whether the field offset vector is dependent, etc. Apart from performing dynamic layout for resiliently-sized fields in concrete classes, this also lets us *skip* dynamic layout if we have a generic class without any dependent fields. I haven't tested subclassing with resilient field layout yet, but getting that working is the next step and should not be too much work. Also, swift_initClassMetadata_UniversalStrategy() only stores the computed field offsets in the field offset globals when the Objective-C runtime is available, because it gets the offset pointers from the Objective-C class rodata. On Linux, we will need to emit code to copy from the field offset vector into field offset globals in IRGen. This is pretty easy, but I'll do it in a follow-up patch so for now the new execution test is XFAIL'd on Linux.
237 lines
5.1 KiB
Swift
237 lines
5.1 KiB
Swift
// RUN: rm -rf %t && mkdir %t
|
|
// RUN: %target-build-swift %s -o %t/a.out
|
|
// RUN: %target-run %t/a.out | FileCheck %s
|
|
// REQUIRES: executable_test
|
|
|
|
protocol MyPrintable {
|
|
func myPrint()
|
|
}
|
|
|
|
extension Int : MyPrintable {
|
|
func myPrint() {
|
|
print(self.description, terminator: "")
|
|
}
|
|
}
|
|
|
|
extension Double : MyPrintable {
|
|
func myPrint() {
|
|
print(self.description, terminator: "")
|
|
}
|
|
}
|
|
|
|
extension String : MyPrintable {
|
|
func myPrint() {
|
|
print(self.debugDescription, terminator: "")
|
|
}
|
|
}
|
|
|
|
class BufferedPair<T, U> {
|
|
var front: UInt8
|
|
var first: T
|
|
var second: U
|
|
var back: UInt8
|
|
|
|
init(_ front: UInt8, _ first: T, _ second: U, _ back: UInt8) {
|
|
self.front = front
|
|
self.first = first
|
|
self.second = second
|
|
self.back = back
|
|
}
|
|
}
|
|
|
|
enum State : MyPrintable {
|
|
case CA, OR, WA
|
|
|
|
func myPrint() {
|
|
switch self {
|
|
case .CA:
|
|
print("California", terminator: "")
|
|
case .OR:
|
|
print("Oregon", terminator: "")
|
|
case .WA:
|
|
print("Washington", terminator: "")
|
|
}
|
|
}
|
|
}
|
|
|
|
func printPair<A: MyPrintable, B: MyPrintable>(p: BufferedPair<A,B>) {
|
|
print("\(p.front) ", terminator: "")
|
|
p.first.myPrint()
|
|
print(" ", terminator: "")
|
|
p.second.myPrint()
|
|
print(" \(p.back)")
|
|
}
|
|
|
|
var p = BufferedPair(99, State.OR, "Washington's Mexico", 84)
|
|
// CHECK: 99 Oregon "Washington\'s Mexico" 84
|
|
printPair(p)
|
|
|
|
class AwkwardTriple<V, W, X> : BufferedPair<V, W> {
|
|
var third: X
|
|
|
|
init(_ front: UInt8, _ first: V, _ second: W, _ back: UInt8, _ third: X) {
|
|
self.third = third
|
|
super.init(front, first, second, back)
|
|
self.third = third
|
|
}
|
|
}
|
|
|
|
func printTriple
|
|
<D: MyPrintable, E: MyPrintable, F: MyPrintable>
|
|
(p: AwkwardTriple<D, E, F>)
|
|
{
|
|
print("\(p.front) ", terminator: "")
|
|
p.first.myPrint()
|
|
print(" ", terminator: "")
|
|
p.second.myPrint()
|
|
print(" \(p.back) ", terminator: "")
|
|
p.third.myPrint()
|
|
print("")
|
|
}
|
|
|
|
var q = AwkwardTriple(123, State.CA, "Foo", 234, State.WA)
|
|
// CHECK: 123 California "Foo" 234
|
|
printPair(q)
|
|
// CHECK: 123 California "Foo" 234 Washington
|
|
printTriple(q)
|
|
|
|
class FourthWheel<P, Q, R, S> : AwkwardTriple<P, Q, R> {
|
|
var fourth: S
|
|
|
|
init(_ front: UInt8, _ first: P, _ second: Q, _ back: UInt8, _ third: R,
|
|
_ fourth: S) {
|
|
self.fourth = fourth
|
|
super.init(front, first, second, back, third)
|
|
self.fourth = fourth
|
|
}
|
|
}
|
|
|
|
func printQuad
|
|
<G: MyPrintable, H: MyPrintable, I: MyPrintable, J: MyPrintable>
|
|
(p: FourthWheel<G, H, I, J>)
|
|
{
|
|
print("\(p.front) ", terminator: "")
|
|
p.first.myPrint()
|
|
print(" ", terminator: "")
|
|
p.second.myPrint()
|
|
print(" \(p.back) ", terminator: "")
|
|
p.third.myPrint()
|
|
print(" ", terminator: "")
|
|
p.fourth.myPrint()
|
|
print("")
|
|
}
|
|
|
|
var r = FourthWheel(21, State.WA, "Bar", 31, State.OR, 3.125)
|
|
// CHECK: 21 Washington "Bar" 31
|
|
printPair(r)
|
|
// CHECK: 21 Washington "Bar" 31 Oregon
|
|
printTriple(r)
|
|
var rAsPair: BufferedPair<State, String> = r
|
|
// CHECK: 21 Washington "Bar" 31 Oregon
|
|
printTriple(rAsPair as! AwkwardTriple<State, String, State>)
|
|
// CHECK: 21 Washington "Bar" 31 Oregon 3.125
|
|
printQuad(r)
|
|
// CHECK: 21 Washington "Bar" 31 Oregon 3.125
|
|
printQuad(rAsPair as! FourthWheel<State, String, State, Double>)
|
|
|
|
class ConcretePair {
|
|
var first, second: UInt8
|
|
|
|
init(_ first: UInt8, _ second: UInt8) {
|
|
self.first = first
|
|
self.second = second
|
|
}
|
|
}
|
|
|
|
class SemiConcreteTriple<O> : ConcretePair {
|
|
var third: O
|
|
|
|
init(_ first: UInt8, _ second: UInt8, _ third: O) {
|
|
self.third = third
|
|
super.init(first, second)
|
|
self.third = third
|
|
}
|
|
}
|
|
|
|
func printConcretePair(p: ConcretePair) {
|
|
print("\(p.first) \(p.second)")
|
|
}
|
|
|
|
func printSemiTriple<O : MyPrintable>(p: SemiConcreteTriple<O>) {
|
|
print("\(p.first) \(p.second) ", terminator: "")
|
|
p.third.myPrint()
|
|
print("")
|
|
}
|
|
|
|
var s = SemiConcreteTriple(120, 230, State.CA)
|
|
// CHECK: 120 230
|
|
printConcretePair(s)
|
|
// CHECK: 120 230 California
|
|
printSemiTriple(s)
|
|
var t = SemiConcreteTriple(121, 231, "California's Canada")
|
|
// CHECK: 121 231
|
|
printConcretePair(t)
|
|
// CHECK: 121 231 "California\'s Canada"
|
|
printSemiTriple(t)
|
|
|
|
class MoreConcreteQuadruple : SemiConcreteTriple<State> {
|
|
var fourth: String
|
|
|
|
init(_ first: UInt8, _ second: UInt8, _ third: State, _ fourth: String) {
|
|
self.fourth = fourth
|
|
super.init(first, second, third)
|
|
}
|
|
}
|
|
|
|
var u = MoreConcreteQuadruple(10, 17, State.CA, "Hella")
|
|
|
|
// CHECK: 10 17
|
|
printConcretePair(u)
|
|
|
|
class RootGenericFixedLayout<T> {
|
|
let a: [T]
|
|
let b: Int
|
|
|
|
init(a: [T], b: Int) {
|
|
self.a = a
|
|
self.b = b
|
|
}
|
|
}
|
|
|
|
func checkRootGenericFixedLayout<T>(r: RootGenericFixedLayout<T>) {
|
|
print(r.a)
|
|
print(r.b)
|
|
}
|
|
|
|
let rg = RootGenericFixedLayout<Int>(a: [1, 2, 3], b: 4)
|
|
|
|
// CHECK: [1, 2, 3]
|
|
// CHECK: 4
|
|
checkRootGenericFixedLayout(rg)
|
|
|
|
class GenericInheritsGenericFixedLayout<T> : RootGenericFixedLayout<T> {
|
|
let c: Int
|
|
|
|
init(a: [T], b: Int, c: Int) {
|
|
self.c = c
|
|
super.init(a: a, b: b)
|
|
}
|
|
}
|
|
|
|
let gg = GenericInheritsGenericFixedLayout<Int>(a: [1, 2, 3], b: 4, c: 5)
|
|
|
|
func checkGenericInheritsGenericFixedLayout<T>(g: GenericInheritsGenericFixedLayout<T>) {
|
|
print(g.a)
|
|
print(g.b)
|
|
print(g.c)
|
|
}
|
|
|
|
// CHECK: [1, 2, 3]
|
|
// CHECK: 4
|
|
checkRootGenericFixedLayout(gg)
|
|
|
|
// CHECK: [1, 2, 3]
|
|
// CHECK: 4
|
|
// CHECK: 5
|
|
checkGenericInheritsGenericFixedLayout(gg)
|