scc

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

commit 17834699b2e8786effcd3fda322db20779710286
parent e6f7d19657b0acc6a6cbb87da073a18c44efe883
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 15 Nov 2014 05:55:45 -0500

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).

Diffstat:
Mcc1/cc1.h | 17++++++-----------
Mcc1/decl.c | 67++++++++++++++++++++++++-------------------------------------------
Mcc1/expr.c | 4++--
Mcc1/lex.c | 2+-
Mcc1/types.c | 31+++++++++++++++----------------
5 files changed, 48 insertions(+), 73 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -39,23 +39,18 @@ 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 */ - 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 @@ struct symbol { 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), diff --git 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 @@ arydcl(struct dcldata *dp) { expect('['); expect(']'); - return queue(dp, ARY, (union dclunion) {.nelem = 0}); + return queue(dp, ARY, 0, NULL); } static Type *parameter(void); @@ -46,38 +44,29 @@ static struct dcldata * 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 @@ directdcl(struct dcldata *dp) 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 @@ declarator0(struct dcldata *dp) dp = directdcl(dp); while (n--) - dp = queue(dp, PTR, (union dclunion) {}); + dp = queue(dp, PTR, 0, NULL); return dp; } @@ -148,18 +137,10 @@ declarator(Type *tp, int8_t flags) 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 @@ newtag(uint8_t tag) 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); diff --git a/cc1/expr.c b/cc1/expr.c @@ -114,7 +114,7 @@ integeruop(char op, Node *np) 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 @@ address(char op, Node *np) 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 * diff --git a/cc1/lex.c b/cc1/lex.c @@ -181,7 +181,7 @@ end_string: *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; } diff --git a/cc1/types.c b/cc1/types.c @@ -186,7 +186,7 @@ invalid_type: } 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 @@ mktype(Type *tp, uint8_t op, void *data) 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 @@ mktype(Type *tp, uint8_t op, void *data) 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 @@ mktype(Type *tp, uint8_t op, void *data) bp->op = op; bp->letter = letter; bp->defined = def; + bp->nelem = nelem; bp->u = u; return *tbl = bp; } @@ -255,25 +255,24 @@ mktype(Type *tp, uint8_t op, void *data) 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 @@ eqtype(Type *tp1, Type *tp2) 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: