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