scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit f73cc2f511c03315a6a4dfe6b8450b57b4fd1b49
parent c3b98d1587e0da7811403997cabbaa5a425b1d7a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 14 Feb 2014 15:24:29 +0100

Move check of tag already defined out of aggregate

aggregate function is going to be called each time an aggregate declaration
begins, in normal declaration and in forward declarations, but the check
of 'tag already defined' must be done only in the case of normal
declaration. The place where we know if the declaration is normal or
forward is in structdcl after the aggregate() call, so the check is
moved there.

Diffstat:
Mdecl.c | 39++++++++++++++++++++++++++-------------
1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/decl.c b/decl.c @@ -65,28 +65,37 @@ directdcl(register struct ctype *tp, unsigned char ns) } } -static void +/* TODO: Add the type to the symbol */ +static struct symbol * aggregate(register struct ctype *tp) { struct symbol *sym = NULL; + tp->forward = 1; if (yytoken == IDEN) { register struct ctype *aux; sym = lookup(yytext, NS_TAG); if (aux = sym->ctype) { - if (!aux->forward) - error("struct/union already defined"); - delctype(aux); - } - sym->ctype = xmalloc(sizeof(*tp)); - next(); + if (aux->type != tp->type) { + error("'%s' defined as wrong kind of tag", + yytext); + } + *tp = *aux; + } else { + sym->ctype = xmalloc(sizeof(*tp)); + tp->sym = sym; + tp->ns = ++nr_tags; /* FIX: It is only necessary */ + } /* in struct and union */ + next(); /* This way of handling nr_tag */ + } else { /* is incorrect once is incorrect*/ + tp->ns = ++nr_tags; /* it will be incorrect forever*/ } + if (nr_tags == NS_TAG + NR_MAXSTRUCTS) error("too much structs/unions/enum defined"); - tp->ns = ++nr_tags; - tp->forward = 1; - tp->sym = sym; + + return sym; } static bool @@ -135,13 +144,17 @@ structdcl(register struct ctype *tp) { struct symbol *sym; - aggregate(tp); - if (nested_tags == NR_STRUCT_LEVEL) - error("too much nested structs/unions"); + sym = aggregate(tp); if (!accept('{')) return; + if (sym && !sym->ctype->forward) + error("struct/union already defined"); + + if (nested_tags == NR_STRUCT_LEVEL) + error("too much nested structs/unions"); + ++nested_tags; do fielddcl(tp->ns);