shithub: scc

Download patch

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");