mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #10832 from rjmccall/fix-function-component-bridging-import
Bridge types during import only if we are in a fully-bridgeable context.
This commit is contained in:
@@ -2303,7 +2303,7 @@ namespace {
|
|||||||
SwiftType = Impl.importType(ClangType,
|
SwiftType = Impl.importType(ClangType,
|
||||||
ImportTypeKind::Typedef,
|
ImportTypeKind::Typedef,
|
||||||
isInSystemModule(DC),
|
isInSystemModule(DC),
|
||||||
ClangType->isBlockPointerType(),
|
getTypedefBridgeability(ClangType),
|
||||||
OTK_Optional);
|
OTK_Optional);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2410,7 +2410,7 @@ namespace {
|
|||||||
auto underlyingType = Impl.importType(decl->getIntegerType(),
|
auto underlyingType = Impl.importType(decl->getIntegerType(),
|
||||||
ImportTypeKind::Enum,
|
ImportTypeKind::Enum,
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!underlyingType)
|
if (!underlyingType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -2447,7 +2447,7 @@ namespace {
|
|||||||
// Compute the underlying type.
|
// Compute the underlying type.
|
||||||
auto underlyingType = Impl.importType(
|
auto underlyingType = Impl.importType(
|
||||||
decl->getIntegerType(), ImportTypeKind::Enum, isInSystemModule(dc),
|
decl->getIntegerType(), ImportTypeKind::Enum, isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/ false);
|
Bridgeability::None);
|
||||||
if (!underlyingType)
|
if (!underlyingType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -3063,7 +3063,7 @@ namespace {
|
|||||||
auto type = Impl.importType(clangContext.getTagDeclType(clangEnum),
|
auto type = Impl.importType(clangContext.getTagDeclType(clangEnum),
|
||||||
ImportTypeKind::Value,
|
ImportTypeKind::Value,
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!type)
|
if (!type)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
// FIXME: Importing the type will recursively revisit this same
|
// FIXME: Importing the type will recursively revisit this same
|
||||||
@@ -3101,7 +3101,7 @@ namespace {
|
|||||||
Impl.getClangASTContext().getTagDeclType(clangEnum),
|
Impl.getClangASTContext().getTagDeclType(clangEnum),
|
||||||
ImportTypeKind::Value,
|
ImportTypeKind::Value,
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!enumType)
|
if (!enumType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -3162,7 +3162,7 @@ namespace {
|
|||||||
auto type = Impl.importType(decl->getType(),
|
auto type = Impl.importType(decl->getType(),
|
||||||
ImportTypeKind::Variable,
|
ImportTypeKind::Variable,
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!type)
|
if (!type)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -3385,7 +3385,7 @@ namespace {
|
|||||||
auto type = Impl.importType(decl->getType(),
|
auto type = Impl.importType(decl->getType(),
|
||||||
ImportTypeKind::RecordField,
|
ImportTypeKind::RecordField,
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!type)
|
if (!type)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -3454,7 +3454,7 @@ namespace {
|
|||||||
(isAudited ? ImportTypeKind::AuditedVariable
|
(isAudited ? ImportTypeKind::AuditedVariable
|
||||||
: ImportTypeKind::Variable),
|
: ImportTypeKind::Variable),
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -4332,7 +4332,7 @@ namespace {
|
|||||||
superclassType = Impl.importType(clangSuperclassType,
|
superclassType = Impl.importType(clangSuperclassType,
|
||||||
ImportTypeKind::Abstract,
|
ImportTypeKind::Abstract,
|
||||||
isInSystemModule(dc),
|
isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (superclassType) {
|
if (superclassType) {
|
||||||
assert(superclassType->is<ClassType>() ||
|
assert(superclassType->is<ClassType>() ||
|
||||||
superclassType->is<BoundGenericClassType>());
|
superclassType->is<BoundGenericClassType>());
|
||||||
@@ -4938,7 +4938,7 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl,
|
|||||||
// Import the type of the underlying storage
|
// Import the type of the underlying storage
|
||||||
auto storedUnderlyingType = Impl.importType(
|
auto storedUnderlyingType = Impl.importType(
|
||||||
decl->getUnderlyingType(), ImportTypeKind::Value, isInSystemModule(dc),
|
decl->getUnderlyingType(), ImportTypeKind::Value, isInSystemModule(dc),
|
||||||
decl->getUnderlyingType()->isBlockPointerType(), OTK_None);
|
Bridgeability::None, OTK_None);
|
||||||
|
|
||||||
if (auto objTy = storedUnderlyingType->getAnyOptionalObjectType())
|
if (auto objTy = storedUnderlyingType->getAnyOptionalObjectType())
|
||||||
storedUnderlyingType = objTy;
|
storedUnderlyingType = objTy;
|
||||||
@@ -4956,7 +4956,7 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl,
|
|||||||
// Find a bridged type, which may be different
|
// Find a bridged type, which may be different
|
||||||
auto computedPropertyUnderlyingType = Impl.importType(
|
auto computedPropertyUnderlyingType = Impl.importType(
|
||||||
decl->getUnderlyingType(), ImportTypeKind::Property, isInSystemModule(dc),
|
decl->getUnderlyingType(), ImportTypeKind::Property, isInSystemModule(dc),
|
||||||
decl->getUnderlyingType()->isBlockPointerType(), OTK_None);
|
Bridgeability::Full, OTK_None);
|
||||||
if (auto objTy = computedPropertyUnderlyingType->getAnyOptionalObjectType())
|
if (auto objTy = computedPropertyUnderlyingType->getAnyOptionalObjectType())
|
||||||
computedPropertyUnderlyingType = objTy;
|
computedPropertyUnderlyingType = objTy;
|
||||||
|
|
||||||
@@ -5173,7 +5173,7 @@ SwiftDeclConverter::importAsOptionSetType(DeclContext *dc, Identifier name,
|
|||||||
// Compute the underlying type.
|
// Compute the underlying type.
|
||||||
auto underlyingType = Impl.importType(
|
auto underlyingType = Impl.importType(
|
||||||
decl->getIntegerType(), ImportTypeKind::Enum, isInSystemModule(dc),
|
decl->getIntegerType(), ImportTypeKind::Enum, isInSystemModule(dc),
|
||||||
/*isFullyBridgeable*/ false);
|
Bridgeability::None);
|
||||||
if (!underlyingType)
|
if (!underlyingType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -5492,7 +5492,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
|
|||||||
Type swiftPropertyType = Impl.importType(
|
Type swiftPropertyType = Impl.importType(
|
||||||
propertyType, ImportTypeKind::Property,
|
propertyType, ImportTypeKind::Property,
|
||||||
Impl.shouldAllowNSUIntegerAsInt(isFromSystemModule, getter),
|
Impl.shouldAllowNSUIntegerAsInt(isFromSystemModule, getter),
|
||||||
/*isFullyBridgeable*/ true, OTK_ImplicitlyUnwrappedOptional);
|
Bridgeability::Full, OTK_ImplicitlyUnwrappedOptional);
|
||||||
if (!swiftPropertyType)
|
if (!swiftPropertyType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -6406,7 +6406,8 @@ Optional<GenericParamList *> SwiftDeclConverter::importObjCGenericParams(
|
|||||||
clangBound->stripObjCKindOfTypeAndQuals(Impl.getClangASTContext());
|
clangBound->stripObjCKindOfTypeAndQuals(Impl.getClangASTContext());
|
||||||
Type superclassType =
|
Type superclassType =
|
||||||
Impl.importType(clang::QualType(unqualifiedClangBound, 0),
|
Impl.importType(clang::QualType(unqualifiedClangBound, 0),
|
||||||
ImportTypeKind::Abstract, false, false);
|
ImportTypeKind::Abstract, false,
|
||||||
|
Bridgeability::None);
|
||||||
if (!superclassType) {
|
if (!superclassType) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
|
|||||||
auto clangTy = parsed->getType();
|
auto clangTy = parsed->getType();
|
||||||
auto literalType = Impl.importType(clangTy, ImportTypeKind::Value,
|
auto literalType = Impl.importType(clangTy, ImportTypeKind::Value,
|
||||||
isInSystemModule(DC),
|
isInSystemModule(DC),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!literalType)
|
if (!literalType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
|
|||||||
} else {
|
} else {
|
||||||
constantType = Impl.importType(castType, ImportTypeKind::Value,
|
constantType = Impl.importType(castType, ImportTypeKind::Value,
|
||||||
isInSystemModule(DC),
|
isInSystemModule(DC),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!constantType)
|
if (!constantType)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ static Optional<std::pair<llvm::APSInt, Type>>
|
|||||||
auto type = impl.importType(literal->getType(),
|
auto type = impl.importType(literal->getType(),
|
||||||
ImportTypeKind::Value,
|
ImportTypeKind::Value,
|
||||||
isInSystemModule(DC),
|
isInSystemModule(DC),
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
return {{ value, type }};
|
return {{ value, type }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,14 +176,14 @@ namespace {
|
|||||||
{
|
{
|
||||||
ClangImporter::Implementation &Impl;
|
ClangImporter::Implementation &Impl;
|
||||||
bool AllowNSUIntegerAsInt;
|
bool AllowNSUIntegerAsInt;
|
||||||
bool CanFullyBridgeTypes;
|
Bridgeability Bridging;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SwiftTypeConverter(ClangImporter::Implementation &impl,
|
SwiftTypeConverter(ClangImporter::Implementation &impl,
|
||||||
bool allowNSUIntegerAsInt,
|
bool allowNSUIntegerAsInt,
|
||||||
bool canFullyBridgeTypes)
|
Bridgeability bridging)
|
||||||
: Impl(impl), AllowNSUIntegerAsInt(allowNSUIntegerAsInt),
|
: Impl(impl), AllowNSUIntegerAsInt(allowNSUIntegerAsInt),
|
||||||
CanFullyBridgeTypes(canFullyBridgeTypes) {}
|
Bridging(bridging) {}
|
||||||
|
|
||||||
using TypeVisitor::Visit;
|
using TypeVisitor::Visit;
|
||||||
ImportResult Visit(clang::QualType type) {
|
ImportResult Visit(clang::QualType type) {
|
||||||
@@ -356,7 +356,7 @@ namespace {
|
|||||||
pointeeType = Impl.importType(pointeeQualType,
|
pointeeType = Impl.importType(pointeeQualType,
|
||||||
ImportTypeKind::Pointee,
|
ImportTypeKind::Pointee,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
|
|
||||||
// If the pointed-to type is unrepresentable in Swift, import as
|
// If the pointed-to type is unrepresentable in Swift, import as
|
||||||
// OpaquePointer.
|
// OpaquePointer.
|
||||||
@@ -404,7 +404,7 @@ namespace {
|
|||||||
Type pointeeType = Impl.importType(type->getPointeeType(),
|
Type pointeeType = Impl.importType(type->getPointeeType(),
|
||||||
ImportTypeKind::Abstract,
|
ImportTypeKind::Abstract,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
CanFullyBridgeTypes);
|
Bridging);
|
||||||
if (!pointeeType)
|
if (!pointeeType)
|
||||||
return Type();
|
return Type();
|
||||||
FunctionType *fTy = pointeeType->castTo<FunctionType>();
|
FunctionType *fTy = pointeeType->castTo<FunctionType>();
|
||||||
@@ -443,7 +443,7 @@ namespace {
|
|||||||
Type elementType = Impl.importType(type->getElementType(),
|
Type elementType = Impl.importType(type->getElementType(),
|
||||||
ImportTypeKind::Pointee,
|
ImportTypeKind::Pointee,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
/*isFullyBridgeable*/false);
|
Bridgeability::None);
|
||||||
if (!elementType)
|
if (!elementType)
|
||||||
return Type();
|
return Type();
|
||||||
|
|
||||||
@@ -498,7 +498,7 @@ namespace {
|
|||||||
auto resultTy = Impl.importType(type->getReturnType(),
|
auto resultTy = Impl.importType(type->getReturnType(),
|
||||||
ImportTypeKind::Result,
|
ImportTypeKind::Result,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
CanFullyBridgeTypes,
|
Bridging,
|
||||||
OTK_Optional);
|
OTK_Optional);
|
||||||
if (!resultTy)
|
if (!resultTy)
|
||||||
return Type();
|
return Type();
|
||||||
@@ -509,7 +509,7 @@ namespace {
|
|||||||
param != paramEnd; ++param) {
|
param != paramEnd; ++param) {
|
||||||
auto swiftParamTy = Impl.importType(*param, ImportTypeKind::Parameter,
|
auto swiftParamTy = Impl.importType(*param, ImportTypeKind::Parameter,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
CanFullyBridgeTypes,
|
Bridging,
|
||||||
OTK_Optional);
|
OTK_Optional);
|
||||||
if (!swiftParamTy)
|
if (!swiftParamTy)
|
||||||
return Type();
|
return Type();
|
||||||
@@ -534,7 +534,7 @@ namespace {
|
|||||||
auto resultTy = Impl.importType(type->getReturnType(),
|
auto resultTy = Impl.importType(type->getReturnType(),
|
||||||
ImportTypeKind::Result,
|
ImportTypeKind::Result,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
CanFullyBridgeTypes,
|
Bridging,
|
||||||
OTK_Optional);
|
OTK_Optional);
|
||||||
if (!resultTy)
|
if (!resultTy)
|
||||||
return Type();
|
return Type();
|
||||||
@@ -665,12 +665,32 @@ namespace {
|
|||||||
}
|
}
|
||||||
// Any other interesting mapped types should be hinted here.
|
// Any other interesting mapped types should be hinted here.
|
||||||
|
|
||||||
// Otherwise, recurse on the underlying type in order to compute
|
// Otherwise, recurse on the underlying type. We need to recompute
|
||||||
// the hint correctly.
|
// the hint, and if the typedef uses different bridgeability than the
|
||||||
|
// context then we may also need to bypass the typedef.
|
||||||
} else {
|
} else {
|
||||||
|
auto underlyingType = type->desugar();
|
||||||
|
|
||||||
|
// Figure out the bridgeability we would normally use for this typedef.
|
||||||
|
auto typedefBridgeability = getTypedefBridgeability(underlyingType);
|
||||||
|
|
||||||
|
// Figure out the typedef we should actually use.
|
||||||
|
auto underlyingBridgeability =
|
||||||
|
(Bridging == Bridgeability::Full
|
||||||
|
? typedefBridgeability : Bridgeability::None);
|
||||||
SwiftTypeConverter innerConverter(Impl, AllowNSUIntegerAsInt,
|
SwiftTypeConverter innerConverter(Impl, AllowNSUIntegerAsInt,
|
||||||
/*can fully bridge*/false);
|
underlyingBridgeability);
|
||||||
auto underlyingResult = innerConverter.Visit(type->desugar());
|
auto underlyingResult = innerConverter.Visit(underlyingType);
|
||||||
|
|
||||||
|
// If we used different bridgeability than this typedef normally
|
||||||
|
// would because we're in a non-bridgeable context, and therefore
|
||||||
|
// the underlying type is different from the mapping of the typedef,
|
||||||
|
// use the underlying type.
|
||||||
|
if (underlyingBridgeability != typedefBridgeability &&
|
||||||
|
!underlyingResult.AbstractType->isEqual(mappedType)) {
|
||||||
|
return underlyingResult;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
switch (underlyingResult.Hint) {
|
switch (underlyingResult.Hint) {
|
||||||
case ImportHint::Block:
|
case ImportHint::Block:
|
||||||
@@ -960,7 +980,7 @@ namespace {
|
|||||||
Type importedTypeArg = Impl.importType(typeArg,
|
Type importedTypeArg = Impl.importType(typeArg,
|
||||||
ImportTypeKind::BridgedValue,
|
ImportTypeKind::BridgedValue,
|
||||||
AllowNSUIntegerAsInt,
|
AllowNSUIntegerAsInt,
|
||||||
CanFullyBridgeTypes,
|
Bridging,
|
||||||
OTK_None);
|
OTK_None);
|
||||||
if (!importedTypeArg) {
|
if (!importedTypeArg) {
|
||||||
importedTypeArgs.clear();
|
importedTypeArgs.clear();
|
||||||
@@ -1146,7 +1166,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
ImportTypeKind importKind,
|
ImportTypeKind importKind,
|
||||||
ImportHint hint,
|
ImportHint hint,
|
||||||
bool allowNSUIntegerAsInt,
|
bool allowNSUIntegerAsInt,
|
||||||
bool canFullyBridgeTypes,
|
Bridgeability bridging,
|
||||||
OptionalTypeKind optKind,
|
OptionalTypeKind optKind,
|
||||||
bool resugarNSErrorPointer) {
|
bool resugarNSErrorPointer) {
|
||||||
if (importKind == ImportTypeKind::Abstract) {
|
if (importKind == ImportTypeKind::Abstract) {
|
||||||
@@ -1261,10 +1281,14 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
importedType = outParamTy;
|
importedType = outParamTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn block pointer types back into normal function types in any
|
// SwiftTypeConverter turns block pointers into @convention(block) types.
|
||||||
// context where bridging is possible, unless the block has a typedef.
|
// In a bridgeable context, or in the direct structure of a typedef,
|
||||||
|
// we would prefer to instead use the default Swift convention. But this
|
||||||
|
// does means that, when we're using a typedef of a block pointer type in
|
||||||
|
// an unbridgable context, we need to go back and do a fully-unbridged
|
||||||
|
// import of the underlying type.
|
||||||
if (hint == ImportHint::Block) {
|
if (hint == ImportHint::Block) {
|
||||||
if (!canFullyBridgeTypes) {
|
if (bridging == Bridgeability::None) {
|
||||||
if (auto typedefType = clangType->getAs<clang::TypedefType>()) {
|
if (auto typedefType = clangType->getAs<clang::TypedefType>()) {
|
||||||
// In non-bridged contexts, drop the typealias sugar for blocks.
|
// In non-bridged contexts, drop the typealias sugar for blocks.
|
||||||
// FIXME: This will do the wrong thing if there's any adjustment to do
|
// FIXME: This will do the wrong thing if there's any adjustment to do
|
||||||
@@ -1272,7 +1296,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
Type underlyingTy = impl.importType(typedefType->desugar(),
|
Type underlyingTy = impl.importType(typedefType->desugar(),
|
||||||
importKind,
|
importKind,
|
||||||
allowNSUIntegerAsInt,
|
allowNSUIntegerAsInt,
|
||||||
canFullyBridgeTypes,
|
bridging,
|
||||||
OTK_None);
|
OTK_None);
|
||||||
if (Type unwrappedTy = underlyingTy->getAnyOptionalObjectType())
|
if (Type unwrappedTy = underlyingTy->getAnyOptionalObjectType())
|
||||||
underlyingTy = unwrappedTy;
|
underlyingTy = unwrappedTy;
|
||||||
@@ -1281,7 +1305,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canBridgeTypes(importKind) || importKind == ImportTypeKind::Typedef) {
|
if (bridging == Bridgeability::Full) {
|
||||||
auto fTy = importedType->castTo<FunctionType>();
|
auto fTy = importedType->castTo<FunctionType>();
|
||||||
FunctionType::ExtInfo einfo = fTy->getExtInfo();
|
FunctionType::ExtInfo einfo = fTy->getExtInfo();
|
||||||
if (einfo.getRepresentation() != FunctionTypeRepresentation::Swift) {
|
if (einfo.getRepresentation() != FunctionTypeRepresentation::Swift) {
|
||||||
@@ -1294,7 +1318,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
// Turn BOOL and DarwinBoolean into Bool in contexts that can bridge types
|
// Turn BOOL and DarwinBoolean into Bool in contexts that can bridge types
|
||||||
// losslessly.
|
// losslessly.
|
||||||
if ((hint == ImportHint::BOOL || hint == ImportHint::Boolean) &&
|
if ((hint == ImportHint::BOOL || hint == ImportHint::Boolean) &&
|
||||||
canFullyBridgeTypes && canBridgeTypes(importKind)) {
|
bridging == Bridgeability::Full && canBridgeTypes(importKind)) {
|
||||||
return impl.SwiftContext.getBoolDecl()->getDeclaredType();
|
return impl.SwiftContext.getBoolDecl()->getDeclaredType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1323,7 +1347,9 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
|
|
||||||
// If we have a bridged Objective-C type and we are allowed to
|
// If we have a bridged Objective-C type and we are allowed to
|
||||||
// bridge, do so.
|
// bridge, do so.
|
||||||
if (hint == ImportHint::ObjCBridged && canBridgeTypes(importKind) &&
|
if (hint == ImportHint::ObjCBridged &&
|
||||||
|
bridging == Bridgeability::Full &&
|
||||||
|
canBridgeTypes(importKind) &&
|
||||||
importKind != ImportTypeKind::PropertyWithReferenceSemantics) {
|
importKind != ImportTypeKind::PropertyWithReferenceSemantics) {
|
||||||
// id and Any can be bridged without Foundation. There would be
|
// id and Any can be bridged without Foundation. There would be
|
||||||
// bootstrapping issues with the ObjectiveC module otherwise.
|
// bootstrapping issues with the ObjectiveC module otherwise.
|
||||||
@@ -1373,7 +1399,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
|
|||||||
Type ClangImporter::Implementation::importType(clang::QualType type,
|
Type ClangImporter::Implementation::importType(clang::QualType type,
|
||||||
ImportTypeKind importKind,
|
ImportTypeKind importKind,
|
||||||
bool allowNSUIntegerAsInt,
|
bool allowNSUIntegerAsInt,
|
||||||
bool canFullyBridgeTypes,
|
Bridgeability bridging,
|
||||||
OptionalTypeKind optionality,
|
OptionalTypeKind optionality,
|
||||||
bool resugarNSErrorPointer) {
|
bool resugarNSErrorPointer) {
|
||||||
if (type.isNull())
|
if (type.isNull())
|
||||||
@@ -1414,14 +1440,13 @@ Type ClangImporter::Implementation::importType(clang::QualType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform abstract conversion, ignoring how the type is actually used.
|
// Perform abstract conversion, ignoring how the type is actually used.
|
||||||
SwiftTypeConverter converter(*this, allowNSUIntegerAsInt,canFullyBridgeTypes);
|
SwiftTypeConverter converter(*this, allowNSUIntegerAsInt, bridging);
|
||||||
auto importResult = converter.Visit(type);
|
auto importResult = converter.Visit(type);
|
||||||
|
|
||||||
// Now fix up the type based on we're concretely using it.
|
// Now fix up the type based on we're concretely using it.
|
||||||
return adjustTypeForConcreteImport(*this, type, importResult.AbstractType,
|
return adjustTypeForConcreteImport(*this, type, importResult.AbstractType,
|
||||||
importKind, importResult.Hint,
|
importKind, importResult.Hint,
|
||||||
allowNSUIntegerAsInt,
|
allowNSUIntegerAsInt, bridging,
|
||||||
canFullyBridgeTypes,
|
|
||||||
optionality,
|
optionality,
|
||||||
resugarNSErrorPointer);
|
resugarNSErrorPointer);
|
||||||
}
|
}
|
||||||
@@ -1493,7 +1518,7 @@ Type ClangImporter::Implementation::importPropertyType(
|
|||||||
OptionalTypeKind optionality = OTK_ImplicitlyUnwrappedOptional;
|
OptionalTypeKind optionality = OTK_ImplicitlyUnwrappedOptional;
|
||||||
return importType(decl->getType(), importKind,
|
return importType(decl->getType(), importKind,
|
||||||
shouldAllowNSUIntegerAsInt(isFromSystemModule, decl),
|
shouldAllowNSUIntegerAsInt(isFromSystemModule, decl),
|
||||||
/*isFullyBridgeable*/ true, optionality);
|
Bridgeability::Full, optionality);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the @noescape attribute
|
/// Apply the @noescape attribute
|
||||||
@@ -1566,7 +1591,7 @@ Type ClangImporter::Implementation::importFunctionReturnType(
|
|||||||
(isAuditedResult ? ImportTypeKind::AuditedResult
|
(isAuditedResult ? ImportTypeKind::AuditedResult
|
||||||
: ImportTypeKind::Result),
|
: ImportTypeKind::Result),
|
||||||
allowNSUIntegerAsInt,
|
allowNSUIntegerAsInt,
|
||||||
/*isFullyBridgeable*/ true, OptionalityOfReturn);
|
Bridgeability::Full, OptionalityOfReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type ClangImporter::Implementation::
|
Type ClangImporter::Implementation::
|
||||||
@@ -1628,7 +1653,7 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
|
|||||||
// Import the parameter type into Swift.
|
// Import the parameter type into Swift.
|
||||||
Type swiftParamTy =
|
Type swiftParamTy =
|
||||||
importType(paramTy, importKind, allowNSUIntegerAsInt,
|
importType(paramTy, importKind, allowNSUIntegerAsInt,
|
||||||
/*isFullyBridgeable*/ true, OptionalityOfParam);
|
Bridgeability::Full, OptionalityOfParam);
|
||||||
if (!swiftParamTy)
|
if (!swiftParamTy)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -1919,7 +1944,7 @@ Type ClangImporter::Implementation::importMethodType(
|
|||||||
clang::QualType resultType = clangDecl->getReturnType();
|
clang::QualType resultType = clangDecl->getReturnType();
|
||||||
swiftResultTy = importType(resultType, resultKind,
|
swiftResultTy = importType(resultType, resultKind,
|
||||||
allowNSUIntegerAsIntInResult,
|
allowNSUIntegerAsIntInResult,
|
||||||
/*isFullyBridgeable*/true,
|
Bridgeability::Full,
|
||||||
OptionalityOfReturn);
|
OptionalityOfReturn);
|
||||||
// Adjust the result type for a throwing function.
|
// Adjust the result type for a throwing function.
|
||||||
if (swiftResultTy && errorInfo) {
|
if (swiftResultTy && errorInfo) {
|
||||||
@@ -1927,7 +1952,7 @@ Type ClangImporter::Implementation::importMethodType(
|
|||||||
// Get the original unbridged result type.
|
// Get the original unbridged result type.
|
||||||
origSwiftResultTy = importType(resultType, resultKind,
|
origSwiftResultTy = importType(resultType, resultKind,
|
||||||
allowNSUIntegerAsIntInResult,
|
allowNSUIntegerAsIntInResult,
|
||||||
/*isFullyBridgeable*/false,
|
Bridgeability::None,
|
||||||
OptionalityOfReturn)
|
OptionalityOfReturn)
|
||||||
->getCanonicalType();
|
->getCanonicalType();
|
||||||
|
|
||||||
@@ -2042,7 +2067,7 @@ Type ClangImporter::Implementation::importMethodType(
|
|||||||
// being lazier.)
|
// being lazier.)
|
||||||
swiftParamTy = importType(paramTy, importKind,
|
swiftParamTy = importType(paramTy, importKind,
|
||||||
allowNSUIntegerAsIntInParam,
|
allowNSUIntegerAsIntInParam,
|
||||||
/*isFullyBridgeable*/true,
|
Bridgeability::Full,
|
||||||
optionalityOfParam,
|
optionalityOfParam,
|
||||||
/*resugarNSErrorPointer=*/!paramIsError);
|
/*resugarNSErrorPointer=*/!paramIsError);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,6 +181,22 @@ enum class ImportTypeKind {
|
|||||||
Enum
|
Enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Bridgeability {
|
||||||
|
/// This context does not permit bridging at all. For example, the
|
||||||
|
/// target of a C pointer.
|
||||||
|
None,
|
||||||
|
|
||||||
|
/// This context permits all kinds of bridging. For example, the
|
||||||
|
/// imported result of a method declaration.
|
||||||
|
Full
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline Bridgeability getTypedefBridgeability(clang::QualType type) {
|
||||||
|
return (type->isBlockPointerType() || type->isFunctionType())
|
||||||
|
? Bridgeability::Full
|
||||||
|
: Bridgeability::None;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Describes the kind of the C type that can be mapped to a stdlib
|
/// \brief Describes the kind of the C type that can be mapped to a stdlib
|
||||||
/// swift type.
|
/// swift type.
|
||||||
enum class MappedCTypeKind {
|
enum class MappedCTypeKind {
|
||||||
@@ -893,16 +909,17 @@ public:
|
|||||||
/// \param allowNSUIntegerAsInt If true, NSUInteger will be imported as Int
|
/// \param allowNSUIntegerAsInt If true, NSUInteger will be imported as Int
|
||||||
/// in certain contexts. If false, it will always be imported as UInt.
|
/// in certain contexts. If false, it will always be imported as UInt.
|
||||||
///
|
///
|
||||||
/// \param canFullyBridgeTypes True if we can bridge types losslessly.
|
/// \param bridgeability Whether we can bridge types in this context.
|
||||||
/// This is an additional guarantee on top of the ImportTypeKind
|
/// This may restrict the ability to bridge types even in contexts
|
||||||
/// cases that allow bridging, and applies to the entire type.
|
/// that otherwise allow bridging, such as function results and
|
||||||
|
/// parameters.
|
||||||
///
|
///
|
||||||
/// \returns The imported type, or null if this type could
|
/// \returns The imported type, or null if this type could
|
||||||
/// not be represented in Swift.
|
/// not be represented in Swift.
|
||||||
Type importType(clang::QualType type,
|
Type importType(clang::QualType type,
|
||||||
ImportTypeKind kind,
|
ImportTypeKind kind,
|
||||||
bool allowNSUIntegerAsInt,
|
bool allowNSUIntegerAsInt,
|
||||||
bool canFullyBridgeTypes,
|
Bridgeability bridgeability,
|
||||||
OptionalTypeKind optional = OTK_ImplicitlyUnwrappedOptional,
|
OptionalTypeKind optional = OTK_ImplicitlyUnwrappedOptional,
|
||||||
bool resugarNSErrorPointer = true);
|
bool resugarNSErrorPointer = true);
|
||||||
|
|
||||||
|
|||||||
@@ -24,3 +24,10 @@ idLover.takesArray(ofId: &y) // expected-error{{argument type 'Any' does not con
|
|||||||
|
|
||||||
idLover.takesId(x)
|
idLover.takesId(x)
|
||||||
idLover.takesId(y)
|
idLover.takesId(y)
|
||||||
|
|
||||||
|
install_global_event_handler(idLover) // expected-error {{cannot convert value of type 'NSIdLover' to expected argument type 'event_handler?' (aka 'Optional<@convention(c) (AnyObject) -> ()>')}}
|
||||||
|
|
||||||
|
// FIXME: this should not type-check!
|
||||||
|
// Function conversions are not legal when converting to a thin function type.
|
||||||
|
let handler: @convention(c) (Any) -> () = { object in () }
|
||||||
|
install_global_event_handler(handler)
|
||||||
|
|||||||
@@ -40,9 +40,13 @@ ObjCBoolBlock testObjCBoolFnToBlockTypedef(ObjCBoolFn);
|
|||||||
DarwinBooleanBlock testDarwinBooleanFnToBlockTypedef(DarwinBooleanFn);
|
DarwinBooleanBlock testDarwinBooleanFnToBlockTypedef(DarwinBooleanFn);
|
||||||
|
|
||||||
typedef __typeof(testCBoolFnToBlockTypedef) CBoolFnToBlockType;
|
typedef __typeof(testCBoolFnToBlockTypedef) CBoolFnToBlockType;
|
||||||
typedef __typeof(testObjCBoolFnToBlockTypedef) ObjCCBoolFnToBlockType;
|
typedef __typeof(testObjCBoolFnToBlockTypedef) ObjCBoolFnToBlockType;
|
||||||
typedef __typeof(testDarwinBooleanFnToBlockTypedef) DarwinBooleanFnToBlockType;
|
typedef __typeof(testDarwinBooleanFnToBlockTypedef) DarwinBooleanFnToBlockType;
|
||||||
|
|
||||||
|
extern ObjCBoolFnToBlockType *globalObjCBoolFnToBlockFP;
|
||||||
|
extern ObjCBoolFnToBlockType * __nonnull * __nullable globalObjCBoolFnToBlockFPP;
|
||||||
|
extern ObjCBoolFnToBlockType ^globalObjCBoolFnToBlockBP;
|
||||||
|
|
||||||
extern CBoolFn globalCBoolFn;
|
extern CBoolFn globalCBoolFn;
|
||||||
extern ObjCBoolFn globalObjCBoolFn;
|
extern ObjCBoolFn globalObjCBoolFn;
|
||||||
extern DarwinBooleanFn globalDarwinBooleanFn;
|
extern DarwinBooleanFn globalDarwinBooleanFn;
|
||||||
|
|||||||
@@ -43,8 +43,12 @@ func testObjCBoolFnToBlockTypedef(_: @escaping ObjCBoolFn) -> ObjCBoolBlock
|
|||||||
func testDarwinBooleanFnToBlockTypedef(_: @escaping DarwinBooleanFn) -> DarwinBooleanBlock
|
func testDarwinBooleanFnToBlockTypedef(_: @escaping DarwinBooleanFn) -> DarwinBooleanBlock
|
||||||
|
|
||||||
typealias CBoolFnToBlockType = (CBoolFn) -> CBoolBlock
|
typealias CBoolFnToBlockType = (CBoolFn) -> CBoolBlock
|
||||||
typealias ObjCCBoolFnToBlockType = (ObjCBoolFn) -> (ObjCBool) -> ObjCBool
|
typealias ObjCBoolFnToBlockType = (ObjCBoolFn) -> ObjCBoolBlock
|
||||||
typealias DarwinBooleanFnToBlockType = (DarwinBooleanFn) -> (DarwinBoolean) -> DarwinBoolean
|
typealias DarwinBooleanFnToBlockType = (DarwinBooleanFn) -> DarwinBooleanBlock
|
||||||
|
|
||||||
|
var globalObjCBoolFnToBlockFP: @convention(c) (ObjCBoolFn) -> @convention(block) (ObjCBool) -> ObjCBool
|
||||||
|
var globalObjCBoolFnToBlockFPP: UnsafeMutablePointer<@convention(c) (ObjCBoolFn) -> @convention(block) (ObjCBool) -> ObjCBool>?
|
||||||
|
var globalObjCBoolFnToBlockBP: @convention(block) (ObjCBoolFn) -> @convention(block) (ObjCBool) -> ObjCBool
|
||||||
|
|
||||||
var globalCBoolFn: CBoolFn
|
var globalCBoolFn: CBoolFn
|
||||||
var globalObjCBoolFn: ObjCBoolFn
|
var globalObjCBoolFn: ObjCBoolFn
|
||||||
|
|||||||
@@ -143,7 +143,7 @@
|
|||||||
// CHECK-FOUNDATION: func doSomethingElse(with: NSCopying & NSObjectProtocol)
|
// CHECK-FOUNDATION: func doSomethingElse(with: NSCopying & NSObjectProtocol)
|
||||||
|
|
||||||
// Note: Function type -> "Function".
|
// Note: Function type -> "Function".
|
||||||
// CHECK-FOUNDATION: func sort(_: @escaping @convention(c) (Any, Any) -> Int)
|
// CHECK-FOUNDATION: func sort(_: @escaping @convention(c) (AnyObject, AnyObject) -> Int)
|
||||||
|
|
||||||
// Note: Plural: NSArray without type arguments -> "Objects".
|
// Note: Plural: NSArray without type arguments -> "Objects".
|
||||||
// CHECK-FOUNDATION: func remove(_: [Any])
|
// CHECK-FOUNDATION: func remove(_: [Any])
|
||||||
|
|||||||
@@ -1110,3 +1110,6 @@ typedef enum __attribute__((ns_error_domain(NSLaundryErrorDomain))) __attribute_
|
|||||||
NSLaundryErrorTooMuchSoap = 1,
|
NSLaundryErrorTooMuchSoap = 1,
|
||||||
NSLaundryErrorCatInWasher = 2
|
NSLaundryErrorCatInWasher = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*event_handler)(__nonnull id);
|
||||||
|
void install_global_event_handler(__nullable event_handler handler);
|
||||||
|
|||||||
Reference in New Issue
Block a user