Skip to content

Commit 3887db1

Browse files
authored
Merge pull request #8998 from jrose-apple/4.0-enums-using-attributes
2 parents 54a3d41 + 5e66ed0 commit 3887db1

File tree

11 files changed

+95
-15
lines changed

11 files changed

+95
-15
lines changed

lib/ClangImporter/ImportEnumInfo.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,32 @@ void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl,
5050
nsErrorDomain = ctx.AllocateCopy(domainAttr->getErrorDomain()->getName());
5151
return;
5252
}
53+
if (decl->hasAttr<clang::FlagEnumAttr>()) {
54+
kind = EnumKind::Options;
55+
return;
56+
}
57+
if (decl->hasAttr<clang::EnumExtensibilityAttr>()) {
58+
// FIXME: Distinguish between open and closed enums.
59+
kind = EnumKind::Enum;
60+
return;
61+
}
62+
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+
}
5374

5475
// Was the enum declared using *_ENUM or *_OPTIONS?
55-
// FIXME: Use Clang attributes instead of groveling the macro expansion loc.
76+
// FIXME: Stop using these once flag_enum and enum_extensibility
77+
// have been adopted everywhere, or at least relegate them to Swift 3 mode
78+
// only.
5679
auto loc = decl->getLocStart();
5780
if (loc.isMacroID()) {
5881
StringRef MacroName = pp.getImmediateMacroName(loc);

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,15 +2451,25 @@ class ModuleWriter {
24512451
"# define OBJC_DESIGNATED_INITIALIZER\n"
24522452
"# endif\n"
24532453
"#endif\n"
2454+
"#if !defined(SWIFT_ENUM_ATTR)\n"
2455+
"# if defined(__has_attribute) && "
2456+
"__has_attribute(enum_extensibility)\n"
2457+
"# define SWIFT_ENUM_ATTR "
2458+
"__attribute__((enum_extensibility(open)))\n"
2459+
"# else\n"
2460+
"# define SWIFT_ENUM_ATTR\n"
2461+
"# endif\n"
2462+
"#endif\n"
24542463
"#if !defined(SWIFT_ENUM)\n"
24552464
"# define SWIFT_ENUM(_type, _name) "
24562465
"enum _name : _type _name; "
2457-
"enum SWIFT_ENUM_EXTRA _name : _type\n"
2466+
"enum SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type\n"
24582467
"# if defined(__has_feature) && "
24592468
"__has_feature(generalized_swift_name)\n"
24602469
"# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) "
24612470
"enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); "
2462-
"enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type\n"
2471+
"enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR "
2472+
"SWIFT_ENUM_EXTRA _name : _type\n"
24632473
"# else\n"
24642474
"# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) "
24652475
"SWIFT_ENUM(_type, _name)\n"

test/ClangImporter/Inputs/custom-modules/SwiftName.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define SWIFT_NAME(X) __attribute__((swift_name(#X)))
22

3-
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
3+
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum __attribute__((enum_extensibility(open))) _name : _type
44

55
void drawString(const char *, int x, int y) SWIFT_NAME(drawString(_:x:y:));
66

test/ClangImporter/Inputs/enum-objc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import Foundation;
22

33
#define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
4-
#define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type
4+
#define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) __attribute__((enum_extensibility(open))) SWIFT_ENUM_EXTRA _name : _type
55

66
typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnum, "SwiftEnum") {
77
ObjCEnumOne = 1,

test/ClangImporter/enum.swift

Lines changed: 13 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
@@ -148,6 +149,9 @@ var qualifiedName = NSRuncingMode.mince
148149
var topLevelCaseName = RuncingMince // expected-error{{}}
149150
#endif
150151

152+
let _: EnumViaAttribute = .first
153+
let _: CFEnumWithAttr = .first
154+
151155
// NS_OPTIONS
152156
var withMince: NSRuncingOptions = .enableMince
153157
var withQuince: NSRuncingOptions = .enableQuince
@@ -193,6 +197,8 @@ let audioComponentFlags2: FakeAudioComponentFlags = [.loadOutOfProcess]
193197
let objcFlags: objc_flags = [.taggedPointer, .swiftRefcount]
194198

195199
let optionsWithSwiftName: NSOptionsAlsoGetSwiftName = .Case
200+
let optionsViaAttribute: OptionsViaAttribute = [.first, .second]
201+
let optionsViaAttribute2: CFOptionsWithAttr = [.first]
196202

197203
// <rdar://problem/25168818> Don't import None members in NS_OPTIONS types
198204
#if !IRGEN
@@ -208,3 +214,10 @@ _ = EmptySet3.None
208214
// Just use this type, making sure that its case alias doesn't cause problems.
209215
// rdar://problem/30401506
210216
_ = 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

test/IDE/Inputs/print_clang_header_swift_name.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,23 @@
22

33
#define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
44

5-
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
5+
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum __attribute__((enum_extensibility(open))) SWIFT_ENUM_EXTRA _name : _type
66

77
typedef SWIFT_ENUM(NSInteger, Normal) {
88
NormalOne = 0,
99
NormalTwo,
1010
NormalThree
1111
};
1212

13-
// FIXME (#618): Use SWIFT_ENUM_NAMED() when support for that lands
14-
#undef SWIFT_ENUM
15-
#define SWIFT_ENUM(_type, _name) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_ENUM_NAME); enum SWIFT_COMPILE_NAME(SWIFT_ENUM_NAME) SWIFT_ENUM_EXTRA _name : _type
13+
#define SWIFT_ENUM_NAMED(_type, _name, _swiftName) enum _name : _type _name SWIFT_COMPILE_NAME(_swiftName); enum SWIFT_COMPILE_NAME(_swiftName) __attribute__((enum_extensibility(open))) SWIFT_ENUM_EXTRA _name : _type
1614

17-
#define SWIFT_ENUM_NAME "SwiftEnum"
18-
typedef SWIFT_ENUM(NSInteger, ObjCEnum) {
15+
typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnum, "SwiftEnum") {
1916
ObjCEnumOne = 0,
2017
ObjCEnumTwo,
2118
ObjCEnumThree
2219
};
2320

24-
#undef SWIFT_ENUM_NAME
25-
#define SWIFT_ENUM_NAME "SwiftEnumTwo"
26-
typedef SWIFT_ENUM(NSInteger, ObjCEnumTwo) {
21+
typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnumTwo, "SwiftEnumTwo") {
2722
// the following shouldn't have their prefixes stripped
2823
SwiftEnumTwoA,
2924
SwiftEnumTwoB,

test/IDE/Inputs/swift_name.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#ifndef SWIFT_ENUM
88
# define SWIFT_ENUM(_type, _name) \
99
enum _name : _type _name; \
10-
enum SWIFT_ENUM_EXTRA _name : _type
10+
enum __attribute__((enum_extensibility(open))) SWIFT_ENUM_EXTRA _name : _type
1111
#endif
1212

1313
// Renaming global variables.
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 *

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ typedef NS_ENUM(NSInteger, EnumWithAwkwardDeprecations) {
2929
EnumWithAwkward2BitProblems __attribute__((deprecated)) = EnumWithAwkwardNormalCase1,
3030
};
3131

32+
enum __attribute__((enum_extensibility(open))) EnumViaAttribute {
33+
EnumViaAttributeFirst = 1,
34+
EnumViaAttributeSecond = 2
35+
};
36+
37+
3238
// From <AudioUnit/AudioComponent.h>
3339
// The interesting feature of this enum is that the common prefix before
3440
// taking the enum name itself into account extends past the underscore.
@@ -68,3 +74,8 @@ typedef CF_OPTIONS(UInt32, EmptySet2) {
6874
typedef CF_OPTIONS(UInt32, EmptySet3) {
6975
kEmptySet3None __attribute__((swift_name("None")))
7076
};
77+
78+
enum __attribute__((flag_enum)) OptionsViaAttribute {
79+
OptionsViaAttributeFirst = 1,
80+
OptionsViaAttributeSecond = 2
81+
};

0 commit comments

Comments
 (0)