This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++0x] implementing forward declarations for enums


On Mon, Oct 11, 2010 at 10:35 PM, Jason Merrill <jason@redhat.com> wrote:
> Variants are e.g. const-qualified, typedef'd, or attributed versions of
> types. ÂWe can't have any variants of a type before it is first declared, so
> we should never need to copy_type_enum to variants; since we don't have
> C-like forward declarations with unspecified underlying type, there's no way
> to create a variant before the underlying type is set. ÂI suppose the code
> that was doing that before was a relic of when the C++ front end forked from
> the C front end.
I got it now! I think you're right, of course.

> Let's try removing that call and instead asserting that when we're setting
> the underlying type, there are no variants.
Done!

>> But then, should I modify the debuggers back end? I think that's
>> overkilling!
>
> I don't think it's overkill at all. ÂIf we don't have the enumeration list,
> then we don't have enough information for complete debug info.
I think that doing this right will be more difficult than it appears.
And since I know little about debbuging information it will take a
while for me to do it.
Could it be left for a future patch?
Don't get me wrong, I'm willing to try and do it, but this patch is
already getting big enough.

>> But the opaque-enum *are* definitions: a opaque enum is a complete
>> type. You may not have an enumerator list in this compilation unit
>> while you may have variables of this type:
>
>> enum class E;
>> E e;
>> /* EOF */
>>
>> If I don't emit debugging information for the opaque-enum, then the
>> variable e will lack debugging information.
>
> It should work the same way as a use of an incomplete class:
>
> class A *ap;
>
> When the debugging back end sees a use of a type, it emits it if it hasn't
> already been emitted.
Well, I tried that and when I print 'ptype e' in gdb it says
"incomplete type". But the type is not *incomplete* in the usual
sense. It just lacks the enumerator list. I should be able to do 'p
sizeof e' for example.

>>> BTW, let's improve the diagnostic for "enum E;" in C++0x mode to let the
>>> user know that either "enum E: int;" or "enum class E;" would be OK.
>>
>> Hmmm, as it happens "enum E;" is parsed without diagnostics in C++98
>> if the enumeration is already defined.
>> It emits the error "use of E without a previous definition" because it
>> parses it as an elaborated_type_specifier.
>
> Right, we can just give a different error at the same place in C++0x mode.
Not so easy, actually, because this error is just diagnosing that the
enumeration is unknown, and that is true. If I change the message,
then the following:

enum Unk x;

will also get the new message about opaque enumerations instead of the
probably more useful "use of enum Unk without a previous definition".
Granted, I could peek the next token and see the ';', but this message
is emitted in decl.c, not in parser.c,
I've tried a couple of other alternatives without success, so IMHO,
we'd better leave this message alone.

>>> This test complains about mismatching underlying types for
>>>
>>> enum A { e };
>>> enum A { e };
>>>
>>> which is incorrect.
>>
>> Is is because the parser sees something like that.
>>
>> enum A : unique_type1 { e };
>> enum A : unique_type2 { e };
>>
>> Where unique_typeN is created after the list of enumerators.
>> So the first error it sees it that the underlying types are different.
>> Admittedly, the message is misleading, but correct, from a certain
>> point of view ;-)
>> The only solution I can think of is to add yet another flag to the
>> enumeration tree to signal whether an enum has an explicit underlying
>> type. Checking this flag we can ignore this particular error and it
>> will stump upon the multiple definition error.
>
> Couldn't we just wait to give this error until finish_enum?
No, in finish_enum we'll see just the same underlying types. And AFAIK
there is no way to make a difference between an implicit underlying
type and and explicit one.
I've solve it using TYPE_LANG_FLAG_3, for lack of a better solution.

>> So an "enum template" does not exist. It would be a nice gnu++0x
>> extension, though (too late to try to get it in the draft...).
>
> I'm not so sure it's too late to get it in; it seems like a simple oversight
> to me. ÂI am trying to get it into the draft, for which a working
> implementation would help...:)
I'd be nice for this to get into the final standard, for sure... It
took me a while but I think that I finally got it working!
Note that it only works for the completion of opaque enums from a
template class. A standalone template enumeration is not supported.

And while working on it I discovered a couple of other bugs.

1. Now when parsing a template, I build a new enum declaration for
each enum seen opaque or not, but the enumerator list is always
appended to the first one, since this is the one that gets
instantiated. The other ones are only there because some errors cannot
be checked until instantiation time (if the underlying type is a
dependent name).

2. If an opaque enum defines an underlying type and then an enum
declaration adds the enumerator list without the underlying type, a
distinct error message is emitted ("underlying type mismatch").

I've added also a couple of new testcases.

Waiting your comments...
Best regards.
Rodrigo

Attachment: enum.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]