Files
swift-mirror/test/Interpreter/generic_class.swift
Slava Pestov 800821f980 IRGen: Layout of root classes containing resiliently-sized fields
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.
2015-12-24 02:54:56 -08:00

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)