Пример #1
0
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;
}
Пример #2
0
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;
}