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