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