static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen, SILLocation loc, ManagedValue v, SILType bridgedTy) { CanType loweredBridgedTy = bridgedTy.getSwiftRValueType(); CanType loweredNativeTy = v.getType().getSwiftRValueType(); if (loweredNativeTy == loweredBridgedTy) return v; // FIXME: Handle this via an _ObjectiveCBridgeable query rather than // hardcoding String -> NSString. if (loweredNativeTy == gen.SGM.Types.getStringType() && loweredBridgedTy == gen.SGM.Types.getNSStringType()) { if (auto result = emitBridgeNativeToObjectiveC(gen, loc, v)) return *result; return gen.emitUndef(loc, bridgedTy); } // If the input is a native type with a bridged mapping, convert it. #define BRIDGE_TYPE(BridgedModule,BridgedType, NativeModule,NativeType,Opt) \ if (loweredNativeTy == gen.SGM.Types.get##NativeType##Type() \ && loweredBridgedTy == gen.SGM.Types.get##BridgedType##Type()) { \ return emitBridge##NativeType##To##BridgedType(gen, loc, v); \ } #include "swift/SIL/BridgedTypes.def" // Bridge thick to Objective-C metatypes. if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)) { if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) { SILValue native = gen.B.emitThickToObjCMetatype(loc, v.getValue(), SILType::getPrimitiveObjectType(loweredBridgedTy)); return ManagedValue(native, v.getCleanup()); } } // Bridge native functions to blocks. 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.emitFuncToBlock(loc, v, bridgedFTy); } // If the native type conforms to _ObjectiveCBridgeable, use its // _bridgeToObjectiveC witness. if (auto conformance = gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) { if (auto result = emitBridgeNativeToObjectiveC(gen, loc, v, conformance)) return *result; return gen.emitUndef(loc, bridgedTy); } return v; }
static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen, SILLocation loc, ManagedValue v, SILType bridgedTy) { CanType loweredBridgedTy = bridgedTy.getSwiftRValueType(); CanType loweredNativeTy = v.getType().getSwiftRValueType(); if (loweredNativeTy == loweredBridgedTy) return v; // If the input is a native type with a bridged mapping, convert it. #define BRIDGE_TYPE(BridgedModule,BridgedType, NativeModule,NativeType,Opt) \ if (loweredNativeTy == gen.SGM.Types.get##NativeType##Type() \ && loweredBridgedTy == gen.SGM.Types.get##BridgedType##Type()) { \ return emitBridge##NativeType##To##BridgedType(gen, loc, v); \ } #include "swift/SIL/BridgedTypes.def" // Bridge thick to Objective-C metatypes. if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)) { if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) { SILValue native = gen.B.emitThickToObjCMetatype(loc, v.getValue(), SILType::getPrimitiveObjectType(loweredBridgedTy)); return ManagedValue(native, v.getCleanup()); } } // Bridge native functions to blocks. 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.emitFuncToBlock(loc, v, bridgedFTy); } // Bridge Array to NSArray. if (auto arrayDecl = gen.getASTContext().getArrayDecl()) { if (v.getType().getSwiftRValueType().getAnyNominal() == arrayDecl) { SILDeclRef bridgeFn = gen.SGM.getArrayToNSArrayFn(); return emitBridgeCollectionFromNative(gen, loc, bridgeFn, v, bridgedTy); } } // Bridge Dictionary to NSDictionary. if (auto dictDecl = gen.getASTContext().getDictionaryDecl()) { if (v.getType().getSwiftRValueType().getAnyNominal() == dictDecl) { SILDeclRef bridgeFn = gen.SGM.getDictionaryToNSDictionaryFn(); return emitBridgeCollectionFromNative(gen, loc, bridgeFn, v, bridgedTy); } } // Bridge Set to NSSet. if (auto setDecl = gen.getASTContext().getSetDecl()) { if (v.getType().getSwiftRValueType().getAnyNominal() == setDecl) { SILDeclRef bridgeFn = gen.SGM.getSetToNSSetFn(); return emitBridgeCollectionFromNative(gen, loc, bridgeFn, v, bridgedTy); } } return v; }