diff options
author | Anders Magnusson <ragge@cvs.openbsd.org> | 2007-11-18 17:39:56 +0000 |
---|---|---|
committer | Anders Magnusson <ragge@cvs.openbsd.org> | 2007-11-18 17:39:56 +0000 |
commit | ffbcd0d1cc4b8a79cd425a475380a55dc3d1b6e8 (patch) | |
tree | 3f2710e8c7df5eef44042f03eaf7ecb0918a7553 /usr.bin/pcc/ccom/pftn.c | |
parent | 0002b12aff4753fec661ccc9e71178e0039ede32 (diff) |
(Large) update from master repo:
> Use structure assignment instead of calling memcpy directly in struct return.
> Rewrite enum handling.
> In C99 enums are treated like INTs so convert them early to int.
> Move the enum tag handling out of defid(), tags are in their own namespace.
> This will be done with struct/union tags also.
> Comment out enum types.
> Remove ENUMTY/MOETY from target code.
Diffstat (limited to 'usr.bin/pcc/ccom/pftn.c')
-rw-r--r-- | usr.bin/pcc/ccom/pftn.c | 212 |
1 files changed, 126 insertions, 86 deletions
diff --git a/usr.bin/pcc/ccom/pftn.c b/usr.bin/pcc/ccom/pftn.c index 21c59e71839..a602e7322d9 100644 --- a/usr.bin/pcc/ccom/pftn.c +++ b/usr.bin/pcc/ccom/pftn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pftn.c,v 1.7 2007/11/16 09:00:12 otto Exp $ */ +/* $OpenBSD: pftn.c,v 1.8 2007/11/18 17:39:55 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -89,7 +89,7 @@ int reached, prolab; struct params; -#define ISSTR(ty) (ty == STRTY || ty == UNIONTY || ty == ENUMTY) +#define ISSTR(ty) (ty == STRTY || ty == UNIONTY) #define ISSOU(ty) (ty == STRTY || ty == UNIONTY) #define MKTY(p, t, d, s) r = talloc(); *r = *p; \ r = argcast(r, t, d, s); *p = *r; nfree(r); @@ -204,8 +204,6 @@ defid(NODE *q, int class) case STNAME: case MOU: case UNAME: - case MOE: - case ENAME: case TYPEDEF: ; } @@ -254,9 +252,9 @@ defid(NODE *q, int class) #endif /* check that redeclarations are to the same structure */ - if ((temp == STRTY || temp == UNIONTY || temp == ENUMTY) && + if ((temp == STRTY || temp == UNIONTY) && p->ssue != q->n_sue && - class != STNAME && class != UNAME && class != ENAME) { + class != STNAME && class != UNAME) { goto mismatch; } @@ -334,9 +332,6 @@ defid(NODE *q, int class) } break; - case MOE: - break; - case EXTDEF: switch (scl) { case EXTERN: @@ -350,7 +345,6 @@ defid(NODE *q, int class) case STNAME: case UNAME: - case ENAME: if (scl != class) break; if (p->ssue->suesize == 0) @@ -390,22 +384,26 @@ defid(NODE *q, int class) p->slevel = blevel; p->soffset = NOOFFSET; p->suse = lineno; - if (class == STNAME || class == UNAME || class == ENAME) { + if (class == STNAME || class == UNAME) { p->ssue = permalloc(sizeof(struct suedef)); suedefcnt++; p->ssue->suesize = 0; p->ssue->suelem = NULL; p->ssue->suealign = ALSTRUCT; } else { + if (q->n_sue == NULL) + cerror("q->n_sue == NULL"); + p->ssue = q->n_sue; +#if 0 switch (BTYPE(type)) { case STRTY: case UNIONTY: - case ENUMTY: p->ssue = q->n_sue; break; default: p->ssue = MKSUE(BTYPE(type)); } +#endif } /* copy dimensions */ @@ -464,12 +462,6 @@ defid(NODE *q, int class) strucoff = 0; ssave(p); break; - - case MOE: - p->soffset = strucoff++; - ssave(p); - break; - } #ifdef STABS @@ -656,9 +648,9 @@ rstruct(char *tag, int soru) q = block(NAME, NIL, NIL, 0, 0, 0); q->n_sp = p; q->n_type = (soru&INSTRUCT) ? STRTY : - ((soru&INUNION) ? UNIONTY : ENUMTY); + ((soru&INUNION) ? UNIONTY : 0); defid(q, (soru&INSTRUCT) ? STNAME : - ((soru&INUNION) ? UNAME : ENAME)); + ((soru&INUNION) ? UNAME : 0)); nfree(q); break; @@ -672,26 +664,122 @@ rstruct(char *tag, int soru) break; goto def; - case ENUMTY: - if (!(soru&(INUNION|INSTRUCT))) - break; - goto def; - } q = mkty(p->stype, 0, p->ssue); q->n_sue = p->ssue; return q; } +/* + * Declare a struct/union/enum tag. + * If not found, create a new tag with UNDEF type. + */ +static struct symtab * +deftag(char *name, int class) +{ + struct symtab *sp; + + sp = lookup(name, STAGNAME); + if (sp->ssue == NULL) + sp->ssue = permalloc(sizeof(struct suedef)); + if (sp->sclass == SNULL) { + /* New tag */ + sp->sclass = class; + } else if (sp->slevel < blevel) { + /* declared at different block level, hide it */ + sp = hide(sp); + sp->sclass = class; + } else if (sp->sclass != class) { + /* redeclaration of tag */ + uerror("tag %s redeclared", name); + } + return sp; +} + +static int enumlow, enumhigh; +int enummer; + +/* + * Declare a member of enum. + */ void moedef(char *name) { - NODE *q; + struct symtab *sp; - q = block(NAME, NIL, NIL, MOETY, 0, 0); - q->n_sp = lookup(name, 0); - defid(q, MOE); - nfree(q); + sp = lookup(name, SNORMAL); + if (sp->stype == UNDEF || (sp->slevel < blevel)) { + if (sp->stype != UNDEF) + sp = hide(sp); + sp->stype = INT; /* always */ + sp->ssue = MKSUE(INT); + sp->sclass = MOE; + sp->soffset = enummer; + } else + uerror("%s redeclared", name); + if (enummer < enumlow) + enumlow = enummer; + if (enummer > enumhigh) + enumhigh = enummer; + enummer++; +} + +/* + * Declare an enum tag. Complain if already defined. + */ +struct symtab * +enumhd(char *name) +{ + struct symtab *sp; + + enummer = enumlow = enumhigh = 0; + if (name == NULL) + return NULL; + + sp = deftag(name, ENAME); + if (sp->stype != UNDEF) /* enum type already declared */ + uerror("%s redeclared", name); + return sp; +} + +/* + * finish declaration of an enum + */ +NODE * +enumdcl(struct symtab *sp) +{ + TWORD t; + +#ifdef ENUMSIZE + t = ENUMSIZE(enumhigh, enumlow); +#else + if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR) + t = ctype(CHAR); + else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT) + t = ctype(SHORT); + else + t = ctype(INT); +#endif + if (sp) { + sp->stype = t; + sp->ssue = MKSUE(t); + } + return mkty(t, 0, MKSUE(t)); +} + +/* + * Handle reference to an enum + */ +NODE * +enumref(char *name) +{ + struct symtab *sp; + + sp = lookup(name, STAGNAME); + if (sp->sclass != ENAME) + uerror("enum %s undeclared", name); + + return mkty(sp->stype, 0, sp->ssue); } /* @@ -728,11 +816,8 @@ bstruct(char *name, int soru) q->n_type = UNIONTY; if (s != NULL) defid(q, UNAME); - } else { /* enum */ - strunem = MOE; - q->n_type = ENUMTY; - if (s != NULL) - defid(q, ENAME); + } else { + cerror("bstruct"); } r->rsym = q->n_sp; r->rlparam = lparam; @@ -767,7 +852,7 @@ dclstruct(struct rstack *r, int pa) if (ddebug) printf("dclstruct(%s)\n", r->rsym ? r->rsym->sname : "??"); #endif - temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY); + temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:0); instruct = r->rinstruct; strunem = r->rclass; al = ALSTRUCT; @@ -793,14 +878,6 @@ dclstruct(struct rstack *r, int pa) if (p == NULL) cerror("gummy structure member"); - if (temp == ENUMTY) { - if (p->soffset < low) - low = p->soffset; - if (p->soffset > high) - high = p->soffset; - p->ssue = sue; - continue; - } sa = talign(p->stype, p->ssue); if (p->sclass & FIELD) sz = p->sclass&FLDSIZ; @@ -827,23 +904,6 @@ dclstruct(struct rstack *r, int pa) sue->suelem[i] = NULL; SETOFF(strucoff, al); - if (temp == ENUMTY) { - TWORD ty; - -#ifdef ENUMSIZE - ty = ENUMSIZE(high,low); -#else - if ((char)high == high && (char)low == low) - ty = ctype(CHAR); - else if ((short)high == high && (short)low == low) - ty = ctype(SHORT); - else - ty = ctype(INT); -#endif - strucoff = tsize(ty, 0, MKSUE(ty)); - sue->suealign = al = talign(ty, MKSUE(ty)); - } - sue->suesize = strucoff; sue->suealign = al; @@ -1001,7 +1061,6 @@ talign(unsigned int ty, struct suedef *sue) switch( BTYPE(ty) ){ case UNIONTY: - case ENUMTY: case STRTY: return((unsigned int)sue->suealign); case BOOL: @@ -1366,14 +1425,6 @@ falloc(struct symtab *p, int w, int new, NODE *pty) /* this must be fixed to use the current type in alignments */ switch( new<0?pty->n_type:p->stype ){ - case ENUMTY: { - struct suedef *sue; - sue = new < 0 ? pty->n_sue : p->ssue; - al = sue->suealign; - sz = sue->suesize; - break; - } - case CHAR: case UCHAR: al = ALCHAR; @@ -1777,7 +1828,7 @@ tymerge(NODE *typ, NODE *idp) idp->n_qual = DECQAL(idp->n_qual); /* in case ctype has rewritten things */ - if ((t = BTYPE(idp->n_type)) != STRTY && t != UNIONTY && t != ENUMTY) + if ((t = BTYPE(idp->n_type)) != STRTY && t != UNIONTY) idp->n_sue = MKSUE(t); if (idp->n_op != NAME) { @@ -1816,8 +1867,7 @@ arglist(NODE *n) if (w->n_right->n_op == ELLIPSIS) continue; ty = w->n_right->n_type; - if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY || - BTYPE(ty) == ENUMTY) + if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY) num++; while (ISFTN(ty) == 0 && ISARY(ty) == 0 && ty > BTMASK) ty = DECREF(ty); @@ -1826,8 +1876,7 @@ arglist(NODE *n) } cnt++; ty = w->n_type; - if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY || - BTYPE(ty) == ENUMTY) + if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY) num++; while (ISFTN(ty) == 0 && ISARY(ty) == 0 && ty > BTMASK) ty = DECREF(ty); @@ -1861,8 +1910,7 @@ arglist(NODE *n) ap[j]->n_type = INCREF(ap[j]->n_type); ty = ap[j]->n_type; al[k++].type = ty; - if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY || - BTYPE(ty) == ENUMTY) + if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY) al[k++].sue = ap[j]->n_sue; while (ISFTN(ty) == 0 && ISARY(ty) == 0 && ty > BTMASK) ty = DECREF(ty); @@ -2124,7 +2172,7 @@ alprint(union arglist *al, int in) if (ISARY(al->type)) { printf(" dim %d\n", al->df->ddim); } else if (BTYPE(al->type) == STRTY || - BTYPE(al->type) == UNIONTY || BTYPE(al->type) == ENUMTY) { + BTYPE(al->type) == UNIONTY) { al++; printf(" (size %d align %d)", al->sue->suesize, al->sue->suealign); @@ -2311,9 +2359,6 @@ incomp: uerror("incompatible types for arg %d", } else goto out; } - if (BTYPE(arrt) == ENUMTY && BTYPE(type) == INT && - (arrt & ~BTMASK) == (type & ~BTMASK)) - goto skip; /* XXX enumty destroyed in optim() */ if (BTYPE(arrt) == VOID && type > BTMASK) goto skip; /* void *f = some pointer */ if (arrt > BTMASK && BTYPE(type) == VOID) @@ -2546,10 +2591,6 @@ fixclass(int class, TWORD type) if( !(instruct&INSTRUCT) ) uerror( "illegal MOS class" ); return( class ); - case MOE: - if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal MOE class" ); - return( class ); - case REGISTER: if (blevel == 0) uerror( "illegal register declaration" ); @@ -2576,7 +2617,6 @@ fixclass(int class, TWORD type) } case STNAME: case UNAME: - case ENAME: case EXTERN: case STATIC: case EXTDEF: |