Skip to content

Commit 239b5e0

Browse files
committed
[ClangImporter] Import NS_OPTIONS 0 values with explicit Swift-names.
This shows that the owner of the option set has thought about the zero case, and wants it to be available in Swift, rather than disabling it with the default "use [] to construct an empty option set" message. rdar://problem/26290766
1 parent ad6de9b commit 239b5e0

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,7 +2066,8 @@ namespace {
20662066
const clang::EnumDecl *clangEnum,
20672067
NominalTypeDecl *theStruct) {
20682068
Optional<ImportedName> swift3Name;
2069-
auto name = importFullName(decl, swift3Name).Imported.getBaseName();
2069+
ImportedName nameInfo = importFullName(decl, swift3Name);
2070+
Identifier name = nameInfo.Imported.getBaseName();
20702071
if (name.empty())
20712072
return nullptr;
20722073

@@ -2083,7 +2084,8 @@ namespace {
20832084
// NS_OPTIONS members that have a value of 0 (typically named "None") do
20842085
// not operate as a set-like member. Mark them unavailable with a message
20852086
// that says that they should be used as [].
2086-
if (!decl->getInitVal() && !CD->getAttrs().hasAttribute<AvailableAttr>()){
2087+
if (decl->getInitVal() == 0 && !nameInfo.HasCustomName &&
2088+
!CD->getAttrs().isUnavailable(Impl.SwiftContext)) {
20872089
/// Create an AvailableAttr that indicates specific availability
20882090
/// for all platforms.
20892091
auto attr =

test/ClangModules/enum.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,14 @@ let audioComponentFlags2: FakeAudioComponentFlags = [.loadOutOfProcess]
179179
let objcFlags: objc_flags = [.taggedPointer, .swiftRefcount]
180180

181181
let optionsWithSwiftName: NSOptionsAlsoGetSwiftName = .Case
182+
183+
// <rdar://problem/25168818> Don't import None members in NS_OPTIONS types
184+
#if !IRGEN
185+
let _ = NSRuncingOptions.none // expected-error {{'none' is unavailable: use [] to construct an empty option set}}
186+
#endif
187+
// ...but do if they have a custom name
188+
_ = EmptySet1.default
189+
// ...even if the custom name is the same as the name they would have had
190+
_ = EmptySet2.none
191+
// ...or the original name.
192+
_ = EmptySet3.None

test/ClangModules/objc_parse.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,3 @@ func testNSUInteger(_ obj: NSUIntegerTests, uint: UInt, int: Int) {
598598
let _: String = num.uintValue // expected-error {{cannot convert value of type 'UInt' to specified type 'String'}}
599599
}
600600

601-
602-
// <rdar://problem/25168818> Don't import None members in NS_OPTIONS types
603-
let _ = NSRuncingOptions.none // expected-error {{'none' is unavailable: use [] to construct an empty option set}}
604-

test/Inputs/clang-importer-sdk/usr/include/user_objc.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,13 @@ typedef CF_ENUM(UInt32, AU3DMixerAttenuationCurve) {
5252
k3DMixerAttenuationCurve_Inverse = 2,
5353
k3DMixerAttenuationCurve_Linear = 3
5454
};
55+
56+
typedef CF_OPTIONS(UInt32, EmptySet1) {
57+
kEmptySet1DefaultOptions __attribute__((swift_name("default")))
58+
};
59+
typedef CF_OPTIONS(UInt32, EmptySet2) {
60+
kEmptySet2None __attribute__((swift_name("none")))
61+
};
62+
typedef CF_OPTIONS(UInt32, EmptySet3) {
63+
kEmptySet3None __attribute__((swift_name("None")))
64+
};

0 commit comments

Comments
 (0)