static ManagedValue emitCBridgedToNativeValue(SILGenFunction &gen, SILLocation loc, ManagedValue v, SILType nativeTy) { CanType loweredNativeTy = nativeTy.getSwiftRValueType(); CanType loweredBridgedTy = v.getType().getSwiftRValueType(); if (loweredNativeTy == loweredBridgedTy) return v; if (loweredNativeTy.getAnyOptionalObjectType()) { return gen.emitOptionalToOptional(loc, v, nativeTy, emitCBridgedToNativeValue); } // Bridge Bool to ObjCBool or DarwinBoolean when requested. if (loweredNativeTy == gen.SGM.Types.getBoolType()) { if (loweredBridgedTy == gen.SGM.Types.getObjCBoolType()) { return emitBridgeForeignBoolToBool(gen, loc, v, gen.SGM.getObjCBoolToBoolFn()); } if (loweredBridgedTy == gen.SGM.Types.getDarwinBooleanType()) { return emitBridgeForeignBoolToBool(gen, loc, v, gen.SGM.getDarwinBooleanToBoolFn()); } } // Bridge Objective-C to thick metatypes. if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)){ if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) { SILValue native = gen.B.emitObjCToThickMetatype(loc, v.getValue(), gen.getLoweredType(loweredNativeTy)); return ManagedValue(native, v.getCleanup()); } } // Bridge blocks back into native function types. auto bridgedFTy = dyn_cast<SILFunctionType>(loweredBridgedTy); if (bridgedFTy && bridgedFTy->getRepresentation() == SILFunctionType::Representation::Block){ auto nativeFTy = cast<SILFunctionType>(loweredNativeTy); if (nativeFTy->getRepresentation() != SILFunctionType::Representation::Block) return gen.emitBlockToFunc(loc, v, nativeFTy); } // Bridge via _ObjectiveCBridgeable. if (auto conformance = gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) { if (auto result = emitBridgeObjectiveCToNative(gen, loc, v, conformance)) return *result; assert(gen.SGM.getASTContext().Diags.hadAnyError() && "Bridging code should have complained"); return gen.emitUndef(loc, nativeTy); } return v; }
static ManagedValue emitCBridgedToNativeValue(SILGenFunction &gen, SILLocation loc, ManagedValue v, SILType nativeTy) { CanType loweredNativeTy = nativeTy.getSwiftRValueType(); CanType loweredBridgedTy = v.getType().getSwiftRValueType(); if (loweredNativeTy == loweredBridgedTy) return v; if (loweredNativeTy.getAnyOptionalObjectType()) { return gen.emitOptionalToOptional(loc, v, nativeTy, emitCBridgedToNativeValue); } // Bridge Bool to ObjCBool or DarwinBoolean when requested. if (loweredNativeTy == gen.SGM.Types.getBoolType()) { if (loweredBridgedTy == gen.SGM.Types.getObjCBoolType()) { return emitBridgeForeignBoolToBool(gen, loc, v, gen.SGM.getObjCBoolToBoolFn()); } if (loweredBridgedTy == gen.SGM.Types.getDarwinBooleanType()) { return emitBridgeForeignBoolToBool(gen, loc, v, gen.SGM.getDarwinBooleanToBoolFn()); } } // Bridge Objective-C to thick metatypes. if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)){ if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) { SILValue native = gen.B.emitObjCToThickMetatype(loc, v.getValue(), gen.getLoweredType(loweredNativeTy)); return ManagedValue(native, v.getCleanup()); } } // Bridge blocks back into native function types. auto bridgedFTy = dyn_cast<SILFunctionType>(loweredBridgedTy); if (bridgedFTy && bridgedFTy->getRepresentation() == SILFunctionType::Representation::Block){ auto nativeFTy = cast<SILFunctionType>(loweredNativeTy); if (nativeFTy->getRepresentation() != SILFunctionType::Representation::Block) return gen.emitBlockToFunc(loc, v, nativeFTy); } // Bridge NSString to String. if (auto stringDecl = gen.getASTContext().getStringDecl()) { if (nativeTy.getSwiftRValueType()->getAnyNominal() == stringDecl) { return emitBridgeNSStringToString(gen, loc, v); } } // Bridge NSArray to Array. if (auto arrayDecl = gen.getASTContext().getArrayDecl()) { if (nativeTy.getSwiftRValueType()->getAnyNominal() == arrayDecl) { SILDeclRef bridgeFn = gen.SGM.getNSArrayToArrayFn(); return emitBridgeCollectionToNative(gen, loc, bridgeFn, v, nativeTy); } } // Bridge NSDictionary to Dictionary. if (auto dictDecl = gen.getASTContext().getDictionaryDecl()) { if (nativeTy.getSwiftRValueType()->getAnyNominal() == dictDecl) { SILDeclRef bridgeFn = gen.SGM.getNSDictionaryToDictionaryFn(); return emitBridgeCollectionToNative(gen, loc, bridgeFn, v, nativeTy); } } // Bridge NSSet to Set. if (auto setDecl = gen.getASTContext().getSetDecl()) { if (nativeTy.getSwiftRValueType()->getAnyNominal() == setDecl) { SILDeclRef bridgeFn = gen.SGM.getNSSetToSetFn(); return emitBridgeCollectionToNative(gen, loc, bridgeFn, v, nativeTy); } } return v; }