|
|
1.1 root 1: /*
2: * C compiler, phase 1
3: * Handles processing of declarations,
4: * except for top-level processing of
5: * externals.
6: */
7:
8: #include "c0.h"
9:
10: /*
11: * Process a sequence of declaration statements
12: */
13: declist(sclass)
14: {
15: register sc, offset;
16: struct nmlist typer;
17:
18: offset = 0;
19: sc = sclass;
20: while (getkeywords(&sclass, &typer)) {
21: offset = declare(sclass, &typer, offset);
22: sclass = sc;
23: }
24: return(offset+align(INT, offset, 0));
25: }
26:
27: /*
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.
31: */
32: getkeywords(scptr, tptr)
33: int *scptr;
34: struct nmlist *tptr;
35: {
36: register skw, tkw, longf;
37: int o, isadecl, ismos, unsignf;
38:
39: isadecl = 0;
40: longf = 0;
41: unsignf = 0;
42: tptr->htype = INT;
43: tptr->hstrp = NULL;
44: tptr->hsubsp = NULL;
45: tkw = -1;
46: skw = *scptr;
47: ismos = skw==MOS||skw==MOU? FMOS: 0;
48: for (;;) {
49: mosflg = isadecl? ismos: 0;
50: o = symbol();
51: if (o==NAME && csym->hclass==TYPEDEF && tkw<0) {
52: tkw = csym->htype;
53: tptr->hsubsp = csym->hsubsp;
54: tptr->hstrp = csym->hstrp;
55: isadecl++;
56: continue;
57: }
58: switch (o==KEYW? cval: -1) {
59: case AUTO:
60: case STATIC:
61: case EXTERN:
62: case REG:
63: case TYPEDEF:
64: if (skw && skw!=cval) {
65: if (skw==ARG && cval==REG)
66: cval = AREG;
67: else
68: error("Conflict in storage class");
69: }
70: skw = cval;
71: break;
72:
73: case UNSIGN:
74: unsignf++;
75: break;
76:
77: case LONG:
78: longf++;
79: break;
80:
81: case ENUM:
82: if (longf || unsignf)
83: error("Perverse modifier on 'enum'");
84: strdec(ismos, cval);
85: cval = INT;
86: goto types;
87:
88: case UNION:
89: case STRUCT:
90: tptr->hstrp = strdec(ismos, cval);
91: cval = STRUCT;
92: case INT:
93: case CHAR:
94: case FLOAT:
95: case DOUBLE:
96: case VOID:
97: types:
98: if (tkw>=0 && (tkw!=INT || cval!=INT))
99: error("Type clash");
100: tkw = cval;
101: if (unscflg && cval==CHAR)
102: unsignf++;
103: break;
104:
105: default:
106: peeksym = o;
107: if (isadecl==0)
108: return(0);
109: if (tkw<0)
110: tkw = INT;
111: if (skw==0)
112: skw = blklev==0? DEFXTRN: AUTO;
113: if (unsignf) {
114: if (tkw==INT)
115: tkw = UNSIGN;
116: else if (tkw==CHAR)
117: tkw = UNCHAR;
118: else
119: error("Misplaced 'unsigned'");
120: }
121: if (longf) {
122: if (tkw==FLOAT)
123: tkw = DOUBLE;
124: else if (tkw==INT)
125: tkw = LONG;
126: else
127: error("Misplaced 'long'");
128: }
129: *scptr = skw;
130: tptr->htype = tkw;
131: return(1);
132: }
133: isadecl++;
134: }
135: }
136:
137: /*
138: * Process a structure, union, or enum declaration; a subroutine
139: * of getkeywords.
140: */
141: union str *
142: strdec(mosf, kind)
143: {
144: register elsize, o;
145: register struct nmlist *ssym;
146: int savebits;
147: struct nmlist **savememlist;
148: union str *savesparent;
149: int savenmems;
150: union str *strp;
151: struct nmlist *ds;
152: struct nmlist *mems[NMEMS];
153: struct nmlist typer;
154: int tagkind;
155:
156: if (kind!=ENUM) {
157: tagkind = STRTAG;
158: mosflg = FTAG;
159: if (kind==UNION)
160: mosflg = FUNION;
161: } else {
162: tagkind = ENUMTAG;
163: mosflg = FENUM;
164: }
165: ssym = 0;
166: if ((o=symbol())==NAME) {
167: ssym = csym;
168: mosflg = mosf;
169: o = symbol();
170: if (o==LBRACE && ssym->hblklev<blklev)
171: ssym = pushdecl(ssym);
172: if (ssym->hclass && ssym->hclass!=tagkind) {
173: defsym = ssym;
174: redec();
175: ssym = pushdecl(ssym);
176: }
177: if (ssym->hclass==0) {
178: ssym->hclass = tagkind;
179: ssym->hstrp = (union str *)Dblock(sizeof(struct SS));
180: ssym->hstrp->S.ssize = 0;
181: ssym->hstrp->S.memlist = NULL;
182: }
183: strp = ssym->hstrp;
184: } else {
185: strp = (union str *)Dblock(sizeof(struct SS));
186: strp->S.ssize = 0;
187: strp->S.memlist = NULL;
188: }
189: mosflg = 0;
190: if (o != LBRACE) {
191: if (ssym==0)
192: goto syntax;
193: if (ssym->hclass!=tagkind)
194: error("Bad structure/union/enum name");
195: peeksym = o;
196: } else {
197: ds = defsym;
198: mosflg = 0;
199: savebits = bitoffs;
200: savememlist = memlist;
201: savesparent = sparent;
202: savenmems = nmems;
203: memlist = mems;
204: sparent = strp;
205: nmems = 2;
206: bitoffs = 0;
207: if (kind==ENUM) {
208: typer.htype = INT;
209: typer.hstrp = strp;
210: declare(ENUM, &typer, 0);
211: } else
212: elsize = declist(kind==UNION?MOU:MOS);
213: bitoffs = savebits;
214: defsym = ds;
215: if (strp->S.ssize)
216: error("%.8s redeclared", ssym->name);
217: strp->S.ssize = elsize;
218: *memlist++ = NULL;
219: strp->S.memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
220: for (o=0; &mems[o] != memlist; o++)
221: strp->S.memlist[o] = mems[o];
222: memlist = savememlist;
223: sparent = savesparent;
224: nmems = savenmems;
225: if ((o = symbol()) != RBRACE)
226: goto syntax;
227: }
228: return(strp);
229: syntax:
230: decsyn(o);
231: return(0);
232: }
233:
234: /*
235: * Process a comma-separated list of declarators
236: */
237: declare(askw, tptr, offset)
238: struct nmlist *tptr;
239: {
240: register int o;
241: register int skw, isunion;
242: struct nmlist abs, *aptr;
243:
244: skw = askw;
245: isunion = 0;
246: if (skw==MOU) {
247: skw = MOS;
248: isunion++;
249: mosflg = FMOS;
250: if ((peeksym=symbol()) == SEMI) {
251: o = length((union tree *)tptr);
252: if (o>offset)
253: offset = o;
254: }
255: }
256: do {
257: if (skw==ENUM && (peeksym=symbol())==RBRACE) {
258: o = peeksym;
259: peeksym = -1;
260: break;
261: }
262: if (skw == MOS) {
263: abs.hclass = 0;
264: abs.hflag = 0;
265: abs.htype = 0;
266: abs.hsubsp = 0;
267: abs.hstrp = 0;
268: abs.nextnm = 0;
269: abs.sparent = 0;
270: abs.hblklev = blklev;
271: strcpy(abs.name, "<none>");
272: aptr = &abs;
273: } else
274: aptr = NULL;
275: o = decl1(skw, tptr, isunion?0:offset, aptr);
276: if (isunion) {
277: o += align(CHAR, o, 0);
278: if (o>offset)
279: offset = o;
280: } else
281: offset += o;
282: } while ((o=symbol()) == COMMA);
283: if (o==RBRACE) {
284: peeksym = o;
285: o = SEMI;
286: }
287: if (o!=SEMI && (o!=RPARN || skw!=ARG1))
288: decsyn(o);
289: return(offset);
290: }
291:
292: /*
293: * Process a single declarator
294: */
295: decl1(askw, atptr, offset, absname)
296: struct nmlist *atptr, *absname;
297: {
298: int t1, a, elsize;
299: register int skw;
300: int type;
301: register struct nmlist *dsym;
302: register struct nmlist *tptr;
303: struct tdim dim;
304: int *dp;
305: int isinit;
306:
307: skw = askw;
308: tptr = atptr;
309: mosflg = skw==MOS? FMOS: 0;
310: dim.rank = 0;
311: if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
312: return(0);
313: /*
314: * Filler field
315: */
316: if (peeksym==COLON && skw==MOS) {
317: peeksym = -1;
318: t1 = conexp();
319: if (t1<0) {
320: error("Negative field width");
321: t1 = 0;
322: }
323: elsize = align(tptr->htype, offset, t1);
324: bitoffs += t1;
325: return(elsize);
326: }
327: t1 = getype(&dim, absname);
328: if (t1 == -1)
329: return(0);
330: if (defsym)
331: absname = NULL;
332: if (tptr->hsubsp) {
333: type = tptr->htype;
334: for (a=0; type&XTYPE;) {
335: if ((type&XTYPE)==ARRAY)
336: dim.dimens[dim.rank++] = tptr->hsubsp[a++];
337: type >>= TYLEN;
338: }
339: }
340: type = tptr->htype & ~TYPE;
341: while (t1&XTYPE) {
342: if (type&BIGTYPE) {
343: typov();
344: type = t1 = 0;
345: }
346: type = type<<TYLEN | (t1 & XTYPE);
347: t1 >>= TYLEN;
348: }
349: type |= tptr->htype&TYPE;
350: if ((type&XTYPE) == FUNC) {
351: if (skw==AUTO)
352: skw = EXTERN;
353: if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
354: error("Bad func. storage class");
355: }
356: if (defsym)
357: dsym = defsym;
358: else if (absname)
359: dsym = absname;
360: else {
361: error("Name required in declaration");
362: return(0);
363: }
364: if (defsym)
365: if (dsym->hblklev<blklev || dsym->hclass==MOS && skw==MOS) {
366: if (skw==MOS && dsym->sparent==sparent)
367: redec();
368: defsym = dsym;
369: if (skw==EXTERN) {
370: for (; dsym!=NULL; dsym = dsym->nextnm) {
371: if (dsym->hclass==EXTERN
372: && strncmp(dsym->name, defsym->name, NCPS)==0) {
373: defsym = dsym;
374: break;
375: }
376: }
377: dsym = defsym;
378: } else
379: defsym = dsym = pushdecl(dsym);
380: }
381: if (dim.rank == 0)
382: dsym->hsubsp = NULL;
383: else {
384: dp = (int *)Dblock(dim.rank*sizeof(dim.rank));
385: for (a=0; a<dim.rank; a++) {
386: if ((t1 = dp[a] = dim.dimens[a])
387: && (dsym->htype&XTYPE) == ARRAY
388: && dsym->hsubsp[a] && t1!=dsym->hsubsp[a])
389: redec();
390: }
391: dsym->hsubsp = dp;
392: }
393: if (!(dsym->hclass==0
394: || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1)
395: || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type))) {
396: redec();
397: goto syntax;
398: }
399: if (dsym->hclass && (dsym->htype&TYPE)==STRUCT && (type&TYPE)==STRUCT)
400: if (dsym->hstrp != tptr->hstrp) {
401: error("structure redeclaration");
402: }
403: dsym->htype = type;
404: if (tptr->hstrp)
405: dsym->hstrp = tptr->hstrp;
406: if (skw==TYPEDEF) {
407: dsym->hclass = TYPEDEF;
408: return(0);
409: }
410: if (skw==ARG1) {
411: if (paraml==NULL)
412: paraml = dsym;
413: else
414: parame->sparent = (union str *)dsym;
415: parame = dsym;
416: dsym->hclass = skw;
417: return(0);
418: }
419: elsize = 0;
420: if (skw==MOS) {
421: elsize = length((union tree *)dsym);
422: if ((peeksym = symbol())==COLON) {
423: elsize = 0;
424: peeksym = -1;
425: t1 = conexp();
426: a = align(type, offset, t1);
427: if (dsym->hflag&FFIELD) {
428: if (dsym->hstrp->F.bitoffs!=bitoffs
429: || dsym->hstrp->F.flen!=t1)
430: redec();
431: } else {
432: dsym->hstrp = (union str *)Dblock(sizeof(struct FS));
433: }
434: dsym->hflag |= FFIELD;
435: dsym->hstrp->F.bitoffs = bitoffs;
436: dsym->hstrp->F.flen = t1;
437: bitoffs += t1;
438: } else
439: a = align(type, offset, 0);
440: elsize += a;
441: offset += a;
442: if (++nmems >= NMEMS) {
443: error("Too many structure members");
444: nmems -= NMEMS/2;
445: memlist -= NMEMS/2;
446: }
447: if (a)
448: *memlist++ = &structhole;
449: dsym->hoffset = offset;
450: *memlist++ = dsym;
451: dsym->sparent = sparent;
452: }
453: if (skw==REG)
454: if ((dsym->hoffset = goodreg(dsym)) < 0)
455: skw = AUTO;
456: dsym->hclass = skw;
457: isinit = 0;
458: if ((a=symbol()) == ASSIGN)
459: isinit++;
460: else
461: peeksym = a;
462: if (skw==AUTO) {
463: /* if (STAUTO < 0) { */
464: autolen -= rlength((union tree *)dsym);
465: dsym->hoffset = autolen;
466: if (autolen < maxauto)
467: maxauto = autolen;
468: /* } else { */
469: /* dsym->hoffset = autolen; */
470: /* autolen += rlength(dsym); */
471: /* if (autolen > maxauto) */
472: /* maxauto = autolen; */
473: /* } */
474: if (isinit)
475: cinit(dsym, 0, AUTO);
476: isinit = 0;
477: } else if (skw==STATIC) {
478: dsym->hoffset = isn;
479: if (isinit) {
480: outcode("BBN", DATA, LABEL, isn++);
481: if (cinit(dsym, 1, STATIC) & ALIGN)
482: outcode("B", EVEN);
483: } else
484: outcode("BBNBN", BSS, LABEL, isn++, SSPACE,
485: rlength((union tree *)dsym));
486: outcode("B", PROG);
487: isinit = 0;
488: } else if (skw==REG && isinit) {
489: cinit(dsym, 0, REG);
490: isinit = 0;
491: } else if (skw==ENUM) {
492: if (type!=INT)
493: error("Illegal enumeration %.8s", dsym->name);
494: dsym->hclass = ENUMCON;
495: dsym->hoffset = offset;
496: if (isinit)
497: cinit(dsym, 0, ENUMCON);
498: elsize = dsym->hoffset-offset+1;
499: isinit = 0;
500: }
501: if (absname==0)
502: prste(dsym);
503: if (isinit)
504: peeksym = ASSIGN;
505: syntax:
506: return(elsize);
507: }
508:
509: /*
510: * Push down an outer-block declaration
511: * after redeclaration in an inner block.
512: */
513: struct nmlist *
514: pushdecl(sp)
515: register struct nmlist *sp;
516: {
517: register struct nmlist *nsp, **hsp;
518:
519: nsp = (struct nmlist *)Dblock(sizeof(struct nmlist));
520: *nsp = *sp;
521: nsp->hclass = 0;
522: nsp->hflag &= FKIND;
523: nsp->htype = 0;
524: nsp->hoffset = 0;
525: nsp->hblklev = blklev;
526: nsp->hstrp = NULL;
527: nsp->hsubsp = NULL;
528: nsp->sparent = NULL;
529: hsp = &hshtab[hash(sp->name)];
530: nsp->nextnm = *hsp;
531: *hsp = nsp;
532: return(nsp);
533: }
534:
535: /*
536: * Read a declarator and get the implied type
537: */
538: getype(dimp, absname)
539: register struct tdim *dimp;
540: struct nmlist *absname;
541: {
542: static struct nmlist argtype;
543: int type;
544: register int o;
545: register struct nmlist *ds;
546:
547: defsym = 0;
548: type = 0;
549: switch(o=symbol()) {
550:
551: case TIMES:
552: type = getype(dimp, absname);
553: if (type==-1)
554: return(type);
555: if (type&BIGTYPE) {
556: typov();
557: type = 0;
558: }
559: return(type<<TYLEN | PTR);
560:
561: case LPARN:
562: if (absname==NULL || nextchar()!=')') {
563: type = getype(dimp, absname);
564: if (type==-1)
565: return(type);
566: if ((o=symbol()) != RPARN)
567: goto syntax;
568: goto getf;
569: }
570:
571: default:
572: peeksym = o;
573: if (absname)
574: goto getf;
575: break;
576:
577: case NAME:
578: defsym = ds = csym;
579: getf:
580: switch(o=symbol()) {
581:
582: case LPARN:
583: if (blklev==0) {
584: blklev++;
585: ds = defsym;
586: declare(ARG1, &argtype, 0);
587: defsym = ds;
588: blklev--;
589: } else
590: if ((o=symbol()) != RPARN)
591: goto syntax;
592: if (type&BIGTYPE) {
593: typov();
594: type = 0;
595: }
596: type = type<<TYLEN | FUNC;
597: goto getf;
598:
599: case LBRACK:
600: if (dimp->rank>=5) {
601: error("Rank too large");
602: dimp->rank = 4;
603: }
604: if ((o=symbol()) != RBRACK) {
605: peeksym = o;
606: ds = defsym;
607: cval = conexp();
608: defsym = ds;
609: if ((o=symbol())!=RBRACK)
610: goto syntax;
611: } else {
612: if (dimp->rank!=0)
613: error("Null dimension");
614: cval = 0;
615: }
616: dimp->dimens[dimp->rank++] = cval;
617: if (type&BIGTYPE) {
618: typov();
619: type = 0;
620: }
621: type = type<<TYLEN | ARRAY;
622: goto getf;
623: }
624: peeksym = o;
625: return(type);
626: }
627: syntax:
628: decsyn(o);
629: return(-1);
630: }
631:
632: /*
633: * More bits required for type than allowed.
634: */
635: typov()
636: {
637: error("Type is too complicated");
638: }
639:
640: /*
641: * Enforce alignment restrictions in structures,
642: * including bit-field considerations.
643: */
644: align(type, offset, aflen)
645: {
646: register a, t, flen;
647: char *ftl;
648:
649: flen = aflen;
650: a = offset;
651: t = type;
652: ftl = "Field too long";
653: if (flen==0) {
654: a += (NBPC+bitoffs-1) / NBPC;
655: bitoffs = 0;
656: }
657: while ((t&XTYPE)==ARRAY)
658: t = decref(t);
659: if (t!=CHAR && t!=UNCHAR) {
660: a = (a+ALIGN) & ~ALIGN;
661: if (a>offset)
662: bitoffs = 0;
663: }
664: if (flen) {
665: if (type==INT || type==UNSIGN) {
666: if (flen > NBPW)
667: error(ftl);
668: if (flen+bitoffs > NBPW) {
669: bitoffs = 0;
670: a += NCPW;
671: }
672: } else if (type==CHAR || type==UNCHAR) {
673: if (flen > NBPC)
674: error(ftl);
675: if (flen+bitoffs > NBPC) {
676: bitoffs = 0;
677: a += 1;
678: }
679: } else
680: error("Bad type for field");
681: }
682: return(a-offset);
683: }
684:
685: /*
686: * Complain about syntax error in declaration
687: */
688: decsyn(o)
689: {
690: error("Declaration syntax");
691: errflush(o);
692: }
693:
694: /*
695: * Complain about a redeclaration
696: */
697: redec()
698: {
699: error("%.8s redeclared", defsym->name);
700: }
701:
702: /*
703: * Determine if a variable is suitable for storage in
704: * a register; if so return the register number
705: */
706: goodreg(hp)
707: struct nmlist *hp;
708: {
709: int type;
710:
711: type = hp->htype;
712: if ((type!=INT && type!=UNSIGN && (type&XTYPE)==0)
713: || (type&XTYPE)>PTR || regvar<3)
714: return(-1);
715: return(--regvar);
716: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.