|
|
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.%d", fakestub, lineno, ++fakenum); ! 622: idn = lookup(hash(fakename), STAG); ! 623: } ! 624: psave( instruct ); ! 625: psave( curclass ); ! 626: psave( strucoff ); ! 627: strucoff = 0; ! 628: instruct = soru; ! 629: q = block( FREE, NIL, NIL, 0, 0, 0 ); ! 630: q->tn.rval = idn; ! 631: if( instruct==INSTRUCT ) ! 632: { ! 633: curclass = MOS; ! 634: q->in.type = STRTY; ! 635: defid( q, STNAME ); ! 636: } ! 637: else if( instruct == INUNION ) ! 638: { ! 639: curclass = MOU; ! 640: q->in.type = UNIONTY; ! 641: defid( q, UNAME ); ! 642: } ! 643: else ! 644: { ! 645: /* enum */ ! 646: curclass = MOE; ! 647: q->in.type = ENUMTY; ! 648: defid( q, ENAME ); ! 649: } ! 650: psave( idn = q->tn.rval ); ! 651: /* the "real" definition is where the members are seen */ ! 652: if( idn >= 0 ) stab[idn].suse = lineno; ! 653: return( paramno-4 ); ! 654: } ! 655: ! 656: # ifndef ENUMSIZE ! 657: # define ENUMSIZE(h,l) INT ! 658: # endif ! 659: ! 660: NODE * ! 661: dclstruct( oparam ) ! 662: register oparam; ! 663: { ! 664: register struct symtab *p; ! 665: register i, al, sa, j, sz, szindex; ! 666: register TWORD temp; ! 667: register high, low; ! 668: ! 669: /* paramstack contains: ! 670: ** paramstack[ oparam ] = previous instruct ! 671: ** paramstack[ oparam+1 ] = previous class ! 672: ** paramstk[ oparam+2 ] = previous strucoff ! 673: ** paramstk[ oparam+3 ] = structure name ! 674: ** ! 675: ** paramstk[ oparam+4, ... ] = member stab indices ! 676: ** ! 677: */ ! 678: ! 679: ! 680: if( (i=paramstk[oparam+3]) < 0 ) ! 681: { ! 682: szindex = curdim; ! 683: dstash( 0 ); /* size */ ! 684: dstash( -1 ); /* index to member names */ ! 685: dstash( ALSTRUCT ); /* alignment */ ! 686: dstash( -lineno ); /* name of structure */ ! 687: } ! 688: else ! 689: { ! 690: szindex = stab[i].sizoff; ! 691: } ! 692: ! 693: ! 694: # ifndef NODBG ! 695: if( ddebug ) ! 696: { ! 697: printf( "dclstruct( %szindex = %d\n", ! 698: (i>=0)? stab[i].sname : "??", szindex ); ! 699: } ! 700: # endif ! 701: temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY); ! 702: stwart = instruct = paramstk[ oparam ]; ! 703: curclass = paramstk[ oparam+1 ]; ! 704: dimtab[ szindex+1 ] = curdim; ! 705: al = ALSTRUCT; ! 706: ! 707: high = low = 0; ! 708: ! 709: for( i = oparam+4; i< paramno; ++i ) ! 710: { ! 711: dstash( j=paramstk[i] ); ! 712: if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" ); ! 713: p = &stab[j]; ! 714: if( temp == ENUMTY ) ! 715: { ! 716: if( p->offset < low ) low = p->offset; ! 717: if( p->offset > high ) high = p->offset; ! 718: p->sizoff = szindex; ! 719: continue; ! 720: } ! 721: sa = talign( p->stype, p->sizoff ); ! 722: if( p->sclass & FIELD ) ! 723: { ! 724: sz = p->sclass&FLDSIZ; ! 725: } ! 726: else ! 727: { ! 728: sz = tsize( p->stype, p->dimoff, p->sizoff ); ! 729: } ! 730: if( sz == 0 ) ! 731: { ! 732: werror( "structure member has size 0: %s", p->sname ); ! 733: } ! 734: if( sz > strucoff ) strucoff = sz; /* for use with unions */ ! 735: SETOFF( al, sa ); ! 736: /* al, the alignment, to the LCM of the members' alignments */ ! 737: } ! 738: dstash( -1 ); /* endmarker */ ! 739: SETOFF( strucoff, al ); ! 740: ! 741: if( temp == ENUMTY ) ! 742: { ! 743: register TWORD ty; ! 744: ! 745: ty = ENUMSIZE(high,low); ! 746: strucoff = tsize( ty, 0, (int)ty ); ! 747: dimtab[ szindex+2 ] = al = talign( ty, (int)ty ); ! 748: } ! 749: ! 750: if( strucoff == 0 ) uerror( "zero sized structure" ); ! 751: dimtab[ szindex ] = strucoff; ! 752: dimtab[ szindex+2 ] = al; ! 753: dimtab[ szindex+3 ] = paramstk[ oparam+3 ]; /* name index */ ! 754: ! 755: #ifdef FIXSTRUCT ! 756: FIXSTRUCT( szindex, oparam ); /* local hook for debugging */ ! 757: #endif ! 758: ! 759: # ifndef NODBG ! 760: if( ddebug>1 ) ! 761: { ! 762: printf( "\tdimtab[%d,%d,%d,%d] = %d,%d,%d,%d\n", ! 763: szindex,szindex+1,szindex+2,szindex+3, ! 764: dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2], ! 765: dimtab[szindex+3] ); ! 766: for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i ) ! 767: { ! 768: printf( "\tmember %s(%d)\n", stab[dimtab[i]].sname, dimtab[i] ); ! 769: } ! 770: } ! 771: # endif ! 772: ! 773: strucoff = paramstk[ oparam+2 ]; ! 774: paramno = oparam; ! 775: ! 776: return( mkty( temp, 0, szindex ) ); ! 777: } ! 778: ! 779: /* VARARGS */ ! 780: yyerror( s, a, b, c, d, e, f, g ) char *s; ! 781: ! 782: { ! 783: /* error printing routine in parser */ ! 784: uerror( s, a, b, c, d, e, f, g ); ! 785: ! 786: } ! 787: ! 788: yyaccpt() ! 789: { ! 790: ftnend(); ! 791: } ! 792: ! 793: ftnarg( idn ) ! 794: register idn; ! 795: { ! 796: register struct symtab *p; ! 797: p = &stab[idn]; ! 798: switch( p->stype ) ! 799: { ! 800: ! 801: case UNDEF: ! 802: /* this parameter, entered at scan */ ! 803: break; ! 804: case FARG: ! 805: uerror("redeclaration of formal parameter, %s",p->sname); ! 806: /* fall thru */ ! 807: case FTN: ! 808: /* the name of this function matches parm */ ! 809: /* fall thru */ ! 810: default: ! 811: idn = hide(p); ! 812: p = &stab[idn]; ! 813: break; ! 814: case TNULL: ! 815: /* unused entry, fill it */ ! 816: ; ! 817: } ! 818: p->stype = FARG; ! 819: p->sclass = PARAM; ! 820: asave( idn ); ! 821: } ! 822: ! 823: talign( ty, s) ! 824: register unsigned ty; ! 825: register s; ! 826: { ! 827: /* compute the alignment of an object with type ty, sizeoff index s */ ! 828: ! 829: register i; ! 830: # ifdef FUNNYFLDS ! 831: if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT ! 832: #ifdef LONGFIELDS ! 833: && ty!=LONG && ty!=ULONG ! 834: #endif ! 835: ) ! 836: { ! 837: return( fldal( ty ) ); ! 838: } ! 839: # endif ! 840: ! 841: for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ) ! 842: { ! 843: switch( (ty>>i)&TMASK ) ! 844: { ! 845: ! 846: case FTN: ! 847: cerror( "compiler takes alignment of function"); ! 848: case PTR: ! 849: return( ALPOINT ); ! 850: case ARY: ! 851: continue; ! 852: case 0: ! 853: break; ! 854: } ! 855: } ! 856: ! 857: switch( BTYPE(ty) ) ! 858: { ! 859: ! 860: case UNIONTY: ! 861: case ENUMTY: ! 862: case STRTY: ! 863: return( dimtab[ s+2 ] ); ! 864: case CHAR: ! 865: case UCHAR: ! 866: return( ALCHAR ); ! 867: case FLOAT: ! 868: return( ALFLOAT ); ! 869: case DOUBLE: ! 870: return( ALDOUBLE ); ! 871: case LONG: ! 872: case ULONG: ! 873: return( ALLONG ); ! 874: case SHORT: ! 875: case USHORT: ! 876: return( ALSHORT ); ! 877: default: ! 878: return( ALINT ); ! 879: } ! 880: } ! 881: ! 882: OFFSZ ! 883: tsize( ty, d, s ) ! 884: register TWORD ty; ! 885: { ! 886: /* compute the size associated with type ty, ! 887: ** dimoff d, and sizoff s ! 888: */ ! 889: /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */ ! 890: ! 891: register i; ! 892: register OFFSZ mult; ! 893: ! 894: mult = 1; ! 895: ! 896: for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ) ! 897: { ! 898: switch( (ty>>i)&TMASK ) ! 899: { ! 900: ! 901: case FTN: ! 902: uerror("illegal use of function pointer"); ! 903: case PTR: ! 904: return( SZPOINT * mult ); ! 905: case ARY: ! 906: mult *= dimtab[ d++ ]; ! 907: continue; ! 908: case 0: ! 909: break; ! 910: ! 911: } ! 912: } ! 913: if(ty == ENUMTY) ! 914: return(SZINT); ! 915: if(ty == VOID) ! 916: uerror("using a void value"); ! 917: if( dimtab[s]==0 ) { ! 918: uerror( "unknown size"); ! 919: return( SZINT ); ! 920: } ! 921: return( dimtab[ s ] * mult ); ! 922: } ! 923: ! 924: inforce( n ) ! 925: register OFFSZ n; ! 926: { ! 927: /* force inoff to have the value n */ ! 928: /* inoff is updated to have the value n */ ! 929: register OFFSZ wb; ! 930: register rest; ! 931: /* rest is used to do a lot of conversion to ints... */ ! 932: ! 933: if( inoff == n ) return; ! 934: if( inoff > n ) ! 935: { ! 936: uerror("too many initializers (%d>%d)", inoff, n); ! 937: inoff = n; ! 938: return; ! 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 (%d>%d)", ! 1202: n, d1); ! 1203: if( n==0 ) werror( "empty array declaration"); ! 1204: dimtab[d] = n; ! 1205: } ! 1206: ! 1207: else if( t == STRTY || t == UNIONTY ) ! 1208: { ! 1209: /* clearly not fields either */ ! 1210: inforce( tsize( t, d, s ) ); ! 1211: } ! 1212: else if( n > 1 ) uerror("%d initializers for a scalar", n); ! 1213: /* this will never be called with a field element... */ ! 1214: else inforce( tsize(t,d,s) ); ! 1215: ! 1216: paramno = 0; ! 1217: vfdalign( ALINIT ); ! 1218: inoff = 0; ! 1219: iclass = SNULL; ! 1220: ! 1221: } ! 1222: ! 1223: doinit( p ) ! 1224: register NODE *p; ! 1225: ! 1226: { ! 1227: ! 1228: /* take care of generating a value for the initializer p */ ! 1229: /* inoff has the current offset (last bit written) ! 1230: ** in the current word being generated ! 1231: */ ! 1232: ! 1233: register sz, d, s; ! 1234: register TWORD t; ! 1235: ! 1236: /* note: size of an individual initializer assumed to fit into an int */ ! 1237: ! 1238: if(nerrors) ! 1239: goto leave; ! 1240: if( iclass < 0 ) goto leave; ! 1241: if( iclass == EXTERN || iclass == UNAME ) ! 1242: { ! 1243: uerror( "cannot initialize extern or union" ); ! 1244: iclass = -1; ! 1245: goto leave; ! 1246: } ! 1247: ! 1248: if( iclass == AUTO || iclass == REGISTER ) ! 1249: { ! 1250: /* do the initialization and get out, without regard ! 1251: ** for filing out the variable with zeros, etc. ! 1252: */ ! 1253: bccode(); ! 1254: idname = pstk->in_id; ! 1255: p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p ); ! 1256: ecomp(p); ! 1257: return; ! 1258: } ! 1259: ! 1260: if( p == NIL ) return; /* throw away strings already made into lists */ ! 1261: ! 1262: if( ibseen ) ! 1263: { ! 1264: uerror( "} expected"); ! 1265: goto leave; ! 1266: } ! 1267: ! 1268: # ifndef NODBG ! 1269: if( idebug > 1 ) printf( "doinit(%o)\n", p ); ! 1270: # endif ! 1271: ! 1272: t = pstk->in_t; /* type required */ ! 1273: d = pstk->in_d; ! 1274: s = pstk->in_s; ! 1275: if( pstk->in_sz < 0 ) ! 1276: { ! 1277: /* bit field */ ! 1278: sz = -pstk->in_sz; ! 1279: } ! 1280: else ! 1281: { ! 1282: sz = tsize( t, d, s ); ! 1283: } ! 1284: ! 1285: inforce( pstk->in_off ); ! 1286: ! 1287: p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p ); ! 1288: p->in.left->in.op = FREE; ! 1289: p->in.left = p->in.right; ! 1290: p->in.right = NIL; ! 1291: p->in.left = optim( p->in.left ); ! 1292: if( p->in.left->in.op == UNARY AND ) ! 1293: { ! 1294: p->in.left->in.op = FREE; ! 1295: p->in.left = p->in.left->in.left; ! 1296: } ! 1297: p->in.op = INIT; ! 1298: p = optim(p); ! 1299: ! 1300: # ifndef NOFLOAT ! 1301: if( p->in.left->in.op == FCON ) ! 1302: { ! 1303: fincode( p->in.left->fpn.dval, sz ); ! 1304: } ! 1305: else ! 1306: # endif ! 1307: if( p->in.left->in.op != ICON ) ! 1308: { ! 1309: uerror( "initialization by non-constant" ); ! 1310: inoff += sz; ! 1311: } ! 1312: else ! 1313: { ! 1314: /* a constant is being used as initializer */ ! 1315: if( sz < SZINT ) ! 1316: { ! 1317: /* special case: bit fields, etc. */ ! 1318: incode( p->in.left, sz ); ! 1319: } ! 1320: else ! 1321: { ! 1322: # ifdef MYINIT ! 1323: MYINIT( optim(p), sz ); ! 1324: # else ! 1325: ecode( optim(p) ); ! 1326: inoff += sz; ! 1327: # endif ! 1328: } ! 1329: } ! 1330: ! 1331: gotscal(); ! 1332: ! 1333: leave: ! 1334: tfree(p); ! 1335: } ! 1336: ! 1337: gotscal() ! 1338: { ! 1339: register t, ix; ! 1340: register n, id; ! 1341: register struct symtab *p; ! 1342: register OFFSZ temp; ! 1343: ! 1344: for( ; pstk > instack; ) ! 1345: { ! 1346: ! 1347: if( pstk->in_fl ) ++ibseen; ! 1348: ! 1349: --pstk; ! 1350: ! 1351: t = pstk->in_t; ! 1352: ! 1353: if( t == STRTY ) ! 1354: { ! 1355: ix = ++pstk->in_x; ! 1356: if( (id=dimtab[ix]) < 0 ) continue; ! 1357: ! 1358: /* otherwise, put next element on the stack */ ! 1359: ! 1360: p = &stab[id]; ! 1361: instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off ); ! 1362: return; ! 1363: } ! 1364: else if( ISARY(t) ) ! 1365: { ! 1366: n = ++pstk->in_n; ! 1367: if( n >= dimtab[pstk->in_d] && pstk > instack ) continue; ! 1368: ! 1369: /* put the new element onto the stack */ ! 1370: ! 1371: temp = pstk->in_sz; ! 1372: instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s, ! 1373: pstk->in_off+n*temp ); ! 1374: return; ! 1375: } ! 1376: ! 1377: } ! 1378: ! 1379: } ! 1380: ! 1381: ilbrace() ! 1382: { ! 1383: /* process an initializer's left brace */ ! 1384: register t; ! 1385: register struct instk *temp; ! 1386: ! 1387: temp = pstk; ! 1388: ! 1389: for( ; pstk > instack; --pstk ) ! 1390: { ! 1391: ! 1392: t = pstk->in_t; ! 1393: if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */ ! 1394: if( pstk->in_fl ) ! 1395: { ! 1396: /* already associated with a { */ ! 1397: if( pstk->in_n ) uerror( "illegal {"); ! 1398: continue; ! 1399: } ! 1400: ! 1401: /* we have one ... */ ! 1402: pstk->in_fl = 1; ! 1403: break; ! 1404: } ! 1405: ! 1406: /* cannot find one */ ! 1407: /* ignore such right braces */ ! 1408: ! 1409: pstk = temp; ! 1410: } ! 1411: ! 1412: irbrace() ! 1413: { ! 1414: /* called when a '}' is seen */ ! 1415: ! 1416: # ifndef NODBG ! 1417: if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno ); ! 1418: # endif ! 1419: ! 1420: if( ibseen ) ! 1421: { ! 1422: --ibseen; ! 1423: return; ! 1424: } ! 1425: ! 1426: for( ; pstk > instack; --pstk ) ! 1427: { ! 1428: if( !pstk->in_fl ) continue; ! 1429: ! 1430: /* we have one now */ ! 1431: ! 1432: pstk->in_fl = 0; /* cancel { */ ! 1433: gotscal(); /* take it away... */ ! 1434: return; ! 1435: } ! 1436: ! 1437: /* these right braces match ignored left braces: throw out */ ! 1438: ! 1439: } ! 1440: ! 1441: upoff( size, alignment, poff ) ! 1442: register alignment, *poff; ! 1443: { ! 1444: /* update the offset pointed to by poff; return the ! 1445: ** offset of a value of size `size', alignment `alignment', ! 1446: ** given that off is increasing ! 1447: */ ! 1448: ! 1449: register off; ! 1450: ! 1451: off = *poff; ! 1452: SETOFF( off, alignment ); ! 1453: if( (maxoffset-off) < size ) ! 1454: { ! 1455: if( instruct!=INSTRUCT )cerror("local variables fill memory"); ! 1456: else cerror("structure larger than address space"); ! 1457: } ! 1458: *poff = off+size; ! 1459: return( off ); ! 1460: } ! 1461: ! 1462: oalloc( p, poff ) ! 1463: register struct symtab *p; ! 1464: register *poff; ! 1465: { ! 1466: /* allocate p with offset *poff, and update *poff */ ! 1467: register al, off, tsz; ! 1468: int noff; ! 1469: ! 1470: al = talign( p->stype, p->sizoff ); ! 1471: noff = off = *poff; ! 1472: tsz = tsize( p->stype, p->dimoff, p->sizoff ); ! 1473: #ifdef BACKAUTO ! 1474: if( p->sclass == AUTO ) ! 1475: { ! 1476: if( (maxoffset-off) < tsz ) cerror("local variables fill memory"); ! 1477: noff = off + tsz; ! 1478: SETOFF( noff, al ); ! 1479: off = -noff; ! 1480: } ! 1481: else ! 1482: #endif ! 1483: #ifdef BACKPARAM ! 1484: /* this is rather nonstandard, and may be buggy in some cases */ ! 1485: /* in particular, won't work with ARGSRET and ARGALLRET */ ! 1486: if( p->sclass == PARAM ) ! 1487: { ! 1488: if( (maxoffset-off) < tsz ) ! 1489: cerror("local variables fill memory"); ! 1490: /* if( tsz < SZINT ) */ ! 1491: { ! 1492: noff = off + SZINT; ! 1493: SETOFF( noff, ALINT ); ! 1494: off = -noff; ! 1495: # ifndef RTOLBYTES ! 1496: off += tsz; ! 1497: #endif ! 1498: } ! 1499: /* else ! 1500: /* { ! 1501: /* noff = off + tsz; ! 1502: /* SETOFF( noff, al ); ! 1503: /* off = -noff; ! 1504: /* } ! 1505: */ ! 1506: } ! 1507: else ! 1508: #endif ! 1509: if( p->sclass == PARAM && ( tsz % SZINT ) ) ! 1510: { /* pjw stuff here. caller and callee must agree ! 1511: that params are 4 byte aligned */ ! 1512: tsz = (tsz+SZINT-1)/SZINT; ! 1513: off = upoff(tsz*SZINT, ALSTACK, &noff ); ! 1514: # ifndef RTOLBYTES ! 1515: off = noff - tsz;????(see note above) ! 1516: #endif ! 1517: } ! 1518: else ! 1519: { ! 1520: off = upoff( tsz, al, &noff ); ! 1521: } ! 1522: ! 1523: if( p->sclass != REGISTER ) ! 1524: { ! 1525: /* in case we are allocating stack space for register arguments */ ! 1526: if( p->offset == NOOFFSET ) p->offset = off; ! 1527: else if( off != p->offset ) return(1); ! 1528: } ! 1529: ! 1530: *poff = noff; ! 1531: return(0); ! 1532: } ! 1533: ! 1534: falloc( p, w, new, pty ) ! 1535: register struct symtab *p; ! 1536: register NODE *pty; ! 1537: { ! 1538: /* allocate a field of width w */ ! 1539: /* new is 0 if new entry, 1 if redefinition, -1 if alignment */ ! 1540: ! 1541: register al,sz,type; ! 1542: ! 1543: type = (new<0)? pty->in.type : p->stype; ! 1544: ! 1545: /* this must be fixed to use the current type in alignments */ ! 1546: switch( new<0?pty->in.type:p->stype ) ! 1547: { ! 1548: ! 1549: case ENUMTY: ! 1550: { ! 1551: register s; ! 1552: s = new<0 ? pty->fn.csiz : p->sizoff; ! 1553: al = dimtab[s+2]; ! 1554: sz = dimtab[s]; ! 1555: break; ! 1556: } ! 1557: ! 1558: case CHAR: ! 1559: case UCHAR: ! 1560: al = ALCHAR; ! 1561: sz = SZCHAR; ! 1562: break; ! 1563: ! 1564: case SHORT: ! 1565: case USHORT: ! 1566: al = ALSHORT; ! 1567: sz = SZSHORT; ! 1568: break; ! 1569: ! 1570: case INT: ! 1571: case UNSIGNED: ! 1572: al = ALINT; ! 1573: sz = SZINT; ! 1574: break; ! 1575: #ifdef LONGFIELDS ! 1576: ! 1577: case LONG: ! 1578: case ULONG: ! 1579: al = ALLONG; ! 1580: sz = SZLONG; ! 1581: break; ! 1582: #endif ! 1583: ! 1584: default: ! 1585: # ifdef FUNNYFLDS ! 1586: if( new < 0 ) ! 1587: { ! 1588: # endif ! 1589: uerror( "illegal field type" ); ! 1590: al = ALINT; ! 1591: # ifdef FUNNYFLDS ! 1592: } ! 1593: else ! 1594: { ! 1595: al = fldal( p->stype ); ! 1596: sz =SZINT; ! 1597: } ! 1598: # endif ! 1599: } ! 1600: ! 1601: if( w > sz ) ! 1602: { ! 1603: uerror( "field too big (%d>%d)", w, sz); ! 1604: w = sz; ! 1605: } ! 1606: ! 1607: if( w == 0 ) ! 1608: { ! 1609: /* align only */ ! 1610: SETOFF( strucoff, al ); ! 1611: if( new >= 0 ) uerror( "zero size field"); ! 1612: return(0); ! 1613: } ! 1614: ! 1615: if( strucoff%al + w > sz ) SETOFF( strucoff, al ); ! 1616: if( new < 0 ) ! 1617: { ! 1618: if( (maxoffset-strucoff) < w ) ! 1619: cerror("structure fills memory"); ! 1620: strucoff += w; /* we know it will fit */ ! 1621: return(0); ! 1622: } ! 1623: ! 1624: /* establish the field */ ! 1625: ! 1626: if( new == 1 ) ! 1627: { ! 1628: /* previous definition */ ! 1629: if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1); ! 1630: } ! 1631: p->offset = strucoff; ! 1632: if( (maxoffset-strucoff) < w ) cerror("structure overflows memory"); ! 1633: strucoff += w; ! 1634: p->stype = type; ! 1635: return(0); ! 1636: } ! 1637: ! 1638: # ifndef EXCLASS ! 1639: # define EXCLASS EXTERN ! 1640: # endif ! 1641: ! 1642: nidcl( p ) ! 1643: register NODE *p; ! 1644: { ! 1645: /* handle unitialized declarations */ ! 1646: /* assumed to be not functions */ ! 1647: register class; ! 1648: register commflag; /* flag for labelled common declarations */ ! 1649: ! 1650: commflag = 0; ! 1651: ! 1652: /* compute class */ ! 1653: if( (class=curclass) == SNULL ) ! 1654: { ! 1655: if( blevel > 1 ) class = AUTO; ! 1656: else if( blevel != 0 || instruct ) cerror( "nidcl error" ); ! 1657: else ! 1658: { ! 1659: /* blevel = 0 */ ! 1660: if( (class = EXCLASS) == EXTERN ) commflag = 1; ! 1661: } ! 1662: } ! 1663: ! 1664: defid( p, class ); ! 1665: ! 1666: if( class==EXTDEF || class==STATIC ) ! 1667: { ! 1668: ! 1669: # ifndef ALLCOMM ! 1670: /* simulate initialization by 0 */ ! 1671: beginit( p->tn.rval ); ! 1672: endinit(); ! 1673: # else ! 1674: commflag = 1; ! 1675: # endif ! 1676: ! 1677: } ! 1678: if( commflag ) commdec( p->tn.rval ); ! 1679: } ! 1680: ! 1681: TWORD ! 1682: types( t1, t2, t3 ) ! 1683: register TWORD t1, t2, t3; ! 1684: { ! 1685: /* return a basic type from basic types t1, t2, and t3 */ ! 1686: ! 1687: TWORD t[3]; ! 1688: register TWORD noun, adj, unsg; ! 1689: register i; ! 1690: ! 1691: t[0] = t1; ! 1692: t[1] = t2; ! 1693: t[2] = t3; ! 1694: ! 1695: unsg = INT; /* INT or UNSIGNED */ ! 1696: noun = UNDEF; /* INT, CHAR, or FLOAT */ ! 1697: adj = INT; /* INT, LONG, or SHORT */ ! 1698: ! 1699: for( i=0; i<3; ++i ) ! 1700: { ! 1701: switch( t[i] ) ! 1702: { ! 1703: ! 1704: default: ! 1705: bad: ! 1706: uerror( "illegal type combination" ); ! 1707: return( INT ); ! 1708: ! 1709: case UNDEF: ! 1710: continue; ! 1711: ! 1712: case UNSIGNED: ! 1713: if( unsg != INT ) goto bad; ! 1714: unsg = UNSIGNED; ! 1715: continue; ! 1716: ! 1717: case LONG: ! 1718: case SHORT: ! 1719: if( adj != INT ) goto bad; ! 1720: adj = t[i]; ! 1721: continue; ! 1722: ! 1723: case INT: ! 1724: case CHAR: ! 1725: case FLOAT: ! 1726: if( noun != UNDEF ) goto bad; ! 1727: noun = t[i]; ! 1728: continue; ! 1729: } ! 1730: } ! 1731: ! 1732: /* now, construct final type */ ! 1733: if( noun == UNDEF ) noun = INT; ! 1734: else if( noun == FLOAT ) ! 1735: { ! 1736: if( unsg != INT || adj == SHORT ) goto bad; ! 1737: return( adj==LONG ? DOUBLE : FLOAT ); ! 1738: } ! 1739: else if( noun == CHAR && adj != INT ) goto bad; ! 1740: ! 1741: /* now, noun is INT or CHAR */ ! 1742: if( adj != INT ) noun = adj; ! 1743: if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) ); ! 1744: else return( noun ); ! 1745: } ! 1746: ! 1747: NODE * ! 1748: tymerge( typ, idp ) ! 1749: register NODE *typ, *idp; ! 1750: ! 1751: { ! 1752: /* merge type typ with identifier idp */ ! 1753: ! 1754: register unsigned t; ! 1755: register i; ! 1756: ! 1757: if( typ->in.op != TYPE ) cerror( "tymerge: arg 1" ); ! 1758: if(idp == NIL ) return( NIL ); ! 1759: ! 1760: # ifndef NODBG ! 1761: if( ddebug > 2 ) eprint(idp); ! 1762: # endif ! 1763: ! 1764: idp->in.type = typ->in.type; ! 1765: idp->fn.cdim = curdim; ! 1766: tyreduce( idp ); ! 1767: idp->fn.csiz = typ->fn.csiz; ! 1768: ! 1769: for( t=typ->in.type, i=typ->fn.cdim; t&TMASK; t = DECREF(t) ) ! 1770: { ! 1771: if( ISARY(t) ) dstash( dimtab[i++] ); ! 1772: } ! 1773: ! 1774: /* now idp is a single node: fix up type */ ! 1775: ! 1776: idp->in.type = ctype( idp->in.type ); ! 1777: ! 1778: if( (t = BTYPE(idp->in.type)) != STRTY && t != UNIONTY && t != ENUMTY ) ! 1779: { ! 1780: idp->fn.csiz = t; /* in case ctype has rewritten things */ ! 1781: } ! 1782: ! 1783: return( idp ); ! 1784: } ! 1785: ! 1786: tyreduce( p ) ! 1787: register NODE *p; ! 1788: ! 1789: { ! 1790: ! 1791: /* build a type, stash away dimensions, from a declaration parse tree */ ! 1792: /* the type is built top down, the dimensions bottom up */ ! 1793: ! 1794: register o, temp; ! 1795: register unsigned t; ! 1796: ! 1797: o = p->in.op; ! 1798: p->in.op = FREE; ! 1799: ! 1800: if( o == NAME ) return; ! 1801: ! 1802: t = INCREF( p->in.type ); ! 1803: if( o == UNARY CALL ) t += (FTN-PTR); ! 1804: else if( o == LB ) ! 1805: { ! 1806: t += (ARY-PTR); ! 1807: temp = p->in.right->tn.lval; ! 1808: p->in.right->in.op = FREE; ! 1809: } ! 1810: ! 1811: p->in.left->in.type = t; ! 1812: tyreduce( p->in.left ); ! 1813: ! 1814: if( o == LB ) dstash( temp ); ! 1815: ! 1816: p->tn.rval = p->in.left->tn.rval; ! 1817: p->in.type = p->in.left->in.type; ! 1818: ! 1819: } ! 1820: ! 1821: fixtype( p, class ) ! 1822: register NODE *p; ! 1823: register class; ! 1824: { ! 1825: register unsigned t, type; ! 1826: register mod1, mod2; ! 1827: /* fix up the types, and check for legality */ ! 1828: ! 1829: if( (type = p->in.type) == UNDEF ) return; ! 1830: if( mod2 = (type&TMASK) ) ! 1831: { ! 1832: t = DECREF(type); ! 1833: while( mod1=mod2, mod2 = (t&TMASK) ) ! 1834: { ! 1835: if( mod1 == ARY && mod2 == FTN ) ! 1836: { ! 1837: uerror( "array of functions is illegal" ); ! 1838: type = 0; ! 1839: } ! 1840: else if( mod1==FTN && ( mod2==ARY || mod2==FTN ) ) ! 1841: { ! 1842: uerror( "function returns array or function" ); ! 1843: type = 0; ! 1844: } ! 1845: t = DECREF(t); ! 1846: } ! 1847: } ! 1848: ! 1849: /* detect function arguments, watching out for structure declarations */ ! 1850: /* for example, beware of f(x) struct [ int a[10]; } *x; { ... } */ ! 1851: /* the danger is that "a" will be converted to a pointer */ ! 1852: ! 1853: if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) ! 1854: class = PARAM; ! 1855: if( class == PARAM || ( class==REGISTER && blevel==1 ) ) ! 1856: { ! 1857: if( type == FLOAT ) type = DOUBLE; ! 1858: else if( ISARY(type) ) ! 1859: { ! 1860: ++p->fn.cdim; ! 1861: type += (PTR-ARY); ! 1862: } ! 1863: else if( ISFTN(type) ) ! 1864: { ! 1865: werror( "a function is declared as an argument" ); ! 1866: type = INCREF(type); ! 1867: } ! 1868: } ! 1869: ! 1870: if( instruct && ISFTN(type) ) ! 1871: { ! 1872: uerror( "function illegal in structure or union" ); ! 1873: type = INCREF(type); ! 1874: } ! 1875: p->in.type = type; ! 1876: } ! 1877: ! 1878: # ifndef MYCTYPE ! 1879: TWORD ! 1880: ctype( t ) ! 1881: register TWORD t; ! 1882: { ! 1883: register TWORD bt; ! 1884: bt = BTYPE(t); ! 1885: ! 1886: # ifdef NOFLOAT ! 1887: if( bt==FLOAT || bt==DOUBLE ) cerror( "ctype:f" ); ! 1888: # endif ! 1889: ! 1890: # ifdef NOSHORT ! 1891: # ifdef NOUNSIGNED ! 1892: if( bt==SHORT || bt==USHORT ) MODTYPE(t,INT); ! 1893: # else ! 1894: if( bt==SHORT ) MODTYPE(t,INT); ! 1895: else if( bt==USHORT) MODTYPE(t,UNSIGNED); ! 1896: # endif ! 1897: # endif ! 1898: ! 1899: # ifdef NOLONG ! 1900: # ifdef NOUNSIGNED ! 1901: if( bt==LONG || bt==ULONG ) MODTYPE(t,INT); ! 1902: # else ! 1903: if( bt==LONG ) MODTYPE(t,INT); ! 1904: else if( bt==ULONG) MODTYPE(t,UNSIGNED); ! 1905: # endif ! 1906: # endif ! 1907: ! 1908: #if defined(M32B) && defined(IMPREGAL) ! 1909: radbl( t ); ! 1910: #endif ! 1911: return( t ); ! 1912: } ! 1913: # endif ! 1914: ! 1915: uclass( class ) ! 1916: register class; ! 1917: { ! 1918: /* give undefined version of class */ ! 1919: if( class == SNULL ) return( EXTERN ); ! 1920: else if( class == STATIC ) return( USTATIC ); ! 1921: else if( class == FORTRAN ) return( UFORTRAN ); ! 1922: else return( class ); ! 1923: } ! 1924: ! 1925: fixclass( class, type ) ! 1926: register TWORD type; ! 1927: register class; ! 1928: ! 1929: { ! 1930: ! 1931: /* first, fix null class */ ! 1932: ! 1933: if( class == SNULL ) ! 1934: { ! 1935: if( instruct&INSTRUCT ) class = MOS; ! 1936: else if( instruct&INUNION ) class = MOU; ! 1937: else if( blevel == 0 ) class = EXTDEF; ! 1938: else if( blevel == 1 ) class = PARAM; ! 1939: else class = AUTO; ! 1940: ! 1941: } ! 1942: ! 1943: /* now, do general checking */ ! 1944: if(blevel == 1 && (class == STATIC || class == EXTERN)) ! 1945: uerror("parameter declared with weird storage classs"); ! 1946: if( ISFTN( type ) ) ! 1947: { ! 1948: switch( class ) ! 1949: { ! 1950: default: ! 1951: uerror( "function has illegal storage class" ); ! 1952: case AUTO: ! 1953: class = EXTERN; ! 1954: case EXTERN: ! 1955: case EXTDEF: ! 1956: case FORTRAN: ! 1957: case TYPEDEF: ! 1958: case STATIC: ! 1959: case UFORTRAN: ! 1960: case USTATIC: ! 1961: ; ! 1962: } ! 1963: } ! 1964: ! 1965: if( class&FIELD ) ! 1966: { ! 1967: if( !(instruct&INSTRUCT) ) uerror( "field not in structure" ); ! 1968: return( class ); ! 1969: } ! 1970: ! 1971: switch( class ) ! 1972: { ! 1973: ! 1974: case MOU: ! 1975: if( !(instruct&INUNION) ) uerror( "illegal class" ); ! 1976: return( class ); ! 1977: ! 1978: case MOS: ! 1979: if( !(instruct&INSTRUCT) ) uerror( "illegal class" ); ! 1980: return( class ); ! 1981: ! 1982: case MOE: ! 1983: if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" ); ! 1984: return( class ); ! 1985: ! 1986: case REGISTER: ! 1987: if( blevel == 0 ) uerror( "register declaration outside a fncn" ); ! 1988: /* if cisreg returns 1, nextrvar has the reg. number */ ! 1989: else if( cisreg( type ) ) return( class ); ! 1990: if( blevel == 1 ) return( PARAM ); ! 1991: else return( AUTO ); ! 1992: ! 1993: case AUTO: ! 1994: case LABEL: ! 1995: case ULABEL: ! 1996: if( blevel < 2 ) uerror( "auto outside function" ); ! 1997: return( class ); ! 1998: ! 1999: case PARAM: ! 2000: if( blevel != 1 ) uerror( "illegal class" ); ! 2001: return( class ); ! 2002: ! 2003: case UFORTRAN: ! 2004: case FORTRAN: ! 2005: # ifdef NOFORTRAN ! 2006: NOFORTRAN; /* a condition which can regulate the FORTRAN usage */ ! 2007: # endif ! 2008: if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" ); ! 2009: else ! 2010: { ! 2011: type = DECREF(type); ! 2012: if( ISFTN(type) || ISARY(type) || ISPTR(type) ) ! 2013: { ! 2014: uerror( "fortran function has wrong type" ); ! 2015: } ! 2016: } ! 2017: case STNAME: ! 2018: case UNAME: ! 2019: case ENAME: ! 2020: case EXTERN: ! 2021: case STATIC: ! 2022: case EXTDEF: ! 2023: case TYPEDEF: ! 2024: case USTATIC: ! 2025: return( class ); ! 2026: ! 2027: default: ! 2028: cerror( "illegal class: %d", class ); ! 2029: /* NOTREACHED */ ! 2030: } ! 2031: } ! 2032: ! 2033: struct symtab * ! 2034: mknonuniq(idindex) ! 2035: register *idindex; ! 2036: { ! 2037: /* locate a symbol table entry for */ ! 2038: /* an occurrence of a nonunique structure member name */ ! 2039: /* or field */ ! 2040: register i; ! 2041: register struct symtab * sp; ! 2042: ! 2043: sp = & stab[ i= *idindex ]; /* position search at old entry */ ! 2044: while( sp->stype != TNULL ) ! 2045: { ! 2046: /* locate unused entry */ ! 2047: if( ++i >= SYMTSZ ) ! 2048: { ! 2049: /* wrap around symbol table */ ! 2050: i = 0; ! 2051: sp = stab; ! 2052: } ! 2053: else ++sp; ! 2054: if( i == *idindex ) cerror("Symbol table full"); ! 2055: } ! 2056: sp->sflags = SNONUNIQ | SMOS; ! 2057: sp->sname = stab[*idindex].sname; /* old entry name */ ! 2058: *idindex = i; ! 2059: # ifndef NODBG ! 2060: if( ddebug ) ! 2061: { ! 2062: printf( "\tnonunique entry for %s from %d to %d\n", ! 2063: sp->sname, *idindex, i ); ! 2064: } ! 2065: # endif ! 2066: return ( sp ); ! 2067: } ! 2068: ! 2069: #ifndef checkst ! 2070: /* if not debugging, make checkst a macro */ ! 2071: checkst(lev) ! 2072: { ! 2073: register int s, i, j; ! 2074: register struct symtab *p, *q; ! 2075: ! 2076: for( i=0, p=stab; i<SYMTSZ; ++i, ++p ) ! 2077: { ! 2078: if( p->stype == TNULL ) continue; ! 2079: j = lookup( p->sname, p->sflags&(SMOS|STAG) ); ! 2080: if( j != i ) ! 2081: { ! 2082: q = &stab[j]; ! 2083: if( q->stype == UNDEF || ! 2084: q->slevel <= p->slevel ) ! 2085: { ! 2086: cerror( "check error: %s", q->sname ); ! 2087: } ! 2088: } ! 2089: else if( p->slevel > lev ) cerror( "%s check at level %d", p->sname, lev ); ! 2090: } ! 2091: } ! 2092: #endif ! 2093: ! 2094: struct symtab * ! 2095: relook(p) ! 2096: register struct symtab *p; ! 2097: ! 2098: { ! 2099: /* look up p again, and see where it lies */ ! 2100: register struct symtab *q; ! 2101: ! 2102: /* I'm not sure that this handles towers of several hidden definitions in all cases */ ! 2103: q = &stab[lookup( p->sname, p->sflags&(STAG|SMOS|SHIDDEN) )]; ! 2104: /* make relook always point to either p or an empty cell */ ! 2105: if( q->stype == UNDEF ) ! 2106: { ! 2107: q->stype = TNULL; ! 2108: return(q); ! 2109: } ! 2110: while( q != p ) ! 2111: { ! 2112: if( q->stype == TNULL ) break; ! 2113: if( ++q >= &stab[SYMTSZ] ) q=stab; ! 2114: } ! 2115: return(q); ! 2116: } ! 2117: ! 2118: uplevel() ! 2119: { ! 2120: ++blevel; ! 2121: #ifdef GDEBUG ! 2122: dblbrac(); ! 2123: #endif ! 2124: } ! 2125: ! 2126: clearst( lev ) ! 2127: { ! 2128: /* clear entries of internal scope from the symbol table */ ! 2129: extern struct symtab *scopestack[]; ! 2130: register struct symtab *p, *q, *r; ! 2131: ! 2132: # ifdef GDEBUG ! 2133: /* do this first, so structure members don't get clobbered ! 2134: ** before they are printed out... ! 2135: */ ! 2136: aobeg(); ! 2137: p = scopestack[blevel]; ! 2138: while (p) ! 2139: { ! 2140: aocode(p); ! 2141: p = p->scopelink; ! 2142: } ! 2143: aoend(); ! 2144: if (lev != 1) /* param level */ ! 2145: dbrbrac(); ! 2146: # endif ! 2147: ! 2148: /* q is to collect enteries which properly belong to ! 2149: an outer scope */ ! 2150: q = (struct symtab *) NULL; ! 2151: /* first, find an empty slot to prevent newly hashed entries ! 2152: ** from being slopped into... ! 2153: */ ! 2154: ! 2155: p = scopestack[lev]; ! 2156: while (p) ! 2157: { ! 2158: # ifndef NODBG ! 2159: if (ddebug) ! 2160: printf("removing %s = stab[ %d], flags %o level %d\n", ! 2161: p->sname,p-stab,p->sflags,p->slevel); ! 2162: # endif ! 2163: /* if this is still undefined, complain */ ! 2164: if (p->stype == UNDEF || ! 2165: ( p->sclass == ULABEL && lev <=2) ) { ! 2166: uerror("%s undefined", p->sname); ! 2167: } ! 2168: if( p->sflags & SHIDES ) ! 2169: unhide(p); ! 2170: if( (r=relook(p)) != p ) ! 2171: *r = *p; ! 2172: if ( lev > p->slevel ) { ! 2173: /* collect outer scope entries first ! 2174: appearing in inner scope */ ! 2175: r = p; ! 2176: p = p->scopelink; ! 2177: r->scopelink = q; ! 2178: q = r; ! 2179: } else { ! 2180: p->stype = TNULL; ! 2181: p = p->scopelink; ! 2182: } ! 2183: } ! 2184: scopestack[lev] = (struct symtab *) NULL; ! 2185: /* move outer scope entries into holes, and up a level */ ! 2186: while( q ) ! 2187: { ! 2188: r = &stab[ lookup( q->sname, q->sflags ) ]; ! 2189: if ( r != q ) ! 2190: { ! 2191: *r = *q; ! 2192: q->stype = TNULL; ! 2193: } ! 2194: q = q->scopelink; ! 2195: r->scopelink = scopestack[ lev-1 ]; ! 2196: scopestack[ lev-1 ] = r; ! 2197: } ! 2198: } ! 2199: ! 2200: hide( p ) ! 2201: register struct symtab *p; ! 2202: { ! 2203: register struct symtab *q; ! 2204: for( q=p+1; ; ++q ) ! 2205: { ! 2206: if( q >= &stab[SYMTSZ] ) q = stab; ! 2207: if( q == p ) cerror( "symbol table full" ); ! 2208: if( q->stype == TNULL ) break; ! 2209: } ! 2210: *q = *p; ! 2211: p->sflags |= SHIDDEN; ! 2212: q->sflags = (p->sflags&(SMOS|STAG)) | SHIDES; ! 2213: if( hflag ) werror( "%s redefinition hides earlier one", p->sname ); ! 2214: # ifndef NODBG ! 2215: if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab ); ! 2216: # endif ! 2217: return( idname = q-stab ); ! 2218: } ! 2219: ! 2220: unhide( p ) ! 2221: register struct symtab *p; ! 2222: { ! 2223: register struct symtab *q; ! 2224: register s; ! 2225: ! 2226: s = p->sflags & (SMOS|STAG); ! 2227: q = p; ! 2228: ! 2229: for(;;) ! 2230: { ! 2231: ! 2232: if( q == stab ) q = &stab[SYMTSZ-1]; ! 2233: else --q; ! 2234: ! 2235: if( q == p ) break; ! 2236: ! 2237: if( (q->sflags&(SMOS|STAG)) == s ) ! 2238: { ! 2239: if ( p->sname == q->sname ) ! 2240: { ! 2241: /* found the name */ ! 2242: q->sflags &= ~SHIDDEN; ! 2243: # ifndef NODBG ! 2244: if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab); ! 2245: # endif ! 2246: return; ! 2247: } ! 2248: } ! 2249: ! 2250: } ! 2251: cerror( "unhide fails" ); ! 2252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.