@@ -1020,16 +1020,11 @@ SILGenFunction::emitBlockToFunc(SILLocation loc,
10201020 loc, thunkedFn, SILType::getPrimitiveObjectType (loweredFuncTy));
10211021}
10221022
1023- static ManagedValue emitCBridgedToNativeValue (SILGenFunction &SGF,
1024- SILLocation loc,
1025- ManagedValue v,
1026- CanType bridgedType,
1027- CanType nativeType,
1028- SILType loweredNativeTy,
1029- bool isCallResult,
1030- SGFContext C) {
1023+ static ManagedValue emitCBridgedToNativeValue (
1024+ SILGenFunction &SGF, SILLocation loc, ManagedValue v, CanType bridgedType,
1025+ SILType loweredBridgedTy, CanType nativeType, SILType loweredNativeTy,
1026+ int bridgedOptionalsToUnwrap, bool isCallResult, SGFContext C) {
10311027 assert (loweredNativeTy.isObject ());
1032- SILType loweredBridgedTy = v.getType ();
10331028 if (loweredNativeTy == loweredBridgedTy.getObjectType ())
10341029 return v;
10351030
@@ -1040,37 +1035,50 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
10401035 if (!bridgedObjectType) {
10411036 auto helper = [&](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
10421037 auto loweredNativeObjectTy = loweredNativeTy.getOptionalObjectType ();
1043- return emitCBridgedToNativeValue (SGF, loc, v, bridgedType,
1044- nativeObjectType,
1045- loweredNativeObjectTy,
1046- isCallResult, C);
1038+ return emitCBridgedToNativeValue (
1039+ SGF, loc, v, bridgedType, loweredBridgedTy, nativeObjectType,
1040+ loweredNativeObjectTy, bridgedOptionalsToUnwrap, isCallResult, C);
10471041 };
10481042 return SGF.emitOptionalSome (loc, loweredNativeTy, helper, C);
10491043 }
10501044
10511045 // Optional-to-optional.
1052- auto helper =
1053- [=](SILGenFunction &SGF, SILLocation loc, ManagedValue v,
1054- SILType loweredNativeObjectTy, SGFContext C) {
1055- return emitCBridgedToNativeValue ( SGF, loc, v, bridgedObjectType,
1056- nativeObjectType, loweredNativeObjectTy ,
1057- isCallResult, C);
1046+ auto helper = [=](SILGenFunction &SGF, SILLocation loc, ManagedValue v,
1047+ SILType loweredNativeObjectTy, SGFContext C) {
1048+ return emitCBridgedToNativeValue (
1049+ SGF, loc, v, bridgedObjectType,
1050+ loweredBridgedTy. getOptionalObjectType (), nativeObjectType ,
1051+ loweredNativeObjectTy, bridgedOptionalsToUnwrap, isCallResult, C);
10581052 };
10591053 return SGF.emitOptionalToOptional (loc, v, loweredNativeTy, helper, C);
10601054 }
1055+ if (auto bridgedObjectType = bridgedType.getOptionalObjectType ()) {
1056+ return emitCBridgedToNativeValue (
1057+ SGF, loc, v, bridgedObjectType,
1058+ loweredBridgedTy.getOptionalObjectType (), nativeType, loweredNativeTy,
1059+ bridgedOptionalsToUnwrap + 1 , isCallResult, C);
1060+ }
1061+
1062+ auto unwrapBridgedOptionals = [&](ManagedValue v) {
1063+ for (int i = 0 ; i < bridgedOptionalsToUnwrap; ++i) {
1064+ v = SGF.emitPreconditionOptionalHasValue (loc, v,
1065+ /* implicit*/ true );
1066+ };
1067+ return v;
1068+ };
10611069
10621070 // Bridge ObjCBool, DarwinBoolean, WindowsBool to Bool when requested.
10631071 if (nativeType == SGF.SGM .Types .getBoolType ()) {
10641072 if (bridgedType == SGF.SGM .Types .getObjCBoolType ()) {
1065- return emitBridgeForeignBoolToBool (SGF, loc, v ,
1073+ return emitBridgeForeignBoolToBool (SGF, loc, unwrapBridgedOptionals (v) ,
10661074 SGF.SGM .getObjCBoolToBoolFn ());
10671075 }
10681076 if (bridgedType == SGF.SGM .Types .getDarwinBooleanType ()) {
1069- return emitBridgeForeignBoolToBool (SGF, loc, v ,
1077+ return emitBridgeForeignBoolToBool (SGF, loc, unwrapBridgedOptionals (v) ,
10701078 SGF.SGM .getDarwinBooleanToBoolFn ());
10711079 }
10721080 if (bridgedType == SGF.SGM .Types .getWindowsBoolType ()) {
1073- return emitBridgeForeignBoolToBool (SGF, loc, v ,
1081+ return emitBridgeForeignBoolToBool (SGF, loc, unwrapBridgedOptionals (v) ,
10741082 SGF.SGM .getWindowsBoolToBoolFn ());
10751083 }
10761084 }
@@ -1080,8 +1088,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
10801088 auto bridgedMetaTy = cast<AnyMetatypeType>(bridgedType);
10811089 if (bridgedMetaTy->hasRepresentation () &&
10821090 bridgedMetaTy->getRepresentation () == MetatypeRepresentation::ObjC) {
1083- SILValue native =
1084- SGF. B . emitObjCToThickMetatype ( loc, v .getValue (), loweredNativeTy);
1091+ SILValue native = SGF. B . emitObjCToThickMetatype (
1092+ loc, unwrapBridgedOptionals (v) .getValue (), loweredNativeTy);
10851093 // *NOTE*: ObjCMetatypes are trivial types. They only gain ARC semantics
10861094 // when they are converted to an object via objc_metatype_to_object.
10871095 assert (!v.hasCleanup () && " Metatypes are trivial and should not have "
@@ -1097,7 +1105,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
10971105 == AnyFunctionType::Representation::Block
10981106 && nativeFTy->getRepresentation ()
10991107 != AnyFunctionType::Representation::Block) {
1100- return SGF.emitBlockToFunc (loc, v, bridgedFTy, nativeFTy,
1108+ return SGF.emitBlockToFunc (loc, unwrapBridgedOptionals (v), bridgedFTy,
1109+ nativeFTy,
11011110 loweredNativeTy.castTo <SILFunctionType>());
11021111 }
11031112 }
@@ -1106,8 +1115,10 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11061115 if (auto conformance =
11071116 SGF.SGM .getConformanceToObjectiveCBridgeable (loc, nativeType)) {
11081117 if (auto result = emitBridgeObjectiveCToNative (SGF, loc, v, bridgedType,
1109- conformance))
1110- return *result;
1118+ conformance)) {
1119+ --bridgedOptionalsToUnwrap;
1120+ return unwrapBridgedOptionals (*result);
1121+ }
11111122
11121123 assert (SGF.SGM .getASTContext ().Diags .hadAnyError () &&
11131124 " Bridging code should have complained" );
@@ -1118,7 +1129,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11181129 if (nativeType->isAny ()) {
11191130 // If this is not a call result, use the normal erasure logic.
11201131 if (!isCallResult) {
1121- return SGF.emitTransformedValue (loc, v, bridgedType, nativeType, C);
1132+ return SGF.emitTransformedValue (loc, unwrapBridgedOptionals (v),
1133+ bridgedType, nativeType, C);
11221134 }
11231135
11241136 // Otherwise, we use more complicated logic that handles results that
@@ -1130,7 +1142,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11301142 CanType anyObjectTy =
11311143 SGF.getASTContext ().getAnyObjectType ()->getCanonicalType ();
11321144 if (bridgedType != anyObjectTy) {
1133- v = SGF.emitTransformedValue (loc, v, bridgedType, anyObjectTy);
1145+ v = SGF.emitTransformedValue (loc, unwrapBridgedOptionals (v), bridgedType,
1146+ anyObjectTy);
11341147 }
11351148
11361149 // TODO: Ever need to handle +0 values here?
@@ -1143,8 +1156,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11431156 // Bitcast to Optional. This provides a barrier to the optimizer to prevent
11441157 // it from attempting to eliminate null checks.
11451158 auto optionalBridgedTy = SILType::getOptionalType (loweredBridgedTy);
1146- auto optionalMV =
1147- SGF. B . createUncheckedBitCast ( loc, v , optionalBridgedTy);
1159+ auto optionalMV = SGF. B . createUncheckedBitCast (
1160+ loc, unwrapBridgedOptionals (v) , optionalBridgedTy);
11481161 return SGF.emitApplyOfLibraryIntrinsic (loc,
11491162 SGF.getASTContext ().getBridgeAnyObjectToAny (),
11501163 SubstitutionMap (), optionalMV, C)
@@ -1153,9 +1166,9 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
11531166
11541167 // Bridge NSError to Error.
11551168 if (bridgedType == SGF.SGM .Types .getNSErrorType ())
1156- return SGF.emitBridgedToNativeError (loc, v );
1169+ return SGF.emitBridgedToNativeError (loc, unwrapBridgedOptionals (v) );
11571170
1158- return v ;
1171+ return unwrapBridgedOptionals (v) ;
11591172}
11601173
11611174ManagedValue SILGenFunction::emitBridgedToNativeValue (SILLocation loc,
@@ -1166,8 +1179,10 @@ ManagedValue SILGenFunction::emitBridgedToNativeValue(SILLocation loc,
11661179 SGFContext C,
11671180 bool isCallResult) {
11681181 loweredNativeTy = loweredNativeTy.getObjectType ();
1169- return emitCBridgedToNativeValue (*this , loc, v, bridgedType, nativeType,
1170- loweredNativeTy, isCallResult, C);
1182+ SILType loweredBridgedTy = v.getType ();
1183+ return emitCBridgedToNativeValue (
1184+ *this , loc, v, bridgedType, loweredBridgedTy, nativeType, loweredNativeTy,
1185+ /* bridgedOptionalsToUnwrap=*/ 0 , isCallResult, C);
11711186}
11721187
11731188// / Bridge a possibly-optional foreign error type to Error.
0 commit comments