ref: f73cc2f511c03315a6a4dfe6b8450b57b4fd1b49
parent: c3b98d1587e0da7811403997cabbaa5a425b1d7a
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Feb 14 10:24:29 EST 2014
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.
--- a/decl.c
+++ b/decl.c
@@ -65,10 +65,12 @@
}
}
-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;
@@ -75,18 +77,25 @@
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,12 +144,16 @@
{
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
--
⑨