shithub: scc

Download patch

ref: b030a1fcb12be82e5c78e76c3a9a3eb76879334c
parent: 627efdb4af18c26fa5707e247fc276837cfed3db
author: Roberto E. Vargas Caballero <[email protected]>
date: Mon Mar 17 14:02:22 EDT 2014

Create newtag function

This function will be used by struct, enum and union in order to create
a new tag.

--- a/decl.c
+++ b/decl.c
@@ -177,6 +177,7 @@
 			switch (sym->u.c) {
 			case ENUM: case STRUCT: case UNION:
 				t = sym->u.c;
+				next();
 				tp = (t == UNION) ? enumdcl(t) : structdcl(t);
 				p = &type;
 				goto check_spec;
@@ -288,14 +289,11 @@
 }
 
 static struct ctype *
-structdcl(uint8_t tag)
+newtag(uint8_t tag)
 {
 	register struct symbol *sym;
-	struct ctype *tp;
-	short size;
 	extern uint8_t namespace;
 
-	next();
 	if (yytoken == IDEN) {
 		sym = lookup(yytext, NS_TAG);
 		if (sym) {
@@ -308,28 +306,40 @@
 	} else {
 		sym = install(NULL, NS_TAG);
 	}
-	sym->type = tp = mktype(NULL, STRUCT, NULL, 0);
 	++namespace;
+	return sym->type = mktype(NULL, tag, NULL, 0);
 
+bad_tag:
+	error("'%s' defined as wrong kind of tag", yytext);
+}
+
+static struct ctype *
+structdcl(uint8_t tag)
+{
+	struct ctype *tp;
+	short size = 0;
+
+	tp = newtag(tag);
 	if (yytoken != ';') {
 		expect('{');
+		if (tp->defined)
+			goto redefined;
 		while (!accept('}'))
 			size = fielddcl(namespace, tag);
-	} else {
-		size = 0;
+		tp->size = size;
+		tp->defined = 1;
 	}
-	tp->size = size;
 
 	return tp;
 
-bad_tag:
-	error("error '%s' defined as wrong kind of tag", yytext);
+redefined:
+	error("redefinition of struct/union '%s'", yytext);
 }
 
 static struct ctype *
 enumdcl(uint8_t token)
 {
-	return NULL;
+	/* TODO: create function for creating identifiers */
 }
 
 struct node *
--- a/symbol.h
+++ b/symbol.h
@@ -21,9 +21,9 @@
 
 struct ctype {
 	uint8_t op;           /* type builder operator */
-	uint8_t size;         /* size of variables */
-	uint16_t nelem;       /* number of elements in arrays */
-	unsigned forward : 1; /* forward type */
+	short size;           /* size of variables */
+	short nelem;          /* number of elements in arrays */
+	unsigned defined : 1; /* type defined (is not a forward reference) */
 	unsigned cplex : 1;   /* complex specifier */
 	unsigned imag : 1;
 	unsigned sign : 1;    /* sign type */
--- a/types.c
+++ b/types.c
@@ -162,7 +162,7 @@
 	t = (op  ^  (uint8_t) ((unsigned short) tp >> 3))
 	         & NR_TYPE_HASH-1;
 	tbl = &typetab[t];
-	if (op != FTN || op != STRUCT || op != ENUM) {
+	if (op != FTN || op != STRUCT || op != UNION || op != ENUM) {
 		for (bp = *tbl; bp; bp = bp->next) {
 			if (bp->type == tp && bp->op == op &&
 			    bp->sym == sym && bp->nelem == nelem) {