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