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