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