@@ -1019,16 +1019,11 @@ SILGenFunction::emitBlockToFunc(SILLocation loc,
1019
1019
loc, thunkedFn, SILType::getPrimitiveObjectType (loweredFuncTy));
1020
1020
}
1021
1021
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) {
1030
1026
assert (loweredNativeTy.isObject ());
1031
- SILType loweredBridgedTy = v.getType ();
1032
1027
if (loweredNativeTy == loweredBridgedTy.getObjectType ())
1033
1028
return v;
1034
1029
@@ -1039,37 +1034,50 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1039
1034
if (!bridgedObjectType) {
1040
1035
auto helper = [&](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
1041
1036
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);
1046
1040
};
1047
1041
return SGF.emitOptionalSome (loc, loweredNativeTy, helper, C);
1048
1042
}
1049
1043
1050
1044
// 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);
1057
1051
};
1058
1052
return SGF.emitOptionalToOptional (loc, v, loweredNativeTy, helper, C);
1059
1053
}
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
+ };
1060
1068
1061
1069
// Bridge ObjCBool, DarwinBoolean, WindowsBool to Bool when requested.
1062
1070
if (nativeType == SGF.SGM .Types .getBoolType ()) {
1063
1071
if (bridgedType == SGF.SGM .Types .getObjCBoolType ()) {
1064
- return emitBridgeForeignBoolToBool (SGF, loc, v ,
1072
+ return emitBridgeForeignBoolToBool (SGF, loc, unwrapBridgedOptionals (v) ,
1065
1073
SGF.SGM .getObjCBoolToBoolFn ());
1066
1074
}
1067
1075
if (bridgedType == SGF.SGM .Types .getDarwinBooleanType ()) {
1068
- return emitBridgeForeignBoolToBool (SGF, loc, v ,
1076
+ return emitBridgeForeignBoolToBool (SGF, loc, unwrapBridgedOptionals (v) ,
1069
1077
SGF.SGM .getDarwinBooleanToBoolFn ());
1070
1078
}
1071
1079
if (bridgedType == SGF.SGM .Types .getWindowsBoolType ()) {
1072
- return emitBridgeForeignBoolToBool (SGF, loc, v ,
1080
+ return emitBridgeForeignBoolToBool (SGF, loc, unwrapBridgedOptionals (v) ,
1073
1081
SGF.SGM .getWindowsBoolToBoolFn ());
1074
1082
}
1075
1083
}
@@ -1079,8 +1087,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1079
1087
auto bridgedMetaTy = cast<AnyMetatypeType>(bridgedType);
1080
1088
if (bridgedMetaTy->hasRepresentation () &&
1081
1089
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);
1084
1092
// *NOTE*: ObjCMetatypes are trivial types. They only gain ARC semantics
1085
1093
// when they are converted to an object via objc_metatype_to_object.
1086
1094
assert (!v.hasCleanup () && " Metatypes are trivial and should not have "
@@ -1096,7 +1104,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1096
1104
== AnyFunctionType::Representation::Block
1097
1105
&& nativeFTy->getRepresentation ()
1098
1106
!= AnyFunctionType::Representation::Block) {
1099
- return SGF.emitBlockToFunc (loc, v, bridgedFTy, nativeFTy,
1107
+ return SGF.emitBlockToFunc (loc, unwrapBridgedOptionals (v), bridgedFTy,
1108
+ nativeFTy,
1100
1109
loweredNativeTy.castTo <SILFunctionType>());
1101
1110
}
1102
1111
}
@@ -1105,8 +1114,10 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1105
1114
if (auto conformance =
1106
1115
SGF.SGM .getConformanceToObjectiveCBridgeable (loc, nativeType)) {
1107
1116
if (auto result = emitBridgeObjectiveCToNative (SGF, loc, v, bridgedType,
1108
- conformance))
1109
- return *result;
1117
+ conformance)) {
1118
+ --bridgedOptionalsToUnwrap;
1119
+ return unwrapBridgedOptionals (*result);
1120
+ }
1110
1121
1111
1122
assert (SGF.SGM .getASTContext ().Diags .hadAnyError () &&
1112
1123
" Bridging code should have complained" );
@@ -1117,7 +1128,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1117
1128
if (nativeType->isAny ()) {
1118
1129
// If this is not a call result, use the normal erasure logic.
1119
1130
if (!isCallResult) {
1120
- return SGF.emitTransformedValue (loc, v, bridgedType, nativeType, C);
1131
+ return SGF.emitTransformedValue (loc, unwrapBridgedOptionals (v),
1132
+ bridgedType, nativeType, C);
1121
1133
}
1122
1134
1123
1135
// Otherwise, we use more complicated logic that handles results that
@@ -1129,7 +1141,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1129
1141
CanType anyObjectTy =
1130
1142
SGF.getASTContext ().getAnyObjectType ()->getCanonicalType ();
1131
1143
if (bridgedType != anyObjectTy) {
1132
- v = SGF.emitTransformedValue (loc, v, bridgedType, anyObjectTy);
1144
+ v = SGF.emitTransformedValue (loc, unwrapBridgedOptionals (v), bridgedType,
1145
+ anyObjectTy);
1133
1146
}
1134
1147
1135
1148
// TODO: Ever need to handle +0 values here?
@@ -1142,8 +1155,8 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1142
1155
// Bitcast to Optional. This provides a barrier to the optimizer to prevent
1143
1156
// it from attempting to eliminate null checks.
1144
1157
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);
1147
1160
return SGF.emitApplyOfLibraryIntrinsic (loc,
1148
1161
SGF.getASTContext ().getBridgeAnyObjectToAny (),
1149
1162
SubstitutionMap (), optionalMV, C)
@@ -1152,9 +1165,9 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
1152
1165
1153
1166
// Bridge NSError to Error.
1154
1167
if (bridgedType == SGF.SGM .Types .getNSErrorType ())
1155
- return SGF.emitBridgedToNativeError (loc, v );
1168
+ return SGF.emitBridgedToNativeError (loc, unwrapBridgedOptionals (v) );
1156
1169
1157
- return v ;
1170
+ return unwrapBridgedOptionals (v) ;
1158
1171
}
1159
1172
1160
1173
ManagedValue SILGenFunction::emitBridgedToNativeValue (SILLocation loc,
@@ -1165,8 +1178,10 @@ ManagedValue SILGenFunction::emitBridgedToNativeValue(SILLocation loc,
1165
1178
SGFContext C,
1166
1179
bool isCallResult) {
1167
1180
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);
1170
1185
}
1171
1186
1172
1187
// / Bridge a possibly-optional foreign error type to Error.
0 commit comments