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