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