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