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