Fix initializers in anonymous structs and unions

The "trivial fix" is to just save off the offset in check_designators
(add a new field to the "EXPR_IDENTIFIER" part of "struct expression"
and then pick up that offset in "convert_ident()"

However, that has exactly the same issue with the whole fake
EXPR_IDENTIFIER created by "next_designators()". Now we need to
initialize the offset field there too. And, for the same reason as
before, the field that "next_designator()" picks may not *have* an
identifier, because the next designator may in fact be an anonymous
union.

Anyway, with all that said, maybe this really confusing and hacky
patch would work. It passes my tests. The magic offset calculation in
next_designators() has a big comment about what the heck it is doing,
and otherwise it's a fairly straightforward case of "save offset from
check_designators() time to be used by convert_ident()".

My stupid test-case is this incredibly hacky thing:

    struct A {
        int aa;
        int bb;
    };

    struct S {
        int a;
        union {
            int b;
            int c;
        } u[10];
        int dummy;
        union {
            int d;
            int e;
        };
    };

    int fn(void)
    {
        struct S s = {
            .a = 1,
            .u[2].b = 2,
            .dummy = 1,
             { 3 }
        };
        return s.dummy*1000 + s.d*100 + s.u[2].b*10 + s.a; // 1321
    }

where I use "./test-linearize" to verify that the initializer layout
matches the code generation layout (so that 'fn' function *should*
linearize to just a simple "ret.32 $1321", and with this patch it
does).

But I bet this misses some case. However, the current state wrt
initializer offsets really is very broken, so maybe it's ok.

Signed-off-by: Christopher Li <sparse@chrisli.org>
2 files changed