From 2c983d968e361fbeddeaf9003316c3a6b4fb2ba4 Mon Sep 17 00:00:00 2001 From: zoecarver Date: Tue, 19 Apr 2022 12:03:12 -0700 Subject: [PATCH] [cxx-interop] Apply typedef -> enum patch to method param types as well. Basically just applying https://github.com/apple/swift/pull/42431 to ObjC method param tyeps. --- lib/ClangImporter/ImportType.cpp | 44 ++++++++++++++++--- .../enum/Inputs/anonymous-with-swift-name.h | 7 +++ ...ith-swift-name-objc-module-interface.swift | 18 ++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 test/Interop/Cxx/enum/anonymous-with-swift-name-objc-module-interface.swift diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 3fabe1b7057d3..1f368e4a454cd 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -2734,10 +2734,28 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType( ImportDiagnosticAdder addImportDiag(*this, clangDecl, clangDecl->getLocation()); clang::QualType resultType = clangDecl->getReturnType(); - auto importedType = - importType(resultType, resultKind, addImportDiag, - allowNSUIntegerAsIntInResult, Bridgeability::Full, - getImportTypeAttrs(clangDecl), OptionalityOfReturn); + + + ImportedType importedType; + if (auto typedefType = dyn_cast(resultType.getTypePtr())) { + if (isUnavailableInSwift(typedefType->getDecl())) { + if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) { + // If this fails, it means that we need a stronger predicate for + // determining the relationship between an enum and typedef. + assert(clangEnum.getValue()->getIntegerType()->getCanonicalTypeInternal() == + typedefType->getCanonicalTypeInternal()); + if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) { + importedType = {cast(swiftEnum)->getDeclaredType(), false}; + } + } + } + } + + if (!importedType) + importedType = importType(resultType, resultKind, addImportDiag, + allowNSUIntegerAsIntInResult, Bridgeability::Full, + getImportTypeAttrs(clangDecl), + OptionalityOfReturn); // Adjust the result type for a throwing function. if (importedType.getType() && errorInfo) { @@ -2847,7 +2865,21 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType( ImportTypeKind importKind = ImportTypeKind::Parameter; ImportDiagnosticAdder paramAddDiag(*this, clangDecl, param->getLocation()); Type swiftParamTy; - bool paramIsIUO; + bool paramIsIUO = false; + if (auto typedefType = dyn_cast(paramTy.getTypePtr())) { + if (isUnavailableInSwift(typedefType->getDecl())) { + if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) { + // If this fails, it means that we need a stronger predicate for + // determining the relationship between an enum and typedef. + assert(clangEnum.getValue()->getIntegerType()->getCanonicalTypeInternal() == + typedefType->getCanonicalTypeInternal()); + if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) { + swiftParamTy = cast(swiftEnum)->getDeclaredType(); + } + } + } + } + if (kind == SpecialMethodKind::NSDictionarySubscriptGetter && paramTy->isObjCIdType()) { // Not using `getImportTypeAttrs()` is unprincipled but OK for this hack. @@ -2859,7 +2891,7 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType( swiftParamTy = OptionalType::get(swiftParamTy); paramIsIUO = optionalityOfParam == OTK_ImplicitlyUnwrappedOptional; - } else { + } else if (!swiftParamTy) { if (param->hasAttr()) importKind = ImportTypeKind::CFRetainedOutParameter; else if (param->hasAttr()) diff --git a/test/Interop/Cxx/enum/Inputs/anonymous-with-swift-name.h b/test/Interop/Cxx/enum/Inputs/anonymous-with-swift-name.h index e153219610421..b7c9744723ff4 100644 --- a/test/Interop/Cxx/enum/Inputs/anonymous-with-swift-name.h +++ b/test/Interop/Cxx/enum/Inputs/anonymous-with-swift-name.h @@ -22,4 +22,11 @@ typedef CF_OPTIONS(unsigned, CFColorMask) { inline SOColorMask useSOColorMask(SOColorMask mask) { return mask; } inline CFColorMask useCFColorMask(CFColorMask mask) { return mask; } +#if __OBJC__ +@interface ColorMaker +- (void)makeColorWithOptions:(SOColorMask)opts; +- (void)makeOtherColorWithInt:(int) x withOptions:(CFColorMask)opts; +@end +#endif // SWIFT_OBJC_INTEROP + #endif // TEST_INTEROP_CXX_ENUM_INPUTS_ANONYMOUS_WITH_SWIFT_NAME_H \ No newline at end of file diff --git a/test/Interop/Cxx/enum/anonymous-with-swift-name-objc-module-interface.swift b/test/Interop/Cxx/enum/anonymous-with-swift-name-objc-module-interface.swift new file mode 100644 index 0000000000000..79a0f0ba2a69c --- /dev/null +++ b/test/Interop/Cxx/enum/anonymous-with-swift-name-objc-module-interface.swift @@ -0,0 +1,18 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=AnonymousWithSwiftName -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s +// +// REQUIRES: objc_interop + +// CHECK: class ColorMaker { +// CHECK: class func makeColor(withOptions opts: SOColorMask) +// CHECK: func makeColor(withOptions opts: SOColorMask) +// CHECK: @available(swift, obsoleted: 3, renamed: "makeColor(withOptions:)") +// CHECK: class func makeColorWithOptions(_ opts: SOColorMask) +// CHECK: @available(swift, obsoleted: 3, renamed: "makeColor(withOptions:)") +// CHECK: func makeColorWithOptions(_ opts: SOColorMask) +// CHECK: class func makeOtherColor(with x: Int32, withOptions opts: CFColorMask) +// CHECK: func makeOtherColor(with x: Int32, withOptions opts: CFColorMask) +// CHECK: @available(swift, obsoleted: 3, renamed: "makeOtherColor(with:withOptions:)") +// CHECK: class func makeOtherColorWithInt(_ x: Int32, withOptions opts: CFColorMask) +// CHECK: @available(swift, obsoleted: 3, renamed: "makeOtherColor(with:withOptions:)") +// CHECK: func makeOtherColorWithInt(_ x: Int32, withOptions opts: CFColorMask) +// CHECK: }