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