3 * Handles processing of declarations,
4 * except for top-level processing of
13 * Process a sequence of declaration statements
15 int declist(sclass) int sclass; {
16 register int sc, offset;
17 /* struct nmlist typer;*/
19 static struct type t_int = {INT};
23 while (/*getkeywords(&sclass, &typer)*/(dtype = getkeywords(&sclass)) != NULL) {
24 offset = declare(sclass, /*&typer*/dtype, offset);
27 return(offset+align(/*INT*/&t_int, offset, 0));
31 * Read the keywords introducing a declaration statement
32 * Store back the storage class, and fill in the type
33 * entry, which looks like a hash table entry.
35 /*int*/struct type *getkeywords(scptr/*, tptr*/) int *scptr; /*struct nmlist *tptr;*/ {
36 register int skw, tkw, longf;
37 int o, isadecl, ismos, unsignf;
39 static struct type basic_types[] = {
56 /* tptr->nl_type = INT;
58 tptr->nl_subsp = NULL;*/
61 ismos = skw==MOS||skw==MOU? FMOS: 0;
64 mosflg = isadecl? ismos: 0;
66 if (o==NAME && csym->nl_class==TYPEDEF) {
69 /* tkw = csym->nl_type;
70 tptr->nl_subsp = csym->nl_subsp;
71 tptr->nl_strp = csym->nl_strp;*/
72 dtype = csym->nl_dtype;
76 switch (o==KEYW? cval: -1) {
82 if (skw && skw!=cval) {
83 if (skw==ARG && cval==REG)
86 error0("Conflict in storage class");
100 /* note: this code accepts silly declarations like "enum a int b;" */
101 /* it also accepts modifiers if placed later like "enum a long b;" */
102 /* eventually we should modify this to be more like the struct case */
103 if (longf || unsignf)
104 error0("Perverse modifier on 'enum'");
111 /* tptr->nl_strp = strdec(ismos, cval); */
113 error0("type clash");
114 dtype = (struct type *)strdec(ismos, cval);
126 if (tkw>=0 && (tkw!=INT || cval!=INT))
128 error0("Type clash");
130 if (unscflg && cval==CHAR)
141 skw = blklev==0? DEFXTRN: AUTO;
144 goto misplaced_unsigned;
153 error0("Misplaced 'unsigned'");
162 else if (tkw==UNSIGN)
166 error0("Misplaced 'long'");
169 /* tptr->nl_type = tkw;
171 return dtype ? dtype : basic_types + tkw;
178 * Process a structure, union, or enum declaration; a subroutine
181 /*union str*/struct stype *strdec(mosf, kind) int mosf; int kind; {
182 register int elsize, o;
183 register struct nmlist *ssym;
185 struct nmlist **savememlist;
186 union str *savesparent;
188 /* union str *strp;*/
191 struct nmlist *mems[NMEMS];
192 /* struct nmlist typer;*/
194 static struct type t_int = {INT};
206 if ((o=symbol())==NAME) {
210 if (o==LBRACE && ssym->nl_blklev<blklev)
211 ssym = pushdecl(ssym);
212 if (ssym->nl_class && ssym->nl_class!=tagkind) {
215 ssym = pushdecl(ssym);
217 if (ssym->nl_class==0) {
218 ssym->nl_class = tagkind;
219 /* ssym->nl_strp = (union str *)Dblock(sizeof(struct SS));*/
220 stype = (struct stype *)Dblock(sizeof(struct stype));
221 stype->st_id = STRUCT;
222 /*ssym->nl_strp->S.ssize*/stype->st_ssize = 0;
223 /*ssym->nl_strp->S.memlist*/stype->st_memlist = NULL;
224 /*ssym->nl_strp = (union str *)&stype->st_S;*/
225 ssym->nl_dtype = (struct type *)stype;
227 /* strp = ssym->nl_strp;*/
229 stype = (struct stype *)ssym->nl_dtype;
231 /* strp = (union str *)Dblock(sizeof(struct SS));*/
232 stype = (struct stype *)Dblock(sizeof(struct stype));
233 stype->st_id = STRUCT;
234 /*strp->S.ssize*/stype->st_ssize = 0;
235 /*strp->S.memlist*/stype->st_memlist = NULL;
241 if (ssym->nl_class!=tagkind)
242 error0("Bad structure/union/enum name");
248 savememlist = memlist;
249 savesparent = sparent;
252 sparent = /*strp*/(union str *)&stype->st_S;
256 /* typer.nl_type = INT;
257 typer.nl_strp = strp;*/
258 /* strp above seems to be vestigial, I don't think it is ever referenced */
259 declare(ENUM, /*&typer*/&t_int, 0);
261 elsize = declist(kind==UNION?MOU:MOS);
263 #if 1 /* just save a bit of string space */
264 if (/*strp->S.ssize*/stype->st_ssize) {
272 error0("%s redeclared", ssym->nl_name);
274 /*strp->S.ssize*/stype->st_ssize = elsize;
276 /*strp->S.memlist*/stype->st_memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
277 for (o=0; &mems[o] != memlist; o++)
278 /*strp->S.memlist*/stype->st_memlist[o] = mems[o];
279 memlist = savememlist;
280 sparent = savesparent;
282 if ((o = symbol()) != RBRACE)
285 /*fprintf(stderr, "stype=%p,%p\n", stype, &stype->st_S);*/
286 return(/*strp*/stype);
293 * Process a comma-separated list of declarators
295 int declare(askw, tptr, offset) int askw; struct /*nmlist*/type *tptr; int offset; {
297 register int skw, isunion;
298 struct nmlist abs, *aptr;
299 static struct type t_char = {CHAR};
307 if ((peeksym=symbol()) == SEMI) {
308 o = length(/*(struct node *)*/tptr);
314 if (skw==ENUM && (peeksym=symbol())==RBRACE) {
328 abs.nl_blklev = blklev;
329 abs.nl_name = "<none>";
333 o = decl1(skw, tptr, isunion?0:offset, aptr);
335 o += align(/*CHAR*/&t_char, o, 0);
340 } while ((o=symbol()) == COMMA);
345 if (o!=SEMI && (o!=RPARN || skw!=ARG1))
351 * Process a single declarator
353 /* convert detailed type description to old type description */
354 void XXXdumptype(dtype) struct type *dtype; {
355 static char *basic_types[] = {
370 switch (dtype->t_id) {
372 fprintf(stderr, "PTR");
375 #define fdtype ((struct ftype *)dtype)
376 fprintf(stderr, "FUNC");
377 /*if (fdtype->ft_arglist) {
380 for (i = 0; fdtype->ft_arglist[i]; ++i) {
383 fprintf(stderr, "%s", fdtype->ft_arglist[i]->nl_name);
390 fprintf(stderr, "ARRAY(%d)", ((struct atype *)dtype)->at_nelt);
393 XXXdumptype(((struct rtype *)dtype)->rt_reftype);
396 fprintf(stderr, "%s", basic_types[dtype->t_id]);
400 int XXXoldtype(dtype, dimp, strp) struct type *dtype; struct tdim *dimp; struct SS **strp; {
402 switch (dtype->t_id) {
404 type = XXXoldtype(((struct rtype *)dtype)->rt_reftype, dimp, strp);
405 if (type & BIGTYPE) {
409 type = (type & TYPE) | (type & ~TYPE) << TYLEN | PTR;
412 type = XXXoldtype(((struct ftype *)dtype)->ft_reftype, dimp, strp);
413 if (type & BIGTYPE) {
417 type = (type & TYPE) | (type & ~TYPE) << TYLEN | FUNC;
421 error0("Rank too large");
424 dimp->dimens[dimp->rank++] = ((struct atype *)dtype)->at_nelt;
425 type = XXXoldtype(((struct atype *)dtype)->at_reftype, dimp, strp);
426 if (type & BIGTYPE) {
430 type = (type & TYPE) | (type & ~TYPE) << TYLEN | ARRAY;
433 *strp = &((struct stype *)dtype)->st_S;
447 int decl1(askw, atptr, offset, absname) int askw; struct /*nmlist*/type *atptr; int offset; struct nmlist *absname; {
450 struct rtype rtype, *tail;
452 register struct nmlist *dsym;
453 /* register struct nmlist *tptr;
461 mosflg = skw==MOS? FMOS: 0;
463 if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
468 if (peeksym==COLON && skw==MOS) {
472 error0("Negative field width");
475 elsize = align(/*tptr->nl_type*/atptr, offset, t1);
479 /* t1 = getype(&dim, absname);
482 /* we will construct a type which looks like a pointer to the real type, */
483 /* this is so that getype() can check the enclosing type, if REF | ARRAY */
484 /* then dimension must be specified, e.g. a[][10] is OK, but a[][] is not */
485 rtype.rt_id = REF | PTR;
486 tail = getype(&rtype, absname!=NULL);
488 tail->rt_reftype = atptr; /* otherwise, had error and set tail to int */
489 /*fprintf(stderr, "name %s type ", defsym ? defsym->nl_name : absname ? absname->nl_name : "???");
490 XXXdumptype(rtype.rt_reftype);
491 fprintf(stderr, "\n");*/
494 /* if (tptr->nl_subsp) {
495 type = tptr->nl_type;
496 for (a=0; type&XTYPE;) {
497 if ((type&XTYPE)==ARRAY)
498 dim.dimens[dim.rank++] = tptr->nl_subsp[a++];
502 type = tptr->nl_type & ~TYPE;
508 type = type<<TYLEN | (t1 & XTYPE);
511 type |= tptr->nl_type&TYPE;*/
512 if (/*(type&XTYPE) == FUNC*/rtype.rt_reftype->t_id == (REF | FUNC)) {
515 if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
516 error0("Bad func. storage class");
523 error0("Name required in declaration");
527 if (dsym->nl_blklev<blklev || dsym->nl_class==MOS && skw==MOS) {
528 if (skw==MOS && dsym->nl_sparent==sparent)
532 for (; dsym!=NULL; dsym = dsym->nl_nextnm) {
533 if (dsym->nl_class==EXTERN
534 && strcmp(dsym->nl_name, defsym->nl_name)==0) {
541 defsym = dsym = pushdecl(dsym);
544 /* if (dim.rank == 0)
545 dsym->nl_subsp = NULL;
548 * If an array is declared twice, make sure the declarations
549 * agree in dimension. This happens typically when a .h
550 * and .c file both declare a variable.
552 if (dsym->nl_subsp) {
553 for (a=0, t1 = dsym->nl_type;
554 a<dim.rank && (t1&XTYPE)==ARRAY);
557 * If we haven't seen a declaration for this
558 * dimension yet, take what's been given now.
560 if (!dsym->nl_subsp[a])
561 dsym->nl_subsp[a] = dim.dimens[a];
562 else if (dim.dimens[a]
563 && dim.dimens[a] != dsym->nl_subsp[a])
565 if (a<dim.rank || (t1&XTYPE)==ARRAY)
568 dp = (int *)Dblock(dim.rank*sizeof(dim.rank));
569 for (a=0; a<dim.rank; a++)
570 dp[a] = dim.dimens[a];
574 if (!(dsym->nl_class==0
575 || ((skw==ARG||skw==AREG) && dsym->nl_class==ARG1)
576 || (skw==EXTERN && dsym->nl_class==EXTERN && dsym->nl_type==type))) {
580 if (dsym->nl_class && (dsym->nl_type&TYPE)==STRUCT && (type&TYPE)==STRUCT)
581 if (dsym->nl_strp != *//*tptr->nl_strp*//*(union str *)&((struct stype *)tptr)->st_S) {
582 error0("structure redeclaration");
584 dsym->nl_type = type;
586 dsym->nl_strp = tptr->nl_strp;*/
588 if (skw==EXTERN && dsym->nl_class==EXTERN) {
589 /* got redeclaration of previously declared extern symbol */
590 /* compare types, picking up any new dimension information */
591 struct type *dt, *dt1;
593 dt = rtype.rt_reftype, dt1 = dsym->nl_dtype;
594 (t1 = dt->t_id) == dt1->t_id;
595 dt=((struct rtype *)dt)->rt_reftype, dt1=((struct rtype *)dt1)->rt_reftype
602 #define adt ((struct atype *)dt)
603 #define adt1 ((struct atype *)dt1)
605 adt1->at_nelt = adt->at_nelt;
606 else if (adt->at_nelt && adt->at_nelt != adt1->at_nelt)
613 error0("structure redeclaration");
622 else if (dsym->nl_class==0 || (skw==ARG||skw==AREG) && dsym->nl_class==ARG1)
623 /* new declaration, or real declaration of K&R function argument */
624 /* just clobber the type, no type compatibility check needed */
625 dsym->nl_dtype = rtype.rt_reftype;
631 dsym->nl_type = XXXoldtype(dsym->nl_dtype, &dim, (struct SS **)&dsym->nl_strp);
632 if (dim.rank && dsym->nl_subsp == 0)
633 dsym->nl_subsp = (int *)Dblock(dim.rank*sizeof(dim.rank));
634 for (a=0; a<dim.rank; a++)
635 dsym->nl_subsp[a] = dim.dimens[a];*/
637 dsym->nl_class = TYPEDEF;
644 parame->nl_sparent = (union str *)dsym;
646 dsym->nl_class = skw;
651 /*fprintf(stderr, "mos %p name %s\n", dsym, dsym->nl_name);*/
652 elsize = length(/*(struct node *)dsym*/dsym->nl_dtype);
653 if ((peeksym = symbol())==COLON) {
657 a = align(/*type*/dsym->nl_dtype, offset, t1);
658 /*fprintf(stderr, "a bitfield strp %p\n", dsym->nl_strp);*/
659 if (dsym->/*nl_flag&FFIELD*/nl_dtype->t_id == BITFLD) {
660 if (/*dsym->nl_strp->F.bitoffs*/((struct btype *)dsym->nl_dtype)->bt_bitoffs!=bitoffs
661 || /*dsym->nl_strp->F.flen*/((struct btype *)dsym->nl_dtype)->bt_flen!=t1)
664 /* dsym->nl_strp = (union str *)Dblock(sizeof(struct FS));*/
665 struct btype *btp = (struct btype *)Dblock(sizeof(struct btype));
668 btp->bt_bitoffs = bitoffs;
669 /*dsym->nl_strp = (union str *)&btp->bt_F;*/
670 dsym->nl_dtype = (struct type *)btp;
672 /*fprintf(stderr, "b bitfield strp %p\n", dsym->nl_strp);*/
673 /* dsym->nl_flag |= FFIELD;
674 dsym->nl_strp->F.bitoffs = bitoffs;
675 dsym->nl_strp->F.flen = t1;*/
678 a = align(/*type*/dsym->nl_dtype, offset, 0);
681 if (++nmems >= NMEMS) {
682 error0("Too many structure members");
687 *memlist++ = &structhole;
688 dsym->nl_offset = offset;
690 dsym->nl_sparent = sparent;
693 if ((dsym->nl_offset = goodreg(dsym)) < 0)
695 dsym->nl_class = skw;
697 if ((a=symbol()) == ASSIGN)
702 /* if (STAUTO < 0) { */
703 /*fprintf(stderr, "%s autolen %d -> ", dsym->nl_name, autolen);*/
704 autolen -= rlength(/*(struct node *)dsym*/dsym->nl_dtype);
705 dsym->nl_offset = autolen;
706 if (autolen < maxauto)
708 /*fprintf(stderr, "%d maxauto %d\n", autolen, maxauto);*/
710 /* dsym->nl_offset = autolen; */
711 /* autolen += rlength(*//*(struct node *)dsym*//*dsym->nl_dtype); */
712 /* if (autolen > maxauto) */
713 /* maxauto = autolen; */
716 cinit(dsym, 0, AUTO);
718 } else if (skw==STATIC) {
719 dsym->nl_offset = isn0;
721 outcode("BBN", DATA, LABEL, isn0++);
722 if (cinit(dsym, 1, STATIC) & ALIGN)
725 outcode("BBNBN", BSS, LABEL, isn0++, SSPACE,
726 rlength(/*(struct node *)dsym*/dsym->nl_dtype));
729 } else if (skw==REG && isinit) {
732 } else if (skw==ENUM) {
733 if (/*type*/dsym->nl_dtype->t_id!=INT)
734 error0("Illegal enumeration %s", dsym->nl_name);
735 dsym->nl_class = ENUMCON;
736 dsym->nl_offset = offset;
738 cinit(dsym, 0, ENUMCON);
739 elsize = dsym->nl_offset-offset+1;
751 * Push down an outer-block declaration
752 * after redeclaration in an inner block.
754 struct nmlist *pushdecl(sp) register struct nmlist *sp; {
755 register struct nmlist *nsp, **hsp;
757 nsp = (struct nmlist *)Dblock(sizeof(struct nmlist));
760 nsp->nl_flag &= FKIND;
761 /* nsp->nl_type = 0;*/
762 nsp->nl_dtype = NULL;
764 nsp->nl_blklev = blklev;
765 /* nsp->nl_strp = NULL;
766 nsp->nl_subsp = NULL;*/
767 nsp->nl_sparent = NULL;
768 hsp = &hshtab[hash(sp->nl_name)];
769 nsp->nl_nextnm = *hsp;
775 * Read a declarator and get the implied type
777 /*int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname;*/ struct rtype *getype(tail, anonok) struct rtype *tail; int anonok; {
778 /* static struct nmlist argtype;*/
779 static struct type t_int = {INT};
781 struct rtype *newtail;
783 register struct nmlist *ds;
790 /* type = getype(dimp, absname);
793 tail = getype(tail, anonok);
796 /* if (type&BIGTYPE) {
800 return(type<<TYLEN | PTR);*/
801 newtail = (struct rtype *)Dblock(sizeof(struct rtype));
802 newtail->rt_id = REF | PTR;
803 tail->rt_reftype = (struct type *)newtail;
807 if (/*absname==NULL*/!anonok || nextchar()!=')') {
808 /* type = getype(dimp, absname);
811 tail = getype(tail, anonok);
814 if ((o=symbol()) != RPARN)
821 if (/*absname*/anonok)
826 defsym = /*ds =*/ csym;
834 declare(ARG1, &/*argtype*/t_int, 0);
838 if ((o=symbol()) != RPARN)
840 /* if (type&BIGTYPE) {
844 type = type<<TYLEN | FUNC;*/
845 #define fnewtail (*(struct ftype **)&newtail)
846 fnewtail = (struct ftype *)Dblock(sizeof(struct ftype));
847 fnewtail->ft_id = REF | FUNC;
848 fnewtail->ft_arglist = NULL;
849 tail->rt_reftype = (struct type *)fnewtail;
850 tail = (struct rtype *)fnewtail;
855 /* if (dimp->rank>=5) {
856 error0("Rank too large");
859 if ((o=symbol()) != RBRACK) {
864 if ((o=symbol())!=RBRACK)
867 /* if (dimp->rank!=0)*/
868 if (tail->rt_id == (REF | ARRAY))
869 error0("Null dimension");
872 /* dimp->dimens[dimp->rank++] = cval;
877 type = type<<TYLEN | ARRAY;*/
878 #define anewtail (*(struct atype **)&newtail)
879 anewtail = (struct atype *)Dblock(sizeof(struct atype));
880 anewtail->at_id = REF | ARRAY;
881 anewtail->at_nelt = cval;
882 tail->rt_reftype = (struct type *)anewtail;
883 tail = (struct rtype *)anewtail;
894 tail->rt_reftype = &t_int;
899 * More bits required for type than allowed.
902 error0("Type is too complicated");
906 * Enforce alignment restrictions in structures,
907 * including bit-field considerations.
909 /* really means make sure aflen bits can be allocated after current position */
910 /* takes size in bytes and the global bitoffs, returns size increase in bytes */
911 int align(type, offset, aflen) /*int*/struct type *type; int offset; int aflen; {
912 register int a, /*t,*/ flen;
913 register struct type *t;
919 ftl = "Field too long";
921 a += (NBPC+bitoffs-1) / NBPC;
924 /* while ((t&XTYPE)==ARRAY)
926 for (t = type; t->t_id == (REF | ARRAY); t = ((struct atype *)t)->at_reftype)
928 if (/*t*/t->t_id!=CHAR && /*t*/t->t_id!=UNCHAR) {
929 a = (a+ALIGN) & ~ALIGN;
934 if (/*type*/type->t_id==INT || /*type*/type->t_id==UNSIGN) {
937 if (flen+bitoffs > NBPW) {
941 } else if (/*type*/type->t_id==CHAR || /*type*/type->t_id==UNCHAR) {
944 if (flen+bitoffs > NBPC) {
949 error0("Bad type for field");
955 * Complain about syntax error in declaration
957 void decsyn(o) int o; {
958 error0("Declaration syntax");
963 * Complain about a redeclaration
966 error0("%s redeclared", defsym->nl_name);
970 * Determine if a variable is suitable for storage in
971 * a register; if so return the register number
973 int goodreg(hp) struct nmlist *hp; {
977 /* type = hp->nl_type;*/
978 dtype = hp->nl_dtype;
979 if ((/*type*/dtype->t_id!=INT && /*type*/dtype->t_id!=UNSIGN && /*(type&XTYPE)==0*/dtype->t_id!=(REF|PTR))
980 || /*(type&XTYPE)>PTR ||*/ regvar<3)