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 10/06/2010 09:42 AM, Rodrigo Rivas wrote:
On Wed, Oct 6, 2010 at 6:35 AM, Jason Merrill<jason@redhat.com> wrote:
Do you really need to do the variant fixup for opaque enums?  It's not clear
to me how you could get a variant with the wrong values unless you had a
forward declaration with a different underlying type, which would only
happen with GCC forward declarations, not with C++0x opaque enums.

I'm afraid I don't really understand this variant stuff or when they are created, so I just did it safely.

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.


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

This way the debugging information for an opaque enumerator will lack
the enumeration list, but that's hard to avoid.

It doesn't seem that hard; we just need to indicate incompleteness to the back end in some way other than not setting TYPE_SIZE. There are lots of free flags still.

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'd suggest reversing the sense of ENUM_HAS_VALUE_LIST_P so that it's only
set on opaque enums, and then moving it to use base.private_flag instead of
lang_flag_2.

I don't think we want to do rest_of_type_compilation for opaque decls,
either; only for the actual definition.

rest_of_type_compilation just emits the debugging information for the type, right?

Yes.


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.

template<typename T>
struct S
{
     enum class E;
};
enum class S<int>::E { a, b, c };
enum class S<double>::E { d, e, f };

Interesting. Yes, it makes sense for that to work, though perhaps they should have "template<>" at the beginning. I'll bring this up with the committee.

template<> makes sense if you see this as a template specialization I see it as two opaque enum listings that happen to be into two class template instantiations.

Yes, but the convention is that we use template<> for definitions of members of template instantiations as well:


template <typename T>
struct S
{
  static T t;
};

template<> int S<int>::t = 42;
template<> double S<double>::t = 3.1415;

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.


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?


template<class T>
struct A
{
  enum E: int;
};

template<class T>
enum A<T>::E { e1 };

This certainly does the wrong thing, but I don't think it should even compile!
According to 14.1 (templ):
"
The declaration in a template-declaration shall
- declare or define a function or a class, or
- define a member function, a member class or a static data member of
a class template or of a class
nested within a class template, or
- define a member template of a class or class template, or
- be an alias-declaration.
"
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...:)


Jason


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