blob: 29d81ef32fca4f83fe1181bfabd0447aa5912e67 [file] [log] [blame]
// RUN: %empty-directory(%t)
// RUN: %build-irgen-test-overlays
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -I %t %S/../Inputs/resilient_struct.swift
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -emit-module-path %t/resilient_class.swiftmodule -enable-library-evolution %S/../Inputs/resilient_class.swift
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -emit-module-path %t/resilient_objc_class.swiftmodule -enable-library-evolution %S/../Inputs/resilient_objc_class.swift
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -I %t -emit-ir -enable-library-evolution -enable-resilient-objc-class-stubs %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-runtime -DINT=i%target-ptrsize
import Foundation
import resilient_class
import resilient_objc_class
// REQUIRES: objc_interop
// -- Nominal type descriptor for ResilientSubclass
// the interesting part is the 'extra class flags' field has a value of 1.
// CHECK-LABEL: @"$s31class_update_callback_with_stub17ResilientSubclassCMn" = constant <{
// -- flags
// CHECK-SAME: i32 1644232784,
// -- parent
// CHECK-SAME: @"$s31class_update_callback_with_stubMXM"
// -- name
// CHECK-SAME: @1
// -- access function
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMa"
// -- field descriptor
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMF"
// -- superclass
// CHECK-SAME: @"symbolic 15resilient_class22ResilientOutsideParentC"
// -- metadata bounds
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMo"
// -- extra class flags -- has Objective-C resilient class stub
// CHECK-SAME: i32 1,
// -- number of immediate members
// CHECK-SAME: i32 0,
// -- number of fields
// CHECK-SAME: i32 0,
// -- field offset vector offset
// CHECK-SAME: i32 0,
// -- resilient superclass
// CHECK-SAME: @"got.$s15resilient_class22ResilientOutsideParentCMn"
// -- singleton metadata initialization
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMl"
// -- resilient class metadata pattern
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMP"
// -- metadata completion callback
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMr"
// -- method override
// CHECK-SAME: @"got.$s15resilient_class22ResilientOutsideParentCMn"
// CHECK-SAME: @"got.$s15resilient_class22ResilientOutsideParentCACycfCTq"
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCACycfC"
// CHECK-SAME: }>, section "__TEXT,__const", align 4
// -- Symbols for full stubs; the address point is one word in, and defined below
// CHECK-LABEL: @"$s31class_update_callback_with_stub17ResilientSubclassCMt" =
// CHECK-SAME: internal global %objc_full_class_stub {
// CHECK-SAME: [[INT]] 0,
// CHECK-SAME: [[INT]] 1,
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub17ResilientSubclassCMU"
// CHECK-SAME: }
// CHECK-LABEL: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMt" =
// CHECK-SAME: internal global %objc_full_class_stub {
// CHECK-SAME: [[INT]] 0,
// CHECK-SAME: [[INT]] 1,
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMU"
// CHECK-SAME: }
// CHECK-LABEL: @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMt" =
// CHECK-SAME: internal global %objc_full_class_stub {
// CHECK-SAME: [[INT]] 0,
// CHECK-SAME: [[INT]] 1,
// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMU"
// CHECK-SAME: }
// -- Categories reference the stubs
// CHECK-LABEL: @"_CATEGORY__TtC31class_update_callback_with_stub17ResilientSubclass_$_class_update_callback_with_stub" = private constant
// CHECK-SAME: @"$s31class_update_callback_with_stub17ResilientSubclassCMs"
// CHECK-LABEL: @"_CATEGORY__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass_$_class_update_callback_with_stub" = private constant
// CHECK-SAME: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMs"
// CHECK-LABEL: @"_CATEGORY__TtC31class_update_callback_with_stub27FixedLayoutNSObjectSubclass_$_class_update_callback_with_stub" = private constant
// CHECK-SAME: @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMs"
// -- The NSObject-derived class appears on the class list
// CHECK-LABEL: @objc_classes = internal global
// CHECK-SAME: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMs"
// CHECK-SAME: @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMs"
// CHECK-SAME: , section "__DATA,__objc_classlist,regular,no_dead_strip"
// -- The category list
// CHECK-LABEL: @objc_categories = internal global
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub17ResilientSubclass_$_class_update_callback_with_stub"
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass_$_class_update_callback_with_stub"
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub27FixedLayoutNSObjectSubclass_$_class_update_callback_with_stub"
// CHECK-SAME: , section "__DATA,__objc_catlist,regular,no_dead_strip"
// -- Address point for class stubs
// CHECK: @"$s31class_update_callback_with_stub17ResilientSubclassCMs" = alias %objc_class_stub, bitcast (i8* getelementptr inbounds (i8, i8* bitcast (%objc_full_class_stub* @"$s31class_update_callback_with_stub17ResilientSubclassCMt" to i8*), [[INT]] {{4|8}}) to %objc_class_stub*)
// CHECK: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMs" = alias %objc_class_stub, bitcast (i8* getelementptr inbounds (i8, i8* bitcast (%objc_full_class_stub* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMt" to i8*), [[INT]] {{4|8}}) to %objc_class_stub*)
// -- Class symbol for NSObject-derived class points at the class stub
// CHECK: @"OBJC_CLASS_$__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass" = alias %objc_class_stub, %objc_class_stub* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMs"
// -- Metadata update callbacks referenced from class stubs
// CHECK-LABEL: define internal %objc_class* @"$s31class_update_callback_with_stub17ResilientSubclassCMU"(%objc_class*, i8*)
// CHECK: entry:
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s31class_update_callback_with_stub17ResilientSubclassCMa"([[INT]] 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[CLASS:%.*]] = bitcast %swift.type* [[METADATA]] to %objc_class*
// CHECK-NEXT: ret %objc_class* [[CLASS]]
// CHECK-NEXT: }
// CHECK-LABEL: define internal %objc_class* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMU"(%objc_class*, i8*)
// CHECK: entry:
// CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMa"([[INT]] 0)
// CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
// CHECK-NEXT: [[CLASS:%.*]] = bitcast %swift.type* [[METADATA]] to %objc_class*
// CHECK-NEXT: ret %objc_class* [[CLASS]]
// CHECK-NEXT: }
open class ResilientSubclass : ResilientOutsideParent {}
open class ResilientNSObjectSubclass : ResilientNSObjectOutsideParent {}
// Note: @_fixed_layout on a class only applies to the storage layout and
// not metadata, which remains resilient.
@_fixed_layout
open class FixedLayoutNSObjectSubclass : FixedLayoutNSObjectOutsideParent {}
extension ResilientSubclass {
@objc public func objcMethod() {}
}
extension ResilientNSObjectSubclass {
@objc public func objcMethod() {}
}
extension FixedLayoutNSObjectSubclass {
@objc public func objcMethod() {}
}