This is an archive of the discontinued LLVM Phabricator instance.

Support enums with a fixed underlying type in all language modes
ClosedPublic

Authored by erik.pilkington on Sep 20 2018, 7:02 PM.

Details

Summary

A significant number of internal C users have been complaining about the lack of support for fixed enums. We already support this in Objective-C mode, as well as in C mode with -fms-extensions. Supporting this in C makes us more consistent, and provides a useful feature to C users!

If there is some doubt as to whether we want this, I can start a thread on cfe-dev for the wider audience.

rdar://43831380

Thanks for taking a look!

Diff Detail

Repository
rC Clang

Event Timeline

aaron.ballman accepted this revision.Sep 21 2018, 7:58 AM
aaron.ballman added a reviewer: aaron.ballman.
aaron.ballman added a subscriber: aaron.ballman.

I really like this idea in general, thank you for proposing this patch!

clang/include/clang/Basic/Features.def
90 ↗(On Diff #166397)

Is this really supported in ObjC1, or is there no longer a distinction to be made there?

233 ↗(On Diff #166397)

Are we sure we want to make this decision for things like OpenCL, Cuda, etc?

This revision is now accepted and ready to land.Sep 21 2018, 7:58 AM
aaron.ballman requested changes to this revision.Sep 21 2018, 7:59 AM

Whoops, that acceptance was accidental. Pretending I want changes just to make it clear in Phab. :-)

This revision now requires changes to proceed.Sep 21 2018, 7:59 AM
jfb added a subscriber: jfb.Sep 21 2018, 9:24 AM

I think we should consider proposing this to the C committee. @aaron.ballman I can help Erik write the paper, would you be able to present it? Too tight for the upcoming meeting, but I'm guessing we have *plenty* of time for ++C17.

In D52339#1242086, @jfb wrote:

I think we should consider proposing this to the C committee. @aaron.ballman I can help Erik write the paper, would you be able to present it? Too tight for the upcoming meeting, but I'm guessing we have *plenty* of time for ++C17.

It's already been proposed to WG14 and is currently on the SD-3 list of features to consider for C2x. See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2008.pdf. I know Clive and am happy to point him towards this patch (when it lands) as demonstration of industry desire for the feature, in case he needs to provide updated papers.

jfb added a comment.Sep 21 2018, 9:44 AM
In D52339#1242086, @jfb wrote:

I think we should consider proposing this to the C committee. @aaron.ballman I can help Erik write the paper, would you be able to present it? Too tight for the upcoming meeting, but I'm guessing we have *plenty* of time for ++C17.

It's already been proposed to WG14 and is currently on the SD-3 list of features to consider for C2x. See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2008.pdf. I know Clive and am happy to point him towards this patch (when it lands) as demonstration of industry desire for the feature, in case he needs to provide updated papers.

Wonderful! Does this match he proposed C2x semantics? Once voted in we'll want to change this from just an extension to also be a -std=c2x thing, better have them match now.

In D52339#1242118, @jfb wrote:
In D52339#1242086, @jfb wrote:

I think we should consider proposing this to the C committee. @aaron.ballman I can help Erik write the paper, would you be able to present it? Too tight for the upcoming meeting, but I'm guessing we have *plenty* of time for ++C17.

It's already been proposed to WG14 and is currently on the SD-3 list of features to consider for C2x. See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2008.pdf. I know Clive and am happy to point him towards this patch (when it lands) as demonstration of industry desire for the feature, in case he needs to provide updated papers.

Wonderful! Does this match he proposed C2x semantics? Once voted in we'll want to change this from just an extension to also be a -std=c2x thing, better have them match now.

I have to validate that still, but from a quick look, I think we're in the ballpark if not outright compatible.

In D52339#1242118, @jfb wrote:
In D52339#1242086, @jfb wrote:

I think we should consider proposing this to the C committee. @aaron.ballman I can help Erik write the paper, would you be able to present it? Too tight for the upcoming meeting, but I'm guessing we have *plenty* of time for ++C17.

It's already been proposed to WG14 and is currently on the SD-3 list of features to consider for C2x. See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2008.pdf. I know Clive and am happy to point him towards this patch (when it lands) as demonstration of industry desire for the feature, in case he needs to provide updated papers.

Wonderful! Does this match he proposed C2x semantics? Once voted in we'll want to change this from just an extension to also be a -std=c2x thing, better have them match now.

I have to validate that still, but from a quick look, I think we're in the ballpark if not outright compatible.

From the last line in the paper, it seems that C++ compatibility is a goal of the paper (or at least a consideration). We should probably think about this if/when the final wording gets accepted though.

clang/include/clang/Basic/Features.def
90 ↗(On Diff #166397)

I suppose it's a first class feature in ObjC2, but an extension in ObjC1. On second thought I should probably not change this, because ObjC1 doesn't have this as a feature, although it does have it as an extension.

233 ↗(On Diff #166397)

I can't think of any reason why not, seems there are a handful of other EXTENSION(*, true) features. Do you have a preference?

clang/include/clang/Basic/Features.def
90 ↗(On Diff #166397)

On third thought, it looks like we never even try to compile with ObjC1 = 1 and ObjC2 = 0, so I guess this is fine as-is.

From the last line in the paper, it seems that C++ compatibility is a goal of the paper (or at least a consideration). We should probably think about this if/when the final wording gets accepted though.

Agreed. WG14's charter explicitly prefers compatibility with C++ when possible.

The part that I wasn't quite sure on were the type constraints in the proposal. C++ allows any integral type and ignores cv qualifiers, but the proposal lists specific types and doesn't discuss qualifiers. By my reading, this is code allowed in C++ but prohibited in the proposed wording:

enum E : const int32_t {
  One
};

(Because the type is int32_t and is cv-qualified.) However, it's possible that's an oversight rather than an intentional design. I'll bring it up with Clive to see, but perhaps we can spot other divergences and can provide him with a list of concerns on the implementation side.

clang/include/clang/Basic/Features.def
233 ↗(On Diff #166397)

I think we should probably ask folks from the projects to see if they're okay with the extension or not, but I'd guess this won't be contentious.

From the last line in the paper, it seems that C++ compatibility is a goal of the paper (or at least a consideration). We should probably think about this if/when the final wording gets accepted though.

Agreed. WG14's charter explicitly prefers compatibility with C++ when possible.

The part that I wasn't quite sure on were the type constraints in the proposal. C++ allows any integral type and ignores cv qualifiers, but the proposal lists specific types and doesn't discuss qualifiers. By my reading, this is code allowed in C++ but prohibited in the proposed wording:

enum E : const int32_t {
  One
};

(Because the type is int32_t and is cv-qualified.) However, it's possible that's an oversight rather than an intentional design. I'll bring it up with Clive to see, but perhaps we can spot other divergences and can provide him with a list of concerns on the implementation side.

Not accepting typedefs would be negligence on behalf of the committee, since generally people use this feature specifically to control the size of the enum, which you can't do portably without a typedef. Not accepting qualified types is a justifiable decision.

There's no reason to make this an ObjC2-only feature; we should probably eliminate that distinction throughout the compiler.

There's no reason to make this an ObjC2-only feature; we should probably eliminate that distinction throughout the compiler.

Sure, I was just writing a proposal to do that: http://lists.llvm.org/pipermail/cfe-dev/2018-September/059468.html

erik.pilkington added subscribers: jlebar, Anastasia.
erik.pilkington added inline comments.
clang/include/clang/Basic/Features.def
233 ↗(On Diff #166397)

Sure, @jlebar and @Anastasia: Any thoughts here?

Ping! This doesn't really affect CUDA or OpenCL more than any change to the compiler, so I don't think it makes sense to block this until we hear from them.

aaron.ballman accepted this revision.Sep 28 2018, 11:12 AM

Ping! This doesn't really affect CUDA or OpenCL more than any change to the compiler, so I don't think it makes sense to block this until we hear from them.

It impacts them insomuch as they're standards and they may want to opt out of extensions for keeping code portable to other compilers.

However, short of that concern, this LGTM. I've spoken with the paper author for the WG14 paper and I think this approach fits their general proposal, so I don't think we'll have divergence here.

This revision is now accepted and ready to land.Sep 28 2018, 11:12 AM

Ping! This doesn't really affect CUDA or OpenCL more than any change to the compiler, so I don't think it makes sense to block this until we hear from them.

It impacts them insomuch as they're standards and they may want to opt out of extensions for keeping code portable to other compilers.

My view is that that's what -pedantic / -pedantic-errors are for. We want Clang to have a consistent user experience across languages, so if we're supporting fixed underlying types as an official Clang extension in languages that don't have it as a feature, that should apply everywhere it makes sense.

Ping! This doesn't really affect CUDA or OpenCL more than any change to the compiler, so I don't think it makes sense to block this until we hear from them.

It impacts them insomuch as they're standards and they may want to opt out of extensions for keeping code portable to other compilers.

My view is that that's what -pedantic / -pedantic-errors are for. We want Clang to have a consistent user experience across languages, so if we're supporting fixed underlying types as an official Clang extension in languages that don't have it as a feature, that should apply everywhere it makes sense.

That sounds like a reasonable approach to me. I'll switch my LGTM to RLGTM (Really LGTM). :-)

However, short of that concern, this LGTM. I've spoken with the paper author for the WG14 paper and I think this approach fits their general proposal, so I don't think we'll have divergence here.

Okay, great! Thanks for verifying that.

This revision was automatically updated to reflect the committed changes.

@erik.pilkington the change to make objc_fixed_enum true in non-ObjC mode turned out to be problematic for our adoption. Could you please fix it before LLVM8 is wrapped up so that we don't ship this extension as on by default for all language modes?

We could introduce a new extension flag like c_fixed_enum that can be set for all language modes. objc_fixed_enum should apply to ObjC only.

@erik.pilkington the change to make objc_fixed_enum true in non-ObjC mode turned out to be problematic for our adoption. Could you please fix it before LLVM8 is wrapped up so that we don't ship this extension as on by default for all language modes?

Yeah, now that I look again, we shouldn't be changing the FEATURE(...) flag behaviour, because fixed enums in C aren't a formal language feature. I removed this in r352672.

We could introduce a new extension flag like c_fixed_enum that can be set for all language modes. objc_fixed_enum should apply to ObjC only.

Can't we just use cxx_fixed_enum?