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