Files
swift-mirror/test/Interpreter/SDK/archive_attributes.swift
John McCall 31f2eec044 Change type metadata accessors to support incomplete metadata.
This includes global generic and non-generic global access
functions, protocol associated type access functions,
swift_getGenericMetadata, and generic type completion functions.

The main part of this change is that the functions now need to take
a MetadataRequest and return a MetadataResponse, which is capable
of expressing that the request can fail.  The state of the returned
metadata is reported as an second, independent return value; this
allows the caller to easily check the possibility of failure without
having to mask it out from the returned metadata pointer, as well
as allowing it to be easily ignored.

Also, change metadata access functions to use swiftcc to ensure that
this return value is indeed returned in two separate registers.

Also, change protocol associated conformance access functions to use
swiftcc.  This isn't really related, but for some reason it snuck in.
Since it's clearly the right thing to do, and since I really didn't
want to retroactively tease that back out from all the rest of the
test changes, I've left it in.

Also, change generic metadata access functions to either pass all
the generic arguments directly or pass them all indirectly.  I don't
know how we ended up with the hybrid approach.  I needed to change all
the code-generation and calls here anyway in order to pass the request
parameter, and I figured I might as well change the ABI to something
sensible.
2018-03-18 21:38:08 -04:00

192 lines
4.5 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift %s -module-name=test -DENCODE -o %t/encode
// RUN: %target-build-swift %s -module-name=test -o %t/decode
// RUN: %target-build-swift %s -module-name=test -Xfrontend -disable-llvm-optzns -emit-ir | %FileCheck -check-prefix=CHECK-IR %s
// RUN: %target-run %t/encode %t/test.arc
// RUN: plutil -p %t/test.arc | %FileCheck -check-prefix=CHECK-ARCHIVE %s
// RUN: %target-run %t/decode %t/test.arc | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: objc_interop
// REQUIRES: CPU=i386 || CPU=x86_64
// UNSUPPORTED: OS=tvos
// UNSUPPORTED: OS=watchos
import Foundation
struct ABC {
// CHECK-ARCHIVE-DAG: "$classname" => "nested_class_coding"
@objc(nested_class_coding)
class NestedClass : NSObject, NSCoding {
var i : Int
init(_ ii: Int) {
i = ii
}
required init(coder aDecoder: NSCoder) {
i = aDecoder.decodeInteger(forKey: "i")
}
func encode(with aCoder: NSCoder) {
aCoder.encode(i, forKey: "i")
}
}
}
// CHECK-ARCHIVE-DAG: "$classname" => "private_class_coding"
@objc(private_class_coding)
private class PrivateClass : NSObject, NSCoding {
var pi : Int
init(_ ii: Int) {
pi = ii
}
required init(coder aDecoder: NSCoder) {
pi = aDecoder.decodeInteger(forKey: "pi")
}
func encode(with aCoder: NSCoder) {
aCoder.encode(pi, forKey: "pi")
}
}
class GenericClass<T> : NSObject, NSCoding {
var gi : T? = nil
override init() {
}
required init(coder aDecoder: NSCoder) {
}
func encode(with aCoder: NSCoder) {
}
}
// CHECK-ARCHIVE-DAG: "$classname" => "test.IntClass"
class IntClass : GenericClass<Int> {
init(ii: Int) {
super.init()
gi = ii
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
gi = aDecoder.decodeInteger(forKey: "gi")
}
override func encode(with aCoder: NSCoder) {
aCoder.encode(gi!, forKey: "gi")
}
}
// CHECK-ARCHIVE-DAG: "$classname" => "double_class_coding"
@objc(double_class_coding)
class DoubleClass : GenericClass<Double> {
init(dd: Double) {
super.init()
gi = dd
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
gi = aDecoder.decodeDouble(forKey: "gi")
}
override func encode(with aCoder: NSCoder) {
aCoder.encode(gi!, forKey: "gi")
}
}
// CHECK-ARCHIVE-DAG: "$classname" => "top_level_coding"
@objc(top_level_coding)
class TopLevel : NSObject, NSCoding {
var tli : Int
var nested: ABC.NestedClass?
fileprivate var priv: PrivateClass?
var intc : IntClass?
var doublec : DoubleClass?
init(_ ii: Int) {
tli = ii
}
required init(coder aDecoder: NSCoder) {
tli = aDecoder.decodeInteger(forKey: "tli")
nested = aDecoder.decodeObject(forKey: "nested") as? ABC.NestedClass
priv = aDecoder.decodeObject(forKey: "priv") as? PrivateClass
intc = aDecoder.decodeObject(forKey: "int") as? IntClass
doublec = aDecoder.decodeObject(forKey: "double") as? DoubleClass
}
func encode(with aCoder: NSCoder) {
aCoder.encode(tli, forKey: "tli")
aCoder.encode(nested, forKey: "nested")
aCoder.encode(priv, forKey: "priv")
aCoder.encode(intc, forKey: "int")
aCoder.encode(doublec, forKey: "double")
}
}
func main() {
let args = CommandLine.arguments
#if ENCODE
let c = TopLevel(27)
c.nested = ABC.NestedClass(28)
c.priv = PrivateClass(29)
c.intc = IntClass(ii: 42)
c.doublec = DoubleClass(dd: 3.14)
NSKeyedArchiver.archiveRootObject(c, toFile: args[1])
#else
if let u = NSKeyedUnarchiver.unarchiveObject(withFile: args[1]) {
if let x = u as? TopLevel {
// CHECK: top-level: 27
print("top-level: \(x.tli)")
if let n = x.nested {
// CHECK: nested: 28
print("nested: \(n.i)")
}
if let p = x.priv {
// CHECK: private: 29
print("private: \(p.pi)")
}
if let g = x.intc {
// CHECK: int: 42
print("int: \(g.gi!)")
}
if let d = x.doublec {
// CHECK: double: 3.14
print("double: \(d.gi!)")
}
} else {
print(u)
}
} else {
print("nil")
}
#endif
}
main()
// Check that we eagerly create metadata of generic classes, but not for nested classes.
// CHECK-IR-LABEL: define {{.*}} @_swift_eager_class_initialization
// CHECK-IR-NEXT: entry:
// CHECK-IR-NEXT: call {{.*}}IntClassCMa
// CHECK-IR-NEXT: extractvalue
// CHECK-IR-NEXT: call void asm
// CHECK-IR-NEXT: call {{.*}}DoubleClassCMa
// CHECK-IR-NEXT: extractvalue
// CHECK-IR-NEXT: call void asm
// CHECK-IR-NEXT: ret