https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124200
--- Comment #7 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
(In reply to Thomas Berger from comment #5)
> Created attachment 63776 [details]
> tested/working impl
>
> Your patch was mostly working @Nathaniel, i only had to add some
> deduplication logic for function decls.
>
Hm, why was this necessary? I would expect modules declarations to have merged
function decls and completely deduplicated them. This logic doesn't seem to
get hit by my testcase, do you have another testcase that checks this?
(In reply to Jakub Jelinek from comment #6)
> Note, for members_of vs. modules there is another problem: we order
> reflections in *members_of returned vectors by DECL_UID (because for class
> queries they are required to be ordered by the order of declarations - and
> unfortunately TYPE_FIELDS are only partially ordered by the order of
> declarations - and for namespaces it is nice to have predictable order).
> Now, because the standard doesn't say anything about ordering of namespace
> queries, if the above patch results in some consistent ordering, not e.g.
> dependent on compiler AS randomization, that is fine,
Namespace-scope declarations should be deterministic, for declarations that
don't have any ordering requirements we fall back to using DECL_UID to sort
them; so the order won't really be predictable but at least it won't be
completely random.
> but I'm really unsure
> in which order TYPE_FIELDS of classes are streamed out and in for modules.
> Testcase would be exporting some class like:
> struct A {
> int a;
> typedef int b;
> struct C {};
> int foo () { return 42; }
> using D = C;
> long e;
> };
> and in a TU which imports that do members_of (^^A) and verify the exact
> order of the non-synthetized members.
Modules just streams directly in TYPE_FIELDS order. This means that the
DECL_UIDs that are constructed are the TYPE_FIELDS order as well, and since
TYPE_FIELDS is not in the correct order things go awry here I guess.
And things get more complex too because modules streams TYPE_DECLs and
FUNCTION_DECLs first, then FIELD_DECLs get streamed later. Because TYPE_DECLs
and FUNCTION_DECLs (even members) might be depended on by other decls and so
might get streamed early (in a somewhat arbitrary order, see above) based on
what other decls depend on them in what order.
In this testcase we happen to get order [D, C, foo(), b, a, e, ...]. Because
dependency ordering chose [D, foo, C, b] and streaming D then streamed C as its
DECL_ORIGINAL_TYPE before we started streaming foo.
I don't think relying on DECL_UID for member ordering will be easy unless we
somehow stream them independently as well and then remap the relevant UIDs in
modules (but this will then also probably break things because modules uses
DECL_UID as the key for various lookup maps). I guess we need to either be
able to adjust TYPE_FIELDS so that it's actually in declaration order and fix
any breakage from that, or we need some additional information that we can
attach that isn't as flakey as DECL_UID.