// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) -import-objc-header %S/Inputs/keypaths_objc.h %s | %FileCheck %s // RUN: %target-swift-emit-ir(mock-sdk: %clang-importer-sdk) -import-objc-header %S/Inputs/keypaths_objc.h %s // REQUIRES: objc_interop import Foundation struct NonObjC { var x: Int var y: NSObject } class Foo: NSObject { @objc var int: Int { fatalError() } @objc var bar: Bar { fatalError() } var nonobjc: NonObjC { fatalError() } @objc(thisIsADifferentName) var differentName: Bar { fatalError() } @objc subscript(x: Int) -> Foo { return self } @objc subscript(x: Bar) -> Foo { return self } @objc dynamic var dyn: String { fatalError() } } class Bar: NSObject { @objc var foo: Foo { fatalError() } } // CHECK-LABEL: sil hidden [ossa] @$s13keypaths_objc0B8KeypathsyyF func objcKeypaths() { // CHECK: keypath $WritableKeyPath, (root _ = \NonObjC.x // CHECK: keypath $WritableKeyPath, (root _ = \NonObjC.y // CHECK: keypath $KeyPath, (objc "int" _ = \Foo.int // CHECK: keypath $KeyPath, (objc "bar" _ = \Foo.bar // CHECK: keypath $KeyPath, (objc "bar.foo" _ = \Foo.bar.foo // CHECK: keypath $KeyPath, (objc "bar.foo.bar" _ = \Foo.bar.foo.bar // CHECK: keypath $KeyPath, (root _ = \Foo.nonobjc // CHECK: keypath $KeyPath, (root _ = \Foo.bar.foo.nonobjc.y // CHECK: keypath $KeyPath, (objc "thisIsADifferentName" _ = \Foo.differentName } // CHECK-LABEL: sil hidden [ossa] @$s13keypaths_objc0B18KeypathIdentifiersyyF func objcKeypathIdentifiers() { // CHECK: keypath $KeyPath, (objc "objcProp"; {{.*}} id #ObjCFoo.objcProp!getter.foreign _ = \ObjCFoo.objcProp // CHECK: keypath $KeyPath, (objc "dyn"; {{.*}} id #Foo.dyn!getter.foreign _ = \Foo.dyn // CHECK: keypath $KeyPath, (objc "int"; {{.*}} id #Foo.int!getter : _ = \Foo.int } struct X {} extension NSObject { var x: X { return X() } @objc var objc: Int { return 0 } @objc dynamic var dynamic: Int { return 0 } } // CHECK-LABEL: sil hidden [ossa] @{{.*}}nonobjcExtensionOfObjCClass func nonobjcExtensionOfObjCClass() { // Should be treated as a statically-dispatch property // CHECK: keypath $KeyPath, ({{.*}} id @ _ = \NSObject.x // CHECK: keypath $KeyPath, ({{.*}} id #NSObject.objc!getter.foreign _ = \NSObject.objc // CHECK: keypath $KeyPath, ({{.*}} id #NSObject.dynamic!getter.foreign _ = \NSObject.dynamic } @objc protocol ObjCProto { var objcRequirement: Int { get set } } // CHECK-LABEL: sil hidden [ossa] @{{.*}}ProtocolRequirement func objcProtocolRequirement(_: T) { // CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.foreign _ = \T.objcRequirement // CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.foreign _ = \ObjCProto.objcRequirement } // CHECK-LABEL: sil hidden [ossa] @{{.*}}externalObjCProperty func externalObjCProperty() { // Pure ObjC-dispatched properties do not have external descriptors. // CHECK: keypath $KeyPath, // CHECK-NOT: external #NSObject.description _ = \NSObject.description } func sharedCProperty() { // CHECK: keypath $WritableKeyPath // CHECK-NOT: external #c_union.some_field let dataKeyPath: WritableKeyPath? = \c_union.some_field } class OverrideFrameworkObjCProperty: A { override var counter: Int32 { get { return 0 } set { } } } func overrideFrameworkObjCProperty() { let _ = \OverrideFrameworkObjCProperty.counter } @dynamicMemberLookup class DynamicClass { init() {} subscript(dynamicMember member: KeyPath) -> DynamicClass { fatalError() } } // CHECK-LABEL: sil hidden [ossa] @{{.*}}dynamicMemberLookupSimple func dynamicMemberLookupSimple(foo: DynamicClass, nonobjc: DynamicClass) { // CHECK: keypath $KeyPath, (objc "bar" _ = foo.bar // CHECK: keypath $KeyPath, (objc "int" _ = foo.int // CHECK: keypath $KeyPath, (objc "bar" // CHECK: keypath $KeyPath, (objc "foo" _ = foo.bar.foo // CHECK: keypath $KeyPath, (root _ = foo.nonobjc // CHECK: keypath $KeyPath, (objc "thisIsADifferentName" _ = foo.differentName // CHECK: keypath $KeyPath, (root _ = nonobjc.x // CHECK: keypath $KeyPath, (root _ = nonobjc.y } // CHECK-LABEL: sil hidden [ossa] @{{.*}}dynamicMemberLookupNestedKeypaths func dynamicMemberLookupNestedKeypaths(foo: DynamicClass) { // CHECK: keypath $KeyPath, (objc "bar" // CHECK: keypath $KeyPath, (objc "foo" // CHECK: keypath $KeyPath, (objc "bar" _ = foo.bar.foo.bar } // CHECK-LABEL: sil hidden [ossa] @{{.*}}dynamicMemberLookupMixedKeypaths func dynamicMemberLookupMixedKeypaths(foo: DynamicClass) { // CHECK: keypath $KeyPath, (objc "bar" // CHECK: keypath $KeyPath, (objc "foo" // CHECK: keypath $KeyPath, (root // CHECK: keypath $KeyPath, (root _ = foo.bar.foo.nonobjc.y }