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