Skip to content

[ClangImporter] Classify enums using flag_enum and enum_extensibility #8910

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
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
13 changes: 12 additions & 1 deletion lib/ClangImporter/ImportEnumInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,20 @@ void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl,
nsErrorDomain = ctx.AllocateCopy(domainAttr->getErrorDomain()->getName());
return;
}
if (decl->hasAttr<clang::FlagEnumAttr>()) {
kind = EnumKind::Options;
return;
}
if (decl->hasAttr<clang::EnumExtensibilityAttr>()) {
// FIXME: Distinguish between open and closed enums.
kind = EnumKind::Enum;
return;
}

// Was the enum declared using *_ENUM or *_OPTIONS?
// FIXME: Use Clang attributes instead of groveling the macro expansion loc.
// FIXME: Stop using these once flag_enum and enum_extensibility
// have been adopted everywhere, or at least relegate them to Swift 3 mode
// only.
auto loc = decl->getLocStart();
if (loc.isMacroID()) {
StringRef MacroName = pp.getImmediateMacroName(loc);
Expand Down
14 changes: 12 additions & 2 deletions lib/PrintAsObjC/PrintAsObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2451,15 +2451,25 @@ class ModuleWriter {
"# define OBJC_DESIGNATED_INITIALIZER\n"
"# endif\n"
"#endif\n"
"#if !defined(SWIFT_ENUM_ATTR)\n"
"# if defined(__has_attribute) && "
"__has_attribute(enum_extensibility)\n"
"# define SWIFT_ENUM_ATTR "
"__attribute__((enum_extensibility(open)))\n"
"# else\n"
"# define SWIFT_ENUM_ATTR\n"
"# endif\n"
"#endif\n"
"#if !defined(SWIFT_ENUM)\n"
"# define SWIFT_ENUM(_type, _name) "
"enum _name : _type _name; "
"enum SWIFT_ENUM_EXTRA _name : _type\n"
"enum SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type\n"
"# if defined(__has_feature) && "
"__has_feature(generalized_swift_name)\n"
"# 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\n"
"enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR "
"SWIFT_ENUM_EXTRA _name : _type\n"
"# else\n"
"# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) "
"SWIFT_ENUM(_type, _name)\n"
Expand Down
2 changes: 1 addition & 1 deletion test/ClangImporter/Inputs/custom-modules/SwiftName.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define SWIFT_NAME(X) __attribute__((swift_name(#X)))

#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum __attribute__((enum_extensibility(open))) _name : _type

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

Expand Down
2 changes: 1 addition & 1 deletion test/ClangImporter/Inputs/enum-objc.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import Foundation;

#define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#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
#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

typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnum, "SwiftEnum") {
ObjCEnumOne = 1,
Expand Down
3 changes: 3 additions & 0 deletions test/ClangImporter/enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ var qualifiedName = NSRuncingMode.mince
var topLevelCaseName = RuncingMince // expected-error{{}}
#endif

let _: EnumViaAttribute = .first

// NS_OPTIONS
var withMince: NSRuncingOptions = .enableMince
var withQuince: NSRuncingOptions = .enableQuince
Expand Down Expand Up @@ -193,6 +195,7 @@ let audioComponentFlags2: FakeAudioComponentFlags = [.loadOutOfProcess]
let objcFlags: objc_flags = [.taggedPointer, .swiftRefcount]

let optionsWithSwiftName: NSOptionsAlsoGetSwiftName = .Case
let optionsViaAttribute: OptionsViaAttribute = [.first, .second]

// <rdar://problem/25168818> Don't import None members in NS_OPTIONS types
#if !IRGEN
Expand Down
13 changes: 4 additions & 9 deletions test/IDE/Inputs/print_clang_header_swift_name.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,23 @@

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

#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum __attribute__((enum_extensibility(open))) SWIFT_ENUM_EXTRA _name : _type

typedef SWIFT_ENUM(NSInteger, Normal) {
NormalOne = 0,
NormalTwo,
NormalThree
};

// FIXME (#618): Use SWIFT_ENUM_NAMED() when support for that lands
#undef SWIFT_ENUM
#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
#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

#define SWIFT_ENUM_NAME "SwiftEnum"
typedef SWIFT_ENUM(NSInteger, ObjCEnum) {
typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnum, "SwiftEnum") {
ObjCEnumOne = 0,
ObjCEnumTwo,
ObjCEnumThree
};

#undef SWIFT_ENUM_NAME
#define SWIFT_ENUM_NAME "SwiftEnumTwo"
typedef SWIFT_ENUM(NSInteger, ObjCEnumTwo) {
typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnumTwo, "SwiftEnumTwo") {
// the following shouldn't have their prefixes stripped
SwiftEnumTwoA,
SwiftEnumTwoB,
Expand Down
2 changes: 1 addition & 1 deletion test/IDE/Inputs/swift_name.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef SWIFT_ENUM
# define SWIFT_ENUM(_type, _name) \
enum _name : _type _name; \
enum SWIFT_ENUM_EXTRA _name : _type
enum __attribute__((enum_extensibility(open))) SWIFT_ENUM_EXTRA _name : _type
#endif

// Renaming global variables.
Expand Down
11 changes: 11 additions & 0 deletions test/Inputs/clang-importer-sdk/usr/include/user_objc.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ typedef NS_ENUM(NSInteger, EnumWithAwkwardDeprecations) {
EnumWithAwkward2BitProblems __attribute__((deprecated)) = EnumWithAwkwardNormalCase1,
};

enum __attribute__((enum_extensibility(open))) EnumViaAttribute {
EnumViaAttributeFirst = 1,
EnumViaAttributeSecond = 2
};


// From <AudioUnit/AudioComponent.h>
// The interesting feature of this enum is that the common prefix before
// taking the enum name itself into account extends past the underscore.
Expand Down Expand Up @@ -68,3 +74,8 @@ typedef CF_OPTIONS(UInt32, EmptySet2) {
typedef CF_OPTIONS(UInt32, EmptySet3) {
kEmptySet3None __attribute__((swift_name("None")))
};

enum __attribute__((flag_enum)) OptionsViaAttribute {
OptionsViaAttributeFirst = 1,
OptionsViaAttributeSecond = 2
};