shithub: scc

Download patch

ref: 17834699b2e8786effcd3fda322db20779710286
parent: e6f7d19657b0acc6a6cbb87da073a18c44efe883
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Nov 15 00:55:45 EST 2014

Fix error creating types of functions

Function types had a field for the parameters of the function, but
this field was not set. This patch fixes this problem and changes the list
of parameters to an array. We can use a dinamic array here, but the limit
is big enough (if someone uses more parameters then he should go to the
hell).

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -39,23 +39,18 @@
 	struct field *next;
 } Field;
 
-typedef struct funpar {
-	Type *type;
-	struct funpar *next;
-} Funpar;
-
 struct ctype {
 	uint8_t op;           /* type builder operator */
 	char letter;          /* letter of the type */
-	bool defined : 1; /* type defined (is not a forward reference) */
-	bool sign : 1;    /* sign type */
+	bool defined : 1;     /* type defined (is not a forward reference) */
+	bool sign : 1;        /* sign type */
 	struct ctype *type;   /* base type */
 	struct ctype *next;   /* next element in the hash */
+	short nelem;          /* number of elements in ary/ftn/strct/union */
 	union typeval {
 		unsigned char rank;   /* convertion rank */
-		short nelem;          /* number of elements in arrays */
-		struct funpar *pars;  /* function parameters */
-		Field *fields; /* aggregate fields */
+		Type **pars;         /* function parameters */
+		Field *fields;        /* aggregate fields */
 	} u;
 };
 
@@ -87,7 +82,7 @@
 
 extern bool eqtype(Type *tp1, Type *tp2);
 extern Type *ctype(int8_t type, int8_t sign, int8_t size),
-	*mktype(Type *tp, uint8_t op, void *data);
+	*mktype(Type *tp, uint8_t op, short nelem, void *data);
 
 extern Symbol
 	*lookup(char *s, unsigned char ns),
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -15,20 +15,18 @@
 
 struct dcldata {
 	uint8_t op;
-	union dclunion {
-		unsigned short nelem;
-		Symbol *sym;
-		Funpar *pars;
-	} u;
+	unsigned short nelem;
+	void *data;
 };
 
 static struct dcldata *
-queue(struct dcldata *dp, uint8_t op, union dclunion u)
+queue(struct dcldata *dp, uint8_t op, short nelem, void *data)
 {
 	if (dp->op == 255)
 		error("too much declarators");
 	dp->op = op;
-	dp->u = u;
+	dp->nelem = nelem;
+	dp->data = data;
 	return dp + 1;
 }
 
@@ -37,7 +35,7 @@
 {
 	expect('[');
 	expect(']');
-	return queue(dp, ARY, (union dclunion) {.nelem = 0});
+	return queue(dp, ARY, 0, NULL);
 }
 
 static Type *parameter(void);
@@ -46,38 +44,29 @@
 fundcl(struct dcldata *dp)
 {
 	uint8_t n = 0;
-	Funpar *fp;
+	size_t siz;
+	Type *pars[NR_FUNPARAM], **tp = &pars[0];
 
 	expect('(');
 
 	do {
-		Type *tp;
-
-		if ((tp = parameter()) == voidtype) {
+		if (tp == &pars[NR_FUNPARAM])
+			error("too much parameters in function definition");
+		
+		if ((*tp++ = parameter()) == voidtype) {
 			if (n == 0)
 				break;
 			else
 				error("incorrect void parameter");
 		}
-		/* TODO: Use an array and allocate memory at the end */
-		fp = xmalloc(sizeof(*fp));
-		fp->type = tp;
-		fp->next = NULL;
-		if (!dp->u.pars) {
-			dp->u.pars = fp;
-		} else {
-			register Funpar *p, *q;
-
-			for (p = dp->u.pars; q = p->next; p = q)
-				/* nothing */;
-			p->next = fp;
-		}
 		++n;
 	} while (accept(','));
 
-ret:
-	expect(')');;
-	return queue(dp, FTN, (union dclunion) {.pars = fp});
+	expect(')');
+	siz = sizeof(*tp) * n;
+	tp = (siz > 0) ? memcpy(xmalloc(siz), pars, siz) : NULL;
+
+	return queue(dp, FTN, n, tp);
 }
 
 static Symbol *
@@ -108,7 +97,7 @@
 			sym = newiden();
 		else
 			sym = install("", NS_IDEN);
-		dp = queue(dp, IDEN, (union dclunion) {.sym = sym});
+		dp = queue(dp, IDEN, 0, sym);
 	}
 
 	for (;;) {
@@ -133,7 +122,7 @@
 	dp = directdcl(dp);
 
 	while (n--)
-		dp = queue(dp, PTR, (union dclunion) {});
+		dp = queue(dp, PTR, 0, NULL);
 
 	return dp;
 }
@@ -148,18 +137,10 @@
 	memset(data, 0, sizeof(data));
 	data[NR_DECLARATORS].op = 255;
 	for (bp = declarator0(data)-1; bp >= data; --bp) {
-		switch (bp->op) {
-		case PTR:
-			tp = mktype(tp, PTR, NULL);
-			break;
-		case ARY:
-			tp = mktype(tp, ARY, &bp->u.nelem);
-			break;
-		case FTN:
-			tp = mktype(tp, FTN, bp->u.pars);
-			break;
-		case IDEN:
-			sym = bp->u.sym;
+		if (bp->op != IDEN) {
+			tp = mktype(tp, bp->op, bp->nelem, bp->data);
+		} else {
+			sym = bp->data;
 			if (flags == ID_EXPECTED && *sym->name == '\0')
 				error("missed identifier in declaration");
 			if (flags == ID_FORBIDDEN && *sym->name != '\0')
@@ -344,7 +325,7 @@
 		break;
 	}
 	if (!sym->type)
-		sym->type = mktype(NULL, tag, NULL);
+		sym->type = mktype(NULL, tag, 0, NULL);
 	tp = sym->type;
 	if (tp->op != tag)
 		error("'%s' defined as wrong kind of tag", yytext);
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -114,7 +114,7 @@
 static Node *
 decay(Node *np)
 {
-	return unarycode(OADDR, mktype(np->type, PTR, NULL), np);
+	return unarycode(OADDR, mktype(np->type, PTR, 0, NULL), np);
 }
 
 /*
@@ -378,7 +378,7 @@
 		error("lvalue required in unary expression");
 	if (np->b.symbol && np->u.sym->s.isregister)
 		error("address of register variable '%s' requested", yytext);
-	return unarycode(op, mktype(np->type, PTR, 0), np);
+	return unarycode(op, mktype(np->type, PTR, 0, NULL), np);
 }
 
 static Node *
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -181,7 +181,7 @@
 	*bp = '\0';
 	sym = install("", NS_IDEN);
 	sym->u.s = xstrdup(buf);
-	sym->type = mktype(chartype, PTR, 0);
+	sym->type = mktype(chartype, PTR, 0, NULL);
 	yylval.sym = sym;
 	return STRING;
 }
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -186,7 +186,7 @@
 }
 
 Type *
-mktype(Type *tp, uint8_t op, void *data)
+mktype(Type *tp, uint8_t op, short nelem, void *data)
 {
 	static Type *typetab[NR_TYPE_HASH], **tbl;
 	static uint8_t t, def;
@@ -203,9 +203,8 @@
 		look = 1;
 		break;
 	case ARY:
-		u.nelem = *(unsigned short *) data;
 		letter = L_ARRAY;
-		def = u.nelem != 0;
+		def = nelem != 0;
 		look = 1;
 		break;
 	case FTN:
@@ -236,7 +235,7 @@
 	if (look) {
 		for (bp = *tbl; bp; bp = bp->next) {
 			if (bp->type == tp && bp->op == op &&
-			    (op != ARY || bp->u.nelem == u.nelem)) {
+			    (op != ARY || bp->nelem == nelem)) {
 				return bp;
 			}
 		}
@@ -248,6 +247,7 @@
 	bp->op = op;
 	bp->letter = letter;
 	bp->defined = def;
+	bp->nelem = nelem;
 	bp->u = u;
 	return *tbl = bp;
 }
@@ -255,25 +255,24 @@
 bool
 eqtype(Type *tp1, Type *tp2)
 {
+	uint8_t n;
+	Type **p1, **p2;
+
 	if (tp1 == tp2)
 		return 1;
-	if (tp1->op != tp2->op)
+	if (tp1->op != tp2->op || tp1->nelem != tp2->nelem)
 		return 0;
 	switch (tp1->op) {
 	case PTR:
 		return eqtype(tp1->type, tp2->type);
 	/* TODO: use the same struct for function parameters and fields */
-	case FTN: {
-		Funpar *fp1 = tp1->u.pars, *fp2 = tp2->u.pars;
-
-		while (fp1 && fp2) {
-			if (!eqtype(fp1->type, fp2->type))
-				break;
-			fp1 = fp1->next;
-			fp2 = fp2->next;
+	case FTN:
+		p1 = tp1->u.pars, p2 = tp2->u.pars;
+		for (n = tp1->nelem; n != 0; --n) {
+			if (!eqtype(*p1++, *p2++))
+				return 0;
 		}
-		return fp1 == fp2;
-	}
+		return 1;
 	case UNION:
 	case STRUCT: {
 		Field *fp1 = tp1->u.fields, *fp2 = tp2->u.fields;
@@ -289,7 +288,7 @@
 	case ARY:
 		if (!eqtype(tp1->type, tp2->type))
 			return 0;
-		return tp1->u.nelem == tp2->u.nelem;
+		return 1;
 	case ENUM: case INT: case FLOAT:
 		return tp1->letter == tp2->letter;
 	default:
--