ref: 2f1a6880fb5e5d5408c217809ff203a9b942a9b4
parent: 105071d951fde01834dc9f66db522fd186c148e3
author: Roberto E. Vargas Caballero <[email protected]>
date: Sat Mar 8 13:50:55 EST 2014
Unify decl and fielddcl These functions were identical with some small differences.
--- a/decl.c
+++ b/decl.c
@@ -97,49 +97,7 @@
return sym;
}
-static bool
-specifier(register struct ctype *, struct storage *, struct qualifier *);
-
static void
-fielddcl(unsigned char ns)
-{
- struct ctype base;
- struct storage store;
- struct qualifier qlf;
- register struct ctype *tp;
- struct symbol *sym;
-
- initctype(&base);
- initstore(&store);
- initqlf(&qlf);
- specifier(&base, &store, &qlf);
-
- if (store.defined)
- error("storage specifier in a struct/union field declaration");
-
- do {
- sym = declarator(&base, ns);
- tp = decl_type(&base);
- if (accept(':')) {
- expect(CONSTANT);
- switch (tp->type) {
- case INT: case BOOL:
- tp = ctype(NULL, BITFLD);
- tp->len = yyval->i;
- break;
- default:
- error("bit-field '%s' has invalid type",
- sym->name);
- }
- }
- sym->ctype = *tp;
- sym->qlf = qlf;
- } while (accept(','));
-
- expect(';');
-}
-
-static void
structdcl(register struct ctype *tp)
{
struct symbol *sym;
@@ -157,7 +115,7 @@
++nested_tags;
while (!accept('}'))
- fielddcl(tp->ns);
+ decl(tp->ns);
--nested_tags;
if (sym)
@@ -325,6 +283,7 @@
struct storage *store, struct qualifier *qlf, unsigned char ns)
{
struct compound c;
+ char *err;
c.tree = NULL;
@@ -338,23 +297,38 @@
sym->qlf = *qlf;
sym->ctype = *decl_type(base);
tp = &sym->ctype;
+ aux = NULL;
switch (tp->type) {
case FTN:
+ if (ns != NS_IDEN)
+ goto bad_type;
if (yytoken == '{') {
if (curctx != CTX_OUTER)
- error("cannot use local functions");
+ goto local_fun;
aux = function(sym);
addstmt(&c, node(ODEF, nodesym(sym), aux));
return c.tree;
}
- break;
- case STRUCT:
- case UNION:
+ goto add_stmt;
+ case INT: case BOOL:
+ if (ns != NS_IDEN && accept(':')) {
+ expect(CONSTANT);
+ tp = ctype(NULL, BITFLD);
+ tp->len = yyval->i;
+ goto add_stmt;
+ }
+ goto add_init;
+ case STRUCT: case UNION:
if (tp->forward)
- error("declaration of variable with incomplete type");
+ goto incomplete;
default:
- aux = (accept('=')) ? initializer(tp) : NULL;
+ add_init:
+ if (ns == NS_IDEN) {
+ if (accept('='))
+ aux = initializer(tp);
+ }
+ add_stmt:
addstmt(&c, node(ODEF, nodesym(sym), aux));
}
} while (accept(','));
@@ -361,6 +335,16 @@
expect(';');
return c.tree;
+
+bad_type:
+ err = "incorrect type for field";
+ goto error;
+local_fun:
+ err = "cannot use local functions";
+ goto error;
+incomplete:
+ err = "declaration of variable with incomplete type";
+error: error(err);
}
struct node *
@@ -377,6 +361,9 @@
if (!specifier(&base, &store, &qlf))
return NULL;
+ if (store.defined && ns != NS_IDEN)
+ error("storage specifier in a struct/union field declaration");
+
if (accept(';')) {
register unsigned char type = base.type;
@@ -395,7 +382,8 @@
warn(options.useless,
"useless type qualifier in empty declaration");
}
- break;
+ if (ns == NS_IDEN)
+ break;
default:
warn(options.useless,
"useless type name in empty declaration");