scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 7d7ee21e09b35138c6be3cace6c0d9778c90603c
parent 07345f7f24d63fed872049435421452e92622483
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  5 Aug 2014 17:57:51 +0200

Update type union field in mkfile()

mkfile() creates a new type applying an operator to an existing
type. Some of the operators have some parameter, that is stored
in an union in Type. This union was not ever assigned, so the
fields was always empties.

Diffstat:
Mcc1/cc1.h | 18+++++++-----------
Mcc1/decl.c | 13++++++++-----
Mcc1/types.c | 57++++++++++++++++++++++++++++++++++++++++++---------------
3 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -31,7 +31,6 @@ enum { typedef struct ctype Type; typedef struct symbol Symbol; -typedef struct funpar Funpar; typedef struct field { char *name; @@ -40,6 +39,11 @@ typedef struct field { 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 */ @@ -47,7 +51,7 @@ struct ctype { bool sign : 1; /* sign type */ struct ctype *type; /* base type */ struct ctype *next; /* next element in the hash */ - union { + union typeval { unsigned char rank; /* convertion rank */ short nelem; /* number of elements in arrays */ struct funpar *pars; /* function parameters */ @@ -56,16 +60,8 @@ struct ctype { }; - -struct funpar { - Type *type; - struct funpar *next; -}; - /* definition of symbols */ - - struct symbol { char *name; Type *type; @@ -90,7 +86,7 @@ struct symbol { }; extern Type *ctype(int8_t type, int8_t sign, int8_t size), - *mktype(Type *tp, uint8_t op, uint16_t nelem); + *mktype(Type *tp, uint8_t op, void *data); extern Symbol *lookup(char *s, unsigned char ns), diff --git a/cc1/decl.c b/cc1/decl.c @@ -11,6 +11,8 @@ #define ID_ACCEPTED 2 #define ID_FORBIDDEN 3 +/* TODO: check identifiers in enum declaration */ + struct dcldata { uint8_t op; union dclunion { @@ -148,13 +150,13 @@ declarator(Type *tp, int8_t flags) for (bp = declarator0(data); bp >= data; --bp) { switch (bp->op) { case PTR: - tp = mktype(tp, PTR, 0); + tp = mktype(tp, PTR, NULL); break; case ARY: - tp = mktype(tp, ARY, bp->u.nelem); + tp = mktype(tp, ARY, &bp->u.nelem); break; case FTN: - tp = mktype(tp, FTN, 0); + tp = mktype(tp, FTN, bp->u.pars); break; case IDEN: sym = bp->u.sym; @@ -351,8 +353,9 @@ newtag(uint8_t tag) sym = install("", NS_TAG); break; } - if (!(tp = sym->type)) - tp = sym->type = mktype(NULL, tag, 0); + if (!sym->type) + sym->type = mktype(NULL, tag, NULL); + tp = sym->type; if (tp->op != tag) error("'%s' defined as wrong kind of tag", yytext); return tp; diff --git a/cc1/types.c b/cc1/types.c @@ -141,42 +141,69 @@ ctype(int8_t type, int8_t sign, int8_t size) } Type * -mktype(Type *tp, uint8_t op, uint16_t nelem) +mktype(Type *tp, uint8_t op, void *data) { static Type *typetab[NR_TYPE_HASH], **tbl; static uint8_t t, def; register Type *bp; - char letter; + char letter, look; + union typeval u; + + switch (op) { + case PTR: + if (tp == voidtype) + return pvoidtype; + letter = L_POINTER; + def = 1; + look = 1; + break; + case ARY: + u.nelem = *(unsigned short *) data; + letter = L_ARRAY; + def = u.nelem != 0; + look = 1; + break; + case FTN: + u.pars = data; + letter = L_FUNCTION; + def = 1; + look = 0; + break; + case ENUM: + letter = L_INT; + def = 1; + look = 0; + break; + case STRUCT: case UNION: + letter = (op == STRUCT) ? L_STRUCT : L_UNION; + def = 0; + look = 0; + u.fields = NULL; + break; + default: + fputs("internal type error, aborting\n", stderr); + abort(); + } - if (op == PTR && tp == voidtype) - return pvoidtype; t = (op ^ (uint8_t) ((unsigned short) tp >> 3)) & NR_TYPE_HASH-1; tbl = &typetab[t]; - if (op != FTN || op != STRUCT || op != UNION || op != ENUM) { + if (look) { for (bp = *tbl; bp; bp = bp->next) { if (bp->type == tp && bp->op == op && - (op != ARY || bp->u.nelem == nelem)) { + (op != ARY || bp->u.nelem == u.nelem)) { return bp; } } } - switch (op) { - case PTR: letter = L_POINTER, def = 1; break; - case FTN: letter = L_FUNCTION, def = 1; break; - case ARY: letter = L_ARRAY, def = nelem != 0; break; - case ENUM: letter = L_INT, def = 0; break; - case STRUCT: letter = L_STRUCT, def = 0; break; - /* TODO case UNION: */ - default: letter = tp->letter; /* is it possible? */ - } bp = xcalloc(1, sizeof(*bp)); bp->next = *tbl; bp->type = tp; bp->op = op; bp->letter = letter; bp->defined = def; + bp->u = u; return *tbl = bp; }