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