Skip to content

[cxx-interop] Apply typedef -> enum patch to method param types as well. #42452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<clang::TypedefType>(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<NominalTypeDecl>(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) {
Expand Down Expand Up @@ -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<clang::TypedefType>(paramTy.getTypePtr())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this and the previous addition be merged into one function or lambda?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I will do it in a follow-up nfc.

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<NominalTypeDecl>(swiftEnum)->getDeclaredType();
}
}
}
}

if (kind == SpecialMethodKind::NSDictionarySubscriptGetter &&
paramTy->isObjCIdType()) {
// Not using `getImportTypeAttrs()` is unprincipled but OK for this hack.
Expand All @@ -2859,7 +2891,7 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
swiftParamTy = OptionalType::get(swiftParamTy);

paramIsIUO = optionalityOfParam == OTK_ImplicitlyUnwrappedOptional;
} else {
} else if (!swiftParamTy) {
if (param->hasAttr<clang::CFReturnsRetainedAttr>())
importKind = ImportTypeKind::CFRetainedOutParameter;
else if (param->hasAttr<clang::CFReturnsNotRetainedAttr>())
Expand Down
7 changes: 7 additions & 0 deletions test/Interop/Cxx/enum/Inputs/anonymous-with-swift-name.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect you will have to update these now that #42412 is merged.

// 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: }