1 #ifndef lint
2 static char *sccsid ="@(#)pftn.c 1.29 (Berkeley) 06/18/90";
3 #endif lint
4
5 # include "pass1.h"
6
7 unsigned int offsz;
8
9 struct symtab *schain[MAXSCOPES]; /* sym chains for clearst */
10 int chaintop; /* highest active entry */
11
12 struct instk {
13 int in_sz; /* size of array element */
14 int in_x; /* current index for structure member in structure initializations */
15 int in_n; /* number of initializations seen */
16 int in_s; /* sizoff */
17 int in_d; /* dimoff */
18 TWORD in_t; /* type */
19 int in_id; /* stab index */
20 int in_fl; /* flag which says if this level is controlled by {} */
21 OFFSZ in_off; /* offset of the beginning of this level */
22 }
23 instack[10],
24 *pstk;
25
26 /* defines used for getting things off of the initialization stack */
27
28
29 struct symtab *relook();
30
31
32 int ddebug = 0;
33
34 struct symtab * mknonuniq();
35
defid(q,class)36 defid( q, class ) register NODE *q; register int class; {
37 register struct symtab *p;
38 int idp;
39 register TWORD type;
40 TWORD stp;
41 register int scl;
42 int dsym, ddef;
43 int slev, temp;
44 int changed;
45
46 if( q == NIL ) return; /* an error was detected */
47
48 if( q < node || q >= &node[TREESZ] ) cerror( "defid call" );
49
50 idp = q->tn.rval;
51
52 if( idp < 0 ) cerror( "tyreduce" );
53 p = &stab[idp];
54
55 # ifndef BUG1
56 if( ddebug ){
57 #ifndef FLEXNAMES
58 printf( "defid( %.8s (%d), ", p->sname, idp );
59 #else
60 printf( "defid( %s (%d), ", p->sname, idp );
61 #endif
62 tprint( q->in.type );
63 printf( ", %s, (%d,%d) ), level %d\n", scnames(class), q->fn.cdim, q->fn.csiz, blevel );
64 }
65 # endif
66
67 fixtype( q, class );
68
69 type = q->in.type;
70 class = fixclass( class, type );
71
72 stp = p->stype;
73 slev = p->slevel;
74
75 # ifndef BUG1
76 if( ddebug ){
77 printf( " modified to " );
78 tprint( type );
79 printf( ", %s\n", scnames(class) );
80 printf( " previous def'n: " );
81 tprint( stp );
82 printf( ", %s, (%d,%d) ), level %d\n", scnames(p->sclass), p->dimoff, p->sizoff, slev );
83 }
84 # endif
85
86 if( stp == FTN && p->sclass == SNULL )goto enter;
87 if( blevel==1 && stp!=FARG ) switch( class ){
88
89 default:
90 #ifndef FLEXNAMES
91 if(!(class&FIELD)) uerror( "declared argument %.8s is missing", p->sname );
92 #else
93 if(!(class&FIELD)) uerror( "declared argument %s is missing", p->sname );
94 #endif
95 case MOS:
96 case STNAME:
97 case MOU:
98 case UNAME:
99 case MOE:
100 case ENAME:
101 case TYPEDEF:
102 ;
103 }
104 if( stp == UNDEF|| stp == FARG ) goto enter;
105
106 if( type != stp ) goto mismatch;
107 if( blevel > slev && (class == AUTO || class == REGISTER) )
108 /* new scope */
109 goto mismatch;
110
111 /* test (and possibly adjust) dimensions */
112 dsym = p->dimoff;
113 ddef = q->fn.cdim;
114 changed = 0;
115 for( temp=type; temp&TMASK; temp = DECREF(temp) ){
116 if( ISARY(temp) ){
117 if (dimtab[dsym] == 0) {
118 dimtab[dsym] = dimtab[ddef];
119 changed = 1;
120 }
121 else if (dimtab[ddef]!=0&&dimtab[dsym]!=dimtab[ddef]) {
122 goto mismatch;
123 }
124 ++dsym;
125 ++ddef;
126 }
127 }
128
129 if (changed) {
130 FIXDEF(p);
131 }
132
133 /* check that redeclarations are to the same structure */
134 if( (temp==STRTY||temp==UNIONTY||temp==ENUMTY) && p->sizoff != q->fn.csiz
135 && class!=STNAME && class!=UNAME && class!=ENAME ){
136 goto mismatch;
137 }
138
139 scl = ( p->sclass );
140
141 # ifndef BUG1
142 if( ddebug ){
143 printf( " previous class: %s\n", scnames(scl) );
144 }
145 # endif
146
147 if( class&FIELD ){
148 /* redefinition */
149 if( !falloc( p, class&FLDSIZ, 1, NIL ) ) {
150 /* successful allocation */
151 psave( idp );
152 return;
153 }
154 /* blew it: resume at end of switch... */
155 }
156
157 else switch( class ){
158
159 case EXTERN:
160 switch( scl ){
161 case STATIC:
162 case USTATIC:
163 if( slev==0 ) return;
164 break;
165 case EXTDEF:
166 case EXTERN:
167 case FORTRAN:
168 case UFORTRAN:
169 return;
170 }
171 break;
172
173 case STATIC:
174 if( scl==USTATIC || (scl==EXTERN && blevel==0) ){
175 p->sclass = STATIC;
176 if( ISFTN(type) ) curftn = idp;
177 return;
178 }
179 break;
180
181 case USTATIC:
182 if( scl==STATIC || scl==USTATIC ) return;
183 break;
184
185 case LABEL:
186 if( scl == ULABEL ){
187 p->sclass = LABEL;
188 deflab( p->offset );
189 return;
190 }
191 break;
192
193 case TYPEDEF:
194 if( scl == class ) return;
195 break;
196
197 case UFORTRAN:
198 if( scl == UFORTRAN || scl == FORTRAN ) return;
199 break;
200
201 case FORTRAN:
202 if( scl == UFORTRAN ){
203 p->sclass = FORTRAN;
204 if( ISFTN(type) ) curftn = idp;
205 return;
206 }
207 break;
208
209 case MOU:
210 case MOS:
211 if( scl == class ) {
212 if( oalloc( p, &strucoff ) ) break;
213 if( class == MOU ) strucoff = 0;
214 psave( idp );
215 return;
216 }
217 break;
218
219 case MOE:
220 break;
221
222 case EXTDEF:
223 if( scl == EXTERN ) {
224 p->sclass = EXTDEF;
225 if( ISFTN(type) ) curftn = idp;
226 return;
227 }
228 break;
229
230 case STNAME:
231 case UNAME:
232 case ENAME:
233 if( scl != class ) break;
234 if( dimtab[p->sizoff] == 0 ) return; /* previous entry just a mention */
235 break;
236
237 case ULABEL:
238 if( scl == LABEL || scl == ULABEL ) return;
239 case PARAM:
240 case AUTO:
241 case REGISTER:
242 ; /* mismatch.. */
243
244 }
245
246 mismatch:
247 /* allow nonunique structure/union member names */
248
249 if( class==MOU || class==MOS || class & FIELD ){/* make a new entry */
250 register int *memp;
251 p->sflags |= SNONUNIQ; /* old entry is nonunique */
252 /* determine if name has occurred in this structure/union */
253 if (paramno > 0) for( memp = ¶mstk[paramno-1];
254 /* while */ *memp>=0 && stab[*memp].sclass != STNAME
255 && stab[*memp].sclass != UNAME;
256 /* iterate */ --memp){ char *cname, *oname;
257 if( stab[*memp].sflags & SNONUNIQ ){
258 cname=p->sname;
259 oname=stab[*memp].sname;
260 #ifndef FLEXNAMES
261 for(temp=1; temp<=NCHNAM; ++temp){
262 if(*cname++ != *oname)goto diff;
263 if(!*oname++)break;
264 }
265 #else
266 if (cname != oname) goto diff;
267 #endif
268 uerror("redeclaration of: %s",p->sname);
269 break;
270 diff: continue;
271 }
272 }
273 p = mknonuniq( &idp ); /* update p and idp to new entry */
274 goto enter;
275 }
276 if( blevel > slev && class != EXTERN && class != FORTRAN &&
277 class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){
278 q->tn.rval = idp = hide( p );
279 p = &stab[idp];
280 goto enter;
281 }
282 #ifndef FLEXNAMES
283 uerror( "redeclaration of %.8s", p->sname );
284 #else
285 uerror( "redeclaration of %s", p->sname );
286 #endif
287 if( class==EXTDEF && ISFTN(type) ) curftn = idp;
288 return;
289
290 enter: /* make a new entry */
291
292 # ifndef BUG1
293 if( ddebug ) printf( " new entry made\n" );
294 # endif
295 if( type == UNDEF ) uerror("void type for %s",p->sname);
296 p->stype = type;
297 p->sclass = class;
298 p->slevel = blevel;
299 p->offset = NOOFFSET;
300 p->suse = lineno;
301 if( class == STNAME || class == UNAME || class == ENAME ) {
302 p->sizoff = curdim;
303 dstash( 0 ); /* size */
304 dstash( -1 ); /* index to members of str or union */
305 dstash( ALSTRUCT ); /* alignment */
306 dstash( idp );
307 }
308 else {
309 switch( BTYPE(type) ){
310 case STRTY:
311 case UNIONTY:
312 case ENUMTY:
313 p->sizoff = q->fn.csiz;
314 break;
315 default:
316 p->sizoff = BTYPE(type);
317 }
318 }
319
320 /* copy dimensions */
321
322 p->dimoff = q->fn.cdim;
323
324 /* allocate offsets */
325 if( class&FIELD ){
326 (void) falloc( p, class&FLDSIZ, 0, NIL ); /* new entry */
327 psave( idp );
328 }
329 else switch( class ){
330
331 case AUTO:
332 (void) oalloc( p, &autooff );
333 break;
334 case STATIC:
335 case EXTDEF:
336 p->offset = getlab();
337 if( ISFTN(type) ) curftn = idp;
338 break;
339 case ULABEL:
340 case LABEL:
341 p->offset = getlab();
342 p->slevel = 2;
343 if( class == LABEL ){
344 (void) locctr( PROG );
345 deflab( p->offset );
346 }
347 break;
348
349 case EXTERN:
350 case UFORTRAN:
351 case FORTRAN:
352 p->offset = getlab();
353 p->slevel = 0;
354 break;
355 case MOU:
356 case MOS:
357 (void) oalloc( p, &strucoff );
358 if( class == MOU ) strucoff = 0;
359 psave( idp );
360 break;
361
362 case MOE:
363 p->offset = strucoff++;
364 psave( idp );
365 break;
366 case REGISTER:
367 p->offset = regvar--;
368 if( blevel == 1 ) p->sflags |= SSET;
369 if( regvar < minrvar ) minrvar = regvar;
370 break;
371 }
372
373 {
374 register int l = p->slevel;
375
376 if( l >= MAXSCOPES )
377 cerror( "scopes nested too deep" );
378
379 p->snext = schain[l];
380 schain[l] = p;
381 if( l >= chaintop )
382 chaintop = l + 1;
383 }
384
385 /* user-supplied routine to fix up new definitions */
386
387 FIXDEF(p);
388
389 # ifndef BUG1
390 if( ddebug ) printf( " dimoff, sizoff, offset: %d, %d, %d\n", p->dimoff, p->sizoff, p->offset );
391 # endif
392
393 }
394
psave(i)395 psave( i ){
396 if( paramno >= PARAMSZ ){
397 cerror( "parameter stack overflow");
398 }
399 paramstk[ paramno++ ] = i;
400 }
401
ftnend()402 ftnend(){ /* end of function */
403 if( retlab != NOLAB && nerrors == 0 ){ /* inside a real function */
404 efcode();
405 }
406 checkst(0);
407 retstat = 0;
408 tcheck();
409 curclass = SNULL;
410 brklab = contlab = retlab = NOLAB;
411 flostat = 0;
412 if( nerrors == 0 ){
413 if( psavbc != & asavbc[0] ) cerror("bcsave error");
414 if( paramno != 0 ) cerror("parameter reset error");
415 if( swx != 0 ) cerror( "switch error");
416 }
417 psavbc = &asavbc[0];
418 paramno = 0;
419 autooff = AUTOINIT;
420 minrvar = regvar = MAXRVAR;
421 reached = 1;
422 swx = 0;
423 swp = swtab;
424 (void) locctr(DATA);
425 }
426
dclargs()427 dclargs(){
428 register i, j;
429 register struct symtab *p;
430 register NODE *q;
431 argoff = ARGINIT;
432 # ifndef BUG1
433 if( ddebug > 2) printf("dclargs()\n");
434 # endif
435 for( i=0; i<paramno; ++i ){
436 if( (j = paramstk[i]) < 0 ) continue;
437 p = &stab[j];
438 # ifndef BUG1
439 if( ddebug > 2 ){
440 printf("\t%s (%d) ",p->sname, j);
441 tprint(p->stype);
442 printf("\n");
443 }
444 # endif
445 if( p->stype == FARG ) {
446 q = block(FREE,NIL,NIL,INT,0,INT);
447 q->tn.rval = j;
448 defid( q, PARAM );
449 }
450 FIXARG(p); /* local arg hook, eg. for sym. debugger */
451 oalloc( p, &argoff ); /* always set aside space, even for register arguments */
452 }
453 cendarg();
454 (void) locctr(PROG);
455 defalign(ALINT);
456 ftnno = getlab();
457 bfcode( paramstk, paramno );
458 paramno = 0;
459 }
460
461 NODE *
rstruct(idn,soru)462 rstruct( idn, soru ){ /* reference to a structure or union, with no definition */
463 register struct symtab *p;
464 register NODE *q;
465 p = &stab[idn];
466 switch( p->stype ){
467
468 case UNDEF:
469 def:
470 q = block( FREE, NIL, NIL, 0, 0, 0 );
471 q->tn.rval = idn;
472 q->in.type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY );
473 defid( q, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) );
474 break;
475
476 case STRTY:
477 if( soru & INSTRUCT ) break;
478 goto def;
479
480 case UNIONTY:
481 if( soru & INUNION ) break;
482 goto def;
483
484 case ENUMTY:
485 if( !(soru&(INUNION|INSTRUCT)) ) break;
486 goto def;
487
488 }
489 stwart = instruct;
490 return( mkty( p->stype, 0, p->sizoff ) );
491 }
492
moedef(idn)493 moedef( idn ){
494 register NODE *q;
495
496 q = block( FREE, NIL, NIL, MOETY, 0, 0 );
497 q->tn.rval = idn;
498 if( idn>=0 ) defid( q, MOE );
499 }
500
bstruct(idn,soru)501 bstruct( idn, soru ){ /* begining of structure or union declaration */
502 register NODE *q;
503
504 psave( instruct );
505 psave( curclass );
506 psave( strucoff );
507 strucoff = 0;
508 instruct = soru;
509 q = block( FREE, NIL, NIL, 0, 0, 0 );
510 q->tn.rval = idn;
511 if( instruct==INSTRUCT ){
512 curclass = MOS;
513 q->in.type = STRTY;
514 if( idn >= 0 ) defid( q, STNAME );
515 }
516 else if( instruct == INUNION ) {
517 curclass = MOU;
518 q->in.type = UNIONTY;
519 if( idn >= 0 ) defid( q, UNAME );
520 }
521 else { /* enum */
522 curclass = MOE;
523 q->in.type = ENUMTY;
524 if( idn >= 0 ) defid( q, ENAME );
525 }
526 psave( idn = q->tn.rval );
527 /* the "real" definition is where the members are seen */
528 if ( idn >= 0 ) stab[idn].suse = lineno;
529 return( paramno-4 );
530 }
531
532 NODE *
dclstruct(oparam)533 dclstruct( oparam ){
534 register struct symtab *p;
535 register i, al, sa, j, sz, szindex;
536 register TWORD temp;
537 register high, low;
538
539 /* paramstk contains:
540 paramstk[ oparam ] = previous instruct
541 paramstk[ oparam+1 ] = previous class
542 paramstk[ oparam+2 ] = previous strucoff
543 paramstk[ oparam+3 ] = structure name
544
545 paramstk[ oparam+4, ... ] = member stab indices
546
547 */
548
549
550 if( (i=paramstk[oparam+3]) < 0 ){
551 szindex = curdim;
552 dstash( 0 ); /* size */
553 dstash( -1 ); /* index to member names */
554 dstash( ALSTRUCT ); /* alignment */
555 dstash( -lineno ); /* name of structure */
556 }
557 else {
558 szindex = stab[i].sizoff;
559 }
560
561 # ifndef BUG1
562 if( ddebug ){
563 #ifndef FLEXNAMES
564 printf( "dclstruct( %.8s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex );
565 #else
566 printf( "dclstruct( %s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex );
567 #endif
568 }
569 # endif
570 temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
571 stwart = instruct = paramstk[ oparam ];
572 curclass = paramstk[ oparam+1 ];
573 dimtab[ szindex+1 ] = curdim;
574 al = ALSTRUCT;
575
576 high = low = 0;
577
578 for( i = oparam+4; i< paramno; ++i ){
579 dstash( j=paramstk[i] );
580 if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" );
581 p = &stab[j];
582 if( temp == ENUMTY ){
583 if( p->offset < low ) low = p->offset;
584 if( p->offset > high ) high = p->offset;
585 p->sizoff = szindex;
586 continue;
587 }
588 sa = talign( p->stype, p->sizoff );
589 if( p->sclass & FIELD ){
590 sz = p->sclass&FLDSIZ;
591 }
592 else {
593 sz = tsize( p->stype, p->dimoff, p->sizoff );
594 }
595 if( sz == 0 ){
596 #ifndef FLEXNAMES
597 werror( "illegal zero sized structure member: %.8s", p->sname );
598 #else
599 werror( "illegal zero sized structure member: %s", p->sname );
600 #endif
601 }
602 if( sz > strucoff ) strucoff = sz; /* for use with unions */
603 SETOFF( al, sa );
604 /* set al, the alignment, to the lcm of the alignments of the members */
605 }
606 dstash( -1 ); /* endmarker */
607 SETOFF( strucoff, al );
608
609 if( temp == ENUMTY ){
610 register TWORD ty;
611
612 # ifdef ENUMSIZE
613 ty = ENUMSIZE(high,low);
614 # else
615 if( (char)high == high && (char)low == low ) ty = ctype( CHAR );
616 else if( (short)high == high && (short)low == low ) ty = ctype( SHORT );
617 else ty = ctype(INT);
618 #endif
619 strucoff = tsize( ty, 0, (int)ty );
620 dimtab[ szindex+2 ] = al = talign( ty, (int)ty );
621 }
622
623 if( strucoff == 0 ) uerror( "zero sized structure" );
624 dimtab[ szindex ] = strucoff;
625 dimtab[ szindex+2 ] = al;
626 dimtab[ szindex+3 ] = paramstk[ oparam+3 ]; /* name index */
627
628 FIXSTRUCT( szindex, oparam ); /* local hook, eg. for sym debugger */
629 # ifndef BUG1
630 if( ddebug>1 ){
631 printf( "\tdimtab[%d,%d,%d] = %d,%d,%d\n", szindex,szindex+1,szindex+2,
632 dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] );
633 for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){
634 #ifndef FLEXNAMES
635 printf( "\tmember %.8s(%d)\n", stab[dimtab[i]].sname, dimtab[i] );
636 #else
637 printf( "\tmember %s(%d)\n", stab[dimtab[i]].sname, dimtab[i] );
638 #endif
639 }
640 }
641 # endif
642
643 strucoff = paramstk[ oparam+2 ];
644 paramno = oparam;
645
646 return( mkty( temp, 0, szindex ) );
647 }
648
649 /* VARARGS */
yyerror(s)650 yyerror( s ) char *s; { /* error printing routine in parser */
651
652 uerror( s );
653
654 }
655
yyaccpt()656 yyaccpt(){
657 ftnend();
658 }
659
ftnarg(idn)660 ftnarg( idn ) {
661 switch( stab[idn].stype ){
662
663 case UNDEF:
664 /* this parameter, entered at scan */
665 break;
666 case FARG:
667 #ifndef FLEXNAMES
668 uerror("redeclaration of formal parameter, %.8s",
669 #else
670 uerror("redeclaration of formal parameter, %s",
671 #endif
672 stab[idn].sname);
673 /* fall thru */
674 case FTN:
675 /* the name of this function matches parm */
676 /* fall thru */
677 default:
678 idn = hide( &stab[idn]);
679 break;
680 case TNULL:
681 /* unused entry, fill it */
682 ;
683 }
684 stab[idn].stype = FARG;
685 stab[idn].sclass = PARAM;
686 psave( idn );
687 }
688
talign(ty,s)689 talign( ty, s) register unsigned ty; register s; {
690 /* compute the alignment of an object with type ty, sizeoff index s */
691
692 register i;
693 if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT
694 #ifdef LONGFIELDS
695 && ty!=LONG && ty!=ULONG
696 #endif
697 ){
698 return( fldal( ty ) );
699 }
700
701 for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
702 switch( (ty>>i)&TMASK ){
703
704 case FTN:
705 uerror( "can't assign to function" );
706 return( ALCHAR );
707 case PTR:
708 return( ALPOINT );
709 case ARY:
710 continue;
711 case 0:
712 break;
713 }
714 }
715
716 switch( BTYPE(ty) ){
717
718 case UNIONTY:
719 case ENUMTY:
720 case STRTY:
721 return( (unsigned int) dimtab[ s+2 ] );
722 case CHAR:
723 case UCHAR:
724 return( ALCHAR );
725 case FLOAT:
726 return( ALFLOAT );
727 case DOUBLE:
728 return( ALDOUBLE );
729 case LONG:
730 case ULONG:
731 return( ALLONG );
732 case SHORT:
733 case USHORT:
734 return( ALSHORT );
735 default:
736 return( ALINT );
737 }
738 }
739
740 OFFSZ
tsize(ty,d,s)741 tsize( ty, d, s ) TWORD ty; {
742 /* compute the size associated with type ty,
743 dimoff d, and sizoff s */
744 /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
745
746 int i;
747 OFFSZ mult;
748
749 mult = 1;
750
751 for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
752 switch( (ty>>i)&TMASK ){
753
754 case FTN:
755 /* cerror( "compiler takes size of function"); */
756 uerror( "can't take size of function" );
757 return( SZCHAR );
758 case PTR:
759 return( SZPOINT * mult );
760 case ARY:
761 mult *= (unsigned int) dimtab[ d++ ];
762 continue;
763 case 0:
764 break;
765
766 }
767 }
768
769 if( dimtab[s]==0 ) {
770 if( ty == STRTY )
771 uerror( "undefined structure" );
772 else
773 uerror( "unknown size");
774 return( SZINT );
775 }
776 return( (unsigned int) dimtab[ s ] * mult );
777 }
778
inforce(n)779 inforce( n ) OFFSZ n; { /* force inoff to have the value n */
780 /* inoff is updated to have the value n */
781 OFFSZ wb;
782 register rest;
783 /* rest is used to do a lot of conversion to ints... */
784
785 if( inoff == n ) return;
786 if( inoff > n ) {
787 cerror( "initialization alignment error");
788 }
789
790 wb = inoff;
791 SETOFF( wb, SZINT );
792
793 /* wb now has the next higher word boundary */
794
795 if( wb >= n ){ /* in the same word */
796 rest = n - inoff;
797 vfdzero( rest );
798 return;
799 }
800
801 /* otherwise, extend inoff to be word aligned */
802
803 rest = wb - inoff;
804 vfdzero( rest );
805
806 /* now, skip full words until near to n */
807
808 rest = (n-inoff)/SZINT;
809 zecode( rest );
810
811 /* now, the remainder of the last word */
812
813 rest = n-inoff;
814 vfdzero( rest );
815 if( inoff != n ) cerror( "inoff error");
816
817 }
818
vfdalign(n)819 vfdalign( n ){ /* make inoff have the offset the next alignment of n */
820 OFFSZ m;
821
822 m = inoff;
823 SETOFF( m, n );
824 inforce( m );
825 }
826
827
828 int idebug = 0;
829
830 int ibseen = 0; /* the number of } constructions which have been filled */
831
832 int ifull = 0; /* 1 if all initializers have been seen */
833
834 int iclass; /* storage class of thing being initialized */
835
836 int ilocctr = 0; /* location counter for current initialization */
837
beginit(curid)838 beginit(curid){
839 /* beginning of initilization; set location ctr and set type */
840 register struct symtab *p;
841
842 # ifndef BUG1
843 if( idebug >= 3 ) printf( "beginit(), curid = %d\n", curid );
844 # endif
845
846 p = &stab[curid];
847
848 iclass = p->sclass;
849 if( curclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN;
850 switch( iclass ){
851
852 case UNAME:
853 case EXTERN:
854 return;
855 case AUTO:
856 case REGISTER:
857 break;
858 case EXTDEF:
859 case STATIC:
860 ilocctr = ISARY(p->stype)?ADATA:DATA;
861 if( nerrors == 0 ){
862 (void) locctr( ilocctr );
863 defalign( talign( p->stype, p->sizoff ) );
864 defnam( p );
865 }
866
867 }
868
869 inoff = 0;
870 ibseen = 0;
871 ifull = 0;
872
873 pstk = 0;
874
875 instk( curid, p->stype, p->dimoff, p->sizoff, inoff );
876
877 }
878
instk(id,t,d,s,off)879 instk( id, t, d, s, off ) OFFSZ off; TWORD t; {
880 /* make a new entry on the parameter stack to initialize id */
881
882 register struct symtab *p;
883
884 for(;;){
885 # ifndef BUG1
886 if( idebug ) printf( "instk((%d, %o,%d,%d, %d)\n", id, t, d, s, off );
887 # endif
888
889 /* save information on the stack */
890
891 if( !pstk ) pstk = instack;
892 else ++pstk;
893
894 pstk->in_fl = 0; /* { flag */
895 pstk->in_id = id ;
896 pstk->in_t = t ;
897 pstk->in_d = d ;
898 pstk->in_s = s ;
899 pstk->in_n = 0; /* number seen */
900 pstk->in_x = t==STRTY ?dimtab[s+1] : 0 ;
901 pstk->in_off = off; /* offset at the beginning of this element */
902 /* if t is an array, DECREF(t) can't be a field */
903 /* INS_sz has size of array elements, and -size for fields */
904 if( ISARY(t) ){
905 pstk->in_sz = tsize( DECREF(t), d+1, s );
906 }
907 else if( stab[id].sclass & FIELD ){
908 pstk->in_sz = - ( stab[id].sclass & FLDSIZ );
909 }
910 else {
911 pstk->in_sz = 0;
912 }
913
914 if( (iclass==AUTO || iclass == REGISTER ) &&
915 (ISARY(t) || t==STRTY) ) uerror( "no automatic aggregate initialization" );
916
917 /* now, if this is not a scalar, put on another element */
918
919 if( ISARY(t) ){
920 t = DECREF(t);
921 ++d;
922 continue;
923 }
924 else if( t == STRTY ){
925 if( dimtab[pstk->in_s] == 0 ){
926 uerror( "can't initialize undefined structure" );
927 iclass = -1;
928 return;
929 }
930 id = dimtab[pstk->in_x];
931 p = &stab[id];
932 if( p->sclass != MOS && !(p->sclass&FIELD) ) cerror( "insane structure member list" );
933 t = p->stype;
934 d = p->dimoff;
935 s = p->sizoff;
936 off += p->offset;
937 continue;
938 }
939 else return;
940 }
941 }
942
943 NODE *
getstr()944 getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */
945
946 register l, temp;
947 register NODE *p;
948
949 if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) &&
950 pstk!=instack && ISARY( pstk[-1].in_t ) ){
951 /* treat "abc" as { 'a', 'b', 'c', 0 } */
952 strflg = 1;
953 ilbrace(); /* simulate { */
954 inforce( pstk->in_off );
955 /* if the array is inflexible (not top level), pass in the size and
956 be prepared to throw away unwanted initializers */
957 lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0); /* get the contents */
958 irbrace(); /* simulate } */
959 return( NIL );
960 }
961 else { /* make a label, and get the contents and stash them away */
962 if( iclass != SNULL ){ /* initializing */
963 /* fill out previous word, to permit pointer */
964 vfdalign( ALPOINT );
965 }
966 temp = locctr( blevel==0?ISTRNG:STRNG ); /* set up location counter */
967 deflab( l = getlab() );
968 strflg = 0;
969 lxstr(0); /* get the contents */
970 (void) locctr( blevel==0?ilocctr:temp );
971 p = buildtree( STRING, NIL, NIL );
972 p->tn.rval = -l;
973 return(p);
974 }
975 }
976
putbyte(v)977 putbyte( v ){ /* simulate byte v appearing in a list of integer values */
978 register NODE *p;
979 p = bcon(v);
980 incode( p, SZCHAR );
981 tfree( p );
982 gotscal();
983 }
984
endinit()985 endinit(){
986 register TWORD t;
987 register d, s, n, d1;
988
989 # ifndef BUG1
990 if( idebug ) printf( "endinit(), inoff = %d\n", inoff );
991 # endif
992
993 switch( iclass ){
994
995 case EXTERN:
996 case AUTO:
997 case REGISTER:
998 case -1:
999 return;
1000 }
1001
1002 pstk = instack;
1003
1004 t = pstk->in_t;
1005 d = pstk->in_d;
1006 s = pstk->in_s;
1007 n = pstk->in_n;
1008
1009 if( ISARY(t) ){
1010 d1 = dimtab[d];
1011
1012 vfdalign( pstk->in_sz ); /* fill out part of the last element, if needed */
1013 n = inoff/pstk->in_sz; /* real number of initializers */
1014 if( d1 >= n ){
1015 /* once again, t is an array, so no fields */
1016 inforce( tsize( t, d, s ) );
1017 n = d1;
1018 }
1019 if( d1!=0 && d1!=n ) uerror( "too many initializers");
1020 if( n==0 ) werror( "empty array declaration");
1021 dimtab[d] = n;
1022 if( d1==0 ) FIXDEF(&stab[pstk->in_id]);
1023 }
1024
1025 else if( t == STRTY || t == UNIONTY ){
1026 /* clearly not fields either */
1027 inforce( tsize( t, d, s ) );
1028 }
1029 else if( n > 1 ) uerror( "bad scalar initialization");
1030 /* this will never be called with a field element... */
1031 else inforce( tsize(t,d,s) );
1032
1033 paramno = 0;
1034 vfdalign( AL_INIT );
1035 inoff = 0;
1036 iclass = SNULL;
1037
1038 }
1039
fixinit()1040 fixinit(){
1041 /* called from the grammar if we must punt during initialization */
1042 /* stolen from endinit() */
1043 pstk = instack;
1044 paramno = 0;
1045 vfdalign( AL_INIT );
1046 inoff = 0;
1047 iclass = SNULL;
1048 }
1049
doinit(p)1050 doinit( p ) register NODE *p; {
1051
1052 /* take care of generating a value for the initializer p */
1053 /* inoff has the current offset (last bit written)
1054 in the current word being generated */
1055
1056 register sz, d, s;
1057 register TWORD t;
1058 int o;
1059
1060 /* note: size of an individual initializer is assumed to fit into an int */
1061
1062 if( iclass < 0 ) goto leave;
1063 if( iclass == EXTERN || iclass == UNAME ){
1064 uerror( "cannot initialize extern or union" );
1065 iclass = -1;
1066 goto leave;
1067 }
1068
1069 if( iclass == AUTO || iclass == REGISTER ){
1070 /* do the initialization and get out, without regard
1071 for filing out the variable with zeros, etc. */
1072 bccode();
1073 idname = pstk->in_id;
1074 p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p );
1075 ecomp(p);
1076 return;
1077 }
1078
1079 if( p == NIL ) return; /* for throwing away strings that have been turned into lists */
1080
1081 if( ifull ){
1082 uerror( "too many initializers" );
1083 iclass = -1;
1084 goto leave;
1085 }
1086 if( ibseen ){
1087 uerror( "} expected");
1088 goto leave;
1089 }
1090
1091 # ifndef BUG1
1092 if( idebug > 1 ) printf( "doinit(%o)\n", p );
1093 # endif
1094
1095 t = pstk->in_t; /* type required */
1096 d = pstk->in_d;
1097 s = pstk->in_s;
1098 if( pstk->in_sz < 0 ){ /* bit field */
1099 sz = -pstk->in_sz;
1100 }
1101 else {
1102 sz = tsize( t, d, s );
1103 }
1104
1105 inforce( pstk->in_off );
1106
1107 p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p );
1108 #ifdef LINT
1109 /* force lint to treat this like an assignment */
1110 ecode(p);
1111 #endif
1112 p->in.left->in.op = FREE;
1113 p->in.left = p->in.right;
1114 p->in.right = NIL;
1115 p->in.left = optim( p->in.left );
1116 o = p->in.left->in.op;
1117 if( o == UNARY AND ){
1118 o = p->in.left->in.op = FREE;
1119 p->in.left = p->in.left->in.left;
1120 }
1121 p->in.op = INIT;
1122
1123 if( sz < SZINT ){ /* special case: bit fields, etc. */
1124 if( o != ICON || p->in.left->tn.rval != NONAME )
1125 uerror( "illegal initialization" );
1126 else incode( p->in.left, sz );
1127 }
1128 else if( o == FCON ){
1129 fincode( p->in.left->fpn.fval, sz );
1130 }
1131 else if( o == DCON ){
1132 fincode( p->in.left->dpn.dval, sz );
1133 }
1134 else {
1135 p = optim(p);
1136 if( p->in.left->in.op != ICON ) uerror( "illegal initialization" );
1137 else cinit( p, sz );
1138 }
1139
1140 gotscal();
1141
1142 leave:
1143 tfree(p);
1144 }
1145
gotscal()1146 gotscal(){
1147 register t, ix;
1148 register n, id;
1149 struct symtab *p;
1150 OFFSZ temp;
1151
1152 for( ; pstk > instack; ) {
1153
1154 if( pstk->in_fl ) ++ibseen;
1155
1156 --pstk;
1157
1158 t = pstk->in_t;
1159
1160 if( t == STRTY ){
1161 ix = ++pstk->in_x;
1162 if( (id=dimtab[ix]) < 0 ) continue;
1163
1164 /* otherwise, put next element on the stack */
1165
1166 p = &stab[id];
1167 instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off );
1168 return;
1169 }
1170 else if( ISARY(t) ){
1171 n = ++pstk->in_n;
1172 if( n >= dimtab[pstk->in_d] && pstk > instack ) continue;
1173
1174 /* put the new element onto the stack */
1175
1176 temp = pstk->in_sz;
1177 instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s,
1178 pstk->in_off+n*temp );
1179 return;
1180 }
1181
1182 }
1183 ifull = 1;
1184 }
1185
ilbrace()1186 ilbrace(){ /* process an initializer's left brace */
1187 register t;
1188 struct instk *temp;
1189
1190 temp = pstk;
1191
1192 for( ; pstk > instack; --pstk ){
1193
1194 t = pstk->in_t;
1195 if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */
1196 if( pstk->in_fl ){ /* already associated with a { */
1197 if( pstk->in_n ) uerror( "illegal {");
1198 continue;
1199 }
1200
1201 /* we have one ... */
1202 pstk->in_fl = 1;
1203 break;
1204 }
1205
1206 /* cannot find one */
1207 /* ignore such right braces */
1208
1209 pstk = temp;
1210 }
1211
irbrace()1212 irbrace(){
1213 /* called when a '}' is seen */
1214
1215 # ifndef BUG1
1216 if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno );
1217 # endif
1218
1219 if( ibseen ) {
1220 --ibseen;
1221 return;
1222 }
1223
1224 for( ; pstk > instack; --pstk ){
1225 if( !pstk->in_fl ) continue;
1226
1227 /* we have one now */
1228
1229 pstk->in_fl = 0; /* cancel { */
1230 gotscal(); /* take it away... */
1231 return;
1232 }
1233
1234 /* these right braces match ignored left braces: throw out */
1235 ifull = 1;
1236
1237 }
1238
upoff(size,alignment,poff)1239 upoff( size, alignment, poff ) register alignment, *poff; {
1240 /* update the offset pointed to by poff; return the
1241 /* offset of a value of size `size', alignment `alignment',
1242 /* given that off is increasing */
1243
1244 register off;
1245
1246 off = *poff;
1247 SETOFF( off, alignment );
1248 if( (offsz-off) < size ){
1249 if( instruct!=INSTRUCT )cerror("too many local variables");
1250 else cerror("Structure too large");
1251 }
1252 *poff = off+size;
1253 return( off );
1254 }
1255
oalloc(p,poff)1256 oalloc( p, poff ) register struct symtab *p; register *poff; {
1257 /* allocate p with offset *poff, and update *poff */
1258 register al, off, tsz;
1259 int noff;
1260
1261 al = talign( p->stype, p->sizoff );
1262 noff = off = *poff;
1263 tsz = tsize( p->stype, p->dimoff, p->sizoff );
1264 #ifdef BACKAUTO
1265 if( p->sclass == AUTO ){
1266 if( (offsz-off) < tsz ) cerror("too many local variables");
1267 noff = off + tsz;
1268 SETOFF( noff, al );
1269 off = -noff;
1270 }
1271 else
1272 #endif
1273 if( p->sclass == PARAM && ( tsz < SZINT ) ){
1274 off = upoff( SZINT, ALINT, &noff );
1275 # ifndef RTOLBYTES
1276 off = noff - tsz;
1277 #endif
1278 }
1279 else
1280 {
1281 off = upoff( tsz, al, &noff );
1282 }
1283
1284 if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */
1285 if( p->offset == NOOFFSET ) p->offset = off;
1286 else if( off != p->offset ) return(1);
1287 }
1288
1289 *poff = noff;
1290 return(0);
1291 }
1292
falloc(p,w,new,pty)1293 falloc( p, w, new, pty ) register struct symtab *p; NODE *pty; {
1294 /* allocate a field of width w */
1295 /* new is 0 if new entry, 1 if redefinition, -1 if alignment */
1296
1297 register al,sz,type;
1298
1299 type = (new<0)? pty->in.type : p->stype;
1300
1301 /* this must be fixed to use the current type in alignments */
1302 switch( new<0?pty->in.type:p->stype ){
1303
1304 case ENUMTY:
1305 {
1306 int s;
1307 s = new<0 ? pty->fn.csiz : p->sizoff;
1308 al = dimtab[s+2];
1309 sz = dimtab[s];
1310 break;
1311 }
1312
1313 case CHAR:
1314 case UCHAR:
1315 al = ALCHAR;
1316 sz = SZCHAR;
1317 break;
1318
1319 case SHORT:
1320 case USHORT:
1321 al = ALSHORT;
1322 sz = SZSHORT;
1323 break;
1324
1325 case INT:
1326 case UNSIGNED:
1327 al = ALINT;
1328 sz = SZINT;
1329 break;
1330 #ifdef LONGFIELDS
1331
1332 case LONG:
1333 case ULONG:
1334 al = ALLONG;
1335 sz = SZLONG;
1336 break;
1337 #endif
1338
1339 default:
1340 if( new < 0 ) {
1341 uerror( "illegal field type" );
1342 al = ALINT;
1343 }
1344 else {
1345 al = fldal( p->stype );
1346 sz =SZINT;
1347 }
1348 }
1349
1350 if( w > sz ) {
1351 uerror( "field too big");
1352 w = sz;
1353 }
1354
1355 if( w == 0 ){ /* align only */
1356 SETOFF( strucoff, al );
1357 if( new >= 0 ) uerror( "zero size field");
1358 return(0);
1359 }
1360
1361 if( strucoff%al + w > sz ) SETOFF( strucoff, al );
1362 if( new < 0 ) {
1363 if( (offsz-strucoff) < w )
1364 cerror("structure too large");
1365 strucoff += w; /* we know it will fit */
1366 return(0);
1367 }
1368
1369 /* establish the field */
1370
1371 if( new == 1 ) { /* previous definition */
1372 if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1);
1373 }
1374 p->offset = strucoff;
1375 if( (offsz-strucoff) < w ) cerror("structure too large");
1376 strucoff += w;
1377 p->stype = type;
1378 fldty( p );
1379 return(0);
1380 }
1381
nidcl(p)1382 nidcl( p ) NODE *p; { /* handle unitialized declarations */
1383 /* assumed to be not functions */
1384 register class;
1385 register commflag; /* flag for labelled common declarations */
1386
1387 commflag = 0;
1388
1389 /* compute class */
1390 if( (class=curclass) == SNULL ){
1391 if( blevel > 1 ) class = AUTO;
1392 else if( blevel != 0 || instruct ) cerror( "nidcl error" );
1393 else { /* blevel = 0 */
1394 class = noinit();
1395 if( class == EXTERN ) commflag = 1;
1396 }
1397 }
1398 #ifdef LCOMM
1399 /* hack so stab will come out as LCSYM rather than STSYM */
1400 if (class == STATIC) {
1401 extern int stabLCSYM;
1402 stabLCSYM = 1;
1403 }
1404 #endif
1405
1406 defid( p, class );
1407
1408 /* if an array is not initialized, no empty dimension */
1409 if( class!=EXTERN && class!=TYPEDEF &&
1410 ISARY(p->in.type) && dimtab[p->fn.cdim]==0 )
1411 uerror("null storage definition");
1412
1413 #ifndef LCOMM
1414 if( class==EXTDEF || class==STATIC )
1415 #else
1416 if (class==STATIC) {
1417 register struct symtab *s = &stab[p->tn.rval];
1418 extern int stabLCSYM;
1419 int sz = tsize(s->stype, s->dimoff, s->sizoff)/SZCHAR;
1420
1421 stabLCSYM = 0;
1422 if (sz % sizeof (int))
1423 sz += sizeof (int) - (sz % sizeof (int));
1424 if (s->slevel > 1)
1425 printf(" .lcomm L%d,%d\n", s->offset, sz);
1426 else
1427 printf(" .lcomm %s,%d\n", exname(s->sname), sz);
1428 }else if (class == EXTDEF)
1429 #endif
1430 {
1431 /* simulate initialization by 0 */
1432 beginit(p->tn.rval);
1433 endinit();
1434 }
1435 if( commflag ) commdec( p->tn.rval );
1436 }
1437
1438 TWORD
types(t1,t2,t3)1439 types( t1, t2, t3 ) TWORD t1, t2, t3; {
1440 /* return a basic type from basic types t1, t2, and t3 */
1441
1442 TWORD t[3], noun, adj, unsg;
1443 register i;
1444
1445 t[0] = t1;
1446 t[1] = t2;
1447 t[2] = t3;
1448
1449 unsg = INT; /* INT or UNSIGNED */
1450 noun = UNDEF; /* INT, CHAR, or FLOAT */
1451 adj = INT; /* INT, LONG, or SHORT */
1452
1453 for( i=0; i<3; ++i ){
1454 switch( t[i] ){
1455
1456 default:
1457 bad:
1458 uerror( "illegal type combination" );
1459 return( INT );
1460
1461 case UNDEF:
1462 continue;
1463
1464 case UNSIGNED:
1465 if( unsg != INT ) goto bad;
1466 unsg = UNSIGNED;
1467 continue;
1468
1469 case LONG:
1470 case SHORT:
1471 if( adj != INT ) goto bad;
1472 adj = t[i];
1473 continue;
1474
1475 case INT:
1476 case CHAR:
1477 case FLOAT:
1478 if( noun != UNDEF ) goto bad;
1479 noun = t[i];
1480 continue;
1481 }
1482 }
1483
1484 /* now, construct final type */
1485 if( noun == UNDEF ) noun = INT;
1486 else if( noun == FLOAT ){
1487 if( unsg != INT || adj == SHORT ) goto bad;
1488 return( adj==LONG ? DOUBLE : FLOAT );
1489 }
1490 else if( noun == CHAR && adj != INT ) goto bad;
1491
1492 /* now, noun is INT or CHAR */
1493 if( adj != INT ) noun = adj;
1494 if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) );
1495 else return( noun );
1496 }
1497
1498 NODE *
tymerge(typ,idp)1499 tymerge( typ, idp ) NODE *typ, *idp; {
1500 /* merge type typ with identifier idp */
1501
1502 register unsigned t;
1503 register i;
1504 extern int eprint();
1505
1506 if( typ->in.op != TYPE ) cerror( "tymerge: arg 1" );
1507 if(idp == NIL ) return( NIL );
1508
1509 # ifndef BUG1
1510 if( ddebug > 2 ) fwalk( idp, eprint, 0 );
1511 # endif
1512
1513 idp->in.type = typ->in.type;
1514 idp->fn.cdim = curdim;
1515 tyreduce( idp );
1516 idp->fn.csiz = typ->fn.csiz;
1517
1518 for( t=typ->in.type, i=typ->fn.cdim; t&TMASK; t = DECREF(t) ){
1519 if( ISARY(t) ) dstash( dimtab[i++] );
1520 }
1521
1522 /* now idp is a single node: fix up type */
1523
1524 idp->in.type = ctype( idp->in.type );
1525
1526 if( (t = BTYPE(idp->in.type)) != STRTY && t != UNIONTY && t != ENUMTY ){
1527 idp->fn.csiz = t; /* in case ctype has rewritten things */
1528 }
1529
1530 return( idp );
1531 }
1532
tyreduce(p)1533 tyreduce( p ) register NODE *p; {
1534
1535 /* build a type, and stash away dimensions, from a parse tree of the declaration */
1536 /* the type is build top down, the dimensions bottom up */
1537 register o, temp;
1538 register unsigned t;
1539
1540 o = p->in.op;
1541 p->in.op = FREE;
1542
1543 if( o == NAME ) return;
1544
1545 t = INCREF( p->in.type );
1546 if( o == UNARY CALL ) t += (FTN-PTR);
1547 else if( o == LB ){
1548 t += (ARY-PTR);
1549 temp = p->in.right->tn.lval;
1550 p->in.right->in.op = FREE;
1551 if( temp == 0 && p->in.left->tn.op == LB )
1552 uerror( "null dimension" );
1553 }
1554
1555 p->in.left->in.type = t;
1556 tyreduce( p->in.left );
1557
1558 if( o == LB ) dstash( temp );
1559
1560 p->tn.rval = p->in.left->tn.rval;
1561 p->in.type = p->in.left->in.type;
1562
1563 }
1564
fixtype(p,class)1565 fixtype( p, class ) register NODE *p; {
1566 register unsigned t, type;
1567 register mod1, mod2;
1568 /* fix up the types, and check for legality */
1569
1570 if( (type = p->in.type) == UNDEF ) return;
1571 if( mod2 = (type&TMASK) ){
1572 t = DECREF(type);
1573 while( mod1=mod2, mod2 = (t&TMASK) ){
1574 if( mod1 == ARY && mod2 == FTN ){
1575 uerror( "array of functions is illegal" );
1576 type = 0;
1577 }
1578 else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){
1579 uerror( "function returns illegal type" );
1580 type = 0;
1581 }
1582 t = DECREF(t);
1583 }
1584 }
1585
1586 /* detect function arguments, watching out for structure declarations */
1587 /* for example, beware of f(x) struct { int a[10]; } *x; { ... } */
1588 /* the danger is that "a" will be converted to a pointer */
1589
1590 if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) )
1591 class = PARAM;
1592 if( class == PARAM || ( class==REGISTER && blevel==1 ) ){
1593 if( type == FLOAT ) type = DOUBLE;
1594 else if( ISARY(type) ){
1595 #ifdef LINT
1596 if( hflag && dimtab[p->fn.cdim]!=0 )
1597 werror("array[%d] type changed to pointer",
1598 dimtab[p->fn.cdim]);
1599 #endif
1600 ++p->fn.cdim;
1601 type += (PTR-ARY);
1602 }
1603 else if( ISFTN(type) ){
1604 werror( "a function is declared as an argument" );
1605 type = INCREF(type);
1606 }
1607
1608 }
1609
1610 if( instruct && ISFTN(type) ){
1611 uerror( "function illegal in structure or union" );
1612 type = INCREF(type);
1613 }
1614 p->in.type = type;
1615 }
1616
uclass(class)1617 uclass( class ) register class; {
1618 /* give undefined version of class */
1619 if( class == SNULL ) return( EXTERN );
1620 else if( class == STATIC ) return( USTATIC );
1621 else if( class == FORTRAN ) return( UFORTRAN );
1622 else return( class );
1623 }
1624
fixclass(class,type)1625 fixclass( class, type ) TWORD type; {
1626
1627 /* first, fix null class */
1628
1629 if( class == SNULL ){
1630 if( instruct&INSTRUCT ) class = MOS;
1631 else if( instruct&INUNION ) class = MOU;
1632 else if( blevel == 0 ) class = EXTDEF;
1633 else if( blevel == 1 ) class = PARAM;
1634 else class = AUTO;
1635
1636 }
1637
1638 /* now, do general checking */
1639
1640 if( ISFTN( type ) ){
1641 switch( class ) {
1642 default:
1643 uerror( "function has illegal storage class" );
1644 case AUTO:
1645 class = EXTERN;
1646 case EXTERN:
1647 case EXTDEF:
1648 case FORTRAN:
1649 case TYPEDEF:
1650 case STATIC:
1651 case UFORTRAN:
1652 case USTATIC:
1653 ;
1654 }
1655 }
1656
1657 if( class&FIELD ){
1658 if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" );
1659 return( class );
1660 }
1661
1662 switch( class ){
1663
1664 case MOU:
1665 if( !(instruct&INUNION) ) uerror( "illegal class" );
1666 return( class );
1667
1668 case MOS:
1669 if( !(instruct&INSTRUCT) ) uerror( "illegal class" );
1670 return( class );
1671
1672 case MOE:
1673 if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" );
1674 return( class );
1675
1676 case REGISTER:
1677 if( blevel == 0 ) uerror( "illegal register declaration" );
1678 else if( regvar >= MINRVAR && cisreg( type ) ) return( class );
1679 if( blevel == 1 ) return( PARAM );
1680 else return( AUTO );
1681
1682 case AUTO:
1683 case LABEL:
1684 case ULABEL:
1685 if( blevel < 2 ) uerror( "illegal class" );
1686 return( class );
1687
1688 case PARAM:
1689 if( blevel != 1 ) uerror( "illegal class" );
1690 return( class );
1691
1692 case UFORTRAN:
1693 case FORTRAN:
1694 # ifdef NOFORTRAN
1695 NOFORTRAN; /* a condition which can regulate the FORTRAN usage */
1696 # endif
1697 if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" );
1698 else {
1699 type = DECREF(type);
1700 if( ISFTN(type) || ISARY(type) || ISPTR(type) ) {
1701 uerror( "fortran function has wrong type" );
1702 }
1703 }
1704 case EXTERN:
1705 case STATIC:
1706 case EXTDEF:
1707 case TYPEDEF:
1708 case USTATIC:
1709 if( blevel == 1 ){
1710 uerror( "illegal class" );
1711 return( PARAM );
1712 }
1713 case STNAME:
1714 case UNAME:
1715 case ENAME:
1716 return( class );
1717
1718 default:
1719 cerror( "illegal class: %d", class );
1720 /* NOTREACHED */
1721
1722 }
1723 }
1724
1725 struct symtab *
mknonuniq(idindex)1726 mknonuniq(idindex) int *idindex; {/* locate a symbol table entry for */
1727 /* an occurrence of a nonunique structure member name */
1728 /* or field */
1729 register i;
1730 register struct symtab * sp;
1731 char *q;
1732
1733 sp = & stab[ i= *idindex ]; /* position search at old entry */
1734 while( sp->stype != TNULL ){ /* locate unused entry */
1735 if( ++i >= SYMTSZ ){/* wrap around symbol table */
1736 i = 0;
1737 sp = stab;
1738 }
1739 else ++sp;
1740 if( i == *idindex ) cerror("Symbol table full");
1741 }
1742 sp->sflags = SNONUNIQ | SMOS;
1743 q = stab[*idindex].sname; /* old entry name */
1744 #ifdef FLEXNAMES
1745 sp->sname = stab[*idindex].sname;
1746 #endif
1747 # ifndef BUG1
1748 if( ddebug ){
1749 printf("\tnonunique entry for %s from %d to %d\n",
1750 q, *idindex, i );
1751 }
1752 # endif
1753 *idindex = i;
1754 #ifndef FLEXNAMES
1755 {
1756 char *p = sp->sname;
1757 for( i=1; i<=NCHNAM; ++i ) /* copy name */
1758 if( *p++ = *q /* assign */ ) ++q;
1759 }
1760 #endif
1761 return ( sp );
1762 }
1763
lookup(name,s)1764 lookup( name, s) char *name; {
1765 /* look up name: must agree with s w.r.t. STAG, SMOS and SHIDDEN */
1766
1767 register char *p, *q;
1768 int i, ii;
1769 #ifndef FLEXNAMES
1770 int j;
1771 #endif
1772 register struct symtab *sp;
1773
1774 /* compute initial hash index */
1775 # ifndef BUG1
1776 if( ddebug > 2 ){
1777 printf( "lookup( %s, %d ), stwart=%d, instruct=%d\n", name, s, stwart, instruct );
1778 }
1779 # endif
1780
1781 i = 0;
1782 #ifndef FLEXNAMES
1783 for( p=name, j=0; *p != '\0'; ++p ){
1784 i += *p;
1785 if( ++j >= NCHNAM ) break;
1786 }
1787 #else
1788 i = (int)name;
1789 #endif
1790 i = i%SYMTSZ;
1791 sp = &stab[ii=i];
1792
1793 for(;;){ /* look for name */
1794
1795 if( sp->stype == TNULL ){ /* empty slot */
1796 sp->sflags = s; /* set STAG, SMOS if needed, turn off all others */
1797 #ifndef FLEXNAMES
1798 p = sp->sname;
1799 for( j=0; j<NCHNAM; ++j ) if( *p++ = *name ) ++name;
1800 #else
1801 sp->sname = name;
1802 #endif
1803 sp->stype = UNDEF;
1804 sp->sclass = SNULL;
1805 return( i );
1806 }
1807 if( (sp->sflags & (STAG|SMOS|SHIDDEN)) != s ) goto next;
1808 p = sp->sname;
1809 q = name;
1810 #ifndef FLEXNAMES
1811 for( j=0; j<NCHNAM;++j ){
1812 if( *p++ != *q ) goto next;
1813 if( !*q++ ) break;
1814 }
1815 return( i );
1816 #else
1817 if (p == q)
1818 return ( i );
1819 #endif
1820 next:
1821 if( ++i >= SYMTSZ ){
1822 i = 0;
1823 sp = stab;
1824 }
1825 else ++sp;
1826 if( i == ii ) cerror( "symbol table full" );
1827 }
1828 }
1829
1830 #ifndef checkst
1831 /* if not debugging, make checkst a macro */
checkst(lev)1832 checkst(lev){
1833 register int s, i, j;
1834 register struct symtab *p, *q;
1835
1836 for( i=0, p=stab; i<SYMTSZ; ++i, ++p ){
1837 if( p->stype == TNULL ) continue;
1838 j = lookup( p->sname, p->sflags&(SMOS|STAG) );
1839 if( j != i ){
1840 q = &stab[j];
1841 if( q->stype == UNDEF ||
1842 q->slevel <= p->slevel ){
1843 #ifndef FLEXNAMES
1844 cerror( "check error: %.8s", q->sname );
1845 #else
1846 cerror( "check error: %s", q->sname );
1847 #endif
1848 }
1849 }
1850 #ifndef FLEXNAMES
1851 else if( p->slevel > lev ) cerror( "%.8s check at level %d", p->sname, lev );
1852 #else
1853 else if( p->slevel > lev ) cerror( "%s check at level %d", p->sname, lev );
1854 #endif
1855 }
1856 }
1857 #endif
1858
1859 struct symtab *
relook(p)1860 relook(p) register struct symtab *p; { /* look up p again, and see where it lies */
1861
1862 register struct symtab *q;
1863
1864 /* I'm not sure that this handles towers of several hidden definitions in all cases */
1865 q = &stab[lookup( p->sname, p->sflags&(STAG|SMOS|SHIDDEN) )];
1866 /* make relook always point to either p or an empty cell */
1867 if( q->stype == UNDEF ){
1868 q->stype = TNULL;
1869 return(q);
1870 }
1871 while( q != p ){
1872 if( q->stype == TNULL ) break;
1873 if( ++q >= &stab[SYMTSZ] ) q=stab;
1874 }
1875 return(q);
1876 }
1877
clearst(lev)1878 clearst( lev ) register int lev; {
1879 register struct symtab *p, *q;
1880 register int temp;
1881 struct symtab *clist = 0;
1882
1883 temp = lineno;
1884 aobeg();
1885
1886 /* step 1: remove entries */
1887 while( chaintop-1 > lev ){
1888 p = schain[--chaintop];
1889 schain[chaintop] = 0;
1890 for( ; p; p = q ){
1891 q = p->snext;
1892 if( p->stype == TNULL || p->slevel <= lev )
1893 cerror( "schain botch" );
1894 lineno = p->suse < 0 ? -p->suse : p->suse;
1895 if( p->stype==UNDEF || ( p->sclass==ULABEL && lev<2 ) ){
1896 lineno = temp;
1897 #ifndef FLEXNAMES
1898 uerror( "%.8s undefined", p->sname );
1899 #else
1900 uerror( "%s undefined", p->sname );
1901 #endif
1902 }
1903 else aocode(p);
1904 # ifndef BUG1
1905 if( ddebug ){
1906 #ifndef FLEXNAMES
1907 printf( "removing %.8s", p->sname );
1908 #else
1909 printf( "removing %s", p->sname );
1910 #endif
1911 printf( " from stab[%d], flags %o level %d\n",
1912 p-stab, p->sflags, p->slevel);
1913 }
1914 # endif
1915 if( p->sflags & SHIDES )unhide( p );
1916 p->stype = TNULL;
1917 p->snext = clist;
1918 clist = p;
1919 }
1920 }
1921
1922 /* step 2: fix any mishashed entries */
1923 p = clist;
1924 while( p ){
1925 register struct symtab *next, **t, *r;
1926
1927 q = p;
1928 next = p->snext;
1929 for(;;){
1930 if( ++q >= &stab[SYMTSZ] )q = stab;
1931 if( q == p || q->stype == TNULL )break;
1932 if( (r = relook(q)) != q ) {
1933 /* move q in schain list */
1934 t = &schain[q->slevel];
1935 while( *t && *t != q )
1936 t = &(*t)->snext;
1937 if( *t )
1938 *t = r;
1939 else
1940 cerror("schain botch 2");
1941 *r = *q;
1942 q->stype = TNULL;
1943 }
1944 }
1945 p = next;
1946 }
1947
1948 lineno = temp;
1949 aoend();
1950 }
1951
hide(p)1952 hide( p ) register struct symtab *p; {
1953 register struct symtab *q;
1954 for( q=p+1; ; ++q ){
1955 if( q >= &stab[SYMTSZ] ) q = stab;
1956 if( q == p ) cerror( "symbol table full" );
1957 if( q->stype == TNULL ) break;
1958 }
1959 *q = *p;
1960 p->sflags |= SHIDDEN;
1961 q->sflags = (p->sflags&(SMOS|STAG)) | SHIDES;
1962 #ifndef FLEXNAMES
1963 if( hflag ) werror( "%.8s redefinition hides earlier one", p->sname );
1964 #else
1965 if( hflag ) werror( "%s redefinition hides earlier one", p->sname );
1966 #endif
1967 # ifndef BUG1
1968 if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab );
1969 # endif
1970 return( idname = q-stab );
1971 }
1972
unhide(p)1973 unhide( p ) register struct symtab *p; {
1974 register struct symtab *q;
1975 register s;
1976
1977 s = p->sflags & (SMOS|STAG);
1978 q = p;
1979
1980 for(;;){
1981
1982 if( q == stab ) q = &stab[SYMTSZ-1];
1983 else --q;
1984
1985 if( q == p ) break;
1986
1987 if( (q->sflags&(SMOS|STAG)) == s ){
1988 #ifndef FLEXNAMES
1989 register j;
1990 for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break;
1991 if( j == NCHNAM ){ /* found the name */
1992 #else
1993 if (p->sname == q->sname) {
1994 #endif
1995 q->sflags &= ~SHIDDEN;
1996 # ifndef BUG1
1997 if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab);
1998 # endif
1999 return;
2000 }
2001 }
2002
2003 }
2004 cerror( "unhide fails" );
2005 }
2006