Skip to content

Commit a44d790

Browse files
Merge pull request #38862 from nate-chandler/cherrypick/rdar81590807/release/5.5
[5.5] [SILGen] Handled transforming Bridged? -> Swift.
2 parents 8d59fd0 + e99cbaf commit a44d790

File tree

12 files changed

+367
-35
lines changed

12 files changed

+367
-35
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,16 +1019,11 @@ SILGenFunction::emitBlockToFunc(SILLocation loc,
10191019
loc, thunkedFn, SILType::getPrimitiveObjectType(loweredFuncTy));
10201020
}
10211021

1022-
static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1023-
SILLocation loc,
1024-
ManagedValue v,
1025-
CanType bridgedType,
1026-
CanType nativeType,
1027-
SILType loweredNativeTy,
1028-
bool isCallResult,
1029-
SGFContext C) {
1022+
static ManagedValue emitCBridgedToNativeValue(
1023+
SILGenFunction &SGF, SILLocation loc, ManagedValue v, CanType bridgedType,
1024+
SILType loweredBridgedTy, CanType nativeType, SILType loweredNativeTy,
1025+
int bridgedOptionalsToUnwrap, bool isCallResult, SGFContext C) {
10301026
assert(loweredNativeTy.isObject());
1031-
SILType loweredBridgedTy = v.getType();
10321027
if (loweredNativeTy == loweredBridgedTy.getObjectType())
10331028
return v;
10341029

@@ -1039,37 +1034,50 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
10391034
if (!bridgedObjectType) {
10401035
auto helper = [&](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
10411036
auto loweredNativeObjectTy = loweredNativeTy.getOptionalObjectType();
1042-
return emitCBridgedToNativeValue(SGF, loc, v, bridgedType,
1043-
nativeObjectType,
1044-
loweredNativeObjectTy,
1045-
isCallResult, C);
1037+
return emitCBridgedToNativeValue(
1038+
SGF, loc, v, bridgedType, loweredBridgedTy, nativeObjectType,
1039+
loweredNativeObjectTy, bridgedOptionalsToUnwrap, isCallResult, C);
10461040
};
10471041
return SGF.emitOptionalSome(loc, loweredNativeTy, helper, C);
10481042
}
10491043

10501044
// Optional-to-optional.
1051-
auto helper =
1052-
[=](SILGenFunction &SGF, SILLocation loc, ManagedValue v,
1053-
SILType loweredNativeObjectTy, SGFContext C) {
1054-
return emitCBridgedToNativeValue(SGF, loc, v, bridgedObjectType,
1055-
nativeObjectType, loweredNativeObjectTy,
1056-
isCallResult, C);
1045+
auto helper = [=](SILGenFunction &SGF, SILLocation loc, ManagedValue v,
1046+
SILType loweredNativeObjectTy, SGFContext C) {
1047+
return emitCBridgedToNativeValue(
1048+
SGF, loc, v, bridgedObjectType,
1049+
loweredBridgedTy.getOptionalObjectType(), nativeObjectType,
1050+
loweredNativeObjectTy, bridgedOptionalsToUnwrap, isCallResult, C);
10571051
};
10581052
return SGF.emitOptionalToOptional(loc, v, loweredNativeTy, helper, C);
10591053
}
1054+
if (auto bridgedObjectType = bridgedType.getOptionalObjectType()) {
1055+
return emitCBridgedToNativeValue(
1056+
SGF, loc, v, bridgedObjectType,
1057+
loweredBridgedTy.getOptionalObjectType(), nativeType, loweredNativeTy,
1058+
bridgedOptionalsToUnwrap + 1, isCallResult, C);
1059+
}
1060+
1061+
auto unwrapBridgedOptionals = [&](ManagedValue v) {
1062+
for (int i = 0; i < bridgedOptionalsToUnwrap; ++i) {
1063+
v = SGF.emitPreconditionOptionalHasValue(loc, v,
1064+
/*implicit*/ true);
1065+
};
1066+
return v;
1067+
};
10601068

10611069
// Bridge ObjCBool, DarwinBoolean, WindowsBool to Bool when requested.
10621070
if (nativeType == SGF.SGM.Types.getBoolType()) {
10631071
if (bridgedType == SGF.SGM.Types.getObjCBoolType()) {
1064-
return emitBridgeForeignBoolToBool(SGF, loc, v,
1072+
return emitBridgeForeignBoolToBool(SGF, loc, unwrapBridgedOptionals(v),
10651073
SGF.SGM.getObjCBoolToBoolFn());
10661074
}
10671075
if (bridgedType == SGF.SGM.Types.getDarwinBooleanType()) {
1068-
return emitBridgeForeignBoolToBool(SGF, loc, v,
1076+
return emitBridgeForeignBoolToBool(SGF, loc, unwrapBridgedOptionals(v),
10691077
SGF.SGM.getDarwinBooleanToBoolFn());
10701078
}
10711079
if (bridgedType == SGF.SGM.Types.getWindowsBoolType()) {
1072-
return emitBridgeForeignBoolToBool(SGF, loc, v,
1080+
return emitBridgeForeignBoolToBool(SGF, loc, unwrapBridgedOptionals(v),
10731081
SGF.SGM.getWindowsBoolToBoolFn());
10741082
}
10751083
}
@@ -1079,8 +1087,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
10791087
auto bridgedMetaTy = cast<AnyMetatypeType>(bridgedType);
10801088
if (bridgedMetaTy->hasRepresentation() &&
10811089
bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) {
1082-
SILValue native =
1083-
SGF.B.emitObjCToThickMetatype(loc, v.getValue(), loweredNativeTy);
1090+
SILValue native = SGF.B.emitObjCToThickMetatype(
1091+
loc, unwrapBridgedOptionals(v).getValue(), loweredNativeTy);
10841092
// *NOTE*: ObjCMetatypes are trivial types. They only gain ARC semantics
10851093
// when they are converted to an object via objc_metatype_to_object.
10861094
assert(!v.hasCleanup() && "Metatypes are trivial and should not have "
@@ -1096,7 +1104,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
10961104
== AnyFunctionType::Representation::Block
10971105
&& nativeFTy->getRepresentation()
10981106
!= AnyFunctionType::Representation::Block) {
1099-
return SGF.emitBlockToFunc(loc, v, bridgedFTy, nativeFTy,
1107+
return SGF.emitBlockToFunc(loc, unwrapBridgedOptionals(v), bridgedFTy,
1108+
nativeFTy,
11001109
loweredNativeTy.castTo<SILFunctionType>());
11011110
}
11021111
}
@@ -1105,8 +1114,10 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11051114
if (auto conformance =
11061115
SGF.SGM.getConformanceToObjectiveCBridgeable(loc, nativeType)) {
11071116
if (auto result = emitBridgeObjectiveCToNative(SGF, loc, v, bridgedType,
1108-
conformance))
1109-
return *result;
1117+
conformance)) {
1118+
--bridgedOptionalsToUnwrap;
1119+
return unwrapBridgedOptionals(*result);
1120+
}
11101121

11111122
assert(SGF.SGM.getASTContext().Diags.hadAnyError() &&
11121123
"Bridging code should have complained");
@@ -1117,7 +1128,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11171128
if (nativeType->isAny()) {
11181129
// If this is not a call result, use the normal erasure logic.
11191130
if (!isCallResult) {
1120-
return SGF.emitTransformedValue(loc, v, bridgedType, nativeType, C);
1131+
return SGF.emitTransformedValue(loc, unwrapBridgedOptionals(v),
1132+
bridgedType, nativeType, C);
11211133
}
11221134

11231135
// Otherwise, we use more complicated logic that handles results that
@@ -1129,7 +1141,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11291141
CanType anyObjectTy =
11301142
SGF.getASTContext().getAnyObjectType()->getCanonicalType();
11311143
if (bridgedType != anyObjectTy) {
1132-
v = SGF.emitTransformedValue(loc, v, bridgedType, anyObjectTy);
1144+
v = SGF.emitTransformedValue(loc, unwrapBridgedOptionals(v), bridgedType,
1145+
anyObjectTy);
11331146
}
11341147

11351148
// TODO: Ever need to handle +0 values here?
@@ -1142,8 +1155,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11421155
// Bitcast to Optional. This provides a barrier to the optimizer to prevent
11431156
// it from attempting to eliminate null checks.
11441157
auto optionalBridgedTy = SILType::getOptionalType(loweredBridgedTy);
1145-
auto optionalMV =
1146-
SGF.B.createUncheckedBitCast(loc, v, optionalBridgedTy);
1158+
auto optionalMV = SGF.B.createUncheckedBitCast(
1159+
loc, unwrapBridgedOptionals(v), optionalBridgedTy);
11471160
return SGF.emitApplyOfLibraryIntrinsic(loc,
11481161
SGF.getASTContext().getBridgeAnyObjectToAny(),
11491162
SubstitutionMap(), optionalMV, C)
@@ -1152,9 +1165,9 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11521165

11531166
// Bridge NSError to Error.
11541167
if (bridgedType == SGF.SGM.Types.getNSErrorType())
1155-
return SGF.emitBridgedToNativeError(loc, v);
1168+
return SGF.emitBridgedToNativeError(loc, unwrapBridgedOptionals(v));
11561169

1157-
return v;
1170+
return unwrapBridgedOptionals(v);
11581171
}
11591172

11601173
ManagedValue SILGenFunction::emitBridgedToNativeValue(SILLocation loc,
@@ -1165,8 +1178,10 @@ ManagedValue SILGenFunction::emitBridgedToNativeValue(SILLocation loc,
11651178
SGFContext C,
11661179
bool isCallResult) {
11671180
loweredNativeTy = loweredNativeTy.getObjectType();
1168-
return emitCBridgedToNativeValue(*this, loc, v, bridgedType, nativeType,
1169-
loweredNativeTy, isCallResult, C);
1181+
SILType loweredBridgedTy = v.getType();
1182+
return emitCBridgedToNativeValue(
1183+
*this, loc, v, bridgedType, loweredBridgedTy, nativeType, loweredNativeTy,
1184+
/*bridgedOptionalsToUnwrap=*/0, isCallResult, C);
11701185
}
11711186

11721187
/// Bridge a possibly-optional foreign error type to Error.

test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#define MAIN_ACTOR __attribute__((__swift_attr__("@MainActor")))
77
#define MAIN_ACTOR_UNSAFE __attribute__((__swift_attr__("@_unsafeMainActor")))
88

9+
#define NS_EXTENSIBLE_STRING_ENUM __attribute__((swift_wrapper(struct)));
10+
typedef NSString *Flavor NS_EXTENSIBLE_STRING_ENUM;
11+
912
@protocol ServiceProvider
1013
@property(readonly) NSArray<NSString *> *allOperations;
1114
-(void)allOperationsWithCompletionHandler:(void (^)(NSArray<NSString *> *))completion;
@@ -84,6 +87,12 @@ typedef void (^CompletionHandler)(NSString * _Nullable, NSString * _Nullable_res
8487
-(void)asyncImportSame:(NSString *)operation replyTo:(void (^)(NSInteger))handler __attribute__((swift_async(none)));
8588

8689
-(void)overridableButRunsOnMainThreadWithCompletionHandler:(MAIN_ACTOR_UNSAFE void (^ _Nullable)(NSString *))completion;
90+
- (void)obtainClosureWithCompletionHandler:(void (^)(void (^_Nullable)(void),
91+
NSError *_Nullable,
92+
BOOL))completionHandler
93+
__attribute__((swift_async_error(zero_argument, 3)));
94+
- (void)getIceCreamFlavorWithCompletionHandler:
95+
(void (^)(Flavor flavor, NSError *__nullable error))completionHandler;
8796
@end
8897

8998
@protocol RefrigeratorDelegate<NSObject>

test/SILGen/objc_async.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ func testSlowServer(slowServer: SlowServer) async throws {
8585
let _: ((Any) -> Void, (Any) -> Void) = await slowServer.performId2VoidId2Void()
8686

8787
let _: String = try await slowServer.findAnswerFailingly()
88+
89+
let _: () -> Void = try await slowServer.obtainClosure()
90+
91+
let _: Flavor = try await slowServer.iceCreamFlavor()
8892
}
8993

9094
func testGeneric<T: AnyObject>(x: GenericObject<T>) async throws {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <Foundation/Foundation.h>
2+
3+
#pragma clang assume_nonnull begin
4+
5+
typedef NSString *FileProviderItemIdentifier NS_EXTENSIBLE_STRING_ENUM;
6+
FileProviderItemIdentifier const
7+
FileProviderRootContainerItemIdentifier NS_SWIFT_NAME(FileProviderItemIdentifier.rootContainer);
8+
FileProviderItemIdentifier const
9+
FileProviderWorkingSetContainerItemIdentifier NS_SWIFT_NAME(FileProviderItemIdentifier.workingSet);
10+
FileProviderItemIdentifier const
11+
FileProviderTrashContainerItemIdentifier NS_SWIFT_NAME(FileProviderItemIdentifier.trashContainer);
12+
typedef NSString *FileProviderDomainIdentifier NS_EXTENSIBLE_STRING_ENUM;
13+
14+
@interface PFXObject : NSObject
15+
+ (void)getIdentifierForUserVisibleFileAtURL:(NSURL *)url
16+
completionHandler:
17+
(void (^)(FileProviderItemIdentifier __nullable
18+
itemIdentifier,
19+
FileProviderDomainIdentifier __nullable
20+
domainIdentifier,
21+
NSError *__nullable error))
22+
completionHandler;
23+
@end
24+
25+
#pragma clang assume_nonnull end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "rdar80704382.h"
2+
3+
#pragma clang assume_nonnull begin
4+
5+
@implementation PFXObject
6+
- (instancetype)init {
7+
if (self = [super init]) {
8+
}
9+
return self;
10+
}
11+
+ (void)getIdentifierForUserVisibleFileAtURL:(NSURL *)url
12+
completionHandler:
13+
(void (^)(FileProviderItemIdentifier __nullable
14+
itemIdentifier,
15+
FileProviderDomainIdentifier __nullable
16+
domainIdentifier,
17+
NSError *__nullable error))
18+
completionHandler {
19+
completionHandler(@"item_id", @"file_id", NULL);
20+
}
21+
@end
22+
23+
#pragma clang assume_nonnull end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <Foundation/Foundation.h>
2+
3+
#pragma clang assume_nonnull begin
4+
5+
@interface PFXObject : NSObject {
6+
}
7+
- (void)continuePassSyncWithCompletionHandler:(void (^)(void (^_Nullable)(void),
8+
NSError *_Nullable,
9+
BOOL))completionHandler
10+
__attribute__((swift_async_error(zero_argument, 3)));
11+
- (void)continuePassAsyncWithCompletionHandler:
12+
(void (^)(void (^_Nullable)(void), NSError *_Nullable,
13+
BOOL))completionHandler
14+
__attribute__((swift_async_error(zero_argument, 3)));
15+
- (void)continueFailSyncWithCompletionHandler:(void (^)(void (^_Nullable)(void),
16+
NSError *_Nullable,
17+
BOOL))completionHandler
18+
__attribute__((swift_async_error(zero_argument, 3)));
19+
- (void)continueFailAsyncWithCompletionHandler:
20+
(void (^)(void (^_Nullable)(void), NSError *_Nullable,
21+
BOOL))completionHandler
22+
__attribute__((swift_async_error(zero_argument, 3)));
23+
- (void)continueIncorrectWithCompletionHandler:
24+
(void (^)(void (^_Nullable)(void), NSError *_Nullable,
25+
BOOL))completionHandler
26+
__attribute__((swift_async_error(zero_argument, 3)));
27+
@end
28+
29+
#pragma clang assume_nonnull end
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "rdar81590807.h"
2+
3+
#pragma clang assume_nonnull begin
4+
5+
@implementation PFXObject
6+
- (void)continuePassSyncWithCompletionHandler:(void (^)(void (^_Nullable)(void),
7+
NSError *_Nullable,
8+
BOOL))completionHandler
9+
__attribute__((swift_async_error(zero_argument, 3))) {
10+
completionHandler(
11+
^{
12+
NSLog(@"passSync");
13+
},
14+
NULL, YES);
15+
}
16+
- (void)continuePassAsyncWithCompletionHandler:
17+
(void (^)(void (^_Nullable)(void), NSError *_Nullable,
18+
BOOL))completionHandler
19+
__attribute__((swift_async_error(zero_argument, 3))) {
20+
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
21+
completionHandler(
22+
^{
23+
NSLog(@"passAsync");
24+
},
25+
NULL, YES);
26+
});
27+
}
28+
- (void)continueFailSyncWithCompletionHandler:(void (^)(void (^_Nullable)(void),
29+
NSError *_Nullable,
30+
BOOL))completionHandler
31+
__attribute__((swift_async_error(zero_argument, 3))) {
32+
completionHandler(
33+
NULL, [NSError errorWithDomain:@"failSync" code:1 userInfo:nil], NO);
34+
}
35+
- (void)continueFailAsyncWithCompletionHandler:
36+
(void (^)(void (^_Nullable)(void), NSError *_Nullable,
37+
BOOL))completionHandler
38+
__attribute__((swift_async_error(zero_argument, 3))) {
39+
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
40+
completionHandler(
41+
NULL, [NSError errorWithDomain:@"failAsync" code:2 userInfo:nil], NO);
42+
});
43+
}
44+
- (void)continueIncorrectWithCompletionHandler:
45+
(void (^)(void (^_Nullable)(void), NSError *_Nullable,
46+
BOOL))completionHandler
47+
__attribute__((swift_async_error(zero_argument, 3))) {
48+
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
49+
completionHandler(NULL, NULL, NO);
50+
});
51+
}
52+
@end
53+
54+
#pragma clang assume_nonnull end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <Foundation/Foundation.h>
2+
3+
#pragma clang assume_nonnull begin
4+
5+
@interface PFXObject : NSObject {
6+
}
7+
- (void)findAnswerSyncSuccessAsynchronously:
8+
(void (^)(NSString *_Nullable, NSError *_Nullable))handler
9+
__attribute__((swift_name("findAnswerSyncSuccess(completionHandler:)")));
10+
- (void)findAnswerAsyncSuccessAsynchronously:
11+
(void (^)(NSString *_Nullable, NSError *_Nullable))handler
12+
__attribute__((swift_name("findAnswerAsyncSuccess(completionHandler:)")));
13+
- (void)findAnswerSyncFailAsynchronously:
14+
(void (^)(NSString *_Nullable, NSError *_Nullable))handler
15+
__attribute__((swift_name("findAnswerSyncFail(completionHandler:)")));
16+
- (void)findAnswerAsyncFailAsynchronously:
17+
(void (^)(NSString *_Nullable, NSError *_Nullable))handler
18+
__attribute__((swift_name("findAnswerAsyncFail(completionHandler:)")));
19+
- (void)findAnswerIncorrectAsynchronously:
20+
(void (^)(NSString *_Nullable, NSError *_Nullable))handler
21+
__attribute__((swift_name("findAnswerIncorrect(completionHandler:)")));
22+
@end
23+
24+
#pragma clang assume_nonnull end

0 commit comments

Comments
 (0)