diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index e2fb485cb2e66..d2f8ab4abca6d 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -2431,6 +2431,19 @@ DefaultArgumentKind ClangImporter::Implementation::inferDefaultArgument( return DefaultArgumentKind::EmptyArray; } } + } else if (const clang::TypedefType *typedefType = + type->getAs()) { + // Get the AvailabilityAttr that would be set from CF/NS_OPTIONS + if (importer::isUnavailableInSwift(typedefType->getDecl(), nullptr, true)) { + // If we've taken this branch it means we have an enum type, and it is + // likely an integer or NSInteger that is being used by NS/CF_OPTIONS to + // behave like a C enum in the presence of C++. + auto enumName = typedefType->getDecl()->getDeclName().getAsString(); + for (auto word : llvm::reverse(camel_case::getWords(enumName))) { + if (camel_case::sameWordIgnoreFirstCase(word, "options")) + return DefaultArgumentKind::EmptyArray; + } + } } // NSDictionary arguments default to [:] (or nil, if nullable) if "options", diff --git a/test/Interop/Cxx/enum/Inputs/c-enums-withOptions-omit.h b/test/Interop/Cxx/enum/Inputs/c-enums-withOptions-omit.h new file mode 100644 index 0000000000000..8e390a01e14c0 --- /dev/null +++ b/test/Interop/Cxx/enum/Inputs/c-enums-withOptions-omit.h @@ -0,0 +1,8 @@ +// Enum usage that is bitwise-able and assignable in C++, aka how CF_OPTIONS +// does things. +typedef int __attribute__((availability(swift, unavailable))) NSEnumerationOptions; +enum : NSEnumerationOptions { NSEnumerationConcurrent, NSEnumerationReverse }; + +@interface NSSet +- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts ; +@end diff --git a/test/Interop/Cxx/enum/Inputs/module.modulemap b/test/Interop/Cxx/enum/Inputs/module.modulemap index 54df6e9327807..5bbdebe622303 100644 --- a/test/Interop/Cxx/enum/Inputs/module.modulemap +++ b/test/Interop/Cxx/enum/Inputs/module.modulemap @@ -12,3 +12,8 @@ module AnonymousWithSwiftName { header "anonymous-with-swift-name.h" requires cplusplus } + +module CenumsWithOptionsOmit { + header "c-enums-withOptions-omit.h" + requires cplusplus +} diff --git a/test/Interop/Cxx/enum/c-enums-withOptions-omit.swift b/test/Interop/Cxx/enum/c-enums-withOptions-omit.swift new file mode 100644 index 0000000000000..a28385ead2baf --- /dev/null +++ b/test/Interop/Cxx/enum/c-enums-withOptions-omit.swift @@ -0,0 +1,9 @@ +// RUN: %target-swift-ide-test -print-module -module-to-print=CenumsWithOptionsOmit -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s +// REQUIRES: objc_interop + +import CenumsWithOptionsOmit + +// CHECK: class NSSet { +// CHECK-NEXT: class func enumerateObjects(options +// CHECK-NEXT: func enumerateObjects(options +// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "enumerateObjects(options:)")