Skip to content

Commit be3bf99

Browse files
committed
[SILGen] Switch over to _ObjectiveCBridgeable._bridgeToObjective-C.
Use the general implementaion of Swift-to-Objective-C bridging via _ObjectiveCBridgeable._bridgeToObjective-C rather than specialized implementations.
1 parent da9c68d commit be3bf99

File tree

7 files changed

+147
-78
lines changed

7 files changed

+147
-78
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,14 @@ using namespace Lowering;
2727
/// Bridge the given Swift value to its corresponding Objective-C
2828
/// object, using the appropriate witness for the
2929
/// _ObjectiveCBridgeable._bridgeToObjectiveC requirement.
30-
static Optional<ManagedValue> emitBridgeToObjectiveC(SILGenFunction &gen,
31-
SILLocation loc,
32-
ManagedValue swiftValue) {
30+
static Optional<ManagedValue>
31+
emitBridgeToObjectiveC(SILGenFunction &gen,
32+
SILLocation loc,
33+
ManagedValue swiftValue,
34+
ProtocolConformance *conformance) {
3335
// Dig out the nominal type we're bridging from.
3436
Type swiftValueType = swiftValue.getSwiftType()->getRValueType();
3537

36-
// Dig out its conformance to _ObjectiveCBridgeable.
37-
auto conformance =
38-
gen.SGM.getConformanceToObjectiveCBridgeable(loc, swiftValueType);
39-
if (!conformance) return None;
40-
4138
// Find the _bridgeToObjectiveC requirement.
4239
auto requirement = gen.SGM.getBridgeToObjectiveCRequirement(loc);
4340
if (!requirement) return None;
@@ -52,7 +49,7 @@ static Optional<ManagedValue> emitBridgeToObjectiveC(SILGenFunction &gen,
5249

5350
Type objcType =
5451
conformance->getTypeWitness(objcTypeReq, nullptr).getReplacement();
55-
if (!objcTypeReq) return None;
52+
assert(objcType);
5653

5754
// Create a reference to the witness.
5855
SILDeclRef witnessConstant(witness.getDecl());
@@ -80,6 +77,23 @@ static Optional<ManagedValue> emitBridgeToObjectiveC(SILGenFunction &gen,
8077
return gen.emitManagedRValueWithCleanup(bridgedValue);
8178
}
8279

80+
/// Bridge the given Swift value to its corresponding Objective-C
81+
/// object, using the appropriate witness for the
82+
/// _ObjectiveCBridgeable._bridgeToObjectiveC requirement.
83+
static Optional<ManagedValue> emitBridgeToObjectiveC(SILGenFunction &gen,
84+
SILLocation loc,
85+
ManagedValue swiftValue) {
86+
// Dig out the nominal type we're bridging from.
87+
Type swiftValueType = swiftValue.getSwiftType()->getRValueType();
88+
89+
// Dig out its conformance to _ObjectiveCBridgeable.
90+
auto conformance =
91+
gen.SGM.getConformanceToObjectiveCBridgeable(loc, swiftValueType);
92+
if (!conformance) return None;
93+
94+
return emitBridgeToObjectiveC(gen, loc, swiftValue, conformance);
95+
}
96+
8397
static ManagedValue emitBridgeStringToNSString(SILGenFunction &gen,
8498
SILLocation loc,
8599
ManagedValue str) {
@@ -108,40 +122,6 @@ static ManagedValue emitBridgeNSStringToString(SILGenFunction &gen,
108122
return gen.emitManagedRValueWithCleanup(str);
109123
}
110124

111-
static ManagedValue emitBridgeCollectionFromNative(SILGenFunction &gen,
112-
SILLocation loc,
113-
SILDeclRef bridgeFnRef,
114-
ManagedValue collection,
115-
SILType bridgedTy) {
116-
SILValue bridgeFn = gen.emitGlobalFunctionRef(loc, bridgeFnRef);
117-
118-
// If the expected return is optional, we'll need to wrap it.
119-
OptionalTypeKind OTK = OTK_None;
120-
SILType origBridgedTy = bridgedTy;
121-
if (auto bridgedObjTy = bridgedTy.getAnyOptionalObjectType(gen.SGM.M, OTK)) {
122-
bridgedTy = bridgedObjTy;
123-
}
124-
125-
// Figure out the type parameters.
126-
auto inputTy
127-
= collection.getType().getSwiftRValueType()->castTo<BoundGenericType>();
128-
auto subs = inputTy->getSubstitutions(gen.SGM.M.getSwiftModule(), nullptr);
129-
auto substFnType = bridgeFn->getType().substGenericArgs(gen.SGM.M, subs);
130-
SILValue bridged = gen.B.createApply(loc, bridgeFn,
131-
substFnType,
132-
bridgedTy,
133-
subs,
134-
{ collection.forward(gen) });
135-
// Wrap the result if necessary.
136-
if (OTK != OTK_None) {
137-
bridged = gen.B.createEnum(loc, bridged,
138-
gen.getASTContext().getOptionalSomeDecl(OTK),
139-
origBridgedTy);
140-
}
141-
142-
return gen.emitManagedRValueWithCleanup(bridged);
143-
}
144-
145125
static ManagedValue emitBridgeCollectionToNative(SILGenFunction &gen,
146126
SILLocation loc,
147127
SILDeclRef bridgeFnRef,
@@ -429,30 +409,14 @@ static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen,
429409
return gen.emitFuncToBlock(loc, v, bridgedFTy);
430410
}
431411

432-
// Bridge Array to NSArray.
433-
if (auto arrayDecl = gen.getASTContext().getArrayDecl()) {
434-
if (v.getType().getSwiftRValueType().getAnyNominal() == arrayDecl) {
435-
if (auto result = emitBridgeToObjectiveC(gen, loc, v))
436-
return *result;
437-
438-
return gen.emitUndef(loc, bridgedTy);
439-
}
440-
}
441-
442-
// Bridge Dictionary to NSDictionary.
443-
if (auto dictDecl = gen.getASTContext().getDictionaryDecl()) {
444-
if (v.getType().getSwiftRValueType().getAnyNominal() == dictDecl) {
445-
SILDeclRef bridgeFn = gen.SGM.getDictionaryToNSDictionaryFn();
446-
return emitBridgeCollectionFromNative(gen, loc, bridgeFn, v, bridgedTy);
447-
}
448-
}
412+
// If the native type conforms to _ObjectiveCBridgeable, use its
413+
// _bridgeToObjectiveC witness.
414+
if (auto conformance =
415+
gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) {
416+
if (auto result = emitBridgeToObjectiveC(gen, loc, v, conformance))
417+
return *result;
449418

450-
// Bridge Set to NSSet.
451-
if (auto setDecl = gen.getASTContext().getSetDecl()) {
452-
if (v.getType().getSwiftRValueType().getAnyNominal() == setDecl) {
453-
SILDeclRef bridgeFn = gen.SGM.getSetToNSSetFn();
454-
return emitBridgeCollectionFromNative(gen, loc, bridgeFn, v, bridgedTy);
455-
}
419+
return gen.emitUndef(loc, bridgedTy);
456420
}
457421

458422
return v;

test/IRGen/Inputs/Foundation.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,74 @@ extension String : _ObjectiveCBridgeable {
5555
}
5656
}
5757

58+
extension Array : _ObjectiveCBridgeable {
59+
public static func _getObjectiveCType() -> Any.Type {
60+
return NSArray.self
61+
}
62+
public func _bridgeToObjectiveC() -> NSArray {
63+
return NSArray()
64+
}
65+
public static func _forceBridgeFromObjectiveC(
66+
x: NSArray,
67+
result: inout Array?
68+
) {
69+
}
70+
public static func _conditionallyBridgeFromObjectiveC(
71+
x: NSArray,
72+
result: inout Array?
73+
) -> Bool {
74+
return true
75+
}
76+
public static func _isBridgedToObjectiveC() -> Bool {
77+
return Swift._isBridgedToObjectiveC(Element.self)
78+
}
79+
}
80+
81+
extension Dictionary : _ObjectiveCBridgeable {
82+
public static func _getObjectiveCType() -> Any.Type {
83+
return NSDictionary.self
84+
}
85+
public func _bridgeToObjectiveC() -> NSDictionary {
86+
return NSDictionary()
87+
}
88+
public static func _forceBridgeFromObjectiveC(
89+
x: NSDictionary,
90+
result: inout Dictionary?
91+
) {
92+
}
93+
public static func _conditionallyBridgeFromObjectiveC(
94+
x: NSDictionary,
95+
result: inout Dictionary?
96+
) -> Bool {
97+
return true
98+
}
99+
public static func _isBridgedToObjectiveC() -> Bool {
100+
return Swift._isBridgedToObjectiveC(Key.self) && Swift._isBridgedToObjectiveC(Value.self)
101+
}
102+
}
103+
104+
extension Set : _ObjectiveCBridgeable {
105+
public static func _getObjectiveCType() -> Any.Type {
106+
return NSSet.self
107+
}
108+
public func _bridgeToObjectiveC() -> NSSet {
109+
return NSSet()
110+
}
111+
public static func _forceBridgeFromObjectiveC(
112+
x: NSSet,
113+
result: inout Set?
114+
) {
115+
}
116+
public static func _conditionallyBridgeFromObjectiveC(
117+
x: NSSet,
118+
result: inout Set?
119+
) -> Bool {
120+
return true
121+
}
122+
public static func _isBridgedToObjectiveC() -> Bool {
123+
return Swift._isBridgedToObjectiveC(Element.self)
124+
}
125+
}
58126

59127
extension NSError: ErrorProtocol {
60128
public var _domain: String { return domain }

test/SILGen/Inputs/Foundation.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,29 @@ extension Dictionary : _ObjectiveCBridgeable {
134134
}
135135
}
136136

137+
extension Set : _ObjectiveCBridgeable {
138+
public static func _getObjectiveCType() -> Any.Type {
139+
return NSSet.self
140+
}
141+
public func _bridgeToObjectiveC() -> NSSet {
142+
return NSSet()
143+
}
144+
public static func _forceBridgeFromObjectiveC(
145+
x: NSSet,
146+
result: inout Set?
147+
) {
148+
}
149+
public static func _conditionallyBridgeFromObjectiveC(
150+
x: NSSet,
151+
result: inout Set?
152+
) -> Bool {
153+
return true
154+
}
155+
public static func _isBridgedToObjectiveC() -> Bool {
156+
return Swift._isBridgedToObjectiveC(Element.self)
157+
}
158+
}
159+
137160
extension NSObject : Hashable {
138161
public var hashValue: Int { return 0 }
139162
}

test/SILGen/foreign_errors.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -parse-as-library %s | FileCheck %s
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %build-clang-importer-objc-overlays
3+
4+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-silgen -parse-as-library %s | FileCheck %s
25

36
// REQUIRES: objc_interop
47

test/SILGen/objc_dictionary_bridging.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend -emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s | FileCheck %s
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %build-silgen-test-overlays
3+
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -emit-silgen %s | FileCheck %s
25

36
// REQUIRES: objc_interop
47

@@ -26,8 +29,9 @@ import gizmo
2629
// CHECK: [[SWIFT_FN:%[0-9]+]] = function_ref @_TFC24objc_dictionary_bridging3Foo24bridge_Dictionary_result{{.*}} : $@convention(method) (@guaranteed Foo) -> @owned Dictionary<Foo, Foo>
2730
// CHECK-NEXT: [[DICT:%[0-9]+]] = apply [[SWIFT_FN]]([[SELF]]) : $@convention(method) (@guaranteed Foo) -> @owned Dictionary<Foo, Foo>
2831

29-
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation32_convertDictionaryToNSDictionary{{.*}} : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
30-
// CHECK-NEXT: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[DICT]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
32+
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TFE10FoundationVs10Dictionary19_bridgeToObjectiveCfT_CSo12NSDictionary
33+
// CHECK-NEXT: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[DICT]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
34+
// CHECK-NEXT: release_value [[DICT]]
3135
// CHECK-NEXT: return [[NSDICT]] : $NSDictionary
3236
}
3337

@@ -39,8 +43,9 @@ import gizmo
3943
// CHECK: [[GETTER:%[0-9]+]] = function_ref @_TFC24objc_dictionary_bridging3Foog8propertyGVs10DictionaryS0_S0__ : $@convention(method) (@guaranteed Foo) -> @owned Dictionary<Foo, Foo>
4044
// CHECK: [[DICT:%[0-9]+]] = apply [[GETTER]]([[SELF]]) : $@convention(method) (@guaranteed Foo) -> @owned Dictionary<Foo, Foo>
4145

42-
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation32_convertDictionaryToNSDictionary{{.*}} : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
43-
// CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[DICT]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
46+
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TFE10FoundationVs10Dictionary19_bridgeToObjectiveCfT_CSo12NSDictionary
47+
// CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]<Foo, Foo>([[DICT]]) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
48+
// CHECK: release_value [[DICT]]
4449
// CHECK: return [[NSDICT]] : $NSDictionary
4550

4651
// Property setter

test/SILGen/objc_error.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s | FileCheck %s
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %build-clang-importer-objc-overlays
3+
4+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-silgen %s | FileCheck %s
25

36
// REQUIRES: objc_interop
47

test/SILGen/objc_set_bridging.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend -emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s | FileCheck %s
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %build-silgen-test-overlays
3+
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) -emit-silgen %s | FileCheck %s
25

36
// REQUIRES: objc_interop
47

@@ -27,8 +30,8 @@ import gizmo
2730
// CHECK: strong_retain [[SELF]] : $Foo
2831
// CHECK: [[SWIFT_FN:%[0-9]+]] = function_ref @_TFC17objc_set_bridging3Foo17bridge_Set_result{{.*}} : $@convention(method) (@guaranteed Foo) -> @owned Set<Foo>
2932
// CHECK: [[SET:%[0-9]+]] = apply [[SWIFT_FN]]([[SELF]]) : $@convention(method) (@guaranteed Foo) -> @owned Set<Foo>
30-
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation18_convertSetToNSSet{{.*}} : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet
31-
// CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[SET]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet
33+
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TFE10FoundationVs3Set19_bridgeToObjectiveCfT_CSo5NSSet
34+
// CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[SET]]) : $@convention(method) <τ_0_0 where τ_0_0 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned NSSet
3235
// CHECK: return [[NSSET]] : $NSSet
3336
}
3437

@@ -40,8 +43,8 @@ import gizmo
4043
// CHECK: strong_retain [[SELF]] : $Foo
4144
// CHECK: [[GETTER:%[0-9]+]] = function_ref @_TFC17objc_set_bridging3Foog8property{{.*}} : $@convention(method) (@guaranteed Foo) -> @owned Set<Foo>
4245
// CHECK: [[SET:%[0-9]+]] = apply [[GETTER]]([[SELF]]) : $@convention(method) (@guaranteed Foo) -> @owned Set<Foo>
43-
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation18_convertSetToNSSet{{.*}} : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet
44-
// CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[SET]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet
46+
// CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TFE10FoundationVs3Set19_bridgeToObjectiveCfT_CSo5NSSet
47+
// CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]<Foo>([[SET]]) : $@convention(method) <τ_0_0 where τ_0_0 : Hashable> (@guaranteed Set<τ_0_0>) -> @owned NSSet
4548
// CHECK: return [[NSSET]] : $NSSet
4649

4750
// Property setter

0 commit comments

Comments
 (0)