https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123810

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #5 from Jason Merrill <jason at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #2)
> Reduced testcase:
> #include <meta>
> 
> struct S {
>   typedef enum { A, B } C;
> };
> int a = members_of (^^S, std::meta::access_context::unchecked ()).size ();
> 
> The problem is that there are two TYPE_DECLs, one is for the anonymous enum
> but its TREE_TYPE is ENUMERAL_TYPE C, and another one i C with the same
> TREE_TYPE.

Yes, I believe that's what C++ says; there is the unnamed class, and then there
is the typedef for linkage purposes.

> class_members_of puhses into the vector for TYPE_DECLs their TREE_TYPE, so
> pushes twice the same thing, and the assertions is to make sure nothing
> appears more than once in there.

It seems to me that a solution would be to push the (separate) TYPE_DECLs
rather than the (shared) type.

> Anyway, this leads to further questions.
> Should
> #include <meta>
> 
> typedef enum { A, B } C;
> static_assert (is_type_alias (^^C));
> pass or not?  It does on the clang reflection branch, it doesn't in GCC. 

I think it should, C names the typedef.

> When a typedef gives name for linkage purposes to an anonymous
> enum/class/union, that is the enum/class/union type rather than its typedef
> variant.

Reflection is making a distinction that was not previously observable in the
language, so we were just putting the linkage name in TYPE_NAME.  I think it
will be simpler to work around this in reflection rather than change that
choice.

(In reply to Jakub Jelinek from comment #4)
> +  if (flag_reflection)
> +    decl = copy_decl (decl);

Ah, now I understand this approach better: you're creating a second named
TYPE_DECL separate from the typedef, as though there were two typedefs with the
same name.  So that DECL_ORIGINAL_TYPE would give a different _TYPE.

I'm still skeptical of this direction, since as it doesn't correspond to
anything in the language.

Reply via email to