diff options
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 0a1db86..7ec725d 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -2308,17 +2308,36 @@ parseagg(struct parser *P, const char *name, int kind, struct decl **retdecl) { const struct type *pty = NULL; static int id = 0; size_t size = 0, align = 1; + bool decls = 0; vec_t(struct aggfield) flds = {0}; - *retdecl = NULL; - + ty.agg.name = name; if (lexmatch(P, &tok, ';')) { ty.agg.fwd = 1; + ty.agg.id = id++; + return interntype(ty); } else { - lexexpect(P, '{'); + if (name) { + int iid; + struct env env_noparent = *P->curenv; + env_noparent.parent = NULL; + struct decl *decl = (struct decl *)envfind(&env_noparent, name); + if (decl && decl->ty->t == kind) + iid = decl->ty->agg.id; + else + iid = id++; + pty = interntype((struct type) { + kind, .agg.name = name, .agg.id = iid + }); + *retdecl = decl = putdecl(P, P->tokspan, &(struct decl) { + Dtype, name, .span = P->tokspan, .ty = pty }); + } + tok = lexexpect(P, '{'); while (!lexmatch(P, &tok, '}')) { - if (isdecltokt(lexpeek(P).t)) - goto decls; + if (isdecltokt(lexpeek(P).t)) { + decls = 1; + break; + } const char *fnam = (tok = lexexpect(P, TKident)).str; const struct type *ty = parsetype(P); @@ -2348,49 +2367,32 @@ parseagg(struct parser *P, const char *name, int kind, struct decl **retdecl) { break; } } - } - if (0) -decls: { - vec_t(struct decl *) decls = {0}; - struct env env = {.parent = P->curenv}; - struct decl *decl; - - ty.size = ALIGNUP(size, align); - ty.align = align; - ty.agg.name = name; - vec_slice_cpy(&ty.agg.flds, &flds); - ty.agg.id = id++; - pty = interntype(ty); - if (name) { - decl = putdecl(P, tok.span, - &(struct decl){Dtype, name, .span = tok.span, .ty = pty}); - if (decl->ty != pty) - uninterntype(pty); - pty = decl->ty; - } + struct type *ppty = (struct type *)pty; + ppty->size = ALIGNUP(size, align); + ppty->align = align; + vec_slice_cpy(&ppty->agg.flds, &flds); + if (!decls) + return pty; + else { + vec_t(struct decl *) decls = {0}; + struct env env = {.parent = P->curenv}; - struct aggdeclyarg yarg = { - (void *)&decls, P, pty - }; + struct aggdeclyarg yarg = { + (void *)&decls, P, pty + }; - pushenv(P, &env); - while (!lexmatch(P, &tok, '}')) { - vec_slice_cpy(&((struct type *)pty)->agg.decls, &decls); - parsedecl(aggdeclyield, &yarg, P, 0); - } + pushenv(P, &env); + while (!lexmatch(P, &tok, '}')) { + ppty->agg.decls.d = decls.data; + ppty->agg.decls.n = decls.length; + parsedecl(aggdeclyield, &yarg, P, 0); + } - vec_slice_cpy(&((struct type *)pty)->agg.decls, &decls); - popenv(P); - *retdecl = decl; - return decl->ty; + vec_slice_cpy(&ppty->agg.decls, &decls); + popenv(P); + return pty; + } } - - ty.size = ALIGNUP(size, align); - ty.align = align; - ty.agg.name = name; - vec_slice_cpy(&ty.agg.flds, &flds); - ty.agg.id = id++; - return interntype(ty); } static struct comfile |