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