3 * Handles processing of declarations,
4 * except for top-level processing of
12 * Process a sequence of declaration statements
14 int declist(sclass) int sclass; {
15 register int sc, offset;
20 while (getkeywords(&sclass, &typer)) {
21 offset = declare(sclass, &typer, offset);
24 return(offset+align(INT, offset, 0));
28 * Read the keywords introducing a declaration statement
29 * Store back the storage class, and fill in the type
30 * entry, which looks like a hash table entry.
32 int getkeywords(scptr, tptr) int *scptr; struct nmlist *tptr; {
33 register int skw, tkw, longf;
34 int o, isadecl, ismos, unsignf;
44 ismos = skw==MOS||skw==MOU? FMOS: 0;
46 mosflg = isadecl? ismos: 0;
48 if (o==NAME && csym->hclass==TYPEDEF) {
52 tptr->hsubsp = csym->hsubsp;
53 tptr->hstrp = csym->hstrp;
57 switch (o==KEYW? cval: -1) {
63 if (skw && skw!=cval) {
64 if (skw==ARG && cval==REG)
67 error0("Conflict in storage class");
82 error0("Perverse modifier on 'enum'");
89 tptr->hstrp = strdec(ismos, cval);
97 if (tkw>=0 && (tkw!=INT || cval!=INT))
100 if (unscflg && cval==CHAR)
111 skw = blklev==0? DEFXTRN: AUTO;
120 error0("Misplaced 'unsigned'");
127 else if (tkw==UNSIGN)
130 error0("Misplaced 'long'");
141 * Process a structure, union, or enum declaration; a subroutine
144 union str *strdec(mosf, kind) int mosf; int kind; {
145 register int elsize, o;
146 register struct nmlist *ssym;
148 struct nmlist **savememlist;
149 union str *savesparent;
153 struct nmlist *mems[NMEMS];
167 if ((o=symbol())==NAME) {
171 if (o==LBRACE && ssym->hblklev<blklev)
172 ssym = pushdecl(ssym);
173 if (ssym->hclass && ssym->hclass!=tagkind) {
176 ssym = pushdecl(ssym);
178 if (ssym->hclass==0) {
179 ssym->hclass = tagkind;
180 ssym->hstrp = (union str *)Dblock(sizeof(struct SS));
181 ssym->hstrp->S.ssize = 0;
182 ssym->hstrp->S.memlist = NULL;
186 strp = (union str *)Dblock(sizeof(struct SS));
188 strp->S.memlist = NULL;
194 if (ssym->hclass!=tagkind)
195 error0("Bad structure/union/enum name");
201 savememlist = memlist;
202 savesparent = sparent;
211 declare(ENUM, &typer, 0);
213 elsize = declist(kind==UNION?MOU:MOS);
215 #if 1 /* just save a bit of string space */
224 error0("%s redeclared", ssym->name);
226 strp->S.ssize = elsize;
228 strp->S.memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
229 for (o=0; &mems[o] != memlist; o++)
230 strp->S.memlist[o] = mems[o];
231 memlist = savememlist;
232 sparent = savesparent;
234 if ((o = symbol()) != RBRACE)
244 * Process a comma-separated list of declarators
246 int declare(askw, tptr, offset) int askw; struct nmlist *tptr; int offset; {
248 register int skw, isunion;
249 struct nmlist abs, *aptr;
257 if ((peeksym=symbol()) == SEMI) {
258 o = length((union tree *)tptr);
264 if (skw==ENUM && (peeksym=symbol())==RBRACE) {
277 abs.hblklev = blklev;
282 o = decl1(skw, tptr, isunion?0:offset, aptr);
284 o += align(CHAR, o, 0);
289 } while ((o=symbol()) == COMMA);
294 if (o!=SEMI && (o!=RPARN || skw!=ARG1))
300 * Process a single declarator
302 int decl1(askw, atptr, offset, absname) int askw; struct nmlist *atptr; int offset; struct nmlist *absname; {
306 register struct nmlist *dsym;
307 register struct nmlist *tptr;
314 mosflg = skw==MOS? FMOS: 0;
316 if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
321 if (peeksym==COLON && skw==MOS) {
325 error0("Negative field width");
328 elsize = align(tptr->htype, offset, t1);
332 t1 = getype(&dim, absname);
339 for (a=0; type&XTYPE;) {
340 if ((type&XTYPE)==ARRAY)
341 dim.dimens[dim.rank++] = tptr->hsubsp[a++];
345 type = tptr->htype & ~TYPE;
351 type = type<<TYLEN | (t1 & XTYPE);
354 type |= tptr->htype&TYPE;
355 if ((type&XTYPE) == FUNC) {
358 if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
359 error0("Bad func. storage class");
366 error0("Name required in declaration");
370 if (dsym->hblklev<blklev || dsym->hclass==MOS && skw==MOS) {
371 if (skw==MOS && dsym->sparent==sparent)
375 for (; dsym!=NULL; dsym = dsym->nextnm) {
376 if (dsym->hclass==EXTERN
377 && strcmp(dsym->name, defsym->name)==0) {
384 defsym = dsym = pushdecl(dsym);
390 * If an array is declared twice, make sure the declarations
391 * agree in dimension. This happens typically when a .h
392 * and .c file both declare a variable.
395 for (a=0, t1 = dsym->htype;
396 a<dim.rank && (t1&XTYPE)==ARRAY;
399 * If we haven't seen a declaration for this
400 * dimension yet, take what's been given now.
402 if (!dsym->hsubsp[a])
403 dsym->hsubsp[a] = dim.dimens[a];
404 else if (dim.dimens[a]
405 && dim.dimens[a] != dsym->hsubsp[a])
407 if (a<dim.rank || (t1&XTYPE)==ARRAY)
410 dp = (int *)Dblock(dim.rank*sizeof(dim.rank));
411 for (a=0; a<dim.rank; a++)
412 dp[a] = dim.dimens[a];
416 if (!(dsym->hclass==0
417 || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1)
418 || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type))) {
422 if (dsym->hclass && (dsym->htype&TYPE)==STRUCT && (type&TYPE)==STRUCT)
423 if (dsym->hstrp != tptr->hstrp) {
424 error0("structure redeclaration");
428 dsym->hstrp = tptr->hstrp;
430 dsym->hclass = TYPEDEF;
437 parame->sparent = (union str *)dsym;
444 elsize = length((union tree *)dsym);
445 if ((peeksym = symbol())==COLON) {
449 a = align(type, offset, t1);
450 if (dsym->hflag&FFIELD) {
451 if (dsym->hstrp->F.bitoffs!=bitoffs
452 || dsym->hstrp->F.flen!=t1)
455 dsym->hstrp = (union str *)Dblock(sizeof(struct FS));
457 dsym->hflag |= FFIELD;
458 dsym->hstrp->F.bitoffs = bitoffs;
459 dsym->hstrp->F.flen = t1;
462 a = align(type, offset, 0);
465 if (++nmems >= NMEMS) {
466 error0("Too many structure members");
471 *memlist++ = &structhole;
472 dsym->hoffset = offset;
474 dsym->sparent = sparent;
477 if ((dsym->hoffset = goodreg(dsym)) < 0)
481 if ((a=symbol()) == ASSIGN)
486 /* if (STAUTO < 0) { */
487 /*fprintf(stderr, "%s autolen %d -> ", dsym->name, autolen);*/
488 autolen -= rlength((union tree *)dsym);
489 dsym->hoffset = autolen;
490 if (autolen < maxauto)
492 /*fprintf(stderr, "%d maxauto %d\n", autolen, maxauto);*/
494 /* dsym->hoffset = autolen; */
495 /* autolen += rlength(dsym); */
496 /* if (autolen > maxauto) */
497 /* maxauto = autolen; */
500 cinit(dsym, 0, AUTO);
502 } else if (skw==STATIC) {
503 dsym->hoffset = isn0;
505 outcode("BBN", DATA, LABEL, isn0++);
506 if (cinit(dsym, 1, STATIC) & ALIGN)
509 outcode("BBNBN", BSS, LABEL, isn0++, SSPACE,
510 rlength((union tree *)dsym));
513 } else if (skw==REG && isinit) {
516 } else if (skw==ENUM) {
518 error0("Illegal enumeration %s", dsym->name);
519 dsym->hclass = ENUMCON;
520 dsym->hoffset = offset;
522 cinit(dsym, 0, ENUMCON);
523 elsize = dsym->hoffset-offset+1;
535 * Push down an outer-block declaration
536 * after redeclaration in an inner block.
538 struct nmlist *pushdecl(sp) register struct nmlist *sp; {
539 register struct nmlist *nsp, **hsp;
541 nsp = (struct nmlist *)Dblock(sizeof(struct nmlist));
547 nsp->hblklev = blklev;
551 hsp = &hshtab[hash(sp->name)];
558 * Read a declarator and get the implied type
560 int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname; {
561 static struct nmlist argtype;
564 register struct nmlist *ds;
571 type = getype(dimp, absname);
578 return(type<<TYLEN | PTR);
581 if (absname==NULL || nextchar()!=')') {
582 type = getype(dimp, absname);
585 if ((o=symbol()) != RPARN)
605 declare(ARG1, &argtype, 0);
609 if ((o=symbol()) != RPARN)
615 type = type<<TYLEN | FUNC;
620 error0("Rank too large");
623 if ((o=symbol()) != RBRACK) {
628 if ((o=symbol())!=RBRACK)
632 error0("Null dimension");
635 dimp->dimens[dimp->rank++] = cval;
640 type = type<<TYLEN | ARRAY;
652 * More bits required for type than allowed.
655 error0("Type is too complicated");
659 * Enforce alignment restrictions in structures,
660 * including bit-field considerations.
662 int align(type, offset, aflen) int type; int offset; int aflen; {
663 register int a, t, flen;
669 ftl = "Field too long";
671 a += (NBPC+bitoffs-1) / NBPC;
674 while ((t&XTYPE)==ARRAY)
676 if (t!=CHAR && t!=UNCHAR) {
677 a = (a+ALIGN) & ~ALIGN;
682 if (type==INT || type==UNSIGN) {
685 if (flen+bitoffs > NBPW) {
689 } else if (type==CHAR || type==UNCHAR) {
692 if (flen+bitoffs > NBPC) {
697 error0("Bad type for field");
703 * Complain about syntax error in declaration
705 void decsyn(o) int o; {
706 error0("Declaration syntax");
711 * Complain about a redeclaration
714 error0("%s redeclared", defsym->name);
718 * Determine if a variable is suitable for storage in
719 * a register; if so return the register number
721 int goodreg(hp) struct nmlist *hp; {
725 if ((type!=INT && type!=UNSIGN && (type&XTYPE)==0)
726 || (type&XTYPE)>PTR || regvar<3)