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