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