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