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