* Process a single declarator
*/
/* convert detailed type description to old type description */
+void XXXdumptype(dtype) struct type *dtype; {
+ static char *basic_types[] = {
+ "INT",
+ "CHAR",
+ "FLOAT",
+ "DOUBLE",
+ "STRUCT",
+ "RSTRUCT",
+ "LONG",
+ "UNSIGN",
+ "UNCHAR",
+ "UNLONG",
+ "VOID",
+ "REF",
+ "BITFLD"
+ };
+ switch (dtype->t_id) {
+ case REF | PTR:
+ fprintf(stderr, "PTR,");
+ goto reftype;
+ case REF | FUNC:
+ fprintf(stderr, "FUNC,");
+ goto reftype;
+ case REF | ARRAY:
+ fprintf(stderr, "ARRAY(%d),", ((struct atype *)dtype)->at_nelt);
+ reftype:
+ XXXdumptype(((struct rtype *)dtype)->rt_reftype);
+ break;
+ default:
+ fprintf(stderr, "%s", basic_types[dtype->t_id]);
+ break;
+ }
+}
int XXXoldtype(dtype, dimp, strp) struct type *dtype; struct tdim *dimp; struct SS **strp; {
int type;
switch (dtype->t_id) {
case REF | PTR:
- /*fprintf(stderr, "ptr(");*/
type = XXXoldtype(((struct rtype *)dtype)->rt_reftype, dimp, strp);
if (type & BIGTYPE) {
typov();
type = (type & TYPE) | (type & ~TYPE) << TYLEN | PTR;
break;
case REF | FUNC:
- /*fprintf(stderr, "func(");*/
type = XXXoldtype(((struct ftype *)dtype)->ft_reftype, dimp, strp);
if (type & BIGTYPE) {
typov();
type = (type & TYPE) | (type & ~TYPE) << TYLEN | FUNC;
break;
case REF | ARRAY:
- /*fprintf(stderr, "array(%d, ", ((struct atype *)dtype)->at_nelt);*/
if (dimp->rank>=5) {
error0("Rank too large");
dimp->rank = 4;
type = (type & TYPE) | (type & ~TYPE) << TYLEN | ARRAY;
break;
case STRUCT:
- /*fprintf(stderr, "struct(%d", dtype->t_id);*/
*strp = &((struct stype *)dtype)->st_S;
- goto got_strp;
+ type = STRUCT;
+ break;
case BITFLD:
- /*fprintf(stderr, "bitfld(%d", dtype->t_id);*/
*strp = NULL;
type = UNSIGN;
break;
default:
- /*fprintf(stderr, "basic(%d", dtype->t_id);*/
*strp = NULL;
- got_strp:
type = dtype->t_id;
break;
}
- /*fprintf(stderr, ")", type);*/
return type;
}
int decl1(askw, atptr, offset, absname) int askw; struct /*nmlist*/type *atptr; int offset; struct nmlist *absname; {
int t1, a, elsize;
register int skw;
- struct type *dtype, *dt, *dt1;
+ struct rtype rtype, *tail;
/* int type;*/
register struct nmlist *dsym;
- register struct /*nmlist*/type *tptr;
- /* struct tdim dim;*/
+ /* register struct nmlist *tptr;
+ struct tdim dim;*/
/*struct SS *strp;
int *dp;*/
int isinit;
skw = askw;
- tptr = atptr;
+ /* tptr = atptr;*/
mosflg = skw==MOS? FMOS: 0;
/* dim.rank = 0;*/
if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
error0("Negative field width");
t1 = 0;
}
- elsize = align(tptr/*->nl_type*/, offset, t1);
+ elsize = align(/*tptr->nl_type*/atptr, offset, t1);
bitoffs += t1;
return(elsize);
}
/* t1 = getype(&dim, absname);
if (t1 == -1)
return(0);*/
- a = 1; /* nullok */
- dtype = getype(tptr, &a, absname != NULL);
+ /* we will construct a type which looks like a pointer to the real type, */
+ /* this is so that getype() can check the enclosing type, if REF | ARRAY */
+ /* then dimension must be specified, e.g. a[][10] is OK, but a[][] is not */
+ rtype.rt_id = REF | PTR;
+ tail = getype(&rtype, absname!=NULL);
+ if (tail)
+ tail->rt_reftype = atptr; /* otherwise, had error and set tail to int */
+ /*fprintf(stderr, "name %s type ", defsym ? defsym->nl_name : absname ? absname->nl_name : "???");
+ XXXdumptype(rtype.rt_reftype);
+ fprintf(stderr, "\n");*/
if (defsym)
absname = NULL;
/* if (tptr->nl_subsp) {
t1 >>= TYLEN;
}
type |= tptr->nl_type&TYPE;*/
- if (/*(type&XTYPE) == FUNC*/dtype->t_id == (REF | FUNC)) {
+ if (/*(type&XTYPE) == FUNC*/rtype.rt_reftype->t_id == (REF | FUNC)) {
if (skw==AUTO)
skw = EXTERN;
if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
if (tptr->nl_strp)
dsym->nl_strp = tptr->nl_strp;*/
/* new way */
- if ((skw==ARG||skw==AREG) && dsym->nl_class==ARG1)
- /* got type for previously declared K&R function argument */
- /* just clobber the type, no type compatibility check needed */
- dsym->nl_dtype = dtype;
- else if (skw==EXTERN && dsym->nl_class==EXTERN) {
+ if (skw==EXTERN && dsym->nl_class==EXTERN) {
/* got redeclaration of previously declared extern symbol */
/* compare types, picking up any new dimension information */
+ struct type *dt, *dt1;
for (
- dt = dtype, dt1 = dsym->nl_dtype;
+ dt = rtype.rt_reftype, dt1 = dsym->nl_dtype;
(t1 = dt->t_id) == dt1->t_id;
dt=((struct rtype *)dt)->rt_reftype, dt1=((struct rtype *)dt1)->rt_reftype
)
- switch (t1 & TYPE) {
+ switch (t1) {
case REF | PTR:
case FUNC | PTR:
break;
}
redec();
done:
- dtype = dsym->nl_dtype;
+ ;
}
- else if (dsym->nl_class) {
+ else if (dsym->nl_class==0 || (skw==ARG||skw==AREG) && dsym->nl_class==ARG1)
+ /* new declaration, or real declaration of K&R function argument */
+ /* just clobber the type, no type compatibility check needed */
+ dsym->nl_dtype = rtype.rt_reftype;
+ else {
redec();
goto syntax;
}
- else
- dsym->nl_dtype = dtype;
/*dim.rank = 0;
- dsym->nl_type = XXXoldtype(dtype, &dim, (struct SS **)&dsym->nl_strp);
+ dsym->nl_type = XXXoldtype(dsym->nl_dtype, &dim, (struct SS **)&dsym->nl_strp);
if (dim.rank && dsym->nl_subsp == 0)
dsym->nl_subsp = (int *)Dblock(dim.rank*sizeof(dim.rank));
for (a=0; a<dim.rank; a++)
elsize = 0;
if (skw==MOS) {
/*fprintf(stderr, "mos %p name %s\n", dsym, dsym->nl_name);*/
- elsize = length(/*(struct node *)dsym*/dtype);
+ elsize = length(/*(struct node *)dsym*/dsym->nl_dtype);
if ((peeksym = symbol())==COLON) {
elsize = 0;
peeksym = -1;
t1 = conexp();
- a = align(/*type*/dtype, offset, t1);
+ a = align(/*type*/dsym->nl_dtype, offset, t1);
/*fprintf(stderr, "a bitfield strp %p\n", dsym->nl_strp);*/
- if (/*dsym->nl_flag&FFIELD*/dtype->t_id == BITFLD) {
-#define bdtype ((struct btype *)dtype)
- if (/*dsym->nl_strp->F.bitoffs*/bdtype->bt_bitoffs!=bitoffs
- || /*dsym->nl_strp->F.flen*/bdtype->bt_flen!=t1)
+ if (dsym->/*nl_flag&FFIELD*/nl_dtype->t_id == BITFLD) {
+ if (/*dsym->nl_strp->F.bitoffs*/((struct btype *)dsym->nl_dtype)->bt_bitoffs!=bitoffs
+ || /*dsym->nl_strp->F.flen*/((struct btype *)dsym->nl_dtype)->bt_flen!=t1)
redec();
-#undef bdtype
} else {
/* dsym->nl_strp = (union str *)Dblock(sizeof(struct FS));*/
-#define bdtype (*(struct btype **)&dtype)
- bdtype = (struct btype *)Dblock(sizeof(struct btype));
- bdtype->bt_id = BITFLD;
- bdtype->bt_flen = t1;
- bdtype->bt_bitoffs = bitoffs;
- /*dsym->nl_strp = (union str *)&bdtype->bt_F;*/
- dsym->nl_dtype = (struct type *)bdtype;
-#undef bdtype
+ struct btype *btp = (struct btype *)Dblock(sizeof(struct btype));
+ btp->bt_id = BITFLD;
+ btp->bt_flen = t1;
+ btp->bt_bitoffs = bitoffs;
+ /*dsym->nl_strp = (union str *)&btp->bt_F;*/
+ dsym->nl_dtype = (struct type *)btp;
}
/*fprintf(stderr, "b bitfield strp %p\n", dsym->nl_strp);*/
/* dsym->nl_flag |= FFIELD;
dsym->nl_strp->F.flen = t1;*/
bitoffs += t1;
} else
- a = align(/*type*/dtype, offset, 0);
+ a = align(/*type*/dsym->nl_dtype, offset, 0);
elsize += a;
offset += a;
if (++nmems >= NMEMS) {
if (skw==AUTO) {
/* if (STAUTO < 0) { */
/*fprintf(stderr, "%s autolen %d -> ", dsym->nl_name, autolen);*/
- autolen -= rlength(/*(struct node *)dsym*/dtype);
+ autolen -= rlength(/*(struct node *)dsym*/dsym->nl_dtype);
dsym->nl_offset = autolen;
if (autolen < maxauto)
maxauto = autolen;
/*fprintf(stderr, "%d maxauto %d\n", autolen, maxauto);*/
/* } else { */
/* dsym->nl_offset = autolen; */
- /* autolen += rlength(*//*(struct node *)dsym*//*dtype); */
+ /* autolen += rlength(*//*(struct node *)dsym*//*dsym->nl_dtype); */
/* if (autolen > maxauto) */
/* maxauto = autolen; */
/* } */
outcode("B", EVEN);
} else
outcode("BBNBN", BSS, LABEL, isn0++, SSPACE,
- rlength(/*(struct node *)dsym*/dtype));
+ rlength(/*(struct node *)dsym*/dsym->nl_dtype));
outcode("B", PROG);
isinit = 0;
} else if (skw==REG && isinit) {
cinit(dsym, 0, REG);
isinit = 0;
} else if (skw==ENUM) {
- if (/*type*/dtype->t_id!=INT)
+ if (/*type*/dsym->nl_dtype->t_id!=INT)
error0("Illegal enumeration %s", dsym->nl_name);
dsym->nl_class = ENUMCON;
dsym->nl_offset = offset;
/*
* Read a declarator and get the implied type
*/
-/*int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname; {
- static struct nmlist argtype;
- int type;
+/*int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname;*/ struct rtype *getype(tail, anonok) struct rtype *tail; int anonok; {
+ /* static struct nmlist argtype;*/
+ static struct type t_int = {INT};
+ /* int type;*/
+ struct rtype *newtail;
register int o;
register struct nmlist *ds;
defsym = 0;
- type = 0;
+ /* type = 0;*/
switch(o=symbol()) {
case TIMES:
- type = getype(dimp, absname);
+ /* type = getype(dimp, absname);
if (type==-1)
- return(type);
- if (type&BIGTYPE) {
+ return(type);*/
+ tail = getype(tail, anonok);
+ if (tail==NULL)
+ return(NULL);
+ /* if (type&BIGTYPE) {
typov();
type = 0;
}
- return(type<<TYLEN | PTR);
+ return(type<<TYLEN | PTR);*/
+ newtail = (struct rtype *)Dblock(sizeof(struct rtype));
+ newtail->rt_id = REF | PTR;
+ tail->rt_reftype = (struct type *)newtail;
+ return newtail;
case LPARN:
- if (absname==NULL || nextchar()!=')') {
- type = getype(dimp, absname);
+ if (/*absname==NULL*/!anonok || nextchar()!=')') {
+ /* type = getype(dimp, absname);
if (type==-1)
- return(type);
+ return(type);*/
+ tail = getype(tail, anonok);
+ if (tail==NULL)
+ return(NULL);
if ((o=symbol()) != RPARN)
goto syntax;
goto getf;
default:
peeksym = o;
- if (absname)
+ if (/*absname*/anonok)
goto getf;
break;
case NAME:
- defsym = ds = csym;
+ defsym = /*ds =*/ csym;
getf:
switch(o=symbol()) {
if (blklev==0) {
blklev++;
ds = defsym;
- declare(ARG1, &argtype, 0);
+ declare(ARG1, &/*argtype*/t_int, 0);
defsym = ds;
blklev--;
} else
if ((o=symbol()) != RPARN)
goto syntax;
- if (type&BIGTYPE) {
+ /* if (type&BIGTYPE) {
typov();
type = 0;
}
- type = type<<TYLEN | FUNC;
+ type = type<<TYLEN | FUNC;*/
+#define fnewtail (*(struct ftype **)&newtail)
+ fnewtail = (struct ftype *)Dblock(sizeof(struct ftype));
+ fnewtail->ft_id = REF | FUNC;
+ fnewtail->ft_arglist = NULL;
+ tail->rt_reftype = (struct type *)fnewtail;
+ tail = (struct rtype *)fnewtail;
+#undef fnewtail
goto getf;
case LBRACK:
- if (dimp->rank>=5) {
+ /* if (dimp->rank>=5) {
error0("Rank too large");
dimp->rank = 4;
- }
+ }*/
if ((o=symbol()) != RBRACK) {
peeksym = o;
ds = defsym;
if ((o=symbol())!=RBRACK)
goto syntax;
} else {
- if (dimp->rank!=0)
+ /* if (dimp->rank!=0)*/
+ if (tail->rt_id == (REF | ARRAY))
error0("Null dimension");
cval = 0;
}
- dimp->dimens[dimp->rank++] = cval;
+ /* dimp->dimens[dimp->rank++] = cval;
if (type&BIGTYPE) {
typov();
type = 0;
}
- type = type<<TYLEN | ARRAY;
- goto getf;
- }
- peeksym = o;
- return(type);
- }
-syntax:
- decsyn(o);
- return(-1);
-}*/
-static struct type *getail(dtype, nullok) struct type *dtype; int *nullok; {
- static struct type argtype = {INT};
- struct rtype *rt;
- register int o;
- register struct nmlist *ds;
-
- switch(o=symbol()) {
-
- case LPARN:
- if (blklev==0) {
- blklev++;
- ds = defsym;
- declare(ARG1, &argtype, 0);
- defsym = ds;
- blklev--;
- } else
- if ((o=symbol()) != RPARN)
- goto syntax;
-#define ft (*(struct ftype **)&rt)
- ft = (struct ftype *)Dblock(sizeof(struct ftype));
- ft->ft_id = REF | FUNC;
- ft->ft_arglist = NULL;
- goto gett;
-#undef ft
-
- case LBRACK:
- if ((o=symbol()) != RBRACK) {
- peeksym = o;
- ds = defsym;
- cval = conexp();
- defsym = ds;
- if ((o=symbol())!=RBRACK)
- goto syntax;
- } else {
- /* note: this was (and remains) incorrect, as fooled by complicated types */
- if (!*nullok)
- error0("Null dimension");
- cval = 0;
- }
- *nullok = 0;
-#define at (*(struct atype **)&rt)
- at = (struct atype *)Dblock(sizeof(struct atype));
- at->at_id = REF | ARRAY;
- at->at_nelt = cval;
-#undef at
- gett:
- rt->rt_reftype = getail(dtype, nullok);
- return (struct type *)rt;
-
- default:
- peeksym = o;
- return(dtype);
- }
-syntax:
- decsyn(o);
- return(NULL);
-}
-struct type *getype(dtype, nullok, anonok) struct type *dtype; int *nullok; int anonok; {
- struct rtype *rt;
- register int o;
-
- defsym = 0;
-getp:
- switch(o=symbol()) {
-
- case TIMES:
- rt = (struct rtype *)Dblock(sizeof(struct rtype));
- rt->rt_id = REF | PTR;
- rt->rt_reftype = dtype;
- dtype = (struct type *)rt;
- goto getp;
-
- case LPARN:
- if (!anonok || nextchar()!=')') {
- dtype = getype(dtype, nullok, anonok);
- if (dtype==NULL)
- return(NULL);
- if ((o=symbol()) != RPARN)
- goto syntax;
+ type = type<<TYLEN | ARRAY;*/
+#define anewtail (*(struct atype **)&newtail)
+ anewtail = (struct atype *)Dblock(sizeof(struct atype));
+ anewtail->at_id = REF | ARRAY;
+ anewtail->at_nelt = cval;
+ tail->rt_reftype = (struct type *)anewtail;
+ tail = (struct rtype *)anewtail;
+#undef anewtail
goto getf;
}
-
- default:
peeksym = o;
- if (anonok)
- goto getf;
- break;
-
- case NAME:
- defsym = csym;
- getf:
- return getail(dtype, nullok);
+ /* return(type);*/
+ return(tail);
}
syntax:
decsyn(o);
- return(NULL);
+ /* return(-1);*/
+ tail->rt_reftype = &t_int;
+ return(NULL);
}
/*