commit cd295810c421544600c991fbf93c6d8c8b535231
parent 0b8f18a02b36d3cb05b703f9dac7953924942a49
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 13 Aug 2015 11:55:21 +0200
Emit struct types
Diffstat:
4 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -33,6 +33,7 @@ struct type {
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 */
diff --git a/cc1/code.c b/cc1/code.c
@@ -225,6 +225,7 @@ emittype(Type *tp)
{
int n;
Type **vp;
+ Symbol **sp;
if (tp->printed)
return;
@@ -241,6 +242,18 @@ emittype(Type *tp)
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;
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -381,10 +381,14 @@ newtag(void)
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 @@ field(struct decl *dcl)
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;
diff --git a/cc1/types.c b/cc1/types.c
@@ -311,7 +311,7 @@ mktype(Type *tp, unsigned op, short nelem, Type *pars[])
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 @@ eqtype(Type *tp1, Type *tp2)
}
return 1;
case ENUM:
- break;
+ return 0;
case INT:
case FLOAT:
return tp1->letter == tp2->letter;