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