|
|
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.%d", fakestub, lineno, ++fakenum);
622: idn = lookup(hash(fakename), STAG);
623: }
624: psave( instruct );
625: psave( curclass );
626: psave( strucoff );
627: strucoff = 0;
628: instruct = soru;
629: q = block( FREE, NIL, NIL, 0, 0, 0 );
630: q->tn.rval = idn;
631: if( instruct==INSTRUCT )
632: {
633: curclass = MOS;
634: q->in.type = STRTY;
635: defid( q, STNAME );
636: }
637: else if( instruct == INUNION )
638: {
639: curclass = MOU;
640: q->in.type = UNIONTY;
641: defid( q, UNAME );
642: }
643: else
644: {
645: /* enum */
646: curclass = MOE;
647: q->in.type = ENUMTY;
648: defid( q, ENAME );
649: }
650: psave( idn = q->tn.rval );
651: /* the "real" definition is where the members are seen */
652: if( idn >= 0 ) stab[idn].suse = lineno;
653: return( paramno-4 );
654: }
655:
656: # ifndef ENUMSIZE
657: # define ENUMSIZE(h,l) INT
658: # endif
659:
660: NODE *
661: dclstruct( oparam )
662: register oparam;
663: {
664: register struct symtab *p;
665: register i, al, sa, j, sz, szindex;
666: register TWORD temp;
667: register high, low;
668:
669: /* paramstack contains:
670: ** paramstack[ oparam ] = previous instruct
671: ** paramstack[ oparam+1 ] = previous class
672: ** paramstk[ oparam+2 ] = previous strucoff
673: ** paramstk[ oparam+3 ] = structure name
674: **
675: ** paramstk[ oparam+4, ... ] = member stab indices
676: **
677: */
678:
679:
680: if( (i=paramstk[oparam+3]) < 0 )
681: {
682: szindex = curdim;
683: dstash( 0 ); /* size */
684: dstash( -1 ); /* index to member names */
685: dstash( ALSTRUCT ); /* alignment */
686: dstash( -lineno ); /* name of structure */
687: }
688: else
689: {
690: szindex = stab[i].sizoff;
691: }
692:
693:
694: # ifndef NODBG
695: if( ddebug )
696: {
697: printf( "dclstruct( %szindex = %d\n",
698: (i>=0)? stab[i].sname : "??", szindex );
699: }
700: # endif
701: temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
702: stwart = instruct = paramstk[ oparam ];
703: curclass = paramstk[ oparam+1 ];
704: dimtab[ szindex+1 ] = curdim;
705: al = ALSTRUCT;
706:
707: high = low = 0;
708:
709: for( i = oparam+4; i< paramno; ++i )
710: {
711: dstash( j=paramstk[i] );
712: if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" );
713: p = &stab[j];
714: if( temp == ENUMTY )
715: {
716: if( p->offset < low ) low = p->offset;
717: if( p->offset > high ) high = p->offset;
718: p->sizoff = szindex;
719: continue;
720: }
721: sa = talign( p->stype, p->sizoff );
722: if( p->sclass & FIELD )
723: {
724: sz = p->sclass&FLDSIZ;
725: }
726: else
727: {
728: sz = tsize( p->stype, p->dimoff, p->sizoff );
729: }
730: if( sz == 0 )
731: {
732: werror( "structure member has size 0: %s", p->sname );
733: }
734: if( sz > strucoff ) strucoff = sz; /* for use with unions */
735: SETOFF( al, sa );
736: /* al, the alignment, to the LCM of the members' alignments */
737: }
738: dstash( -1 ); /* endmarker */
739: SETOFF( strucoff, al );
740:
741: if( temp == ENUMTY )
742: {
743: register TWORD ty;
744:
745: ty = ENUMSIZE(high,low);
746: strucoff = tsize( ty, 0, (int)ty );
747: dimtab[ szindex+2 ] = al = talign( ty, (int)ty );
748: }
749:
750: if( strucoff == 0 ) uerror( "zero sized structure" );
751: dimtab[ szindex ] = strucoff;
752: dimtab[ szindex+2 ] = al;
753: dimtab[ szindex+3 ] = paramstk[ oparam+3 ]; /* name index */
754:
755: #ifdef FIXSTRUCT
756: FIXSTRUCT( szindex, oparam ); /* local hook for debugging */
757: #endif
758:
759: # ifndef NODBG
760: if( ddebug>1 )
761: {
762: printf( "\tdimtab[%d,%d,%d,%d] = %d,%d,%d,%d\n",
763: szindex,szindex+1,szindex+2,szindex+3,
764: dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2],
765: dimtab[szindex+3] );
766: for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i )
767: {
768: printf( "\tmember %s(%d)\n", stab[dimtab[i]].sname, dimtab[i] );
769: }
770: }
771: # endif
772:
773: strucoff = paramstk[ oparam+2 ];
774: paramno = oparam;
775:
776: return( mkty( temp, 0, szindex ) );
777: }
778:
779: /* VARARGS */
780: yyerror( s, a, b, c, d, e, f, g ) char *s;
781:
782: {
783: /* error printing routine in parser */
784: uerror( s, a, b, c, d, e, f, g );
785:
786: }
787:
788: yyaccpt()
789: {
790: ftnend();
791: }
792:
793: ftnarg( idn )
794: register idn;
795: {
796: register struct symtab *p;
797: p = &stab[idn];
798: switch( p->stype )
799: {
800:
801: case UNDEF:
802: /* this parameter, entered at scan */
803: break;
804: case FARG:
805: uerror("redeclaration of formal parameter, %s",p->sname);
806: /* fall thru */
807: case FTN:
808: /* the name of this function matches parm */
809: /* fall thru */
810: default:
811: idn = hide(p);
812: p = &stab[idn];
813: break;
814: case TNULL:
815: /* unused entry, fill it */
816: ;
817: }
818: p->stype = FARG;
819: p->sclass = PARAM;
820: asave( idn );
821: }
822:
823: talign( ty, s)
824: register unsigned ty;
825: register s;
826: {
827: /* compute the alignment of an object with type ty, sizeoff index s */
828:
829: register i;
830: # ifdef FUNNYFLDS
831: if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT
832: #ifdef LONGFIELDS
833: && ty!=LONG && ty!=ULONG
834: #endif
835: )
836: {
837: return( fldal( ty ) );
838: }
839: # endif
840:
841: for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT )
842: {
843: switch( (ty>>i)&TMASK )
844: {
845:
846: case FTN:
847: cerror( "compiler takes alignment of function");
848: case PTR:
849: return( ALPOINT );
850: case ARY:
851: continue;
852: case 0:
853: break;
854: }
855: }
856:
857: switch( BTYPE(ty) )
858: {
859:
860: case UNIONTY:
861: case ENUMTY:
862: case STRTY:
863: return( dimtab[ s+2 ] );
864: case CHAR:
865: case UCHAR:
866: return( ALCHAR );
867: case FLOAT:
868: return( ALFLOAT );
869: case DOUBLE:
870: return( ALDOUBLE );
871: case LONG:
872: case ULONG:
873: return( ALLONG );
874: case SHORT:
875: case USHORT:
876: return( ALSHORT );
877: default:
878: return( ALINT );
879: }
880: }
881:
882: OFFSZ
883: tsize( ty, d, s )
884: register TWORD ty;
885: {
886: /* compute the size associated with type ty,
887: ** dimoff d, and sizoff s
888: */
889: /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
890:
891: register i;
892: register OFFSZ mult;
893:
894: mult = 1;
895:
896: for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT )
897: {
898: switch( (ty>>i)&TMASK )
899: {
900:
901: case FTN:
902: uerror("illegal use of function pointer");
903: case PTR:
904: return( SZPOINT * mult );
905: case ARY:
906: mult *= dimtab[ d++ ];
907: continue;
908: case 0:
909: break;
910:
911: }
912: }
913: if(ty == ENUMTY)
914: return(SZINT);
915: if(ty == VOID)
916: uerror("using a void value");
917: if( dimtab[s]==0 ) {
918: uerror( "unknown size");
919: return( SZINT );
920: }
921: return( dimtab[ s ] * mult );
922: }
923:
924: inforce( n )
925: register OFFSZ n;
926: {
927: /* force inoff to have the value n */
928: /* inoff is updated to have the value n */
929: register OFFSZ wb;
930: register rest;
931: /* rest is used to do a lot of conversion to ints... */
932:
933: if( inoff == n ) return;
934: if( inoff > n )
935: {
936: uerror("too many initializers (%d>%d)", inoff, n);
937: inoff = n;
938: return;
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 (%d>%d)",
1202: n, d1);
1203: if( n==0 ) werror( "empty array declaration");
1204: dimtab[d] = n;
1205: }
1206:
1207: else if( t == STRTY || t == UNIONTY )
1208: {
1209: /* clearly not fields either */
1210: inforce( tsize( t, d, s ) );
1211: }
1212: else if( n > 1 ) uerror("%d initializers for a scalar", n);
1213: /* this will never be called with a field element... */
1214: else inforce( tsize(t,d,s) );
1215:
1216: paramno = 0;
1217: vfdalign( ALINIT );
1218: inoff = 0;
1219: iclass = SNULL;
1220:
1221: }
1222:
1223: doinit( p )
1224: register NODE *p;
1225:
1226: {
1227:
1228: /* take care of generating a value for the initializer p */
1229: /* inoff has the current offset (last bit written)
1230: ** in the current word being generated
1231: */
1232:
1233: register sz, d, s;
1234: register TWORD t;
1235:
1236: /* note: size of an individual initializer assumed to fit into an int */
1237:
1238: if(nerrors)
1239: goto leave;
1240: if( iclass < 0 ) goto leave;
1241: if( iclass == EXTERN || iclass == UNAME )
1242: {
1243: uerror( "cannot initialize extern or union" );
1244: iclass = -1;
1245: goto leave;
1246: }
1247:
1248: if( iclass == AUTO || iclass == REGISTER )
1249: {
1250: /* do the initialization and get out, without regard
1251: ** for filing out the variable with zeros, etc.
1252: */
1253: bccode();
1254: idname = pstk->in_id;
1255: p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p );
1256: ecomp(p);
1257: return;
1258: }
1259:
1260: if( p == NIL ) return; /* throw away strings already made into lists */
1261:
1262: if( ibseen )
1263: {
1264: uerror( "} expected");
1265: goto leave;
1266: }
1267:
1268: # ifndef NODBG
1269: if( idebug > 1 ) printf( "doinit(%o)\n", p );
1270: # endif
1271:
1272: t = pstk->in_t; /* type required */
1273: d = pstk->in_d;
1274: s = pstk->in_s;
1275: if( pstk->in_sz < 0 )
1276: {
1277: /* bit field */
1278: sz = -pstk->in_sz;
1279: }
1280: else
1281: {
1282: sz = tsize( t, d, s );
1283: }
1284:
1285: inforce( pstk->in_off );
1286:
1287: p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p );
1288: p->in.left->in.op = FREE;
1289: p->in.left = p->in.right;
1290: p->in.right = NIL;
1291: p->in.left = optim( p->in.left );
1292: if( p->in.left->in.op == UNARY AND )
1293: {
1294: p->in.left->in.op = FREE;
1295: p->in.left = p->in.left->in.left;
1296: }
1297: p->in.op = INIT;
1298: p = optim(p);
1299:
1300: # ifndef NOFLOAT
1301: if( p->in.left->in.op == FCON )
1302: {
1303: fincode( p->in.left->fpn.dval, sz );
1304: }
1305: else
1306: # endif
1307: if( p->in.left->in.op != ICON )
1308: {
1309: uerror( "initialization by non-constant" );
1310: inoff += sz;
1311: }
1312: else
1313: {
1314: /* a constant is being used as initializer */
1315: if( sz < SZINT )
1316: {
1317: /* special case: bit fields, etc. */
1318: incode( p->in.left, sz );
1319: }
1320: else
1321: {
1322: # ifdef MYINIT
1323: MYINIT( optim(p), sz );
1324: # else
1325: ecode( optim(p) );
1326: inoff += sz;
1327: # endif
1328: }
1329: }
1330:
1331: gotscal();
1332:
1333: leave:
1334: tfree(p);
1335: }
1336:
1337: gotscal()
1338: {
1339: register t, ix;
1340: register n, id;
1341: register struct symtab *p;
1342: register OFFSZ temp;
1343:
1344: for( ; pstk > instack; )
1345: {
1346:
1347: if( pstk->in_fl ) ++ibseen;
1348:
1349: --pstk;
1350:
1351: t = pstk->in_t;
1352:
1353: if( t == STRTY )
1354: {
1355: ix = ++pstk->in_x;
1356: if( (id=dimtab[ix]) < 0 ) continue;
1357:
1358: /* otherwise, put next element on the stack */
1359:
1360: p = &stab[id];
1361: instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off );
1362: return;
1363: }
1364: else if( ISARY(t) )
1365: {
1366: n = ++pstk->in_n;
1367: if( n >= dimtab[pstk->in_d] && pstk > instack ) continue;
1368:
1369: /* put the new element onto the stack */
1370:
1371: temp = pstk->in_sz;
1372: instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s,
1373: pstk->in_off+n*temp );
1374: return;
1375: }
1376:
1377: }
1378:
1379: }
1380:
1381: ilbrace()
1382: {
1383: /* process an initializer's left brace */
1384: register t;
1385: register struct instk *temp;
1386:
1387: temp = pstk;
1388:
1389: for( ; pstk > instack; --pstk )
1390: {
1391:
1392: t = pstk->in_t;
1393: if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */
1394: if( pstk->in_fl )
1395: {
1396: /* already associated with a { */
1397: if( pstk->in_n ) uerror( "illegal {");
1398: continue;
1399: }
1400:
1401: /* we have one ... */
1402: pstk->in_fl = 1;
1403: break;
1404: }
1405:
1406: /* cannot find one */
1407: /* ignore such right braces */
1408:
1409: pstk = temp;
1410: }
1411:
1412: irbrace()
1413: {
1414: /* called when a '}' is seen */
1415:
1416: # ifndef NODBG
1417: if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno );
1418: # endif
1419:
1420: if( ibseen )
1421: {
1422: --ibseen;
1423: return;
1424: }
1425:
1426: for( ; pstk > instack; --pstk )
1427: {
1428: if( !pstk->in_fl ) continue;
1429:
1430: /* we have one now */
1431:
1432: pstk->in_fl = 0; /* cancel { */
1433: gotscal(); /* take it away... */
1434: return;
1435: }
1436:
1437: /* these right braces match ignored left braces: throw out */
1438:
1439: }
1440:
1441: upoff( size, alignment, poff )
1442: register alignment, *poff;
1443: {
1444: /* update the offset pointed to by poff; return the
1445: ** offset of a value of size `size', alignment `alignment',
1446: ** given that off is increasing
1447: */
1448:
1449: register off;
1450:
1451: off = *poff;
1452: SETOFF( off, alignment );
1453: if( (maxoffset-off) < size )
1454: {
1455: if( instruct!=INSTRUCT )cerror("local variables fill memory");
1456: else cerror("structure larger than address space");
1457: }
1458: *poff = off+size;
1459: return( off );
1460: }
1461:
1462: oalloc( p, poff )
1463: register struct symtab *p;
1464: register *poff;
1465: {
1466: /* allocate p with offset *poff, and update *poff */
1467: register al, off, tsz;
1468: int noff;
1469:
1470: al = talign( p->stype, p->sizoff );
1471: noff = off = *poff;
1472: tsz = tsize( p->stype, p->dimoff, p->sizoff );
1473: #ifdef BACKAUTO
1474: if( p->sclass == AUTO )
1475: {
1476: if( (maxoffset-off) < tsz ) cerror("local variables fill memory");
1477: noff = off + tsz;
1478: SETOFF( noff, al );
1479: off = -noff;
1480: }
1481: else
1482: #endif
1483: #ifdef BACKPARAM
1484: /* this is rather nonstandard, and may be buggy in some cases */
1485: /* in particular, won't work with ARGSRET and ARGALLRET */
1486: if( p->sclass == PARAM )
1487: {
1488: if( (maxoffset-off) < tsz )
1489: cerror("local variables fill memory");
1490: /* if( tsz < SZINT ) */
1491: {
1492: noff = off + SZINT;
1493: SETOFF( noff, ALINT );
1494: off = -noff;
1495: # ifndef RTOLBYTES
1496: off += tsz;
1497: #endif
1498: }
1499: /* else
1500: /* {
1501: /* noff = off + tsz;
1502: /* SETOFF( noff, al );
1503: /* off = -noff;
1504: /* }
1505: */
1506: }
1507: else
1508: #endif
1509: if( p->sclass == PARAM && ( tsz % SZINT ) )
1510: { /* pjw stuff here. caller and callee must agree
1511: that params are 4 byte aligned */
1512: tsz = (tsz+SZINT-1)/SZINT;
1513: off = upoff(tsz*SZINT, ALSTACK, &noff );
1514: # ifndef RTOLBYTES
1515: off = noff - tsz;????(see note above)
1516: #endif
1517: }
1518: else
1519: {
1520: off = upoff( tsz, al, &noff );
1521: }
1522:
1523: if( p->sclass != REGISTER )
1524: {
1525: /* in case we are allocating stack space for register arguments */
1526: if( p->offset == NOOFFSET ) p->offset = off;
1527: else if( off != p->offset ) return(1);
1528: }
1529:
1530: *poff = noff;
1531: return(0);
1532: }
1533:
1534: falloc( p, w, new, pty )
1535: register struct symtab *p;
1536: register NODE *pty;
1537: {
1538: /* allocate a field of width w */
1539: /* new is 0 if new entry, 1 if redefinition, -1 if alignment */
1540:
1541: register al,sz,type;
1542:
1543: type = (new<0)? pty->in.type : p->stype;
1544:
1545: /* this must be fixed to use the current type in alignments */
1546: switch( new<0?pty->in.type:p->stype )
1547: {
1548:
1549: case ENUMTY:
1550: {
1551: register s;
1552: s = new<0 ? pty->fn.csiz : p->sizoff;
1553: al = dimtab[s+2];
1554: sz = dimtab[s];
1555: break;
1556: }
1557:
1558: case CHAR:
1559: case UCHAR:
1560: al = ALCHAR;
1561: sz = SZCHAR;
1562: break;
1563:
1564: case SHORT:
1565: case USHORT:
1566: al = ALSHORT;
1567: sz = SZSHORT;
1568: break;
1569:
1570: case INT:
1571: case UNSIGNED:
1572: al = ALINT;
1573: sz = SZINT;
1574: break;
1575: #ifdef LONGFIELDS
1576:
1577: case LONG:
1578: case ULONG:
1579: al = ALLONG;
1580: sz = SZLONG;
1581: break;
1582: #endif
1583:
1584: default:
1585: # ifdef FUNNYFLDS
1586: if( new < 0 )
1587: {
1588: # endif
1589: uerror( "illegal field type" );
1590: al = ALINT;
1591: # ifdef FUNNYFLDS
1592: }
1593: else
1594: {
1595: al = fldal( p->stype );
1596: sz =SZINT;
1597: }
1598: # endif
1599: }
1600:
1601: if( w > sz )
1602: {
1603: uerror( "field too big (%d>%d)", w, sz);
1604: w = sz;
1605: }
1606:
1607: if( w == 0 )
1608: {
1609: /* align only */
1610: SETOFF( strucoff, al );
1611: if( new >= 0 ) uerror( "zero size field");
1612: return(0);
1613: }
1614:
1615: if( strucoff%al + w > sz ) SETOFF( strucoff, al );
1616: if( new < 0 )
1617: {
1618: if( (maxoffset-strucoff) < w )
1619: cerror("structure fills memory");
1620: strucoff += w; /* we know it will fit */
1621: return(0);
1622: }
1623:
1624: /* establish the field */
1625:
1626: if( new == 1 )
1627: {
1628: /* previous definition */
1629: if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1);
1630: }
1631: p->offset = strucoff;
1632: if( (maxoffset-strucoff) < w ) cerror("structure overflows memory");
1633: strucoff += w;
1634: p->stype = type;
1635: return(0);
1636: }
1637:
1638: # ifndef EXCLASS
1639: # define EXCLASS EXTERN
1640: # endif
1641:
1642: nidcl( p )
1643: register NODE *p;
1644: {
1645: /* handle unitialized declarations */
1646: /* assumed to be not functions */
1647: register class;
1648: register commflag; /* flag for labelled common declarations */
1649:
1650: commflag = 0;
1651:
1652: /* compute class */
1653: if( (class=curclass) == SNULL )
1654: {
1655: if( blevel > 1 ) class = AUTO;
1656: else if( blevel != 0 || instruct ) cerror( "nidcl error" );
1657: else
1658: {
1659: /* blevel = 0 */
1660: if( (class = EXCLASS) == EXTERN ) commflag = 1;
1661: }
1662: }
1663:
1664: defid( p, class );
1665:
1666: if( class==EXTDEF || class==STATIC )
1667: {
1668:
1669: # ifndef ALLCOMM
1670: /* simulate initialization by 0 */
1671: beginit( p->tn.rval );
1672: endinit();
1673: # else
1674: commflag = 1;
1675: # endif
1676:
1677: }
1678: if( commflag ) commdec( p->tn.rval );
1679: }
1680:
1681: TWORD
1682: types( t1, t2, t3 )
1683: register TWORD t1, t2, t3;
1684: {
1685: /* return a basic type from basic types t1, t2, and t3 */
1686:
1687: TWORD t[3];
1688: register TWORD noun, adj, unsg;
1689: register i;
1690:
1691: t[0] = t1;
1692: t[1] = t2;
1693: t[2] = t3;
1694:
1695: unsg = INT; /* INT or UNSIGNED */
1696: noun = UNDEF; /* INT, CHAR, or FLOAT */
1697: adj = INT; /* INT, LONG, or SHORT */
1698:
1699: for( i=0; i<3; ++i )
1700: {
1701: switch( t[i] )
1702: {
1703:
1704: default:
1705: bad:
1706: uerror( "illegal type combination" );
1707: return( INT );
1708:
1709: case UNDEF:
1710: continue;
1711:
1712: case UNSIGNED:
1713: if( unsg != INT ) goto bad;
1714: unsg = UNSIGNED;
1715: continue;
1716:
1717: case LONG:
1718: case SHORT:
1719: if( adj != INT ) goto bad;
1720: adj = t[i];
1721: continue;
1722:
1723: case INT:
1724: case CHAR:
1725: case FLOAT:
1726: if( noun != UNDEF ) goto bad;
1727: noun = t[i];
1728: continue;
1729: }
1730: }
1731:
1732: /* now, construct final type */
1733: if( noun == UNDEF ) noun = INT;
1734: else if( noun == FLOAT )
1735: {
1736: if( unsg != INT || adj == SHORT ) goto bad;
1737: return( adj==LONG ? DOUBLE : FLOAT );
1738: }
1739: else if( noun == CHAR && adj != INT ) goto bad;
1740:
1741: /* now, noun is INT or CHAR */
1742: if( adj != INT ) noun = adj;
1743: if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) );
1744: else return( noun );
1745: }
1746:
1747: NODE *
1748: tymerge( typ, idp )
1749: register NODE *typ, *idp;
1750:
1751: {
1752: /* merge type typ with identifier idp */
1753:
1754: register unsigned t;
1755: register i;
1756:
1757: if( typ->in.op != TYPE ) cerror( "tymerge: arg 1" );
1758: if(idp == NIL ) return( NIL );
1759:
1760: # ifndef NODBG
1761: if( ddebug > 2 ) eprint(idp);
1762: # endif
1763:
1764: idp->in.type = typ->in.type;
1765: idp->fn.cdim = curdim;
1766: tyreduce( idp );
1767: idp->fn.csiz = typ->fn.csiz;
1768:
1769: for( t=typ->in.type, i=typ->fn.cdim; t&TMASK; t = DECREF(t) )
1770: {
1771: if( ISARY(t) ) dstash( dimtab[i++] );
1772: }
1773:
1774: /* now idp is a single node: fix up type */
1775:
1776: idp->in.type = ctype( idp->in.type );
1777:
1778: if( (t = BTYPE(idp->in.type)) != STRTY && t != UNIONTY && t != ENUMTY )
1779: {
1780: idp->fn.csiz = t; /* in case ctype has rewritten things */
1781: }
1782:
1783: return( idp );
1784: }
1785:
1786: tyreduce( p )
1787: register NODE *p;
1788:
1789: {
1790:
1791: /* build a type, stash away dimensions, from a declaration parse tree */
1792: /* the type is built top down, the dimensions bottom up */
1793:
1794: register o, temp;
1795: register unsigned t;
1796:
1797: o = p->in.op;
1798: p->in.op = FREE;
1799:
1800: if( o == NAME ) return;
1801:
1802: t = INCREF( p->in.type );
1803: if( o == UNARY CALL ) t += (FTN-PTR);
1804: else if( o == LB )
1805: {
1806: t += (ARY-PTR);
1807: temp = p->in.right->tn.lval;
1808: p->in.right->in.op = FREE;
1809: }
1810:
1811: p->in.left->in.type = t;
1812: tyreduce( p->in.left );
1813:
1814: if( o == LB ) dstash( temp );
1815:
1816: p->tn.rval = p->in.left->tn.rval;
1817: p->in.type = p->in.left->in.type;
1818:
1819: }
1820:
1821: fixtype( p, class )
1822: register NODE *p;
1823: register class;
1824: {
1825: register unsigned t, type;
1826: register mod1, mod2;
1827: /* fix up the types, and check for legality */
1828:
1829: if( (type = p->in.type) == UNDEF ) return;
1830: if( mod2 = (type&TMASK) )
1831: {
1832: t = DECREF(type);
1833: while( mod1=mod2, mod2 = (t&TMASK) )
1834: {
1835: if( mod1 == ARY && mod2 == FTN )
1836: {
1837: uerror( "array of functions is illegal" );
1838: type = 0;
1839: }
1840: else if( mod1==FTN && ( mod2==ARY || mod2==FTN ) )
1841: {
1842: uerror( "function returns array or function" );
1843: type = 0;
1844: }
1845: t = DECREF(t);
1846: }
1847: }
1848:
1849: /* detect function arguments, watching out for structure declarations */
1850: /* for example, beware of f(x) struct [ int a[10]; } *x; { ... } */
1851: /* the danger is that "a" will be converted to a pointer */
1852:
1853: if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) )
1854: class = PARAM;
1855: if( class == PARAM || ( class==REGISTER && blevel==1 ) )
1856: {
1857: if( type == FLOAT ) type = DOUBLE;
1858: else if( ISARY(type) )
1859: {
1860: ++p->fn.cdim;
1861: type += (PTR-ARY);
1862: }
1863: else if( ISFTN(type) )
1864: {
1865: werror( "a function is declared as an argument" );
1866: type = INCREF(type);
1867: }
1868: }
1869:
1870: if( instruct && ISFTN(type) )
1871: {
1872: uerror( "function illegal in structure or union" );
1873: type = INCREF(type);
1874: }
1875: p->in.type = type;
1876: }
1877:
1878: # ifndef MYCTYPE
1879: TWORD
1880: ctype( t )
1881: register TWORD t;
1882: {
1883: register TWORD bt;
1884: bt = BTYPE(t);
1885:
1886: # ifdef NOFLOAT
1887: if( bt==FLOAT || bt==DOUBLE ) cerror( "ctype:f" );
1888: # endif
1889:
1890: # ifdef NOSHORT
1891: # ifdef NOUNSIGNED
1892: if( bt==SHORT || bt==USHORT ) MODTYPE(t,INT);
1893: # else
1894: if( bt==SHORT ) MODTYPE(t,INT);
1895: else if( bt==USHORT) MODTYPE(t,UNSIGNED);
1896: # endif
1897: # endif
1898:
1899: # ifdef NOLONG
1900: # ifdef NOUNSIGNED
1901: if( bt==LONG || bt==ULONG ) MODTYPE(t,INT);
1902: # else
1903: if( bt==LONG ) MODTYPE(t,INT);
1904: else if( bt==ULONG) MODTYPE(t,UNSIGNED);
1905: # endif
1906: # endif
1907:
1908: #if defined(M32B) && defined(IMPREGAL)
1909: radbl( t );
1910: #endif
1911: return( t );
1912: }
1913: # endif
1914:
1915: uclass( class )
1916: register class;
1917: {
1918: /* give undefined version of class */
1919: if( class == SNULL ) return( EXTERN );
1920: else if( class == STATIC ) return( USTATIC );
1921: else if( class == FORTRAN ) return( UFORTRAN );
1922: else return( class );
1923: }
1924:
1925: fixclass( class, type )
1926: register TWORD type;
1927: register class;
1928:
1929: {
1930:
1931: /* first, fix null class */
1932:
1933: if( class == SNULL )
1934: {
1935: if( instruct&INSTRUCT ) class = MOS;
1936: else if( instruct&INUNION ) class = MOU;
1937: else if( blevel == 0 ) class = EXTDEF;
1938: else if( blevel == 1 ) class = PARAM;
1939: else class = AUTO;
1940:
1941: }
1942:
1943: /* now, do general checking */
1944: if(blevel == 1 && (class == STATIC || class == EXTERN))
1945: uerror("parameter declared with weird storage classs");
1946: if( ISFTN( type ) )
1947: {
1948: switch( class )
1949: {
1950: default:
1951: uerror( "function has illegal storage class" );
1952: case AUTO:
1953: class = EXTERN;
1954: case EXTERN:
1955: case EXTDEF:
1956: case FORTRAN:
1957: case TYPEDEF:
1958: case STATIC:
1959: case UFORTRAN:
1960: case USTATIC:
1961: ;
1962: }
1963: }
1964:
1965: if( class&FIELD )
1966: {
1967: if( !(instruct&INSTRUCT) ) uerror( "field not in structure" );
1968: return( class );
1969: }
1970:
1971: switch( class )
1972: {
1973:
1974: case MOU:
1975: if( !(instruct&INUNION) ) uerror( "illegal class" );
1976: return( class );
1977:
1978: case MOS:
1979: if( !(instruct&INSTRUCT) ) uerror( "illegal class" );
1980: return( class );
1981:
1982: case MOE:
1983: if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" );
1984: return( class );
1985:
1986: case REGISTER:
1987: if( blevel == 0 ) uerror( "register declaration outside a fncn" );
1988: /* if cisreg returns 1, nextrvar has the reg. number */
1989: else if( cisreg( type ) ) return( class );
1990: if( blevel == 1 ) return( PARAM );
1991: else return( AUTO );
1992:
1993: case AUTO:
1994: case LABEL:
1995: case ULABEL:
1996: if( blevel < 2 ) uerror( "auto outside function" );
1997: return( class );
1998:
1999: case PARAM:
2000: if( blevel != 1 ) uerror( "illegal class" );
2001: return( class );
2002:
2003: case UFORTRAN:
2004: case FORTRAN:
2005: # ifdef NOFORTRAN
2006: NOFORTRAN; /* a condition which can regulate the FORTRAN usage */
2007: # endif
2008: if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" );
2009: else
2010: {
2011: type = DECREF(type);
2012: if( ISFTN(type) || ISARY(type) || ISPTR(type) )
2013: {
2014: uerror( "fortran function has wrong type" );
2015: }
2016: }
2017: case STNAME:
2018: case UNAME:
2019: case ENAME:
2020: case EXTERN:
2021: case STATIC:
2022: case EXTDEF:
2023: case TYPEDEF:
2024: case USTATIC:
2025: return( class );
2026:
2027: default:
2028: cerror( "illegal class: %d", class );
2029: /* NOTREACHED */
2030: }
2031: }
2032:
2033: struct symtab *
2034: mknonuniq(idindex)
2035: register *idindex;
2036: {
2037: /* locate a symbol table entry for */
2038: /* an occurrence of a nonunique structure member name */
2039: /* or field */
2040: register i;
2041: register struct symtab * sp;
2042:
2043: sp = & stab[ i= *idindex ]; /* position search at old entry */
2044: while( sp->stype != TNULL )
2045: {
2046: /* locate unused entry */
2047: if( ++i >= SYMTSZ )
2048: {
2049: /* wrap around symbol table */
2050: i = 0;
2051: sp = stab;
2052: }
2053: else ++sp;
2054: if( i == *idindex ) cerror("Symbol table full");
2055: }
2056: sp->sflags = SNONUNIQ | SMOS;
2057: sp->sname = stab[*idindex].sname; /* old entry name */
2058: *idindex = i;
2059: # ifndef NODBG
2060: if( ddebug )
2061: {
2062: printf( "\tnonunique entry for %s from %d to %d\n",
2063: sp->sname, *idindex, i );
2064: }
2065: # endif
2066: return ( sp );
2067: }
2068:
2069: #ifndef checkst
2070: /* if not debugging, make checkst a macro */
2071: checkst(lev)
2072: {
2073: register int s, i, j;
2074: register struct symtab *p, *q;
2075:
2076: for( i=0, p=stab; i<SYMTSZ; ++i, ++p )
2077: {
2078: if( p->stype == TNULL ) continue;
2079: j = lookup( p->sname, p->sflags&(SMOS|STAG) );
2080: if( j != i )
2081: {
2082: q = &stab[j];
2083: if( q->stype == UNDEF ||
2084: q->slevel <= p->slevel )
2085: {
2086: cerror( "check error: %s", q->sname );
2087: }
2088: }
2089: else if( p->slevel > lev ) cerror( "%s check at level %d", p->sname, lev );
2090: }
2091: }
2092: #endif
2093:
2094: struct symtab *
2095: relook(p)
2096: register struct symtab *p;
2097:
2098: {
2099: /* look up p again, and see where it lies */
2100: register struct symtab *q;
2101:
2102: /* I'm not sure that this handles towers of several hidden definitions in all cases */
2103: q = &stab[lookup( p->sname, p->sflags&(STAG|SMOS|SHIDDEN) )];
2104: /* make relook always point to either p or an empty cell */
2105: if( q->stype == UNDEF )
2106: {
2107: q->stype = TNULL;
2108: return(q);
2109: }
2110: while( q != p )
2111: {
2112: if( q->stype == TNULL ) break;
2113: if( ++q >= &stab[SYMTSZ] ) q=stab;
2114: }
2115: return(q);
2116: }
2117:
2118: uplevel()
2119: {
2120: ++blevel;
2121: #ifdef GDEBUG
2122: dblbrac();
2123: #endif
2124: }
2125:
2126: clearst( lev )
2127: {
2128: /* clear entries of internal scope from the symbol table */
2129: extern struct symtab *scopestack[];
2130: register struct symtab *p, *q, *r;
2131:
2132: # ifdef GDEBUG
2133: /* do this first, so structure members don't get clobbered
2134: ** before they are printed out...
2135: */
2136: aobeg();
2137: p = scopestack[blevel];
2138: while (p)
2139: {
2140: aocode(p);
2141: p = p->scopelink;
2142: }
2143: aoend();
2144: if (lev != 1) /* param level */
2145: dbrbrac();
2146: # endif
2147:
2148: /* q is to collect enteries which properly belong to
2149: an outer scope */
2150: q = (struct symtab *) NULL;
2151: /* first, find an empty slot to prevent newly hashed entries
2152: ** from being slopped into...
2153: */
2154:
2155: p = scopestack[lev];
2156: while (p)
2157: {
2158: # ifndef NODBG
2159: if (ddebug)
2160: printf("removing %s = stab[ %d], flags %o level %d\n",
2161: p->sname,p-stab,p->sflags,p->slevel);
2162: # endif
2163: /* if this is still undefined, complain */
2164: if (p->stype == UNDEF ||
2165: ( p->sclass == ULABEL && lev <=2) ) {
2166: uerror("%s undefined", p->sname);
2167: }
2168: if( p->sflags & SHIDES )
2169: unhide(p);
2170: if( (r=relook(p)) != p )
2171: *r = *p;
2172: if ( lev > p->slevel ) {
2173: /* collect outer scope entries first
2174: appearing in inner scope */
2175: r = p;
2176: p = p->scopelink;
2177: r->scopelink = q;
2178: q = r;
2179: } else {
2180: p->stype = TNULL;
2181: p = p->scopelink;
2182: }
2183: }
2184: scopestack[lev] = (struct symtab *) NULL;
2185: /* move outer scope entries into holes, and up a level */
2186: while( q )
2187: {
2188: r = &stab[ lookup( q->sname, q->sflags ) ];
2189: if ( r != q )
2190: {
2191: *r = *q;
2192: q->stype = TNULL;
2193: }
2194: q = q->scopelink;
2195: r->scopelink = scopestack[ lev-1 ];
2196: scopestack[ lev-1 ] = r;
2197: }
2198: }
2199:
2200: hide( p )
2201: register struct symtab *p;
2202: {
2203: register struct symtab *q;
2204: for( q=p+1; ; ++q )
2205: {
2206: if( q >= &stab[SYMTSZ] ) q = stab;
2207: if( q == p ) cerror( "symbol table full" );
2208: if( q->stype == TNULL ) break;
2209: }
2210: *q = *p;
2211: p->sflags |= SHIDDEN;
2212: q->sflags = (p->sflags&(SMOS|STAG)) | SHIDES;
2213: if( hflag ) werror( "%s redefinition hides earlier one", p->sname );
2214: # ifndef NODBG
2215: if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab );
2216: # endif
2217: return( idname = q-stab );
2218: }
2219:
2220: unhide( p )
2221: register struct symtab *p;
2222: {
2223: register struct symtab *q;
2224: register s;
2225:
2226: s = p->sflags & (SMOS|STAG);
2227: q = p;
2228:
2229: for(;;)
2230: {
2231:
2232: if( q == stab ) q = &stab[SYMTSZ-1];
2233: else --q;
2234:
2235: if( q == p ) break;
2236:
2237: if( (q->sflags&(SMOS|STAG)) == s )
2238: {
2239: if ( p->sname == q->sname )
2240: {
2241: /* found the name */
2242: q->sflags &= ~SHIDDEN;
2243: # ifndef NODBG
2244: if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab);
2245: # endif
2246: return;
2247: }
2248: }
2249:
2250: }
2251: cerror( "unhide fails" );
2252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.