On Mon, Mar 16, 2026 at 02:40:09PM -0400, Jason Merrill wrote:
> On 3/15/26 7:57 AM, Thomas Berger wrote:
> > Previously, finish_member_declaration prepended non-type members and
> > appended TYPE_DECLs to TYPE_FIELDS separately, so that the TYPE_DECLs
> > always appeared after all non-type members regardless of their decleration
> > order.
> >
> > Store all members in declaration order instead and update the places,
> > that relied on the old layout.
> >
> > gcc/analyzer/ChangeLog:
> >
> > * region-model.cc (struct_or_union_with_inheritance_p): Skip
> > leading TYPE_DECL nodes before checking for base class field.
> >
> > gcc/cp/ChangeLog:
> >
> > * class.cc (unreverse_member_declarations): Use nreverse for both
> > CLASSTYPE_DECL_LIST and TYPE_FIELDS.
> > * decl.cc (reshape_init_class): Guard anonymous aggregate field
> > search with FIELD_DECL check.
> > * name-lookup.cc (fields_linear_search): Return first non-type
> > match immediately; fall back to TYPE_DECL if no non-type is found.
> > * parser.cc (remove_dummy_lambda_op): Search chain for dummy
> > operator instead of assuming it is the TYPE_FIELDS head.
> > * semantics.cc (finish_member_declaration): Always prepend to
> > FIELD_DECL; remove separate handling for TYPE_DECL.
Also, in ChangeLog the continuation lines should start just with a tab
rather than tab + 2 spaces. So
* class.cc (unreverse_member_declarations): Use nreverse for both
CLASSTYPE_DECL_LIST and TYPE_FIELDS.
etc.
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -4323,24 +4323,8 @@ finish_member_declaration (tree decl)
> > if (add)
> > {
> > - /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
> > - go at the beginning. The reason is that
> > - legacy_nonfn_member_lookup searches the list in order, and we
> > - want a field name to override a type name so that the "struct
> > - stat hack" will work. In particular:
> > -
> > - struct S { enum E { }; static const int E = 5; int ary[S::E]; } s;
> > -
> > - is valid. */
> > -
> > - if (TREE_CODE (decl) == TYPE_DECL)
> > - TYPE_FIELDS (current_class_type)
> > - = chainon (TYPE_FIELDS (current_class_type), decl);
> > - else
> > - {
> > - DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
> > - TYPE_FIELDS (current_class_type) = decl;
> > - }
> > + DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
> > + TYPE_FIELDS (current_class_type) = decl;
I'll just note that while the lookup slows down in some cases because of
this change, it hopefully should be only on classes with very few members
or when building the class, otherwise we have the CLASSTYPE_MEMBER_VEC
and perform binary search (or linear when incomplete) on it and that
shouldn't be slower than it is.
On the other side, the above now removed chainon could be really expensive
on classes with thousands of TYPE_DECLs in it.
Jakub