parse,check,type,wwi: @packed struct attribute, both stages (#51)

Hare/harec @packed struct layout: no inter-field or trailing padding, align =
max field align (NOT forced to 1) — matches harec type_store.c + types.c:621
(packed{u8,u64}=size 9/align 8). Parser consumes inline @packed (loud-rejects
unknown struct attrs, both stages); layout gates padding on !packed; cstage
type_eq enforces packed type-distinctness; the .wwi producer round-trips
"struct @packed {". wwstage sets slotsize=size for packed so its composite-ABI
copy matches cstage byte-for-byte. cstage identity is faithful; wwstage identity
rides the deferred #224 nominal-resolvealias arc (#108). Both stages byte-id;
447 tests pass.
This commit is contained in:
2026-06-19 00:17:49 +09:00
parent 0197dfb9e6
commit 027f90c572
12 changed files with 563 additions and 16 deletions

View File

@@ -204,8 +204,25 @@ parsetype(Parser *p)
}
case TK_STRUCT: {
advance(p);
expect(p, TK_LBRACE);
Node *n = newnode(p->a, N_TSTRUCT, pp);
/* `@packed` is an inline struct TYPE attribute (harec
* ast.h:95 `bool packed`), sitting after `struct` and
* before `{` — NOT a fn-decl attr, so it does not route
* through parseattrs. */
if (p->cur.kind == TK_AT) {
advance(p);
const char *an = expectident(p);
/* p->errs gates the build (cmd/w6c/main.c:82);
* nerrors is advisory-only, so an errorf on a
* clean-recovery path must bump p->errs itself. */
if (strcmp(an, "packed") != 0) {
errorf(p->cur.pos,
"unknown struct attribute '@%s'", an);
p->errs++;
} else
n->packed = 1;
}
expect(p, TK_LBRACE);
Node *head = NULL, *tail = NULL;
while (p->cur.kind != TK_RBRACE && p->cur.kind != TK_EOF) {
Pos fp = p->cur.pos;