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