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