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

Defined functions

beginit defined in line 838; used 2 times
bstruct defined in line 504; used 4 times
checkst defined in line 1800; never used
clearst defined in line 1846; used 2 times
dclargs defined in line 430; used 1 times
dclstruct defined in line 535; used 3 times
defid defined in line 36; used 20 times
doinit defined in line 1038; used 2 times
endinit defined in line 983; used 3 times
falloc defined in line 1276; used 3 times
fixclass defined in line 1597; used 1 times
  • in line 70
fixtype defined in line 1543; used 1 times
  • in line 67
ftnarg defined in line 663; used 2 times
ftnend defined in line 405; used 3 times
getstr defined in line 941; used 2 times
gotscal defined in line 1129; used 3 times
hide defined in line 1915; used 2 times
ilbrace defined in line 1169; used 2 times
inforce defined in line 779; used 6 times
instk defined in line 877; used 3 times
irbrace defined in line 1195; used 2 times
lookup defined in line 1735; used 6 times
mknonuniq defined in line 1697; used 2 times
moedef defined in line 496; used 2 times
nidcl defined in line 1365; used 1 times
oalloc defined in line 1239; used 4 times
psave defined in line 398; used 11 times
putbyte defined in line 975; used 2 times
relook defined in line 1827; used 2 times
rstruct defined in line 464; used 3 times
talign defined in line 692; used 8 times
tsize defined in line 742; used 15 times
tymerge defined in line 1476; used 11 times
types defined in line 1416; used 4 times
tyreduce defined in line 1511; used 2 times
uclass defined in line 1589; used 1 times
unhide defined in line 1936; used 1 times
upoff defined in line 1222; used 2 times
vfdalign defined in line 819; used 3 times
yyaccpt defined in line 659; used 1 times
yyerror defined in line 653; never used

Defined variables

chaintop defined in line 10; used 5 times
ddebug defined in line 32; used 15 times
ibseen defined in line 830; used 5 times
iclass defined in line 834; used 18 times
idebug defined in line 828; used 5 times
ifull defined in line 832; used 4 times
ilocctr defined in line 836; used 3 times
instack defined in line 23; used 8 times
offsz defined in line 7; used 4 times
pstk defined in line 24; used 66 times
sccsid defined in line 2; never used
schain defined in line 9; used 4 times

Defined struct's

instk defined in line 12; used 2 times
Last modified: 1986-04-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5403
Valid CSS Valid XHTML 1.0 Strict