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