shithub: scc

Download patch

ref: cd295810c421544600c991fbf93c6d8c8b535231
parent: 0b8f18a02b36d3cb05b703f9dac7953924942a49
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Aug 13 07:55:21 EDT 2015

Emit struct types

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -33,6 +33,7 @@
 	Type *type;                 /* base type */
 	Type *next;                 /* next element in the hash */
 	Type **pars;                /* type parameters */
+	Symbol **fields;            /* fields of aggregate type */
 	union {
 		unsigned char rank;     /* convertion rank */
 		short elem;             /* number of type parameters */
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -225,6 +225,7 @@
 {
 	int n;
 	Type **vp;
+	Symbol **sp;
 
 	if (tp->printed)
 		return;
@@ -241,6 +242,18 @@
 	case PTR:
 		emittype(tp->type);
 		return;
+	case UNION:
+	case STRUCT:
+		n = tp->n.elem;
+		for (sp = tp->fields; n-- > 0; ++sp)
+			emittype((*sp)->type);
+		emitletter(tp);
+		puts("\t(");
+		n = tp->n.elem;
+		for (sp = tp->fields; n-- > 0; ++sp)
+			emit(ODECL, *sp);
+		puts(")");
+		break;
 	case FTN:
 		emitletter(tp);
 		n = tp->n.elem;
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -381,10 +381,14 @@
 		break;
 	}
 	if (!sym->type) {
+		Type *tp;
+
 		if (ns == NS_STRUCTS + NR_MAXSTRUCTS)
 			error("too much tags declared");
-		sym->type = mktype(NULL, tag, 0, NULL);
-		sym->type->ns = ns++;
+		tp = mktype(NULL, tag, 0, NULL);
+		tp->ns = ns++;
+		tp->fields = NULL;
+		sym->type = tp;
 	}
 
 	if ((op = sym->type->op) != tag &&  op != INT)
@@ -499,8 +503,8 @@
 	sym->flags |= ISFIELD;
 	if (n++ == NR_FUNPARAM)
 		error("too much fields in struct/union");
-	structp->pars = xrealloc(structp->pars, n);
-	structp->pars[n-1] = tp;
+	structp->fields = xrealloc(structp->fields, n * sizeof(*sym));
+	structp->fields[n-1] = sym;
 	structp->n.elem = n;
 
 	return sym;
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -311,7 +311,7 @@
 	t = (op ^ (uintptr_t) tp >> 3) & NR_TYPE_HASH-1;
 	tbl = &typetab[t];
 	for (bp = *tbl; bp; bp = bp->next) {
-		if (eqtype(bp, &type)) {
+		if (eqtype(bp, &type) && op != STRUCT && op != UNION) {
 			/*
 			 * pars was allocated by the caller
 			 * but the type already exists, so
@@ -353,7 +353,7 @@
 		}
 		return 1;
 	case ENUM:
-		break;
+		return 0;
 	case INT:
 	case FLOAT:
 		return tp1->letter == tp2->letter;
--