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