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