1: # include "mfile1" 2: 3: struct instk { 4: int in_sz; /* size of array element */ 5: int in_x; /* current index for structure member in structure initializations */ 6: int in_n; /* number of initializations seen */ 7: int in_s; /* sizoff */ 8: int in_d; /* dimoff */ 9: TWORD in_t; /* type */ 10: int in_id; /* stab index */ 11: int in_fl; /* flag which says if this level is controlled by {} */ 12: OFFSZ in_off; /* offset of the beginning of this level */ 13: } 14: instack[10], 15: *pstk; 16: 17: /* defines used for getting things off of the initialization stack */ 18: 19: 20: struct symtab *relook(); 21: 22: 23: int ddebug = 0; 24: 25: int defid(); 26: psave( i ){ 27: if( paramno >= PARAMSZ ){ 28: cerror( "parameter stack overflow"); 29: } 30: paramstk[ paramno++ ] = i; 31: } 32: 33: ftnend(){ /* end of function */ 34: if( retlab != NOLAB ){ /* inside a real function */ 35: efcode(); 36: } 37: checkst(0); 38: retstat = 0; 39: tcheck(); 40: curclass = SNULL; 41: brklab = contlab = retlab = NOLAB; 42: flostat = 0; 43: if( nerrors == 0 ){ 44: if( psavbc != & asavbc[0] ) cerror("bcsave error"); 45: if( paramno != 0 ) cerror("parameter reset error"); 46: if( swx != 0 ) cerror( "switch error"); 47: } 48: psavbc = &asavbc[0]; 49: paramno = 0; 50: autooff = AUTOINIT; 51: minrvar = regvar = MAXRVAR; 52: reached = 1; 53: swx = 0; 54: swp = swtab; 55: locctr(DATA); 56: } 57: 58: dclargs(){ 59: register i, j; 60: register struct symtab *p; 61: register NODE *q; 62: argoff = ARGINIT; 63: for( i=0; i<paramno; ++i ){ 64: if( (j = paramstk[i]) < 0 ) continue; 65: p = &stab[j]; 66: if( p->stype == FARG ) { 67: q = block(FREE,NIL,NIL,INT,0,INT); 68: q->rval = j; 69: defid( q, PARAM ); 70: } 71: oalloc( p, &argoff ); /* always set aside space, even for register arguments */ 72: } 73: cendarg(); 74: locctr(PROG); 75: defalign(ALINT); 76: ++ftnno; 77: bfcode( paramstk, paramno ); 78: paramno = 0; 79: } 80: 81: NODE * 82: rstruct( idn, soru ){ /* reference to a structure or union, with no definition */ 83: register struct symtab *p; 84: register NODE *q; 85: p = &stab[idn]; 86: switch( p->stype ){ 87: 88: case UNDEF: 89: def: 90: q = block( FREE, NIL, NIL, 0, 0, 0 ); 91: q->rval = idn; 92: q->type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY ); 93: defid( q, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) ); 94: break; 95: 96: case STRTY: 97: if( soru & INSTRUCT ) break; 98: goto def; 99: 100: case UNIONTY: 101: if( soru & INUNION ) break; 102: goto def; 103: 104: case ENUMTY: 105: if( !(soru&(INUNION|INSTRUCT)) ) break; 106: goto def; 107: 108: } 109: stwart = instruct; 110: return( mkty( p->stype, 0, p->sizoff ) ); 111: } 112: 113: moedef( idn ){ 114: register NODE *q; 115: 116: q = block( FREE, NIL, NIL, MOETY, 0, 0 ); 117: q -> rval = idn; 118: if( idn>=0 ) defid( q, MOE ); 119: } 120: 121: bstruct( idn, soru ){ /* begining of structure or union declaration */ 122: register NODE *q; 123: 124: psave( instruct ); 125: psave( curclass ); 126: psave( strucoff ); 127: strucoff = 0; 128: instruct = soru; 129: q = block( FREE, NIL, NIL, 0, 0, 0 ); 130: q->rval = idn; 131: if( instruct==INSTRUCT ){ 132: curclass = MOS; 133: q->type = STRTY; 134: if( idn >= 0 ) defid( q, STNAME ); 135: } 136: else if( instruct == INUNION ) { 137: curclass = MOU; 138: q->type = UNIONTY; 139: if( idn >= 0 ) defid( q, UNAME ); 140: } 141: else { /* enum */ 142: curclass = MOE; 143: q->type = ENUMTY; 144: if( idn >= 0 ) defid( q, ENAME ); 145: } 146: psave( q->rval ); 147: return( paramno-4 ); 148: } 149: 150: NODE * 151: dclstruct( oparam ){ 152: register struct symtab *p; 153: register i, al, sa, j, sz, szindex; 154: register TWORD temp; 155: register high, low; 156: 157: /* paramstack contains: 158: paramstack[ oparam ] = previous instruct 159: paramstack[ oparam+1 ] = previous class 160: paramstk[ oparam+2 ] = previous strucoff 161: paramstk[ oparam+3 ] = structure name 162: 163: paramstk[ oparam+4, ... ] = member stab indices 164: 165: */ 166: 167: 168: if( (i=paramstk[oparam+3]) < 0 ){ 169: szindex = curdim; 170: dstash( 0 ); /* size */ 171: dstash( -1 ); /* index to member names */ 172: dstash( ALSTRUCT ); /* alignment */ 173: } 174: else { 175: szindex = stab[i].sizoff; 176: } 177: 178: if( ddebug ){ 179: printf( "dclstruct( %.8s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex ); 180: } 181: temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY); 182: stwart = instruct = paramstk[ oparam ]; 183: curclass = paramstk[ oparam+1 ]; 184: dimtab[ szindex+1 ] = curdim; 185: al = ALSTRUCT; 186: 187: high = low = 0; 188: 189: for( i = oparam+4; i< paramno; ++i ){ 190: dstash( j=paramstk[i] ); 191: if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" ); 192: p = &stab[j]; 193: if( temp == ENUMTY ){ 194: if( p->offset < low ) low = p->offset; 195: if( p->offset > high ) high = p->offset; 196: p->sizoff = szindex; 197: continue; 198: } 199: sa = talign( p->stype, p->sizoff ); 200: if( p->sclass & FIELD ){ 201: sz = p->sclass&FLDSIZ; 202: } 203: else { 204: sz = tsize( p->stype, p->dimoff, p->sizoff ); 205: } 206: if( sz == 0 ){ 207: uerror( "illegal zero sized structure member: %.8s", p->sname ); 208: } 209: if( sz > strucoff ) strucoff = sz; /* for use with unions */ 210: SETOFF( al, sa ); 211: /* set al, the alignment, to the lcm of the alignments of the members */ 212: } 213: dstash( -1 ); /* endmarker */ 214: SETOFF( strucoff, al ); 215: 216: if( temp == ENUMTY ){ 217: register TWORD ty; 218: 219: # ifdef ENUMSIZE 220: ty = ENUMSIZE(high,low); 221: # else 222: if( (char)high == high && (char)low == low ) ty = ctype( CHAR ); 223: else if( (short)high == high && (short)low == low ) ty = ctype( SHORT ); 224: else ty = ctype(INT); 225: #endif 226: strucoff = tsize( ty, 0, (int)ty ); 227: dimtab[ szindex+2 ] = al = talign( ty, (int)ty ); 228: } 229: 230: if( strucoff == 0 ) uerror( "zero sized structure" ); 231: dimtab[ szindex ] = strucoff; 232: dimtab[ szindex+2 ] = al; 233: 234: if( ddebug>1 ){ 235: printf( "\tdimtab[%d,%d,%d] = %d,%d,%d\n", szindex,szindex+1,szindex+2, 236: dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] ); 237: for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){ 238: printf( "\tmember %.8s(%d)\n", stab[dimtab[i]].sname, dimtab[i] ); 239: } 240: } 241: 242: strucoff = paramstk[ oparam+2 ]; 243: paramno = oparam; 244: 245: return( mkty( temp, 0, szindex ) ); 246: } 247: 248: /* VARARGS */ 249: yyerror( s ) char *s; { /* error printing routine in parser */ 250: 251: uerror( s ); 252: 253: } 254: 255: yyaccpt(){ 256: ftnend(); 257: } 258: 259: ftnarg( idn ) { 260: if( stab[idn].stype != UNDEF ){ 261: idn = hide( &stab[idn]); 262: } 263: stab[idn].stype = FARG; 264: stab[idn].sclass = PARAM; 265: psave( idn ); 266: } 267: 268: talign( ty, s) register unsigned ty; register s; { 269: /* compute the alignment of an object with type ty, sizeoff index s */ 270: 271: register i; 272: if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT 273: #ifdef LONGFIELDS 274: && ty!=LONG && ty!=ULONG 275: #endif 276: ){ 277: return( fldal( ty ) ); 278: } 279: 280: for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ 281: switch( (ty>>i)&TMASK ){ 282: 283: case FTN: 284: cerror( "compiler takes alignment of function"); 285: case PTR: 286: return( ALPOINT ); 287: case ARY: 288: continue; 289: case 0: 290: break; 291: } 292: } 293: 294: switch( BTYPE(ty) ){ 295: 296: case UNIONTY: 297: case ENUMTY: 298: case STRTY: 299: return( dimtab[ s+2 ] ); 300: case CHAR: 301: case UCHAR: 302: return( ALCHAR ); 303: case FLOAT: 304: return( ALFLOAT ); 305: case DOUBLE: 306: return( ALDOUBLE ); 307: case LONG: 308: case ULONG: 309: return( ALLONG ); 310: case SHORT: 311: case USHORT: 312: return( ALSHORT ); 313: default: 314: return( ALINT ); 315: } 316: } 317: 318: OFFSZ 319: tsize( ty, d, s ) TWORD ty; { 320: /* compute the size associated with type ty, 321: dimoff d, and sizoff s */ 322: /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */ 323: 324: int i; 325: OFFSZ mult; 326: 327: mult = 1; 328: 329: for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ 330: switch( (ty>>i)&TMASK ){ 331: 332: case FTN: 333: cerror( "compiler takes size of function"); 334: case PTR: 335: return( SZPOINT * mult ); 336: case ARY: 337: mult *= dimtab[ d++ ]; 338: continue; 339: case 0: 340: break; 341: 342: } 343: } 344: 345: if( dimtab[s]==0 ) { 346: uerror( "unknown size"); 347: return( SZINT ); 348: } 349: return( dimtab[ s ] * mult ); 350: } 351: 352: inforce( n ) OFFSZ n; { /* force inoff to have the value n */ 353: /* inoff is updated to have the value n */ 354: OFFSZ wb; 355: register rest; 356: /* rest is used to do a lot of conversion to ints... */ 357: 358: if( inoff == n ) return; 359: if( inoff > n ) { 360: cerror( "initialization alignment error"); 361: } 362: 363: wb = inoff; 364: SETOFF( wb, SZINT ); 365: 366: /* wb now has the next higher word boundary */ 367: 368: if( wb >= n ){ /* in the same word */ 369: rest = n - inoff; 370: vfdzero( rest ); 371: return; 372: } 373: 374: /* otherwise, extend inoff to be word aligned */ 375: 376: rest = wb - inoff; 377: vfdzero( rest ); 378: 379: /* now, skip full words until near to n */ 380: 381: rest = (n-inoff)/SZINT; 382: zecode( rest ); 383: 384: /* now, the remainder of the last word */ 385: 386: rest = n-inoff; 387: vfdzero( rest ); 388: if( inoff != n ) cerror( "inoff error"); 389: 390: } 391: 392: vfdalign( n ){ /* make inoff have the offset the next alignment of n */ 393: OFFSZ m; 394: 395: m = inoff; 396: SETOFF( m, n ); 397: inforce( m ); 398: } 399: 400: 401: int idebug = 0; 402: 403: int ibseen = 0; /* the number of } constructions which have been filled */ 404: 405: int iclass; /* storage class of thing being initialized */ 406: 407: int ilocctr = 0; /* location counter for current initialization */ 408: 409: beginit(curid){ 410: /* beginning of initilization; set location ctr and set type */ 411: register struct symtab *p; 412: 413: if( idebug >= 3 ) printf( "beginit(), curid = %d\n", curid ); 414: 415: p = &stab[curid]; 416: 417: iclass = p->sclass; 418: if( curclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN; 419: switch( iclass ){ 420: 421: case UNAME: 422: case EXTERN: 423: return; 424: case AUTO: 425: case REGISTER: 426: break; 427: case EXTDEF: 428: case STATIC: 429: ilocctr = ISARY(p->stype)?ADATA:DATA; 430: locctr( ilocctr ); 431: defalign( talign( p->stype, p->sizoff ) ); 432: defnam( p ); 433: 434: } 435: 436: inoff = 0; 437: ibseen = 0; 438: 439: pstk = 0; 440: 441: instk( curid, p->stype, p->dimoff, p->sizoff, inoff ); 442: 443: } 444: 445: instk( id, t, d, s, off ) OFFSZ off; TWORD t; { 446: /* make a new entry on the parameter stack to initialize id */ 447: 448: register struct symtab *p; 449: 450: for(;;){ 451: if( idebug ) printf( "instk((%d, %o,%d,%d, %d)\n", id, t, d, s, off ); 452: 453: /* save information on the stack */ 454: 455: if( !pstk ) pstk = instack; 456: else ++pstk; 457: 458: pstk->in_fl = 0; /* { flag */ 459: pstk->in_id = id ; 460: pstk->in_t = t ; 461: pstk->in_d = d ; 462: pstk->in_s = s ; 463: pstk->in_n = 0; /* number seen */ 464: pstk->in_x = t==STRTY ?dimtab[s+1] : 0 ; 465: pstk->in_off = off; /* offset at the beginning of this element */ 466: /* if t is an array, DECREF(t) can't be a field */ 467: /* INS_sz has size of array elements, and -size for fields */ 468: if( ISARY(t) ){ 469: pstk->in_sz = tsize( DECREF(t), d+1, s ); 470: } 471: else if( stab[id].sclass & FIELD ){ 472: pstk->in_sz = - ( stab[id].sclass & FLDSIZ ); 473: } 474: else { 475: pstk->in_sz = 0; 476: } 477: 478: if( (iclass==AUTO || iclass == REGISTER ) && 479: (ISARY(t) || t==STRTY) ) uerror( "no automatic aggregate initialization" ); 480: 481: /* now, if this is not a scalar, put on another element */ 482: 483: if( ISARY(t) ){ 484: t = DECREF(t); 485: ++d; 486: continue; 487: } 488: else if( t == STRTY ){ 489: id = dimtab[pstk->in_x]; 490: p = &stab[id]; 491: if( p->sclass != MOS && !(p->sclass&FIELD) ) cerror( "insane structure member list" ); 492: t = p->stype; 493: d = p->dimoff; 494: s = p->sizoff; 495: off += p->offset; 496: continue; 497: } 498: else return; 499: } 500: } 501: 502: NODE * 503: getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */ 504: 505: register l, temp; 506: register NODE *p; 507: 508: if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) && 509: pstk!=instack && ISARY( pstk[-1].in_t ) ){ 510: /* treat "abc" as { 'a', 'b', 'c', 0 } */ 511: strflg = 1; 512: ilbrace(); /* simulate { */ 513: inforce( pstk->in_off ); 514: /* if the array is inflexible (not top level), pass in the size and 515: be prepared to throw away unwanted initializers */ 516: lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0); /* get the contents */ 517: irbrace(); /* simulate } */ 518: return( NIL ); 519: } 520: else { /* make a label, and get the contents and stash them away */ 521: if( iclass != SNULL ){ /* initializing */ 522: /* fill out previous word, to permit pointer */ 523: vfdalign( ALPOINT ); 524: } 525: temp = locctr( blevel==0?ISTRNG:STRNG ); /* set up location counter */ 526: deflab( l = getlab() ); 527: strflg = 0; 528: lxstr(0); /* get the contents */ 529: locctr( blevel==0?ilocctr:temp ); 530: p = buildtree( STRING, NIL, NIL ); 531: p->rval = -l; 532: return(p); 533: } 534: } 535: 536: putbyte( v ){ /* simulate byte v appearing in a list of integer values */ 537: register NODE *p; 538: p = bcon(v); 539: incode( p, SZCHAR ); 540: tfree( p ); 541: gotscal(); 542: } 543: 544: endinit(){ 545: register TWORD t; 546: register d, s, n, d1; 547: 548: if( idebug ) printf( "endinit(), inoff = %d\n", inoff ); 549: 550: switch( iclass ){ 551: 552: case EXTERN: 553: case AUTO: 554: case REGISTER: 555: return; 556: } 557: 558: pstk = instack; 559: 560: t = pstk->in_t; 561: d = pstk->in_d; 562: s = pstk->in_s; 563: n = pstk->in_n; 564: 565: if( ISARY(t) ){ 566: d1 = dimtab[d]; 567: 568: vfdalign( pstk->in_sz ); /* fill out part of the last element, if needed */ 569: n = inoff/pstk->in_sz; /* real number of initializers */ 570: if( d1 >= n ){ 571: /* once again, t is an array, so no fields */ 572: inforce( tsize( t, d, s ) ); 573: n = d1; 574: } 575: if( d1!=0 && d1!=n ) uerror( "too many initializers"); 576: if( n==0 ) werror( "empty array declaration"); 577: dimtab[d] = n; 578: } 579: 580: else if( t == STRTY || t == UNIONTY ){ 581: /* clearly not fields either */ 582: inforce( tsize( t, d, s ) ); 583: } 584: else if( n > 1 ) uerror( "bad scalar initialization"); 585: /* this will never be called with a field element... */ 586: else inforce( tsize(t,d,s) ); 587: 588: paramno = 0; 589: vfdalign( AL_INIT ); 590: inoff = 0; 591: iclass = SNULL; 592: 593: } 594: 595: doinit( p ) register NODE *p; { 596: 597: /* take care of generating a value for the initializer p */ 598: /* inoff has the current offset (last bit written) 599: in the current word being generated */ 600: 601: register sz, d, s; 602: register TWORD t; 603: 604: /* note: size of an individual initializer is assumed to fit into an int */ 605: 606: if( iclass < 0 ) goto leave; 607: if( iclass == EXTERN || iclass == UNAME ){ 608: uerror( "cannot initialize extern or union" ); 609: iclass = -1; 610: goto leave; 611: } 612: 613: if( iclass == AUTO || iclass == REGISTER ){ 614: /* do the initialization and get out, without regard 615: for filing out the variable with zeros, etc. */ 616: bccode(); 617: idname = pstk->in_id; 618: p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p ); 619: ecomp(p); 620: return; 621: } 622: 623: if( p == NIL ) return; /* for throwing away strings that have been turned into lists */ 624: 625: if( ibseen ){ 626: uerror( "} expected"); 627: goto leave; 628: } 629: 630: if( idebug > 1 ) printf( "doinit(%o)\n", p ); 631: 632: t = pstk->in_t; /* type required */ 633: d = pstk->in_d; 634: s = pstk->in_s; 635: if( pstk->in_sz < 0 ){ /* bit field */ 636: sz = -pstk->in_sz; 637: } 638: else { 639: sz = tsize( t, d, s ); 640: } 641: 642: inforce( pstk->in_off ); 643: 644: p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p ); 645: p->left->op = FREE; 646: p->left = p->right; 647: p->right = NIL; 648: p->left = optim( p->left ); 649: if( p->left->op == UNARY AND ){ 650: p->left->op = FREE; 651: p->left = p->left->left; 652: } 653: p->op = INIT; 654: 655: if( sz < SZINT ){ /* special case: bit fields, etc. */ 656: if( p->left->op != ICON ) uerror( "illegal initialization" ); 657: else incode( p->left, sz ); 658: } 659: else if( p->left->op == FCON ){ 660: fincode( p->left->dval, sz ); 661: } 662: else { 663: cinit( optim(p), sz ); 664: } 665: 666: gotscal(); 667: 668: leave: 669: tfree(p); 670: } 671: 672: gotscal(){ 673: register t, ix; 674: register n, id; 675: struct symtab *p; 676: OFFSZ temp; 677: 678: for( ; pstk > instack; ) { 679: 680: if( pstk->in_fl ) ++ibseen; 681: 682: --pstk; 683: 684: t = pstk->in_t; 685: 686: if( t == STRTY ){ 687: ix = ++pstk->in_x; 688: if( (id=dimtab[ix]) < 0 ) continue; 689: 690: /* otherwise, put next element on the stack */ 691: 692: p = &stab[id]; 693: instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off ); 694: return; 695: } 696: else if( ISARY(t) ){ 697: n = ++pstk->in_n; 698: if( n >= dimtab[pstk->in_d] && pstk > instack ) continue; 699: 700: /* put the new element onto the stack */ 701: 702: temp = pstk->in_sz; 703: instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s, 704: pstk->in_off+n*temp ); 705: return; 706: } 707: 708: } 709: 710: } 711: 712: ilbrace(){ /* process an initializer's left brace */ 713: register t; 714: struct instk *temp; 715: 716: temp = pstk; 717: 718: for( ; pstk > instack; --pstk ){ 719: 720: t = pstk->in_t; 721: if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */ 722: if( pstk->in_fl ){ /* already associated with a { */ 723: if( pstk->in_n ) uerror( "illegal {"); 724: continue; 725: } 726: 727: /* we have one ... */ 728: pstk->in_fl = 1; 729: break; 730: } 731: 732: /* cannot find one */ 733: /* ignore such right braces */ 734: 735: pstk = temp; 736: } 737: 738: irbrace(){ 739: /* called when a '}' is seen */ 740: 741: if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno ); 742: 743: if( ibseen ) { 744: --ibseen; 745: return; 746: } 747: 748: for( ; pstk > instack; --pstk ){ 749: if( !pstk->in_fl ) continue; 750: 751: /* we have one now */ 752: 753: pstk->in_fl = 0; /* cancel { */ 754: gotscal(); /* take it away... */ 755: return; 756: } 757: 758: /* these right braces match ignored left braces: throw out */ 759: 760: } 761: 762: upoff( size, alignment, poff ) register alignment, *poff; { 763: /* update the offset pointed to by poff; return the 764: /* offset of a value of size `size', alignment `alignment', 765: /* given that off is increasing */ 766: 767: register off; 768: 769: off = *poff; 770: SETOFF( off, alignment ); 771: *poff = off+size; 772: return( off ); 773: } 774: 775: oalloc( p, poff ) register struct symtab *p; register *poff; { 776: /* allocate p with offset *poff, and update *poff */ 777: register al, off, tsz; 778: int noff; 779: 780: al = talign( p->stype, p->sizoff ); 781: noff = off = *poff; 782: tsz = tsize( p->stype, p->dimoff, p->sizoff ); 783: #ifdef BACKAUTO 784: if( p->sclass == AUTO ){ 785: noff = off + tsz; 786: SETOFF( noff, al ); 787: off = -noff; 788: } 789: else 790: #endif 791: if( p->sclass == PARAM && (p->stype==CHAR||p->stype==UCHAR||p->stype==SHORT|| 792: p->stype==USHORT) ){ 793: off = upoff( SZINT, ALINT, &noff ); 794: # ifndef RTOLBYTES 795: off = noff - tsz; 796: #endif 797: } 798: else 799: { 800: off = upoff( tsz, al, &noff ); 801: } 802: 803: if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */ 804: if( p->offset == NOOFFSET ) p->offset = off; 805: else if( off != p->offset ) return(1); 806: } 807: 808: *poff = noff; 809: return(0); 810: } 811: 812: falloc( p, w, new, pty ) register struct symtab *p; NODE *pty; { 813: /* allocate a field of width w */ 814: /* new is 0 if new entry, 1 if redefinition, -1 if alignment */ 815: 816: register al,sz,type; 817: 818: type = (new<0)? pty->type : p->stype; 819: 820: /* this must be fixed to use the current type in alignments */ 821: switch( new<0?pty->type:p->stype ){ 822: 823: case ENUMTY: 824: { 825: int s; 826: s = new<0 ? pty->csiz : p->sizoff; 827: al = dimtab[s+2]; 828: sz = dimtab[s]; 829: break; 830: } 831: 832: case CHAR: 833: case UCHAR: 834: al = ALCHAR; 835: sz = SZCHAR; 836: break; 837: 838: case SHORT: 839: case USHORT: 840: al = ALSHORT; 841: sz = SZSHORT; 842: break; 843: 844: case INT: 845: case UNSIGNED: 846: al = ALINT; 847: sz = SZINT; 848: break; 849: #ifdef LONGFIELDS 850: 851: case LONG: 852: case ULONG: 853: al = ALLONG; 854: sz = SZLONG; 855: break; 856: #endif 857: 858: default: 859: if( new < 0 ) { 860: uerror( "illegal field type" ); 861: al = ALINT; 862: } 863: else { 864: al = fldal( p->stype ); 865: sz =SZINT; 866: } 867: } 868: 869: if( w > sz ) { 870: uerror( "field too big"); 871: w = sz; 872: } 873: 874: if( w == 0 ){ /* align only */ 875: SETOFF( strucoff, al ); 876: if( new >= 0 ) uerror( "zero size field"); 877: return(0); 878: } 879: 880: if( strucoff%al + w > sz ) SETOFF( strucoff, al ); 881: if( new < 0 ) { 882: strucoff += w; /* we know it will fit */ 883: return(0); 884: } 885: 886: /* establish the field */ 887: 888: if( new == 1 ) { /* previous definition */ 889: if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1); 890: } 891: p->offset = strucoff; 892: strucoff += w; 893: p->stype = type; 894: fldty( p ); 895: return(0); 896: } 897: 898: nidcl( p ) NODE *p; { /* handle unitialized declarations */ 899: /* assumed to be not functions */ 900: register class; 901: register commflag; /* flag for labelled common declarations */ 902: 903: commflag = 0; 904: 905: /* compute class */ 906: if( (class=curclass) == SNULL ){ 907: if( blevel > 1 ) class = AUTO; 908: else if( blevel != 0 || instruct ) cerror( "nidcl error" ); 909: else { /* blevel = 0 */ 910: class = noinit(); 911: if( class == EXTERN ) commflag = 1; 912: } 913: } 914: 915: defid( p, class ); 916: 917: if( class==EXTDEF || class==STATIC ){ 918: /* simulate initialization by 0 */ 919: beginit(p->rval); 920: endinit(); 921: } 922: if( commflag ) commdec( p->rval ); 923: } 924: 925: TWORD 926: types( t1, t2, t3 ) TWORD t1, t2, t3; { 927: /* return a basic type from basic types t1, t2, and t3 */ 928: 929: TWORD t[3], noun, adj, unsg; 930: register i; 931: 932: t[0] = t1; 933: t[1] = t2; 934: t[2] = t3; 935: 936: unsg = INT; /* INT or UNSIGNED */ 937: noun = UNDEF; /* INT, CHAR, or FLOAT */ 938: adj = INT; /* INT, LONG, or SHORT */ 939: 940: for( i=0; i<3; ++i ){ 941: switch( t[i] ){ 942: 943: default: 944: bad: 945: uerror( "illegal type combination" ); 946: return( INT ); 947: 948: case UNDEF: 949: continue; 950: 951: case UNSIGNED: 952: if( unsg != INT ) goto bad; 953: unsg = UNSIGNED; 954: continue; 955: 956: case LONG: 957: case SHORT: 958: if( adj != INT ) goto bad; 959: adj = t[i]; 960: continue; 961: 962: case INT: 963: case CHAR: 964: case FLOAT: 965: if( noun != UNDEF ) goto bad; 966: noun = t[i]; 967: continue; 968: } 969: } 970: 971: /* now, construct final type */ 972: if( noun == UNDEF ) noun = INT; 973: else if( noun == FLOAT ){ 974: if( unsg != INT || adj == SHORT ) goto bad; 975: return( adj==LONG ? DOUBLE : FLOAT ); 976: } 977: else if( noun == CHAR && adj != INT ) goto bad; 978: 979: /* now, noun is INT or CHAR */ 980: if( adj != INT ) noun = adj; 981: if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) ); 982: else return( noun ); 983: } 984: 985: NODE * 986: tymerge( typ, idp ) NODE *typ, *idp; { 987: /* merge type typ with identifier idp */ 988: 989: register unsigned t; 990: register i; 991: extern int eprint(); 992: 993: if( typ->op != TYPE ) cerror( "tymerge: arg 1" ); 994: if(idp == NIL ) return( NIL ); 995: 996: if( ddebug > 2 ) fwalk( idp, eprint, 0 ); 997: 998: idp->type = typ->type; 999: idp->cdim = curdim; 1000: tyreduce( idp ); 1001: idp->csiz = typ->csiz; 1002: 1003: for( t=typ->type, i=typ->cdim; t&TMASK; t = DECREF(t) ){ 1004: if( ISARY(t) ) dstash( dimtab[i++] ); 1005: } 1006: 1007: /* now idp is a single node: fix up type */ 1008: 1009: idp->type = ctype( idp->type ); 1010: 1011: if( (t = BTYPE(idp->type)) != STRTY && t != UNIONTY && t != ENUMTY ){ 1012: idp->csiz = t; /* in case ctype has rewritten things */ 1013: } 1014: 1015: return( idp ); 1016: } 1017: 1018: tyreduce( p ) register NODE *p; { 1019: 1020: /* build a type, and stash away dimensions, from a parse tree of the declaration */ 1021: /* the type is build top down, the dimensions bottom up */ 1022: register o, temp; 1023: register unsigned t; 1024: 1025: o = p->op; 1026: p->op = FREE; 1027: 1028: if( o == NAME ) return; 1029: 1030: t = INCREF( p->type ); 1031: if( o == UNARY CALL ) t += (FTN-PTR); 1032: else if( o == LB ){ 1033: t += (ARY-PTR); 1034: temp = p->right->lval; 1035: p->right->op = FREE; 1036: } 1037: 1038: p->left->type = t; 1039: tyreduce( p->left ); 1040: 1041: if( o == LB ) dstash( temp ); 1042: 1043: p->rval = p->left->rval; 1044: p->type = p->left->type; 1045: 1046: } 1047: 1048: fixtype( p, class ) register NODE *p; { 1049: register unsigned t, type; 1050: register mod1, mod2; 1051: /* fix up the types, and check for legality */ 1052: 1053: if( (type = p->type) == UNDEF ) return; 1054: if( mod2 = (type&TMASK) ){ 1055: t = DECREF(type); 1056: while( mod1=mod2, mod2 = (t&TMASK) ){ 1057: if( mod1 == ARY && mod2 == FTN ){ 1058: uerror( "array of functions is illegal" ); 1059: type = 0; 1060: } 1061: else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){ 1062: uerror( "function returns illegal type" ); 1063: type = 0; 1064: } 1065: t = DECREF(t); 1066: } 1067: } 1068: 1069: /* detect function arguments, watching out for structure declarations */ 1070: 1071: if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) class = PARAM; 1072: if( class == PARAM || ( class==REGISTER && blevel==1 ) ){ 1073: if( type == FLOAT ) type = DOUBLE; 1074: else if( ISARY(type) ){ 1075: ++p->cdim; 1076: type += (PTR-ARY); 1077: } 1078: else if( ISFTN(type) ) type = INCREF(type); 1079: 1080: } 1081: 1082: if( instruct && ISFTN(type) ){ 1083: uerror( "function illegal in structure or union" ); 1084: type = INCREF(type); 1085: } 1086: p->type = type; 1087: } 1088: 1089: uclass( class ) register class; { 1090: /* give undefined version of class */ 1091: if( class == SNULL ) return( EXTERN ); 1092: else if( class == STATIC ) return( USTATIC ); 1093: else if( class == FORTRAN ) return( UFORTRAN ); 1094: else return( class ); 1095: } 1096: 1097: fixclass( class, type ) TWORD type; { 1098: 1099: /* first, fix null class */ 1100: 1101: if( class == SNULL ){ 1102: if( instruct&INSTRUCT ) class = MOS; 1103: else if( instruct&INUNION ) class = MOU; 1104: else if( blevel == 0 ) class = EXTDEF; 1105: else if( blevel == 1 ) class = PARAM; 1106: else class = AUTO; 1107: 1108: } 1109: 1110: /* now, do general checking */ 1111: 1112: if( ISFTN( type ) ){ 1113: switch( class ) { 1114: default: 1115: uerror( "function has illegal storage class" ); 1116: case AUTO: 1117: class = EXTERN; 1118: case EXTERN: 1119: case EXTDEF: 1120: case FORTRAN: 1121: case TYPEDEF: 1122: case STATIC: 1123: case UFORTRAN: 1124: case USTATIC: 1125: ; 1126: } 1127: } 1128: 1129: if( class&FIELD ){ 1130: if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" ); 1131: return( class ); 1132: } 1133: 1134: switch( class ){ 1135: 1136: case MOU: 1137: if( !(instruct&INUNION) ) uerror( "illegal class" ); 1138: return( class ); 1139: 1140: case MOS: 1141: if( !(instruct&INSTRUCT) ) uerror( "illegal class" ); 1142: return( class ); 1143: 1144: case MOE: 1145: if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" ); 1146: return( class ); 1147: 1148: case REGISTER: 1149: if( blevel == 0 ) uerror( "illegal register declaration" ); 1150: else if( regvar >= MINRVAR && cisreg( type ) ) return( class ); 1151: if( blevel == 1 ) return( PARAM ); 1152: else return( AUTO ); 1153: 1154: case AUTO: 1155: case LABEL: 1156: case ULABEL: 1157: if( blevel < 2 ) uerror( "illegal class" ); 1158: return( class ); 1159: 1160: case PARAM: 1161: if( blevel != 1 ) uerror( "illegal class" ); 1162: return( class ); 1163: 1164: case UFORTRAN: 1165: case FORTRAN: 1166: # ifdef NOFORTRAN 1167: NOFORTRAN; /* a condition which can regulate the FORTRAN usage */ 1168: # endif 1169: if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" ); 1170: else { 1171: type = DECREF(type); 1172: if( ISFTN(type) || ISARY(type) || ISPTR(type) ) { 1173: uerror( "fortran function has wrong type" ); 1174: } 1175: } 1176: case STNAME: 1177: case UNAME: 1178: case ENAME: 1179: case EXTERN: 1180: case STATIC: 1181: case EXTDEF: 1182: case TYPEDEF: 1183: case USTATIC: 1184: return( class ); 1185: 1186: default: 1187: cerror( "illegal class: %d", class ); 1188: /* NOTREACHED */ 1189: 1190: } 1191: } 1192: 1193: lookup( name, s) char *name; { 1194: /* look up name: must agree with s w.r.t. SMOS and SHIDDEN */ 1195: 1196: register char *p, *q; 1197: int i, j, ii; 1198: register struct symtab *sp; 1199: 1200: /* compute initial hash index */ 1201: if( ddebug > 2 ){ 1202: printf( "lookup( %s, %d ), stwart=%d, instruct=%d\n", name, s, stwart, instruct ); 1203: } 1204: 1205: i = 0; 1206: for( p=name, j=0; *p != '\0'; ++p ){ 1207: i += *p; 1208: if( ++j >= NCHNAM ) break; 1209: } 1210: i = i%SYMTSZ; 1211: sp = &stab[ii=i]; 1212: 1213: for(;;){ /* look for name */ 1214: 1215: if( sp->stype == TNULL ){ /* empty slot */ 1216: p = sp->sname; 1217: sp->sflags = s; /* set SMOS if needed, turn off all others */ 1218: for( j=0; j<NCHNAM; ++j ) if( *p++ = *name ) ++name; 1219: sp->stype = UNDEF; 1220: sp->sclass = SNULL; 1221: return( i ); 1222: } 1223: if( (sp->sflags & (SMOS|SHIDDEN)) != s ) goto next; 1224: p = sp->sname; 1225: q = name; 1226: for( j=0; j<NCHNAM;++j ){ 1227: if( *p++ != *q ) goto next; 1228: if( !*q++ ) break; 1229: } 1230: return( i ); 1231: next: 1232: if( ++i >= SYMTSZ ){ 1233: i = 0; 1234: sp = stab; 1235: } 1236: else ++sp; 1237: if( i == ii ) cerror( "symbol table full" ); 1238: } 1239: } 1240: 1241: #ifndef checkst 1242: /* if not debugging, make checkst a macro */ 1243: checkst(lev){ 1244: register int s, i, j; 1245: register struct symtab *p, *q; 1246: 1247: for( i=0, p=stab; i<SYMTSZ; ++i, ++p ){ 1248: if( p->stype == TNULL ) continue; 1249: j = lookup( p->sname, p->sflags&SMOS ); 1250: if( j != i ){ 1251: q = &stab[j]; 1252: if( q->stype == UNDEF || 1253: q->slevel <= p->slevel ){ 1254: cerror( "check error: %.8s", q->sname ); 1255: } 1256: } 1257: else if( p->slevel > lev ) cerror( "%.8s check at level %d", p->sname, lev ); 1258: } 1259: } 1260: #endif 1261: 1262: struct symtab * 1263: relook(p) register struct symtab *p; { /* look up p again, and see where it lies */ 1264: 1265: register struct symtab *q; 1266: 1267: /* I'm not sure that this handles towers of several hidden definitions in all cases */ 1268: q = &stab[lookup( p->sname, p->sflags&(SMOS|SHIDDEN) )]; 1269: /* make relook always point to either p or an empty cell */ 1270: if( q->stype == UNDEF ){ 1271: q->stype = TNULL; 1272: return(q); 1273: } 1274: while( q != p ){ 1275: if( q->stype == TNULL ) break; 1276: if( ++q >= &stab[SYMTSZ] ) q=stab; 1277: } 1278: return(q); 1279: } 1280: 1281: clearst( lev ){ /* clear entries of internal scope from the symbol table */ 1282: register struct symtab *p, *q, *r; 1283: register int temp, rehash; 1284: 1285: temp = lineno; 1286: aobeg(); 1287: 1288: /* first, find an empty slot to prevent newly hashed entries from 1289: being slopped into... */ 1290: 1291: for( q=stab; q< &stab[SYMTSZ]; ++q ){ 1292: if( q->stype == TNULL )goto search; 1293: } 1294: 1295: cerror( "symbol table full"); 1296: 1297: search: 1298: p = q; 1299: 1300: for(;;){ 1301: if( p->stype == TNULL ) { 1302: rehash = 0; 1303: goto next; 1304: } 1305: lineno = p->suse; 1306: if( lineno < 0 ) lineno = - lineno; 1307: if( p->slevel>lev ){ /* must clobber */ 1308: if( p->stype == UNDEF || ( p->sclass == ULABEL && lev < 2 ) ){ 1309: lineno = temp; 1310: uerror( "%.8s undefined", p->sname ); 1311: } 1312: else aocode(p); 1313: if (ddebug) printf("removing %8s from stab[ %d], flags %o level %d\n", 1314: p->sname,p-stab,p->sflags,p->slevel); 1315: if( p->sflags & SHIDES ) unhide(p); 1316: p->stype = TNULL; 1317: rehash = 1; 1318: goto next; 1319: } 1320: if( rehash ){ 1321: if( (r=relook(p)) != p ){ 1322: movestab( r, p ); 1323: p->stype = TNULL; 1324: } 1325: } 1326: next: 1327: if( ++p >= &stab[SYMTSZ] ) p = stab; 1328: if( p == q ) break; 1329: } 1330: lineno = temp; 1331: aoend(); 1332: } 1333: 1334: movestab( p, q ) register struct symtab *p, *q; { 1335: int k; 1336: /* structure assignment: *p = *q; */ 1337: p->stype = q->stype; 1338: p->sclass = q->sclass; 1339: p->slevel = q->slevel; 1340: p->offset = q->offset; 1341: p->sflags = q->sflags; 1342: p->dimoff = q->dimoff; 1343: p->sizoff = q->sizoff; 1344: p->suse = q->suse; 1345: for( k=0; k<NCHNAM; ++k ){ 1346: p->sname[k] = q->sname[k]; 1347: } 1348: } 1349: 1350: hide( p ) register struct symtab *p; { 1351: register struct symtab *q; 1352: for( q=p+1; ; ++q ){ 1353: if( q >= &stab[SYMTSZ] ) q = stab; 1354: if( q == p ) cerror( "symbol table full" ); 1355: if( q->stype == TNULL ) break; 1356: } 1357: movestab( q, p ); 1358: p->sflags |= SHIDDEN; 1359: q->sflags = (p->sflags&SMOS) | SHIDES; 1360: if( hflag ) werror( "%.8s redefinition hides earlier one", p->sname ); 1361: if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab ); 1362: return( idname = q-stab ); 1363: } 1364: 1365: unhide( p ) register struct symtab *p; { 1366: register struct symtab *q; 1367: register s, j; 1368: 1369: s = p->sflags & SMOS; 1370: q = p; 1371: 1372: for(;;){ 1373: 1374: if( q == stab ) q = &stab[SYMTSZ-1]; 1375: else --q; 1376: 1377: if( q == p ) break; 1378: 1379: if( (q->sflags&SMOS) == s ){ 1380: for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break; 1381: if( j == NCHNAM ){ /* found the name */ 1382: q->sflags &= ~SHIDDEN; 1383: if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab); 1384: return; 1385: } 1386: } 1387: 1388: } 1389: cerror( "unhide fails" ); 1390: }