Comments

On Wed, Oct 13, 2010 at 2:17 AM, Jason Merrill <jason@redhat.com> wrote:
>> if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE ||>> processing_template_decl)>> The || last should go on the second line.
Done!
>> + ENUM_EXPLICIT_UNDERLYING_TYPE_P (enumtype) = !! underlying_type;>> Is there a reason this needs to be inside the if, rather than outside with> the SET_SCOPED_ENUM_P?
Well... it should only be needed with newly created trees, because if
the left-side if different from the right side you already have a
compilation error.
The reason SET_SCOPED_ENUM_P is outside of the if is that it has
"parsing consequences", so I prefer to get it updated every time.
That said, you could move the ENUM_EXPLICIT_UNDERLYING_TYPE_P out of
the loop without ill effects.
But note that in the latest version of the patch, there is also a
"SET_OPAQUE_ENUM_P (enumtype, true)" in there that must be inside the
if. This is because it is used to check for errors later.
>> +#if 0 /* Are template enums allowed in ISO? */>> + if (template_parm_scope_p () && flag_iso)>> + error_at (input_location, "%qD is an enumerator template",>> name)>> +#endif>> I guess let's make this a pedwarn conditional on OPT_pedantic until it> actually does make it into the draft. Change "enumerator" to "enumeration",> though.
No problem.
>> + /* An opaque-enum-specifier must have a ';' here. */>> + if ((scoped_enum_p || underlying_type)>> + && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))>> + {>> + cp_parser_error (parser, "expected %<;%>");>> ; or {, I'd think.
Right, done!
On 10/12/2010 03:55 PM, Rodrigo Rivas wrote:
> <1><96>: Abbrev Number: 7 (DW_TAG_enumeration_type)> <97> DW_AT_name : V> <99> DW_AT_byte_size : 4> <9a> DW_AT_decl_file : 1> <9b> DW_AT_decl_line : 8>> Right, I think we want to have a DW_AT_declaration here; check ENUM_LACKS_VALUE_LIST in gen_enumeration_type_die.
I've done that, and now it kinda works... with the sample of the previous mail:
//a.cpp:
enum V : int;
V z;
//b.cpp:
enum V : int;
extern V z;
V z2;
enum V : int { v1, v2, v3 };
(With DWARF-2)
(gdb) p z
$1 = <incomplete type>
(gdb) ptype z
type = enum V {}
(gdb) p z2
$2 = v1
(gdb) ptype z2
type = enum V { v1, v2, v3 }
(gdb) p z2
$3 = v1
(gdb) ptype z2
type = enum V { v1, v2, v3 }
So the debugger prints the type of "z" only after printing "z2"!
In addition, I've corrected several additional errors and
improvements, with corresponding testcases:
* Now the underlying types is cv_unqualified(), as required by the draft.
* I've renamed ENUM_EXPLICIT_UNDERLYING_TYPE_P to
ENUM_FIXED_UNDERLYING_TYPE_P to match the wording of the draft.
* ENUM_HAS_VALUE_LIST_P changes logic and name to ENUM_IS_OPAQUE /
OPAQUE_ENUM_P / SET_OPAQUE_ENUM_P. In addition ENUM_IS_OPAQUE is moved
into gcc/tree.h to be visible for the debugger back-ends.
* The following code is now illegal:
template<typename T> struct S
{
enum E : int;
};
/* A */ enum S<int>::E { e }; // error: cannot add an enumerator list
to a template instantiation
Note that the template specialization is not allowed either:
/* B */ template<> enum S<int>::E { e }; // error
Because there is no enum templates. This is forbidden, also:
/* C */ template <typename T> enum E { a, b, c };
But the following is accepted:
/* D */ template<typename T> enum S<T>::E { e }; // ok.
Because it merely completes the declaration of an already existing
enum, so it is not a primary enum template.
I couldn't find any justification in the draft for not allowing the
declaration "A", but I don't feel that both this one and the "D"
should be both allowed. If this last one gets into the final standard,
it should probably add to the "7.2 Enumeration declarations":
A nested-name-specifier shall not refer to a template instantiation.
Regards.

On 10/13/2010 09:29 AM, Rodrigo Rivas wrote:
> * The following code is now illegal:>> template<typename T> struct S> {> enum E : int;> };> /* A */ enum S<int>::E { e }; // error: cannot add an enumerator list> to a template instantiation
Right.
> Note that the template specialization is not allowed either:> /* B */ template<> enum S<int>::E { e }; // error
This should be allowed, just like you can say.
template <typename T> struct A
{
static T t;
};
template<> int A<int>::t = 42;
> Because there is no enum templates. This is forbidden, also:> /* C */ template<typename T> enum E { a, b, c };
Right.
> But the following is accepted:>> /* D */ template<typename T> enum S<T>::E { e }; // ok.
Yes, just like you can say
template <typename T> T A<T>::t = 42;
> Because it merely completes the declaration of an already existing> enum, so it is not a primary enum template.>> I couldn't find any justification in the draft for not allowing the> declaration "A", but I don't feel that both this one and the "D"> should be both allowed.
Agreed; rather, B and D should both be allowed.
> If this last one gets into the final standard,> it should probably add to the "7.2 Enumeration declarations":> A nested-name-specifier shall not refer to a template instantiation.
Something like that, yes.
Jason