mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
719 lines
40 KiB
Swift
719 lines
40 KiB
Swift
// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) -Xllvm -sil-print-types -module-name objc_bridging_any -Xllvm -sil-print-debuginfo %s | %FileCheck %s
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
import objc_generics
|
|
|
|
protocol P {}
|
|
protocol CP: class {}
|
|
|
|
struct KnownUnbridged {}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any11passingToId{{.*}}F
|
|
func passingToId<T: CP, U>(receiver: NSIdLover,
|
|
string: String,
|
|
nsString: NSString,
|
|
object: AnyObject,
|
|
classGeneric: T,
|
|
classExistential: CP,
|
|
generic: U,
|
|
existential: P,
|
|
error: Error,
|
|
any: Any,
|
|
knownUnbridged: KnownUnbridged,
|
|
optionalA: String?,
|
|
optionalB: NSString?,
|
|
optionalC: Any?) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $NSIdLover,
|
|
// CHECK: debug_value [[STRING:%.*]] : $String
|
|
// CHECK: debug_value [[NSSTRING:%.*]] : $NSString
|
|
// CHECK: debug_value [[OBJECT:%.*]] : $AnyObject
|
|
// CHECK: debug_value [[CLASS_GENERIC:%.*]] : $T
|
|
// CHECK: debug_value [[CLASS_EXISTENTIAL:%.*]] : $any CP
|
|
// CHECK: debug_value [[GENERIC:%.*]] : $*U, {{.*}} expr op_deref
|
|
// CHECK: debug_value [[EXISTENTIAL:%.*]] : $*any P, {{.*}} expr op_deref
|
|
// CHECK: debug_value [[ERROR:%.*]] : $any Error
|
|
// CHECK: debug_value [[ANY:%.*]] : $*Any, {{.*}} expr op_deref
|
|
// CHECK: debug_value [[KNOWN_UNBRIDGED:%.*]] : $KnownUnbridged
|
|
// CHECK: debug_value [[OPT_STRING:%.*]] : $Optional<String>
|
|
// CHECK: debug_value [[OPT_NSSTRING:%.*]] : $Optional<NSString>
|
|
// CHECK: debug_value [[OPT_ANY:%.*]] : $*Optional<Any>, {{.*}} expr op_deref
|
|
|
|
// CHECK: [[STRING_COPY:%.*]] = copy_value [[STRING]]
|
|
// CHECK: [[BRIDGE_STRING:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF
|
|
// CHECK: [[BORROWED_STRING_COPY:%.*]] = begin_borrow [[STRING_COPY]]
|
|
// CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[BORROWED_STRING_COPY]])
|
|
// CHECK: end_borrow [[BORROWED_STRING_COPY]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[BRIDGED]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: destroy_value [[STRING_COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]]
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(string)
|
|
|
|
// CHECK: [[NSSTRING_COPY:%.*]] = copy_value [[NSSTRING]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[NSSTRING_COPY]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(nsString)
|
|
|
|
// CHECK: [[CLASS_GENERIC_COPY:%.*]] = copy_value [[CLASS_GENERIC]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[CLASS_GENERIC_COPY]] : $T : $T, $AnyObject
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(classGeneric)
|
|
|
|
// CHECK: [[OBJECT_COPY:%.*]] = copy_value [[OBJECT]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[OBJECT_COPY]], [[SELF]])
|
|
// CHECK: destroy_value [[OBJECT_COPY]]
|
|
receiver.takesId(object)
|
|
|
|
// CHECK: [[CLASS_EXISTENTIAL_COPY:%.*]] = copy_value [[CLASS_EXISTENTIAL]]
|
|
// CHECK: [[OPENED:%.*]] = open_existential_ref [[CLASS_EXISTENTIAL_COPY]] : $any CP
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[OPENED]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(classExistential)
|
|
|
|
// These cases perform a universal bridging conversion.
|
|
|
|
// CHECK: [[COPY:%.*]] = alloc_stack $U
|
|
// CHECK: copy_addr [[GENERIC]] to [init] [[COPY]]
|
|
// CHECK: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<U>([[COPY]])
|
|
// CHECK: dealloc_stack [[COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(generic)
|
|
|
|
// CHECK: [[COPY:%.*]] = alloc_stack $any P
|
|
// CHECK: copy_addr [[EXISTENTIAL]] to [init] [[COPY]]
|
|
// CHECK: [[OPENED_COPY:%.*]] = open_existential_addr immutable_access [[COPY]] : $*any P to $*[[OPENED_TYPE:@opened\(.*, any P\) Self]],
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $[[OPENED_TYPE]]
|
|
// CHECK: copy_addr [[OPENED_COPY]] to [init] [[TMP]]
|
|
// CHECK: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<[[OPENED_TYPE]]>([[TMP]])
|
|
// CHECK: dealloc_stack [[TMP]]
|
|
// CHECK: destroy_addr [[COPY]]
|
|
// CHECK: dealloc_stack [[COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(existential)
|
|
|
|
// CHECK: [[ERROR_COPY:%.*]] = copy_value [[ERROR]] : $any Error
|
|
// CHECK: [[BORROWED_ERROR_COPY:%.*]] = begin_borrow [[ERROR_COPY]]
|
|
// CHECK: [[ERROR_BOX:%[0-9]+]] = open_existential_box [[BORROWED_ERROR_COPY]] : $any Error to $*@opened([[ERROR_ARCHETYPE:"[^"]*"]], any Error) Self
|
|
// CHECK: [[ERROR_STACK:%[0-9]+]] = alloc_stack $@opened([[ERROR_ARCHETYPE]], any Error) Self
|
|
// CHECK: copy_addr [[ERROR_BOX]] to [init] [[ERROR_STACK]] : $*@opened([[ERROR_ARCHETYPE]], any Error) Self
|
|
// CHECK: [[BRIDGE_FUNCTION:%[0-9]+]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK: [[BRIDGED_ERROR:%[0-9]+]] = apply [[BRIDGE_FUNCTION]]<@opened([[ERROR_ARCHETYPE]], any Error) Self>([[ERROR_STACK]])
|
|
// CHECK: dealloc_stack [[ERROR_STACK]] : $*@opened([[ERROR_ARCHETYPE]], any Error) Self
|
|
// CHECK: destroy_value [[ERROR_COPY]] : $any Error
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[BRIDGED_ERROR]], [[SELF]])
|
|
// CHECK: destroy_value [[BRIDGED_ERROR]] : $AnyObject
|
|
receiver.takesId(error)
|
|
|
|
// CHECK: [[COPY:%.*]] = alloc_stack $Any
|
|
// CHECK: copy_addr [[ANY]] to [init] [[COPY]]
|
|
// CHECK: [[OPENED_COPY:%.*]] = open_existential_addr immutable_access [[COPY]] : $*Any to $*[[OPENED_TYPE:@opened\(.*, Any\) Self]],
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $[[OPENED_TYPE]]
|
|
// CHECK: copy_addr [[OPENED_COPY]] to [init] [[TMP]]
|
|
// CHECK: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<[[OPENED_TYPE]]>([[TMP]])
|
|
// CHECK: destroy_addr [[COPY]]
|
|
// CHECK: dealloc_stack [[COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[ANYOBJECT]]
|
|
receiver.takesId(any)
|
|
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $KnownUnbridged
|
|
// CHECK: store [[KNOWN_UNBRIDGED]] to [trivial] [[TMP]]
|
|
// CHECK: [[BRIDGE_ANYTHING:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveC{{.*}}F
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<KnownUnbridged>([[TMP]])
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
receiver.takesId(knownUnbridged)
|
|
|
|
// These cases bridge using Optional's _ObjectiveCBridgeable conformance.
|
|
|
|
// CHECK: [[OPT_STRING_COPY:%.*]] = copy_value [[OPT_STRING]]
|
|
// CHECK: [[BRIDGE_OPTIONAL:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $Optional<String>
|
|
// CHECK: [[BORROWED_OPT_STRING_COPY:%.*]] = begin_borrow [[OPT_STRING_COPY]]
|
|
// CHECK: [[SB1:%.*]] = store_borrow [[BORROWED_OPT_STRING_COPY]] to [[TMP]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_OPTIONAL]]<String>([[SB1]])
|
|
// CHECK: end_borrow [[BORROWED_OPT_STRING_COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
receiver.takesId(optionalA)
|
|
|
|
// CHECK: [[OPT_NSSTRING_COPY:%.*]] = copy_value [[OPT_NSSTRING]]
|
|
// CHECK: [[BRIDGE_OPTIONAL:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $Optional<NSString>
|
|
// CHECK: [[BORROWED_OPT_NSSTRING_COPY:%.*]] = begin_borrow [[OPT_NSSTRING_COPY]]
|
|
// CHECK: [[SB2:%.*]] = store_borrow [[BORROWED_OPT_NSSTRING_COPY]] to [[TMP]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_OPTIONAL]]<NSString>([[SB2]])
|
|
// CHECK: end_borrow [[BORROWED_OPT_NSSTRING_COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
receiver.takesId(optionalB)
|
|
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $Optional<Any>
|
|
// CHECK: copy_addr [[OPT_ANY]] to [init] [[TMP]]
|
|
// CHECK: [[BRIDGE_OPTIONAL:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_OPTIONAL]]<Any>([[TMP]])
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[ANYOBJECT]], [[SELF]])
|
|
receiver.takesId(optionalC)
|
|
|
|
// TODO: Property and subscript setters
|
|
}
|
|
|
|
// Once upon a time, as a workaround for rdar://problem/28318984, we had
|
|
// to skip the peephole for types with nontrivial SIL lowerings because we
|
|
// didn't correctly form the substitutions for a generic
|
|
// _bridgeAnythingToObjectiveC call. That's not true anymore.
|
|
func zim() {}
|
|
struct Zang {}
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any27typesWithNontrivialLowering8receiverySo9NSIdLoverC_tF
|
|
func typesWithNontrivialLowering(receiver: NSIdLover) {
|
|
// CHECK: apply {{.*}}<() -> ()>
|
|
receiver.takesId(zim)
|
|
// CHECK: apply {{.*}}<Zang.Type>
|
|
receiver.takesId(Zang.self)
|
|
// CHECK: apply {{.*}}<(() -> (), Zang.Type)>
|
|
receiver.takesId((zim, Zang.self))
|
|
// CHECK: apply {{%.*}}<(Int, String)>
|
|
receiver.takesId((0, "one"))
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any19passingToNullableId{{.*}}F
|
|
func passingToNullableId<T: CP, U>(receiver: NSIdLover,
|
|
string: String,
|
|
nsString: NSString,
|
|
object: AnyObject,
|
|
classGeneric: T,
|
|
classExistential: CP,
|
|
generic: U,
|
|
existential: P,
|
|
error: Error,
|
|
any: Any,
|
|
knownUnbridged: KnownUnbridged,
|
|
optString: String?,
|
|
optNSString: NSString?,
|
|
optObject: AnyObject?,
|
|
optClassGeneric: T?,
|
|
optClassExistential: CP?,
|
|
optGeneric: U?,
|
|
optExistential: P?,
|
|
optAny: Any?,
|
|
optKnownUnbridged: KnownUnbridged?,
|
|
optOptA: String??,
|
|
optOptB: NSString??,
|
|
optOptC: Any??)
|
|
{
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $NSIdLover,
|
|
// CHECK: [[STRING:%.*]] : $String,
|
|
// CHECK: [[NSSTRING:%.*]] : $NSString
|
|
// CHECK: [[OBJECT:%.*]] : $AnyObject
|
|
// CHECK: [[CLASS_GENERIC:%.*]] : $T
|
|
// CHECK: [[CLASS_EXISTENTIAL:%.*]] : $any CP
|
|
// CHECK: [[GENERIC:%.*]] : $*U
|
|
// CHECK: [[EXISTENTIAL:%.*]] : $*any P
|
|
// CHECK: [[ERROR:%.*]] : $any Error
|
|
// CHECK: [[ANY:%.*]] : $*Any,
|
|
// CHECK: [[KNOWN_UNBRIDGED:%.*]] : $KnownUnbridged,
|
|
// CHECK: [[OPT_STRING:%.*]] : $Optional<String>,
|
|
// CHECK: [[OPT_NSSTRING:%.*]] : $Optional<NSString>
|
|
// CHECK: [[OPT_OBJECT:%.*]] : $Optional<AnyObject>
|
|
// CHECK: [[OPT_CLASS_GENERIC:%.*]] : $Optional<T>
|
|
// CHECK: [[OPT_CLASS_EXISTENTIAL:%.*]] : $Optional<any CP>
|
|
// CHECK: [[OPT_GENERIC:%.*]] : $*Optional<U>
|
|
// CHECK: [[OPT_EXISTENTIAL:%.*]] : $*Optional<any P>
|
|
// CHECK: [[OPT_ANY:%.*]] : $*Optional<Any>
|
|
// CHECK: [[OPT_KNOWN_UNBRIDGED:%.*]] : $Optional<KnownUnbridged>
|
|
// CHECK: [[OPT_OPT_A:%.*]] : $Optional<Optional<String>>
|
|
// CHECK: [[OPT_OPT_B:%.*]] : $Optional<Optional<NSString>>
|
|
// CHECK: [[OPT_OPT_C:%.*]] : $*Optional<Optional<Any>>
|
|
|
|
// CHECK: [[STRING_COPY:%.*]] = copy_value [[STRING]]
|
|
// CHECK: [[BRIDGE_STRING:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF
|
|
// CHECK: [[BORROWED_STRING_COPY:%.*]] = begin_borrow [[STRING_COPY]]
|
|
// CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[BORROWED_STRING_COPY]])
|
|
// CHECK: end_borrow [[BORROWED_STRING_COPY]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[BRIDGED]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK: destroy_value [[STRING_COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]]
|
|
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[OPT_ANYOBJECT]]
|
|
receiver.takesNullableId(string)
|
|
|
|
// CHECK: [[NSSTRING_COPY:%.*]] = copy_value [[NSSTRING]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[NSSTRING_COPY]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
receiver.takesNullableId(nsString)
|
|
|
|
// CHECK: [[OBJECT_COPY:%.*]] = copy_value [[OBJECT]]
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[OBJECT_COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
receiver.takesNullableId(object)
|
|
|
|
// CHECK: [[CLASS_GENERIC_COPY:%.*]] = copy_value [[CLASS_GENERIC]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[CLASS_GENERIC_COPY]] : $T : $T, $AnyObject
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
receiver.takesNullableId(classGeneric)
|
|
|
|
// CHECK: [[CLASS_EXISTENTIAL_COPY:%.*]] = copy_value [[CLASS_EXISTENTIAL]]
|
|
// CHECK: [[OPENED:%.*]] = open_existential_ref [[CLASS_EXISTENTIAL_COPY]] : $any CP
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[OPENED]]
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
// CHECK: destroy_value [[OPT_ANYOBJECT]]
|
|
receiver.takesNullableId(classExistential)
|
|
|
|
// CHECK-NEXT: [[COPY:%.*]] = alloc_stack $U
|
|
// CHECK-NEXT: copy_addr [[GENERIC]] to [init] [[COPY]]
|
|
// CHECK-NEXT: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK-NEXT: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<U>([[COPY]])
|
|
// CHECK-NEXT: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK-NEXT: destroy_addr [[COPY]]
|
|
// CHECK-NEXT: dealloc_stack [[COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPT_ANYOBJECT]]
|
|
receiver.takesNullableId(generic)
|
|
|
|
// CHECK-NEXT: [[COPY:%.*]] = alloc_stack $any P
|
|
// CHECK-NEXT: copy_addr [[EXISTENTIAL]] to [init] [[COPY]]
|
|
// CHECK-NEXT: [[OPENED_COPY:%.*]] = open_existential_addr immutable_access [[COPY]] : $*any P to $*[[OPENED_TYPE:@opened\(.*, any P\) Self]],
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $[[OPENED_TYPE]]
|
|
// CHECK: copy_addr [[OPENED_COPY]] to [init] [[TMP]]
|
|
// CHECK-NEXT: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK-NEXT: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<[[OPENED_TYPE]]>([[TMP]])
|
|
// CHECK-NEXT: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK-NEXT: destroy_addr [[TMP]]
|
|
// CHECK-NEXT: dealloc_stack [[TMP]]
|
|
// CHECK-NEXT: destroy_addr [[COPY]]
|
|
// CHECK-NEXT: dealloc_stack [[COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPT_ANYOBJECT]]
|
|
receiver.takesNullableId(existential)
|
|
|
|
// CHECK-NEXT: [[ERROR_COPY:%.*]] = copy_value [[ERROR]] : $any Error
|
|
// CHECK-NEXT: [[BORROWED_ERROR_COPY:%.*]] = begin_borrow [[ERROR_COPY]]
|
|
// CHECK-NEXT: [[ERROR_BOX:%[0-9]+]] = open_existential_box [[BORROWED_ERROR_COPY]] : $any Error to $*@opened([[ERROR_ARCHETYPE:"[^"]*"]], any Error) Self
|
|
// CHECK-NEXT: [[ERROR_STACK:%[0-9]+]] = alloc_stack $@opened([[ERROR_ARCHETYPE]], any Error) Self
|
|
// CHECK-NEXT: copy_addr [[ERROR_BOX]] to [init] [[ERROR_STACK]] : $*@opened([[ERROR_ARCHETYPE]], any Error) Self
|
|
// CHECK-NEXT: end_borrow [[BORROWED_ERROR_COPY]]
|
|
// CHECK: [[BRIDGE_FUNCTION:%[0-9]+]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[BRIDGED_ERROR:%[0-9]+]] = apply [[BRIDGE_FUNCTION]]<@opened([[ERROR_ARCHETYPE]], any Error) Self>([[ERROR_STACK]])
|
|
// CHECK-NEXT: [[BRIDGED_ERROR_OPT:%[0-9]+]] = enum $Optional<AnyObject>, #Optional.some!enumelt, [[BRIDGED_ERROR]] : $AnyObject
|
|
// CHECK-NEXT: destroy_addr [[ERROR_STACK]]
|
|
// CHECK-NEXT: dealloc_stack [[ERROR_STACK]] : $*@opened([[ERROR_ARCHETYPE]], any Error) Self
|
|
// CHECK-NEXT: destroy_value [[ERROR_COPY]] : $any Error
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK-NEXT: apply [[METHOD]]([[BRIDGED_ERROR_OPT]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[BRIDGED_ERROR_OPT]]
|
|
receiver.takesNullableId(error)
|
|
|
|
// CHECK-NEXT: [[COPY:%.*]] = alloc_stack $Any
|
|
// CHECK-NEXT: copy_addr [[ANY]] to [init] [[COPY]]
|
|
// CHECK-NEXT: [[OPENED_COPY:%.*]] = open_existential_addr immutable_access [[COPY]] : $*Any to $*[[OPENED_TYPE:@opened\(.*, Any\) Self]],
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $[[OPENED_TYPE]]
|
|
// CHECK: copy_addr [[OPENED_COPY]] to [init] [[TMP]]
|
|
// CHECK-NEXT: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK-NEXT: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<[[OPENED_TYPE]]>([[TMP]])
|
|
// CHECK-NEXT: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK-NEXT: destroy_addr [[TMP]]
|
|
// CHECK-NEXT: dealloc_stack [[TMP]]
|
|
// CHECK-NEXT: destroy_addr [[COPY]]
|
|
// CHECK-NEXT: dealloc_stack [[COPY]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPT_ANYOBJECT]]
|
|
receiver.takesNullableId(any)
|
|
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $KnownUnbridged
|
|
// CHECK: store [[KNOWN_UNBRIDGED]] to [trivial] [[TMP]]
|
|
// CHECK: [[BRIDGE_ANYTHING:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveC{{.*}}F
|
|
// CHECK: [[ANYOBJECT:%.*]] = apply [[BRIDGE_ANYTHING]]<KnownUnbridged>([[TMP]])
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $NSIdLover,
|
|
// CHECK: apply [[METHOD]]([[OPT_ANYOBJECT]], [[SELF]])
|
|
receiver.takesNullableId(knownUnbridged)
|
|
|
|
// CHECK: [[OPT_STRING_COPY:%.*]] = copy_value [[OPT_STRING]]
|
|
// CHECK: switch_enum [[OPT_STRING_COPY]] : $Optional<String>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SOME_BB]]([[STRING_DATA:%.*]] : @owned $String):
|
|
// CHECK: [[BRIDGE_STRING:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF
|
|
// CHECK: [[BORROWED_STRING_DATA:%.*]] = begin_borrow [[STRING_DATA]]
|
|
// CHECK: [[BRIDGED:%.*]] = apply [[BRIDGE_STRING]]([[BORROWED_STRING_DATA]])
|
|
// CHECK: end_borrow [[BORROWED_STRING_DATA]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[BRIDGED]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: [[OPT_ANYOBJECT:%.*]] = enum {{.*}} [[ANYOBJECT]]
|
|
// CHECK: destroy_value [[STRING_DATA]]
|
|
// CHECK: br [[JOIN:bb.*]]([[OPT_ANYOBJECT]]
|
|
//
|
|
// CHECK: [[NONE_BB]]:
|
|
// CHECK: [[OPT_NONE:%.*]] = enum $Optional<AnyObject>, #Optional.none!enumelt
|
|
// CHECK: br [[JOIN]]([[OPT_NONE]]
|
|
//
|
|
// CHECK: [[JOIN]]([[PHI:%.*]] : @owned $Optional<AnyObject>):
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]]
|
|
// CHECK: apply [[METHOD]]([[PHI]], [[SELF]])
|
|
// CHECK: destroy_value [[PHI]]
|
|
receiver.takesNullableId(optString)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]]
|
|
receiver.takesNullableId(optNSString)
|
|
|
|
// CHECK: [[OPT_OBJECT_COPY:%.*]] = copy_value [[OPT_OBJECT]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]]
|
|
// CHECK: apply [[METHOD]]([[OPT_OBJECT_COPY]], [[SELF]])
|
|
receiver.takesNullableId(optObject)
|
|
receiver.takesNullableId(optClassGeneric)
|
|
receiver.takesNullableId(optClassExistential)
|
|
receiver.takesNullableId(optGeneric)
|
|
receiver.takesNullableId(optExistential)
|
|
receiver.takesNullableId(optAny)
|
|
receiver.takesNullableId(optKnownUnbridged)
|
|
|
|
receiver.takesNullableId(optOptA)
|
|
receiver.takesNullableId(optOptB)
|
|
receiver.takesNullableId(optOptC)
|
|
}
|
|
|
|
protocol Anyable {
|
|
init(any: Any)
|
|
init(anyMaybe: Any?)
|
|
var anyProperty: Any { get }
|
|
var maybeAnyProperty: Any? { get }
|
|
}
|
|
|
|
// Make sure we generate correct bridging thunks
|
|
class SwiftIdLover : NSObject, Anyable {
|
|
|
|
@objc func methodReturningAny() -> Any { fatalError() }
|
|
// SEMANTIC ARC TODO: This is another case of pattern matching the body of one
|
|
// function in a different function... Just pattern match the unreachable case
|
|
// to preserve behavior. We should check if it is correct.
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC18methodReturningAnyypyF : $@convention(method) (@guaranteed SwiftIdLover) -> @out Any
|
|
// CHECK: unreachable
|
|
// CHECK: } // end sil function '$s17objc_bridging_any12SwiftIdLoverC18methodReturningAnyypyF'
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC18methodReturningAnyypyFTo : $@convention(objc_method) (SwiftIdLover) -> @autoreleased AnyObject {
|
|
// CHECK: bb0([[SELF:%[0-9]+]] : @unowned $SwiftIdLover):
|
|
// CHECK: [[NATIVE_RESULT:%.*]] = alloc_stack $Any
|
|
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] : $SwiftIdLover
|
|
// CHECK: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
|
|
// CHECK: [[NATIVE_IMP:%.*]] = function_ref @$s17objc_bridging_any12SwiftIdLoverC18methodReturningAnyypyF
|
|
// CHECK: apply [[NATIVE_IMP]]([[NATIVE_RESULT]], [[BORROWED_SELF_COPY]])
|
|
// CHECK: end_borrow [[BORROWED_SELF_COPY]]
|
|
// CHECK: destroy_value [[SELF_COPY]]
|
|
// CHECK: [[OPEN_RESULT:%.*]] = open_existential_addr immutable_access [[NATIVE_RESULT]]
|
|
// CHECK: [[TMP:%.*]] = alloc_stack
|
|
// CHECK: copy_addr [[OPEN_RESULT]] to [init] [[TMP]]
|
|
// CHECK: [[BRIDGE_ANYTHING:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveC{{.*}}F
|
|
// CHECK: [[OBJC_RESULT:%.*]] = apply [[BRIDGE_ANYTHING]]<{{.*}}>([[TMP]])
|
|
// CHECK: return [[OBJC_RESULT]]
|
|
// CHECK: } // end sil function '$s17objc_bridging_any12SwiftIdLoverC18methodReturningAnyypyFTo'
|
|
|
|
@objc func methodReturningOptionalAny() -> Any? { fatalError() }
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC26methodReturningOptionalAnyypSgyF
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC26methodReturningOptionalAnyypSgyFTo
|
|
// CHECK: function_ref @$ss27_bridgeAnythingToObjectiveC{{.*}}F
|
|
|
|
@objc func methodTakingAny(a: Any) { fatalError() }
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC15methodTakingAny1ayyp_tFTo : $@convention(objc_method) (AnyObject, SwiftIdLover) -> ()
|
|
// CHECK: bb0([[ARG:%.*]] : @unowned $AnyObject, [[SELF:%.*]] : @unowned $SwiftIdLover):
|
|
// CHECK: function_ref [[BRIDGE_ANYOBJECT_TO_ANY:@\$ss018_bridgeAnyObjectToB0yypyXlSgF]] : $@convention(thin) (@guaranteed Optional<AnyObject>) -> @out Any
|
|
// CHECK: [[METHOD:%.*]] = function_ref @$s17objc_bridging_any12SwiftIdLoverC15methodTakingAny1ayyp_tF
|
|
// CHECK-NEXT: apply [[METHOD]]([[RESULT:%.*]], [[BORROWED_SELF_COPY:%.*]]) :
|
|
|
|
@objc func methodTakingOptionalAny(a: Any?) { fatalError() }
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC23methodTakingOptionalAny1ayypSg_tF
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC23methodTakingOptionalAny1ayypSg_tFTo
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC017methodTakingBlockH3AnyyyyypXEF : $@convention(method) (@guaranteed @noescape @callee_guaranteed (@in_guaranteed Any) -> (), @guaranteed SwiftIdLover) -> ()
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC017methodTakingBlockH3AnyyyyypXEFTo : $@convention(objc_method) (@convention(block) @noescape (AnyObject) -> (), SwiftIdLover) -> ()
|
|
// CHECK: bb0([[BLOCK:%.*]] : @unowned $@convention(block) @noescape (AnyObject) -> (), [[SELF:%.*]] : @unowned $SwiftIdLover):
|
|
// CHECK-NEXT: [[BLOCK_COPY:%.*]] = copy_block [[BLOCK]]
|
|
// CHECK-NEXT: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK: [[THUNK_FN:%.*]] = function_ref @$syXlIyBy_ypIegn_TR
|
|
// CHECK-NEXT: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[BLOCK_COPY]])
|
|
// CHECK-NEXT: [[THUNK_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[THUNK]]
|
|
// CHECK-NEXT: [[THUNK_CVT_B:%.*]] = begin_borrow [[THUNK_CVT]]
|
|
// CHECK: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[METHOD:%.*]] = function_ref @$s17objc_bridging_any12SwiftIdLoverC017methodTakingBlockH3AnyyyyypXEF
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[THUNK_CVT_B]], [[BORROWED_SELF_COPY]])
|
|
// CHECK-NEXT: end_borrow [[BORROWED_SELF_COPY]]
|
|
// CHECK-NEXT: end_borrow [[THUNK_CVT_B]]
|
|
// CHECK-NEXT: destroy_value [[THUNK_CVT]]
|
|
// CHECK-NEXT: destroy_value [[THUNK]]
|
|
// CHECK-NEXT: destroy_value [[SELF_COPY]]
|
|
// CHECK-NEXT: return [[RESULT]]
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$syXlIyBy_ypIegn_TR
|
|
// CHECK: bb0([[ANY:%.*]] : $*Any, [[BLOCK:%.*]] : @guaranteed $@convention(block) @noescape (AnyObject) -> ()):
|
|
// CHECK-NEXT: [[OPENED_ANY:%.*]] = open_existential_addr immutable_access [[ANY]] : $*Any to $*[[OPENED_TYPE:@opened\(.*, Any\) Self]],
|
|
// CHECK: [[TMP:%.*]] = alloc_stack
|
|
// CHECK: copy_addr [[OPENED_ANY]] to [init] [[TMP]]
|
|
// CHECK-NEXT: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK-NEXT: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK-NEXT: [[BRIDGED:%.*]] = apply [[BRIDGE_ANYTHING]]<[[OPENED_TYPE]]>([[TMP]])
|
|
// CHECK-NEXT: apply [[BLOCK]]([[BRIDGED]])
|
|
// CHECK-NEXT: [[VOID:%.*]] = tuple ()
|
|
// CHECK-NEXT: destroy_value [[BRIDGED]]
|
|
// CHECK-NEXT: destroy_addr [[TMP]]
|
|
// CHECK-NEXT: dealloc_stack [[TMP]]
|
|
// CHECK-NEXT: return [[VOID]]
|
|
|
|
@objc func methodTakingBlockTakingAny(_: (Any) -> ()) { fatalError() }
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC29methodReturningBlockTakingAnyyypcyF : $@convention(method) (@guaranteed SwiftIdLover) -> @owned @callee_guaranteed (@in_guaranteed Any) -> ()
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC29methodReturningBlockTakingAnyyypcyFTo : $@convention(objc_method) (SwiftIdLover) -> @autoreleased @convention(block) (AnyObject) -> ()
|
|
// CHECK: bb0([[SELF:%.*]] : @unowned $SwiftIdLover):
|
|
// CHECK-NEXT: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK-NEXT: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[METHOD:%.*]] = function_ref @$s17objc_bridging_any12SwiftIdLoverC29methodReturningBlockTakingAnyyypcyF
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD:%.*]]([[BORROWED_SELF_COPY]])
|
|
// CHECK-NEXT: end_borrow [[BORROWED_SELF_COPY]]
|
|
// CHECK-NEXT: destroy_value [[SELF_COPY]]
|
|
// CHECK-NEXT: [[BLOCK_STORAGE:%.*]] = alloc_stack $@block_storage @callee_guaranteed (@in_guaranteed Any) -> ()
|
|
// CHECK-NEXT: [[BLOCK_STORAGE_ADDR:%.*]] = project_block_storage [[BLOCK_STORAGE]]
|
|
// CHECK-NEXT: store [[RESULT:%.*]] to [init] [[BLOCK_STORAGE_ADDR]]
|
|
// CHECK: [[THUNK_FN:%.*]] = function_ref @$sypIegn_yXlIeyBy_TR
|
|
// CHECK-NEXT: [[BLOCK_HEADER:%.*]] = init_block_storage_header [[BLOCK_STORAGE]] : $*@block_storage @callee_guaranteed (@in_guaranteed Any) -> (), invoke [[THUNK_FN]]
|
|
// CHECK-NEXT: [[BLOCK:%.*]] = copy_block [[BLOCK_HEADER]]
|
|
// CHECK-NEXT: destroy_addr [[BLOCK_STORAGE_ADDR]]
|
|
// CHECK-NEXT: dealloc_stack [[BLOCK_STORAGE]]
|
|
// CHECK-NEXT: return [[BLOCK]]
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIegn_yXlIeyBy_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed (@in_guaranteed Any) -> (), AnyObject) -> ()
|
|
// CHECK: bb0([[BLOCK_STORAGE:%.*]] : $*@block_storage @callee_guaranteed (@in_guaranteed Any) -> (), [[ANY:%.*]] : @unowned $AnyObject):
|
|
// CHECK-NEXT: [[BLOCK_STORAGE_ADDR:%.*]] = project_block_storage [[BLOCK_STORAGE]]
|
|
// CHECK-NEXT: [[FUNCTION:%.*]] = load [copy] [[BLOCK_STORAGE_ADDR]]
|
|
// CHECK-NEXT: [[ANY_COPY:%.*]] = copy_value [[ANY]]
|
|
// CHECK-NEXT: [[OPENED_ANY:%.*]] = open_existential_ref [[ANY_COPY]]
|
|
// CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Any
|
|
// CHECK-NEXT: [[INIT:%.*]] = init_existential_addr [[RESULT]] : $*Any
|
|
// CHECK-NEXT: store [[OPENED_ANY]] to [init] [[INIT]]
|
|
// CHECK-NEXT: [[BORROW_FUN:%.*]] = begin_borrow [[FUNCTION]]
|
|
// CHECK-NEXT: apply [[BORROW_FUN]]([[RESULT]])
|
|
// CHECK-NEXT: end_borrow [[BORROW_FUN]]
|
|
// CHECK-NEXT: [[VOID:%.*]] = tuple ()
|
|
// CHECK-NEXT: destroy_addr [[RESULT]]
|
|
// CHECK-NEXT: dealloc_stack [[RESULT]]
|
|
// CHECK-NEXT: destroy_value [[FUNCTION]]
|
|
// CHECK-NEXT: return [[VOID]] : $()
|
|
|
|
@objc func methodTakingBlockTakingOptionalAny(_: (Any?) -> ()) { fatalError() }
|
|
|
|
@objc func methodReturningBlockTakingAny() -> ((Any) -> ()) { fatalError() }
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC29methodTakingBlockReturningAnyyyypyXEF : $@convention(method) (@guaranteed @noescape @callee_guaranteed () -> @out Any, @guaranteed SwiftIdLover) -> () {
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC29methodTakingBlockReturningAnyyyypyXEFTo : $@convention(objc_method) (@convention(block) @noescape () -> @autoreleased AnyObject, SwiftIdLover) -> ()
|
|
// CHECK: bb0([[BLOCK:%.*]] : @unowned $@convention(block) @noescape () -> @autoreleased AnyObject, [[ANY:%.*]] : @unowned $SwiftIdLover):
|
|
// CHECK-NEXT: [[BLOCK_COPY:%.*]] = copy_block [[BLOCK]]
|
|
// CHECK-NEXT: [[ANY_COPY:%.*]] = copy_value [[ANY]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[THUNK_FN:%.*]] = function_ref @$syXlIyBa_ypIegr_TR
|
|
// CHECK-NEXT: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[BLOCK_COPY]])
|
|
// CHECK-NEXT: [[THUNK_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[THUNK]]
|
|
// CHECK-NEXT: [[THUNK_CVT_B:%.*]] = begin_borrow [[THUNK_CVT]]
|
|
// CHECK-NEXT: [[BORROWED_ANY_COPY:%.*]] = begin_borrow [[ANY_COPY]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[METHOD:%.*]] = function_ref @$s17objc_bridging_any12SwiftIdLoverC29methodTakingBlockReturningAnyyyypyXEF
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[THUNK_CVT_B]], [[BORROWED_ANY_COPY]])
|
|
// CHECK-NEXT: end_borrow [[BORROWED_ANY_COPY]]
|
|
// CHECK-NEXT: end_borrow [[THUNK_CVT_B]]
|
|
// CHECK-NEXT: destroy_value [[THUNK_CVT]]
|
|
// CHECK-NEXT: destroy_value [[THUNK]]
|
|
// CHECK-NEXT: destroy_value [[ANY_COPY]]
|
|
// CHECK-NEXT: return [[RESULT]]
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$syXlIyBa_ypIegr_TR : $@convention(thin) (@guaranteed @convention(block) @noescape () -> @autoreleased AnyObject) -> @out Any
|
|
// CHECK: bb0([[ANY_ADDR:%.*]] : $*Any, [[BLOCK:%.*]] : @guaranteed $@convention(block) @noescape () -> @autoreleased AnyObject):
|
|
// CHECK-NEXT: [[BRIDGED:%.*]] = apply [[BLOCK]]()
|
|
// CHECK-NEXT: [[OPTIONAL:%.*]] = unchecked_ref_cast [[BRIDGED]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[BRIDGE_TO_ANY:%.*]] = function_ref [[BRIDGE_TO_ANY_FUNC:@.*]] :
|
|
// CHECK-NEXT: [[RESULT_VAL:%.*]] = apply [[BRIDGE_TO_ANY]]([[ANY_ADDR]], [[OPTIONAL]])
|
|
// CHECK-NEXT: [[EMPTY:%.*]] = tuple ()
|
|
// CHECK-NEXT: destroy_value [[OPTIONAL]]
|
|
// CHECK-NEXT: return [[EMPTY]]
|
|
|
|
@objc func methodReturningBlockTakingOptionalAny() -> ((Any?) -> ()) { fatalError() }
|
|
|
|
@objc func methodTakingBlockReturningAny(_: () -> Any) { fatalError() }
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any12SwiftIdLoverC020methodReturningBlockH3AnyypycyF : $@convention(method) (@guaranteed SwiftIdLover) -> @owned @callee_guaranteed () -> @out Any
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any12SwiftIdLoverC020methodReturningBlockH3AnyypycyFTo : $@convention(objc_method) (SwiftIdLover) -> @autoreleased @convention(block) () -> @autoreleased AnyObject
|
|
// CHECK: bb0([[SELF:%.*]] : @unowned $SwiftIdLover):
|
|
// CHECK-NEXT: [[SELF_COPY:%.*]] = copy_value [[SELF]]
|
|
// CHECK-NEXT: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[METHOD:%.*]] = function_ref @$s17objc_bridging_any12SwiftIdLoverC020methodReturningBlockH3AnyypycyF
|
|
// CHECK-NEXT: [[FUNCTION:%.*]] = apply [[METHOD]]([[BORROWED_SELF_COPY]])
|
|
// CHECK-NEXT: end_borrow [[BORROWED_SELF_COPY]]
|
|
// CHECK-NEXT: destroy_value [[SELF_COPY]]
|
|
// CHECK-NEXT: [[BLOCK_STORAGE:%.*]] = alloc_stack $@block_storage @callee_guaranteed () -> @out Any
|
|
// CHECK-NEXT: [[BLOCK_STORAGE_ADDR:%.*]] = project_block_storage [[BLOCK_STORAGE]]
|
|
// CHECK-NEXT: store [[FUNCTION]] to [init] [[BLOCK_STORAGE_ADDR]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[THUNK_FN:%.*]] = function_ref @$sypIegr_yXlIeyBa_TR
|
|
// CHECK-NEXT: [[BLOCK_HEADER:%.*]] = init_block_storage_header [[BLOCK_STORAGE]] : $*@block_storage @callee_guaranteed () -> @out Any, invoke [[THUNK_FN]]
|
|
// CHECK-NEXT: [[BLOCK:%.*]] = copy_block [[BLOCK_HEADER]]
|
|
// CHECK-NEXT: destroy_addr [[BLOCK_STORAGE_ADDR]]
|
|
// CHECK-NEXT: dealloc_stack [[BLOCK_STORAGE]]
|
|
// CHECK-NEXT: return [[BLOCK]]
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypIegr_yXlIeyBa_TR : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> @out Any) -> @autoreleased AnyObject
|
|
// CHECK: bb0(%0 : $*@block_storage @callee_guaranteed () -> @out Any):
|
|
// CHECK-NEXT: [[BLOCK_STORAGE_ADDR:%.*]] = project_block_storage %0
|
|
// CHECK-NEXT: [[FUNCTION:%.*]] = load [copy] [[BLOCK_STORAGE_ADDR]]
|
|
// CHECK-NEXT: [[RESULT:%.*]] = alloc_stack $Any
|
|
// CHECK-NEXT: [[BORROW_FUN:%.*]] = begin_borrow [[FUNCTION]]
|
|
// CHECK-NEXT: apply [[BORROW_FUN]]([[RESULT]])
|
|
// CHECK-NEXT: end_borrow [[BORROW_FUN]]
|
|
// CHECK-NEXT: [[OPENED:%.*]] = open_existential_addr immutable_access [[RESULT]] : $*Any to $*[[OPENED_TYPE:@opened\(.*, Any\) Self]],
|
|
// CHECK: [[TMP:%.*]] = alloc_stack $[[OPENED_TYPE]]
|
|
// CHECK: copy_addr [[OPENED]] to [init] [[TMP]]
|
|
// CHECK-NEXT: // function_ref _bridgeAnythingToObjectiveC
|
|
// CHECK-NEXT: [[BRIDGE_ANYTHING:%.*]] = function_ref
|
|
// CHECK-NEXT: [[BRIDGED:%.*]] = apply [[BRIDGE_ANYTHING]]<[[OPENED_TYPE]]>([[TMP]])
|
|
// CHECK-NEXT: destroy_addr [[TMP]]
|
|
// CHECK-NEXT: dealloc_stack [[TMP]]
|
|
// CHECK-NEXT: destroy_addr [[RESULT]]
|
|
// CHECK-NEXT: dealloc_stack [[RESULT]]
|
|
// CHECK-NEXT: destroy_value [[FUNCTION]]
|
|
// CHECK-NEXT: return [[BRIDGED]]
|
|
|
|
@objc func methodTakingBlockReturningOptionalAny(_: () -> Any?) { fatalError() }
|
|
|
|
@objc func methodReturningBlockReturningAny() -> (() -> Any) { fatalError() }
|
|
|
|
@objc func methodReturningBlockReturningOptionalAny() -> (() -> Any?) { fatalError() }
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sypSgIegr_yXlSgIeyBa_TR
|
|
// CHECK: function_ref @$ss27_bridgeAnythingToObjectiveC{{.*}}F
|
|
|
|
override init() { fatalError() }
|
|
@objc dynamic required convenience init(any: Any) { fatalError() }
|
|
@objc dynamic required convenience init(anyMaybe: Any?) { fatalError() }
|
|
@objc dynamic var anyProperty: Any
|
|
@objc dynamic var maybeAnyProperty: Any?
|
|
|
|
subscript(_: IndexForAnySubscript) -> Any { get { fatalError() } set { fatalError() } }
|
|
|
|
@objc func methodReturningAnyOrError() throws -> Any { fatalError() }
|
|
}
|
|
|
|
class IndexForAnySubscript { }
|
|
|
|
func dynamicLookup(x: AnyObject) {
|
|
_ = x.anyProperty
|
|
_ = x[IndexForAnySubscript()]
|
|
}
|
|
|
|
extension GenericClass {
|
|
// CHECK-LABEL: sil hidden [ossa] @$sSo12GenericClassC17objc_bridging_anyE23pseudogenericAnyErasure1xypx_tF :
|
|
@objc func pseudogenericAnyErasure(x: T) -> Any {
|
|
// CHECK: bb0([[ANY_OUT:%.*]] : $*Any, [[ARG:%.*]] : @guaranteed $T, [[SELF:%.*]] : @guaranteed $GenericClass<T>
|
|
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[ARG_COPY]] : $T : $T, $AnyObject
|
|
// CHECK: [[ANY_BUF:%.*]] = init_existential_addr [[ANY_OUT]] : $*Any, $AnyObject
|
|
// CHECK: store [[ANYOBJECT]] to [init] [[ANY_BUF]]
|
|
return x
|
|
}
|
|
// CHECK: } // end sil function '$sSo12GenericClassC17objc_bridging_anyE23pseudogenericAnyErasure1xypx_tF'
|
|
}
|
|
|
|
// Make sure AnyHashable erasure marks Hashable conformance as used
|
|
class AnyHashableClass : NSObject {
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any16AnyHashableClassC07returnsdE0s0dE0VyF
|
|
// CHECK: [[FN:%.*]] = function_ref @$ss21_convertToAnyHashableys0cD0VxSHRzlF
|
|
// CHECK: apply [[FN]]<GenericOption>({{.*}})
|
|
func returnsAnyHashable() -> AnyHashable {
|
|
return GenericOption.multithreaded
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any33bridgeOptionalFunctionToAnyObject2fnyXlyycSg_tF : $@convention(thin) (@guaranteed Optional<@callee_guaranteed () -> ()>) -> @owned AnyObject
|
|
// CHECK: [[BRIDGE:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK: [[FN:%.*]] = function_ref @$sIeg_ytIegr_TR
|
|
// CHECK: partial_apply [callee_guaranteed] [[FN]]
|
|
// CHECK: [[SELF:%.*]] = alloc_stack $Optional<@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>>
|
|
// CHECK: [[SB:%.*]] = store_borrow {{.*}} to [[SELF]]
|
|
// CHECK: apply [[BRIDGE]]<() -> ()>([[SB]])
|
|
func bridgeOptionalFunctionToAnyObject(fn: (() -> ())?) -> AnyObject {
|
|
return fn as AnyObject
|
|
}
|
|
|
|
// When bridging `id _Nonnull` values incoming from unknown ObjC code,
|
|
// turn them into `Any` using a runtime call that defends against the
|
|
// possibility they still may be nil.
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s17objc_bridging_any22bridgeIncomingAnyValueyypSo9NSIdLoverCF
|
|
func bridgeIncomingAnyValue(_ receiver: NSIdLover) -> Any {
|
|
// CHECK: function_ref [[BRIDGE_ANYOBJECT_TO_ANY]]
|
|
return receiver.makesId()
|
|
}
|
|
|
|
class SwiftAnyEnjoyer: NSIdLover, NSIdLoving {
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any15SwiftAnyEnjoyerC7takesIdyyypFTo
|
|
// CHECK: function_ref [[BRIDGE_ANYOBJECT_TO_ANY]]
|
|
override func takesId(_ x: Any) { }
|
|
|
|
// CHECK-LABEL: sil private [thunk] [ossa] @$s17objc_bridging_any15SwiftAnyEnjoyerC7takesId11viaProtocolyyp_tFTo
|
|
// CHECK: function_ref [[BRIDGE_ANYOBJECT_TO_ANY]]
|
|
func takesId(viaProtocol x: Any) { }
|
|
}
|
|
|
|
enum SillyOptional {
|
|
case nothing
|
|
case something(NSObject)
|
|
}
|
|
|
|
func bridgeNoPayloadEnumCase(_ receiver: NSIdLover) {
|
|
let value = SillyOptional.nothing
|
|
receiver.takesId(value)
|
|
}
|
|
|
|
// CHECK-LABEL: sil_witness_table shared [serialized] GenericOption: Hashable module objc_generics {
|
|
// CHECK-NEXT: base_protocol Equatable: GenericOption: Equatable module objc_generics
|
|
// CHECK-DAG: method #Hashable.hashValue!getter: {{.*}} : @$sSo13GenericOptionaSHSCSH9hashValueSivgTW
|
|
// CHECK-DAG: method #Hashable.hash: {{.*}} : @$sSo13GenericOptionaSHSCSH4hash4intoys6HasherVz_tFTW
|
|
// CHECK-DAG: method #Hashable._rawHashValue: {{.*}} : @$sSo13GenericOptionaSHSCSH13_rawHashValue4seedS2i_tFTW
|
|
// CHECK: }
|