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:
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: