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