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