// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -import-objc-header %S/Inputs/keypaths_objc.h %s | %FileCheck %s // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -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 } dynamic var dyn: String { fatalError() } } class Bar: NSObject { @objc var foo: Foo { fatalError() } } // CHECK-LABEL: sil hidden @_T013keypaths_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 @_T013keypaths_objc0B18KeypathIdentifiersyyF func objcKeypathIdentifiers() { // CHECK: keypath $KeyPath, (objc "objcProp"; {{.*}} id #ObjCFoo.objcProp!getter.1.foreign _ = \ObjCFoo.objcProp // CHECK: keypath $KeyPath, (objc "dyn"; {{.*}} id #Foo.dyn!getter.1.foreign _ = \Foo.dyn // CHECK: keypath $KeyPath, (objc "int"; {{.*}} id #Foo.int!getter.1 : _ = \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 @{{.*}}nonobjcExtensionOfObjCClass func nonobjcExtensionOfObjCClass() { // Should be treated as a statically-dispatch property // CHECK: keypath $KeyPath, ({{.*}} id @ _ = \NSObject.x // CHECK: keypath $KeyPath, ({{.*}} id #NSObject.objc!getter.1.foreign _ = \NSObject.objc // CHECK: keypath $KeyPath, ({{.*}} id #NSObject.dynamic!getter.1.foreign _ = \NSObject.dynamic } @objc protocol ObjCProto { var objcRequirement: Int { get set } } // CHECK-LABEL: sil hidden @{{.*}}ProtocolRequirement func objcProtocolRequirement(_: T) { // CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign _ = \T.objcRequirement // CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign _ = \ObjCProto.objcRequirement }