shithub: scc

Download patch

ref: ebe3eda8ec61484d26bdbb754431a19ecdaa32b4
parent: e96a66c1e82580dcb57e90482ef25d25336ac5dc
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Mar 12 07:21:44 EDT 2014

Remove defined field from ctype

It can be known that a type is not defined is the value of type
is 0, so this field is no needed anymore.

--- a/decl.c
+++ b/decl.c
@@ -33,7 +33,7 @@
 	} else if (ns != NS_TYPE) {
 		if (yytoken == IDEN) {
 			sym = lookup(yytext, ns);
-			if (!sym->ctype.defined)
+			if (!sym->ctype.type)
 				sym->ctx = curctx;
 			else if (sym->ctx == curctx)
 				goto redeclared;
@@ -72,107 +72,10 @@
 error:	error(err, yytext);
 }
 
-static unsigned char
-newtag(unsigned char type)
-{
-	if (type == ENUM)
-		return 0;
-	if (nr_tags == NS_TAG + NR_MAXSTRUCTS)
-		error("too much structs/unions defined");
-	return ++nr_tags;
-}
+static void structdcl(register struct ctype *tp);
+static void enumdcl(struct ctype *base);
 
-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);
-		aux = &sym->ctype;
-		if (aux->defined) {
-			if (aux->type != tp->type)
-				goto bad_type;
-			*tp = *aux;
-		} else {
-			tp->tag = sym->name;
-			tp->ns = newtag(tp->type);
-			sym->ctype = *tp;
-		}
-		next();
-	} else {
-		tp->ns = newtag(tp->type);
-	}
-
-	return sym;
-
-bad_type:
-	error("'%s' defined as wrong kind of tag", yytext);
-}
-
 static void
-structdcl(register struct ctype *tp)
-{
-	struct symbol *sym;
-
-	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;
-	while (!accept('}'))
-		decl(tp->ns);
-	--nested_tags;
-
-	if (sym)
-		sym->ctype.forward = 0;
-	tp->forward = 0;
-}
-
-static void
-enumdcl(struct ctype *base)
-{
-	static int val;
-
-	aggregate(base);
-	if (!accept('{'))
-		return;
-	val = 0;
-
-	do {
-		register struct symbol *sym;
-		register struct ctype *tp;
-
-		if (yytoken != IDEN)
-			break;
-		sym = lookup(yytext, NS_IDEN);
-		tp = &sym->ctype;
-		if (tp->defined && sym->ctx == curctx)
-			error("'%s' redefined", yytext);
-		next();
-		if (accept('=')) {
-			expect(CONSTANT);
-			val = yyval->i;
-		}
-		ctype(tp, INT);
-		tp->base = base;
-		sym->i = val++;
-	} while (accept(','));
-
-	expect('}');
-}
-
-static bool
 specifier(register struct ctype *tp, char *store, char *qlf)
 {
 	unsigned char tok;
@@ -201,7 +104,7 @@
 					enumdcl(tp);
 				else
 					structdcl(tp);
-				return true;
+				return;
 			case TYPENAME:
 				tp->base = &yyval->ctype;
 				break;
@@ -213,16 +116,6 @@
 	}
 
 check_type:
-	if (!tp->defined) {
-		if (*store && *qlf &&
-		    curctx != CTX_OUTER &&
-		    nested_tags == 0) {
-			return false;
-		}
-		warn(options.implicit,
-		     "type defaults to 'int' in declaration");
-	}
-
 	if (!tp->c_signed && !tp->c_unsigned) {
 		switch (tp->type) {
 		case CHAR:
@@ -233,8 +126,10 @@
 		case INT: case SHORT: case LONG: case LLONG:
 			tp->c_signed = 1;
 		}
+	} else if (!tp->type) {
+		tp->type = INT;
 	}
-	return true;
+	return;
 }
 
 static struct symbol *
@@ -294,6 +189,9 @@
 
 	c.tree = NULL;
 
+	if (yytoken == ';')
+		return NULL;
+
 	do {
 		struct node *np, *aux;
 		register struct ctype *tp;
@@ -344,7 +242,6 @@
 		}
 	} while (accept(','));
 
-	expect(';');
 	return c.tree;
 
 bad_type:
@@ -358,27 +255,134 @@
 error: error(err);
 }
 
+static unsigned char
+newtag(unsigned char type)
+{
+	if (type == ENUM)
+		return 0;
+	if (nr_tags == NS_TAG + NR_MAXSTRUCTS)
+		error("too much structs/unions defined");
+	return ++nr_tags;
+}
+
+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);
+		aux = &sym->ctype;
+		if (aux->type) {
+			if (aux->type != tp->type)
+				goto bad_type;
+			*tp = *aux;
+		} else {
+			tp->tag = sym->name;
+			tp->ns = newtag(tp->type);
+			sym->ctype = *tp;
+		}
+		next();
+	} else {
+		tp->ns = newtag(tp->type);
+	}
+
+	return sym;
+
+bad_type:
+	error("'%s' defined as wrong kind of tag", yytext);
+}
+
+static void
+structdcl(register struct ctype *tp)
+{
+	struct symbol *sym;
+
+	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;
+	while (!accept('}')) {
+		struct ctype base;
+		struct node *np;
+		char store = 0, qlf = 0;
+
+		initctype(&base);
+		specifier(&base, &store, &qlf);
+
+		if (store)
+			error("storage specifier in a struct/union field declaration");
+
+		listdcl(&base, store, qlf, tp->ns, 0);
+		expect(';');
+	}
+	--nested_tags;
+
+	if (sym)
+		sym->ctype.forward = 0;
+	tp->forward = 0;
+}
+
+static void
+enumdcl(struct ctype *base)
+{
+	static int val;
+
+	aggregate(base);
+	if (!accept('{'))
+		return;
+	val = 0;
+
+	do {
+		register struct symbol *sym;
+		register struct ctype *tp;
+
+		if (yytoken != IDEN)
+			break;
+		sym = lookup(yytext, NS_IDEN);
+		tp = &sym->ctype;
+		if (tp->type && sym->ctx == curctx)
+			error("'%s' redefined", yytext);
+		next();
+		if (accept('=')) {
+			expect(CONSTANT);
+			val = yyval->i;
+		}
+		ctype(tp, INT);
+		tp->base = base;
+		sym->i = val++;
+	} while (accept(','));
+
+	expect('}');
+}
+
 struct node *
 decl(unsigned char ns)
 {
 	struct ctype base;
+	struct node *np;
 	char store = 0, qlf = 0;
 
 	initctype(&base);
+	specifier(&base, &store, &qlf);
 
-	if (!specifier(&base, &store, &qlf))
-		return NULL;
-
 	if (store && ns != NS_IDEN)
 		error("storage specifier in a struct/union field declaration");
 
-	switch (base.type) {
-	case STRUCT: case UNION: case ENUM:
-		if (yytoken == ';')
-			return NULL;
-	default:
-		return listdcl(&base, store, qlf, ns, 0);
-	}
+	np = listdcl(&base, store, qlf, ns, 0);
+	expect(';');
+	return np;
 }
 
 void
@@ -387,11 +391,33 @@
 	char store = 0, qlf = 0;
 
 	initctype(tp);
-
-	if (!specifier(tp, &store, &qlf))
-		return;
-
+	specifier(tp, &store, &qlf);
 	declarator(tp, NS_TYPE, 0);
 	return;
 }
 
+struct node *
+extdecl(void)
+{
+	struct ctype base;
+	struct node *np;
+	char store = 0, qlf = 0;
+
+	initctype(&base);
+
+	switch (yytoken) {
+	case IDEN:
+		warn(options.implicit,
+		     "type defaults to 'int' in declaration");
+		base.type = INT;
+		break;
+	case TYPE: case STORAGE: case TQUALIFIER:
+		specifier(&base, &store, &qlf);
+		break;
+	default:
+		error("declaration expected");
+	}
+
+	np = listdcl(&base, store, qlf, 0, 0);
+	expect(';');
+}
\ No newline at end of file
--- a/expr.c
+++ b/expr.c
@@ -18,7 +18,7 @@
 	switch (yytoken) {
 	case IDEN:
 		sym = lookup(yytext, NS_IDEN);
-		if (!sym->ctype.defined)
+		if (!sym->ctype.type)
 			error("'%s' undeclared", yytext);
 		next();
 		np = nodesym(sym);
--- a/main.c
+++ b/main.c
@@ -19,7 +19,7 @@
 	init_keywords();
 	open_file(NULL);
 	for (next(); yytoken != EOFTOK; run(np))
-		np = decl(0);
+		np = extdecl();
 
 	return 0;
 }
--- a/symbol.h
+++ b/symbol.h
@@ -26,7 +26,6 @@
 	bool c_unsigned : 1;
 	bool c_signed : 1;
 	bool forward : 1;
-	bool defined: 1;
 	union {
 		struct {
 			unsigned char ns;
--- a/syntax.h
+++ b/syntax.h
@@ -29,6 +29,7 @@
 };
 
 extern struct node *expr(void);
+extern struct node *extdecl(void);
 extern struct node *decl(unsigned char ns);
 extern void type_name(struct ctype *tp);
 extern struct node *function(struct symbol *sym);
--- a/types.c
+++ b/types.c
@@ -16,7 +16,6 @@
 initctype(register struct ctype *tp)
 {
 	memset(tp, 0, sizeof(*tp));
-	tp->type = INT;
 	tp->forward = 1;
 	return tp;
 }
@@ -62,7 +61,6 @@
 	default:
 		assert(0);
 	}
-	tp->defined = 1;
 	return tp;
 }
 
@@ -91,10 +89,6 @@
 	register unsigned char type;
 	static char *err;
 
-	if (!tp->defined) {
-		tp->type = 0;
-		tp->defined = 1;
-	}
 	type = tp->type;
 
 
--