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