Skip to content

Commit 6f7925c

Browse files
authored
[ClangImporter] If enum_extensibility was removed, it's not an enum. (#8992)
(and similar for flag_enum) This commit prepares the importer for a world in which NS_ENUM and NS_OPTIONS have adopted the new Clang attributes 'enum_extensibility' and 'flag_enum', but API notes are used to reverse the effect. Without this there would be no transition path for adopting the standard Cocoa macros, which have applied unconditionally up to now. rdar://problem/18744821
1 parent 13abb9a commit 6f7925c

File tree

5 files changed

+50
-0
lines changed

5 files changed

+50
-0
lines changed

lib/ClangImporter/ImportEnumInfo.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl,
6060
return;
6161
}
6262

63+
// If API notes have /removed/ a FlagEnum or EnumExtensibility attribute,
64+
// then we don't need to check the macros.
65+
for (auto *attr : decl->specific_attrs<clang::SwiftVersionedAttr>()) {
66+
if (!attr->getVersion().empty())
67+
continue;
68+
if (isa<clang::FlagEnumAttr>(attr->getAttrToAdd()) ||
69+
isa<clang::EnumExtensibilityAttr>(attr->getAttrToAdd())) {
70+
kind = EnumKind::Unknown;
71+
return;
72+
}
73+
}
74+
6375
// Was the enum declared using *_ENUM or *_OPTIONS?
6476
// FIXME: Stop using these once flag_enum and enum_extensibility
6577
// have been adopted everywhere, or at least relegate them to Swift 3 mode

test/ClangImporter/enum.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import Foundation
1313
import user_objc
14+
import enums_using_attributes
1415

1516
// NS_ENUM
1617
var mince = NSRuncingMode.mince
@@ -149,6 +150,7 @@ var topLevelCaseName = RuncingMince // expected-error{{}}
149150
#endif
150151

151152
let _: EnumViaAttribute = .first
153+
let _: CFEnumWithAttr = .first
152154

153155
// NS_OPTIONS
154156
var withMince: NSRuncingOptions = .enableMince
@@ -196,6 +198,7 @@ let objcFlags: objc_flags = [.taggedPointer, .swiftRefcount]
196198

197199
let optionsWithSwiftName: NSOptionsAlsoGetSwiftName = .Case
198200
let optionsViaAttribute: OptionsViaAttribute = [.first, .second]
201+
let optionsViaAttribute2: CFOptionsWithAttr = [.first]
199202

200203
// <rdar://problem/25168818> Don't import None members in NS_OPTIONS types
201204
#if !IRGEN
@@ -211,3 +214,10 @@ _ = EmptySet3.None
211214
// Just use this type, making sure that its case alias doesn't cause problems.
212215
// rdar://problem/30401506
213216
_ = EnumWithAwkwardDeprecations.normalCase1
217+
218+
#if !IRGEN
219+
let _: UnknownEnumThanksToAPINotes = .first // expected-error {{has no member 'first'}}
220+
let _: UnknownOptionsThanksToAPINotes = .first // expected-error {{has no member 'first'}}
221+
#endif
222+
let _ = UnknownEnumThanksToAPINotesFirst
223+
let _ = UnknownOptionsThanksToAPINotesFirst
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Name: enums_using_attributes
2+
Tags:
3+
- Name: UnknownEnumThanksToAPINotes
4+
EnumKind: none
5+
- Name: UnknownOptionsThanksToAPINotes
6+
EnumKind: none
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#define CF_ENUM(_type, _name) enum _name : _type _name; \
2+
enum __attribute__((enum_extensibility(open))) _name : _type
3+
#define CF_OPTIONS(_type, _name) enum _name : _type _name; \
4+
enum __attribute__((enum_extensibility(open), flag_enum)) _name : _type
5+
6+
typedef CF_ENUM(int, CFEnumWithAttr) {
7+
CFEnumWithAttrFirst = 1,
8+
};
9+
typedef CF_ENUM(int, UnknownEnumThanksToAPINotes) {
10+
UnknownEnumThanksToAPINotesFirst = 1,
11+
};
12+
13+
typedef CF_OPTIONS(int, CFOptionsWithAttr) {
14+
CFOptionsWithAttrFirst = 1,
15+
};
16+
typedef CF_OPTIONS(int, UnknownOptionsThanksToAPINotes) {
17+
UnknownOptionsThanksToAPINotesFirst = 1,
18+
};

test/Inputs/clang-importer-sdk/usr/include/module.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ module objc_structs {
9898
export *
9999
}
100100

101+
module enums_using_attributes {
102+
header "enums_using_attributes.h"
103+
}
104+
101105
module errors {
102106
header "errors.h"
103107
export *

0 commit comments

Comments
 (0)