mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Resilient conformances now put all witnesses into the resilient witness table, so optimize away the witness table pattern for such cases. Teach the runtime to fill in the protocol conformance descriptor, because that’s the only bit of real information that would be in the pattern. This is a minor optimization enabled by rdar://problem/46282080.
198 lines
6.9 KiB
Swift
198 lines
6.9 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %build-irgen-test-overlays
|
|
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -disable-objc-attr-requires-foundation-module -emit-module %S/Inputs/objc_extension_base.swift -o %t
|
|
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -primary-file %s -emit-ir | %FileCheck %s
|
|
|
|
// REQUIRES: CPU=x86_64
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
import gizmo
|
|
import objc_extension_base
|
|
|
|
// Check that metadata for nested enums added in extensions to imported classes
|
|
// gets emitted concretely.
|
|
|
|
// CHECK: [[CATEGORY_NAME:@.*]] = private constant [16 x i8] c"objc_extensions\00"
|
|
// CHECK: [[METHOD_TYPE:@.*]] = private unnamed_addr constant [8 x i8] c"v16@0:8\00"
|
|
|
|
// CHECK-LABEL: @"_CATEGORY_PROTOCOLS_Gizmo_$_objc_extensions" = private constant
|
|
// CHECK-SAME: i64 1,
|
|
// CHECK-SAME: @_PROTOCOL__TtP15objc_extensions11NewProtocol_
|
|
|
|
// CHECK-LABEL: @"_CATEGORY_Gizmo_$_objc_extensions" = private constant
|
|
// CHECK-SAME: i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[CATEGORY_NAME]], i64 0, i64 0),
|
|
// CHECK-SAME: %objc_class* @"OBJC_CLASS_$_Gizmo",
|
|
// CHECK-SAME: @"_CATEGORY_INSTANCE_METHODS_Gizmo_$_objc_extensions",
|
|
// CHECK-SAME: @"_CATEGORY_CLASS_METHODS_Gizmo_$_objc_extensions",
|
|
// CHECK-SAME: @"_CATEGORY_PROTOCOLS_Gizmo_$_objc_extensions",
|
|
// CHECK-SAME: i8* null
|
|
// CHECK-SAME: }, section "__DATA, __objc_const", align 8
|
|
|
|
@objc protocol NewProtocol {
|
|
func brandNewInstanceMethod()
|
|
}
|
|
|
|
extension NSObject {
|
|
@objc func someMethod() -> String { return "Hello" }
|
|
}
|
|
|
|
extension Gizmo: NewProtocol {
|
|
@objc func brandNewInstanceMethod() {
|
|
}
|
|
|
|
@objc class func brandNewClassMethod() {
|
|
}
|
|
|
|
// Overrides an instance method of NSObject
|
|
override func someMethod() -> String {
|
|
return super.someMethod()
|
|
}
|
|
|
|
// Overrides a class method of NSObject
|
|
@objc override class func hasOverride() {}
|
|
}
|
|
|
|
/*
|
|
* Make sure that two extensions of the same ObjC class in the same module can
|
|
* coexist by having different category names.
|
|
*/
|
|
|
|
// CHECK: [[CATEGORY_NAME_1:@.*]] = private unnamed_addr constant [17 x i8] c"objc_extensions1\00"
|
|
|
|
// CHECK: @"_CATEGORY_Gizmo_$_objc_extensions1" = private constant
|
|
// CHECK: i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[CATEGORY_NAME_1]], i64 0, i64 0),
|
|
// CHECK: %objc_class* @"OBJC_CLASS_$_Gizmo",
|
|
// CHECK: {{.*}} @"_CATEGORY_INSTANCE_METHODS_Gizmo_$_objc_extensions1",
|
|
// CHECK: {{.*}} @"_CATEGORY_CLASS_METHODS_Gizmo_$_objc_extensions1",
|
|
// CHECK: i8* null,
|
|
// CHECK: i8* null
|
|
// CHECK: }, section "__DATA, __objc_const", align 8
|
|
|
|
extension Gizmo {
|
|
@objc func brandSpankingNewInstanceMethod() {
|
|
}
|
|
|
|
@objc class func brandSpankingNewClassMethod() {
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Check that extensions of Swift subclasses of ObjC objects get categories.
|
|
*/
|
|
|
|
class Hoozit : NSObject {
|
|
}
|
|
|
|
// CHECK-LABEL: @"_CATEGORY_INSTANCE_METHODS__TtC15objc_extensions6Hoozit_$_objc_extensions" = private constant
|
|
// CHECK: i32 24,
|
|
// CHECK: i32 1,
|
|
// CHECK: [1 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } {
|
|
// CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* @"\01L_selector_data(blibble)", i64 0, i64 0),
|
|
// CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[STR:@.*]], i64 0, i64 0),
|
|
// CHECK: i8* bitcast (void ([[OPAQUE:%.*]]*, i8*)* @"$s15objc_extensions6HoozitC7blibbleyyFTo" to i8*)
|
|
// CHECK: }]
|
|
// CHECK: }, section "__DATA, __objc_const", align 8
|
|
|
|
// CHECK-LABEL: @"_CATEGORY_CLASS_METHODS__TtC15objc_extensions6Hoozit_$_objc_extensions" = private constant
|
|
// CHECK: i32 24,
|
|
// CHECK: i32 1,
|
|
// CHECK: [1 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } {
|
|
// CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* @"\01L_selector_data(blobble)", i64 0, i64 0),
|
|
// CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[STR]], i64 0, i64 0),
|
|
// CHECK: i8* bitcast (void (i8*, i8*)* @"$s15objc_extensions6HoozitC7blobbleyyFZTo" to i8*)
|
|
// CHECK: }]
|
|
// CHECK: }, section "__DATA, __objc_const", align 8
|
|
|
|
// CHECK-LABEL: @"_CATEGORY__TtC15objc_extensions6Hoozit_$_objc_extensions" = private constant
|
|
// CHECK: i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[CATEGORY_NAME]], i64 0, i64 0),
|
|
// CHECK: %swift.type* {{.*}} @"$s15objc_extensions6HoozitCMf",
|
|
// CHECK: {{.*}} @"_CATEGORY_INSTANCE_METHODS__TtC15objc_extensions6Hoozit_$_objc_extensions",
|
|
// CHECK: {{.*}} @"_CATEGORY_CLASS_METHODS__TtC15objc_extensions6Hoozit_$_objc_extensions",
|
|
// CHECK: i8* null,
|
|
// CHECK: i8* null
|
|
// CHECK: }, section "__DATA, __objc_const", align 8
|
|
|
|
extension Hoozit {
|
|
@objc func blibble() { }
|
|
@objc class func blobble() { }
|
|
}
|
|
|
|
class SwiftOnly { }
|
|
|
|
// CHECK-LABEL: @"_CATEGORY_INSTANCE_METHODS__TtC15objc_extensions9SwiftOnly_$_objc_extensions" = private constant
|
|
// CHECK: i32 24,
|
|
// CHECK: i32 1,
|
|
// CHECK: [1 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } {
|
|
// CHECK: i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(wibble)", i64 0, i64 0),
|
|
// CHECK: i8* getelementptr inbounds ([8 x i8], [8 x i8]* [[STR]], i64 0, i64 0),
|
|
// CHECK: i8* bitcast (void (i8*, i8*)* @"$s15objc_extensions9SwiftOnlyC6wibbleyyFTo" to i8*)
|
|
// CHECK: }] }, section "__DATA, __objc_const", align 8
|
|
extension SwiftOnly {
|
|
@objc func wibble() { }
|
|
}
|
|
|
|
class Wotsit: Hoozit {}
|
|
|
|
extension Hoozit {
|
|
@objc func overriddenByExtensionInSubclass() {}
|
|
}
|
|
|
|
extension Wotsit {
|
|
@objc override func overriddenByExtensionInSubclass() {}
|
|
}
|
|
|
|
extension NSObject {
|
|
private enum SomeEnum { case X }
|
|
|
|
@objc public func needMetadataOfSomeEnum() {
|
|
print(NSObject.SomeEnum.X)
|
|
}
|
|
|
|
@objc class func hasOverride() {}
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: @"_CATEGORY__TtCC15objc_extensions5Outer5Inner_$_objc_extensions" = private constant
|
|
// CHECK-SAME: i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[CATEGORY_NAME]], i64 0, i64 0),
|
|
// CHECK-SAME: @"_CATEGORY_INSTANCE_METHODS__TtCC15objc_extensions5Outer5Inner_$_objc_extensions",
|
|
// CHECK-SAME: i8* null
|
|
// CHECK-SAME: }, section "__DATA, __objc_const", align 8
|
|
|
|
class Outer : NSObject {
|
|
class Inner : NSObject {}
|
|
}
|
|
|
|
extension Outer.Inner {
|
|
@objc func innerExtensionMethod() {}
|
|
}
|
|
|
|
|
|
/*
|
|
* Make sure that @NSManaged causes a category to be generated.
|
|
*/
|
|
class NSDogcow : NSObject {}
|
|
|
|
// CHECK: [[NAME:@.*]] = private unnamed_addr constant [5 x i8] c"woof\00"
|
|
// CHECK: [[ATTR:@.*]] = private unnamed_addr constant [7 x i8] c"Tq,N,D\00"
|
|
// CHECK: @"_CATEGORY_PROPERTIES__TtC15objc_extensions8NSDogcow_$_objc_extensions" = private constant {{.*}} [[NAME]], {{.*}} [[ATTR]], {{.*}}, section "__DATA, __objc_const", align 8
|
|
extension NSDogcow {
|
|
@NSManaged var woof: Int
|
|
}
|
|
|
|
// CHECK: @"$sSo8NSObjectC15objc_extensionsE8SomeEnum33_1F05E59585E0BB585FCA206FBFF1A92DLLOSQACMc" =
|
|
|
|
class SwiftSubGizmo : SwiftBaseGizmo {
|
|
|
|
// Don't crash on this call. Emit an objC method call to super.
|
|
//
|
|
// CHECK-LABEL: define {{.*}} @"$s15objc_extensions13SwiftSubGizmoC4frobyyF"
|
|
// CHECK: $s15objc_extensions13SwiftSubGizmoCMa
|
|
// CHECK: objc_msgSendSuper2
|
|
// CHECK: ret
|
|
public override func frob() {
|
|
super.frob()
|
|
}
|
|
}
|
|
|