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 error("Conflict in storage class");
82 error("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 error("Misplaced 'unsigned'");
127 else if (tkw==UNSIGN)
130 error("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 error("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 error("%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 error("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 error("Bad func. storage class");
366 error("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 error("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 error("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 autolen -= rlength((union tree *)dsym);
488 dsym->hoffset = autolen;
489 if (autolen < maxauto)
492 /* dsym->hoffset = autolen; */
493 /* autolen += rlength(dsym); */
494 /* if (autolen > maxauto) */
495 /* maxauto = autolen; */
498 cinit(dsym, 0, AUTO);
500 } else if (skw==STATIC) {
503 outcode("BBN", DATA, LABEL, isn++);
504 if (cinit(dsym, 1, STATIC) & ALIGN)
507 outcode("BBNBN", BSS, LABEL, isn++, SSPACE,
508 rlength((union tree *)dsym));
511 } else if (skw==REG && isinit) {
514 } else if (skw==ENUM) {
516 error("Illegal enumeration %s", dsym->name);
517 dsym->hclass = ENUMCON;
518 dsym->hoffset = offset;
520 cinit(dsym, 0, ENUMCON);
521 elsize = dsym->hoffset-offset+1;
533 * Push down an outer-block declaration
534 * after redeclaration in an inner block.
536 struct nmlist *pushdecl(sp) register struct nmlist *sp; {
537 register struct nmlist *nsp, **hsp;
539 nsp = (struct nmlist *)Dblock(sizeof(struct nmlist));
545 nsp->hblklev = blklev;
549 hsp = &hshtab[hash(sp->name)];
556 * Read a declarator and get the implied type
558 int getype(dimp, absname) register struct tdim *dimp; struct nmlist *absname; {
559 static struct nmlist argtype;
562 register struct nmlist *ds;
569 type = getype(dimp, absname);
576 return(type<<TYLEN | PTR);
579 if (absname==NULL || nextchar()!=')') {
580 type = getype(dimp, absname);
583 if ((o=symbol()) != RPARN)
603 declare(ARG1, &argtype, 0);
607 if ((o=symbol()) != RPARN)
613 type = type<<TYLEN | FUNC;
618 error("Rank too large");
621 if ((o=symbol()) != RBRACK) {
626 if ((o=symbol())!=RBRACK)
630 error("Null dimension");
633 dimp->dimens[dimp->rank++] = cval;
638 type = type<<TYLEN | ARRAY;
650 * More bits required for type than allowed.
653 error("Type is too complicated");
657 * Enforce alignment restrictions in structures,
658 * including bit-field considerations.
660 int align(type, offset, aflen) int type; int offset; int aflen; {
661 register int a, t, flen;
667 ftl = "Field too long";
669 a += (NBPC+bitoffs-1) / NBPC;
672 while ((t&XTYPE)==ARRAY)
674 if (t!=CHAR && t!=UNCHAR) {
675 a = (a+ALIGN) & ~ALIGN;
680 if (type==INT || type==UNSIGN) {
683 if (flen+bitoffs > NBPW) {
687 } else if (type==CHAR || type==UNCHAR) {
690 if (flen+bitoffs > NBPC) {
695 error("Bad type for field");
701 * Complain about syntax error in declaration
703 void decsyn(o) int o; {
704 error("Declaration syntax");
709 * Complain about a redeclaration
712 error("%s redeclared", defsym->name);
716 * Determine if a variable is suitable for storage in
717 * a register; if so return the register number
719 int goodreg(hp) struct nmlist *hp; {
723 if ((type!=INT && type!=UNSIGN && (type&XTYPE)==0)
724 || (type&XTYPE)>PTR || regvar<3)