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