[swift-dev] Proposal: Allow @objc(name) on enum declarations

Douglas Gregor dgregor at apple.com
Mon Dec 14 23:34:36 CST 2015


> On Dec 14, 2015, at 6:52 PM, Kevin Ballard <kevin at sb.org> wrote:
> 
> (moved to swift-dev)
>  
> I went ahead and implemented this over the weekend, but ran into some weird behavior when testing it. I defined a new macro
>  
> # if defined(__has_feature) && __has_feature(generalized_swift_name)
> #  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name; enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type
> # else
> #  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)
> # endif
>  
> and taught ClangImporter to handle macros named SWIFT_ENUM_NAMED in addition to SWIFT_ENUM, and then I generated a header that contains
>  
> typedef SWIFT_ENUM_NAMED(NSInteger, FooBar, "Bar") {
>   FooBarBaz = 0,
>   FooBarQux = 1,
> };
>  
> When I add a module.modulemap and import the module into the swift integrated REPL, :print_module shows the enum
>  
> enum Bar : Int {
>   init?(rawValue: Int)
>   var rawValue: Int {
>     get {}
>   }
>   case FooBarBaz
>   case FooBarQux
> }

Nifty.

> (I haven't touched case prefix stripping; presumably it's trying to strip the Swift name instead of the ObjC name)

Probably. It’s not actually clear which prefix it should try stripping with.

>  
> But if I actually try and reference the type Bar, it tells me it's an undeclared type!

Yeah, there is some known brokenness here: the swift_name attribute doesn’t actually work on global declarations, because the Clang importer currently makes assumptions about the mapping from Swift names to Objective-C names. That’s exactly why I’m introducing the Swift name lookup tables into the Clang importer now, because they make it possible for arbitrary renaming of Objective-C entities to actually work in Swift.

> I tried dumping the importer lookup table with swift-ide-test, and while I don't actually understand the output format, from looking at the IDE/dump_swift_lookup_tables.swift test, I get the impression that the following is wrong (emphasis mine):
>  
> <<Bridging header lookup table>>
> Base name -> entry mappings:
>   Bar:
>     TU: FooBar
>   FooBar:
>     TU: FooBar, FooBar

Your macro is swift_name’ing the enum but not the typedef, which is why there are entries for both Bar -> FooBar and FooBar -> FooBar. The duplication in the FooBar result is interesting, though: perhaps it’s related to the fact that the enum is first declared without the swift_name attribute?

>   FooBarBaz:
>     FooBar: FooBarBaz
>   FooBarQux:
>     FooBar: FooBarQux
>  
> I suspect that using __attribute__((swift_name)) was never tested with enums, because there's no pre-existing enum macro that supports it. Should I just file this as a bug and submit my PR as-is? Or do you have any guidance on what might be going on here?
>  

It’s fine to submit a PR for this that tests what works (e.g., use FileCheck to verify that the Swift API dumps for the imported enum have the right names) and also have some tests that verify the bad behavior (“cannot find Bar”) with a FIXME to say that the test should succeed. That way, you can get your change in and move the needle forward a little, and when we start turning on the Swift name lookup tables, these tests will help us see that more things are working.

	- Doug

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20151214/5ff6f547/attachment.html>


More information about the swift-dev mailing list