1: #
   2: /*
   3:  * C compiler, phase 1
   4:  *
   5:  *
   6:  * Handles processing of declarations,
   7:  * except for top-level processing of
   8:  * externals.
   9:  */
  10: 
  11: #include "c0.h"
  12: 
  13: /*
  14:  * Process a sequence of declaration statements
  15:  */
  16: declist(sclass)
  17: {
  18:     register sc, offset;
  19:     struct hshtab typer;
  20: 
  21:     offset = 0;
  22:     sc = sclass;
  23:     while (getkeywords(&sclass, &typer)) {
  24:         offset = declare(sclass, &typer, offset);
  25:         sclass = sc;
  26:     }
  27:     return(offset+align(INT, offset, 0));
  28: }
  29: 
  30: /*
  31:  * Read the keywords introducing a declaration statement
  32:  * Store back the storage class, and fill in the type
  33:  * entry, which looks like a hash table entry.
  34:  */
  35: getkeywords(scptr, tptr)
  36: int *scptr;
  37: struct hshtab *tptr;
  38: {
  39:     register skw, tkw, longf;
  40:     int o, isadecl, ismos, unsignf;
  41: 
  42:     isadecl = 0;
  43:     longf = 0;
  44:     unsignf = 0;
  45:     tptr->htype = INT;
  46:     tptr->hstrp = NULL;
  47:     tptr->hsubsp = NULL;
  48:     tkw = -1;
  49:     skw = *scptr;
  50:     ismos = skw==MOS||skw==MOU;
  51:     for (;;) {
  52:         mosflg = ismos && isadecl;
  53:         o = symbol();
  54:         if (o==NAME && csym->hclass==TYPEDEF && tkw<0) {
  55:             tkw = csym->htype;
  56:             tptr->hsubsp = csym->hsubsp;
  57:             tptr->hstrp = csym->hstrp;
  58:             isadecl++;
  59:             continue;
  60:         }
  61:         switch (o==KEYW? cval: -1) {
  62:         case AUTO:
  63:         case STATIC:
  64:         case EXTERN:
  65:         case REG:
  66:         case TYPEDEF:
  67:             if (skw && skw!=cval) {
  68:                 if (skw==ARG && cval==REG)
  69:                     cval = AREG;
  70:                 else
  71:                     error("Conflict in storage class");
  72:             }
  73:             skw = cval;
  74:             break;
  75: 
  76:         case UNSIGN:
  77:             unsignf++;
  78:             break;
  79: 
  80:         case LONG:
  81:             longf++;
  82:             break;
  83: 
  84:         case ENUM:
  85:             strdec(ismos, cval);
  86:             cval = INT;
  87:             goto types;
  88: 
  89:         case UNION:
  90:         case STRUCT:
  91:             tptr->hstrp = strdec(ismos, cval);
  92:             cval = STRUCT;
  93:         case INT:
  94:         case CHAR:
  95:         case FLOAT:
  96:         case DOUBLE:
  97:         types:
  98:             if (tkw>=0)
  99:                 error("Type clash");
 100:             tkw = cval;
 101:             break;
 102: 
 103:         default:
 104:             peeksym = o;
 105:             if (isadecl==0)
 106:                 return(0);
 107:             if (tkw<0)
 108:                 tkw = INT;
 109:             if (skw==0)
 110:                 skw = blklev==0? DEFXTRN: AUTO;
 111:             if (unsignf) {
 112:                 if (tkw==INT)
 113:                     tkw = UNSIGN;
 114:                 else
 115:                     error("Misplaced 'unsigned'");
 116:             }
 117:             if (longf) {
 118:                 if (tkw==FLOAT)
 119:                     tkw = DOUBLE;
 120:                 else if (tkw==INT)
 121:                     tkw = LONG;
 122:                 else
 123:                     error("Misplaced 'long'");
 124:             }
 125:             *scptr = skw;
 126:             tptr->htype = tkw;
 127:             return(1);
 128:         }
 129:         isadecl++;
 130:     }
 131: }
 132: 
 133: /*
 134:  * Process a structure, union, or enum declaration; a subroutine
 135:  * of getkeywords.
 136:  */
 137: struct str *
 138: strdec(mosf, kind)
 139: {
 140:     register elsize, o;
 141:     register struct hshtab *ssym;
 142:     int savebits;
 143:     struct hshtab **savememlist;
 144:     int savenmems;
 145:     struct str *strp;
 146:     struct hshtab *ds;
 147:     struct hshtab *mems[NMEMS];
 148:     struct hshtab typer;
 149:     int tagkind;
 150: 
 151:     if (kind!=ENUM) {
 152:         tagkind = STRTAG;
 153:         mosflg = 1;
 154:     } else
 155:         tagkind = ENUMTAG;
 156:     ssym = 0;
 157:     if ((o=symbol())==NAME) {
 158:         ssym = csym;
 159:         mosflg = mosf;
 160:         o = symbol();
 161:         if (o==LBRACE && ssym->hblklev<blklev)
 162:             pushdecl(ssym);
 163:         if (ssym->hclass==0) {
 164:             ssym->hclass = tagkind;
 165:             ssym->strp = gblock(sizeof(*strp));
 166:             funcbase = curbase;
 167:             ssym->strp->ssize = 0;
 168:             ssym->strp->memlist = NULL;
 169:         }
 170:         if (ssym->hclass != tagkind)
 171:             redec();
 172:         strp = ssym->strp;
 173:     } else {
 174:         strp = gblock(sizeof(*strp));
 175:         funcbase = curbase;
 176:         strp->ssize = 0;
 177:         strp->memlist = NULL;
 178:     }
 179:     mosflg = 0;
 180:     if (o != LBRACE) {
 181:         if (ssym==0)
 182:             goto syntax;
 183:         if (ssym->hclass!=tagkind)
 184:             error("Bad structure/union/enum name");
 185:         peeksym = o;
 186:     } else {
 187:         ds = defsym;
 188:         mosflg = 0;
 189:         savebits = bitoffs;
 190:         savememlist = memlist;
 191:         savenmems = nmems;
 192:         memlist = mems;
 193:         nmems = 2;
 194:         bitoffs = 0;
 195:         if (kind==ENUM) {
 196:             typer.htype = INT;
 197:             typer.hstrp = strp;
 198:             declare(ENUM, &typer, 0);
 199:         } else
 200:             elsize = declist(kind==UNION?MOU:MOS);
 201:         bitoffs = savebits;
 202:         defsym = ds;
 203:         if (strp->ssize)
 204:             error("%.8s redeclared", ssym->name);
 205:         strp->ssize = elsize;
 206:         *memlist++ = NULL;
 207:         strp->memlist = gblock((memlist-mems)*sizeof(*memlist));
 208:         funcbase = curbase;
 209:         for (o=0; &mems[o] != memlist; o++)
 210:             strp->memlist[o] = mems[o];
 211:         memlist = savememlist;
 212:         nmems = savenmems;
 213:         if ((o = symbol()) != RBRACE)
 214:             goto syntax;
 215:     }
 216:     return(strp);
 217:    syntax:
 218:     decsyn(o);
 219:     return(0);
 220: }
 221: 
 222: /*
 223:  * Process a comma-separated list of declarators
 224:  */
 225: declare(askw, tptr, offset)
 226: struct hshtab *tptr;
 227: {
 228:     register int o;
 229:     register int skw, isunion;
 230: 
 231:     skw = askw;
 232:     isunion = 0;
 233:     if (skw==MOU) {
 234:         skw = MOS;
 235:         isunion++;
 236:         mosflg = 1;
 237:         if ((peeksym=symbol()) == SEMI) {
 238:             o = length(tptr);
 239:             if (o>offset)
 240:                 offset = o;
 241:         }
 242:     }
 243:     do {
 244:         if (skw==ENUM && (peeksym=symbol())==RBRACE) {
 245:             o = peeksym;
 246:             peeksym = -1;
 247:             break;
 248:         }
 249:         o = decl1(skw, tptr, isunion?0:offset, NULL);
 250:         if (isunion) {
 251:             o =+ align(CHAR, o, 0);
 252:             if (o>offset)
 253:                 offset = o;
 254:         } else
 255:             offset =+ o;
 256:     } while ((o=symbol()) == COMMA);
 257:     if (o==RBRACE) {
 258:         peeksym = o;
 259:         o = SEMI;
 260:     }
 261:     if (o!=SEMI && (o!=RPARN || skw!=ARG1))
 262:         decsyn(o);
 263:     return(offset);
 264: }
 265: 
 266: /*
 267:  * Process a single declarator
 268:  */
 269: decl1(askw, atptr, offset, absname)
 270: struct hshtab *atptr, *absname;
 271: {
 272:     int t1, chkoff, a, elsize;
 273:     register int skw;
 274:     int type;
 275:     register struct hshtab *dsym;
 276:     register struct hshtab *tptr;
 277:     struct tdim dim;
 278:     struct field *fldp;
 279:     int *dp;
 280:     int isinit;
 281: 
 282:     skw = askw;
 283:     tptr = atptr;
 284:     chkoff = 0;
 285:     mosflg = skw==MOS;
 286:     dim.rank = 0;
 287:     if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
 288:         return(0);
 289:     /*
 290: 	 * Filler field
 291: 	 */
 292:     if (peeksym==COLON && skw==MOS) {
 293:         peeksym = -1;
 294:         t1 = conexp();
 295:         elsize = align(tptr->htype, offset, t1);
 296:         bitoffs =+ t1;
 297:         return(elsize);
 298:     }
 299:     t1 = getype(&dim, absname);
 300:     if (t1 == -1)
 301:         return(0);
 302:     if (tptr->hsubsp) {
 303:         type = tptr->htype;
 304:         for (a=0; type&XTYPE;) {
 305:             if ((type&XTYPE)==ARRAY)
 306:                 dim.dimens[dim.rank++] = tptr->hsubsp[a++];
 307:             type =>> TYLEN;
 308:         }
 309:     }
 310:     type = tptr->htype & ~TYPE;
 311:     while (t1&XTYPE) {
 312:         if (type&BIGTYPE) {
 313:             typov();
 314:             type = t1 = 0;
 315:         }
 316:         type = type<<TYLEN | (t1 & XTYPE);
 317:         t1 =>> TYLEN;
 318:     }
 319:     type =| tptr->htype&TYPE;
 320:     if (absname)
 321:         defsym = absname;
 322:     dsym = defsym;
 323:     if (dsym->hblklev < blklev)
 324:         pushdecl(dsym);
 325:     if (dim.rank == 0)
 326:         dsym->subsp = NULL;
 327:     else {
 328:         dp = gblock(dim.rank*sizeof(dim.rank));
 329:         funcbase = curbase;
 330:         if (skw==EXTERN)
 331:             maxdecl = curbase;
 332:         for (a=0; a<dim.rank; a++) {
 333:             if ((t1 = dp[a] = dim.dimens[a])
 334:              && (dsym->htype&XTYPE) == ARRAY
 335:              && dsym->subsp[a] && t1!=dsym->subsp[a])
 336:                 redec();
 337:         }
 338:         dsym->subsp = dp;
 339:     }
 340:     if ((type&XTYPE) == FUNC) {
 341:         if (skw==AUTO)
 342:             skw = EXTERN;
 343:         if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
 344:             error("Bad func. storage class");
 345:     }
 346:     if (!(dsym->hclass==0
 347:        || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1)
 348:        || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type)))
 349:         if (skw==MOS && dsym->hclass==MOS && dsym->htype==type)
 350:             chkoff = 1;
 351:         else {
 352:             redec();
 353:             goto syntax;
 354:         }
 355:     if (dsym->hclass && (dsym->htype&TYPE)==STRUCT && (type&TYPE)==STRUCT)
 356:         if (dsym->hstrp != tptr->hstrp) {
 357:             error("Warning: structure redeclaration");
 358:             nerror--;
 359:         }
 360:     dsym->htype = type;
 361:     if (tptr->hstrp)
 362:         dsym->hstrp = tptr->hstrp;
 363:     if (skw==TYPEDEF) {
 364:         dsym->hclass = TYPEDEF;
 365:         return(0);
 366:     }
 367:     if (absname)
 368:         return(0);
 369:     if (skw==ARG1) {
 370:         if (paraml==0)
 371:             paraml = dsym;
 372:         else
 373:             parame->hoffset = dsym;
 374:         parame = dsym;
 375:         dsym->hclass = skw;
 376:         return(0);
 377:     }
 378:     elsize = 0;
 379:     if (skw==MOS) {
 380:         elsize = length(dsym);
 381:         if ((peeksym = symbol())==COLON) {
 382:             elsize = 0;
 383:             peeksym = -1;
 384:             t1 = conexp();
 385:             a = align(type, offset, t1);
 386:             if (dsym->hflag&FFIELD) {
 387:                 if (dsym->hstrp->bitoffs!=bitoffs
 388:                  || dsym->hstrp->flen!=t1)
 389:                     redec();
 390:             } else {
 391:                 dsym->hstrp = gblock(sizeof(*fldp));
 392:                 funcbase = curbase;
 393:             }
 394:             dsym->hflag =| FFIELD;
 395:             dsym->hstrp->bitoffs = bitoffs;
 396:             dsym->hstrp->flen = t1;
 397:             bitoffs =+ t1;
 398:         } else
 399:             a = align(type, offset, 0);
 400:         elsize =+ a;
 401:         offset =+ a;
 402:         if (++nmems >= NMEMS) {
 403:             error("Too many structure members");
 404:             nmems =- NMEMS/2;
 405:             memlist =- NMEMS/2;
 406:         }
 407:         if (a)
 408:             *memlist++ = &structhole;
 409:         if (chkoff && dsym->hoffset != offset)
 410:             redec();
 411:         dsym->hoffset = offset;
 412:         *memlist++ = dsym;
 413:     }
 414:     if (skw==REG)
 415:         if ((dsym->hoffset = goodreg(dsym)) < 0)
 416:             skw = AUTO;
 417:     dsym->hclass = skw;
 418:     isinit = 0;
 419:     if ((a=symbol())!=COMMA && a!=SEMI && a!=RBRACE)
 420:         isinit++;
 421:     if (a!=ASSIGN)
 422:         peeksym = a;
 423:     if (skw==AUTO) {
 424:     /*	if (STAUTO < 0) {	*/
 425:             autolen =- rlength(dsym);
 426:             dsym->hoffset = autolen;
 427:             if (autolen < maxauto)
 428:                 maxauto = autolen;
 429:     /*	} else { 			*/
 430:     /*		dsym->hoffset = autolen;	*/
 431:     /*		autolen =+ rlength(dsym);	*/
 432:     /*		if (autolen > maxauto)		*/
 433:     /*			maxauto = autolen;	*/
 434:     /*	}			*/
 435:         if (isinit)
 436:             cinit(dsym, 0, AUTO);
 437:     } else if (skw==STATIC) {
 438:         dsym->hoffset = isn;
 439:         if (isinit) {
 440:             outcode("BBN", DATA, LABEL, isn++);
 441:             if (cinit(dsym, 1, STATIC) & ALIGN)
 442:                 outcode("B", EVEN);
 443:         } else
 444:             outcode("BBNBN", BSS, LABEL, isn++, SSPACE, rlength(dsym));
 445:         outcode("B", PROG);
 446:     } else if (skw==REG && isinit)
 447:         cinit(dsym, 0, REG);
 448:     else if (skw==ENUM) {
 449:         if (type!=INT)
 450:             error("Illegal enumeration %.8s", dsym->name);
 451:         dsym->hclass = ENUMCON;
 452:         dsym->hoffset = offset;
 453:         if (isinit)
 454:             cinit(dsym, 0, ENUMCON);
 455:         elsize = dsym->hoffset-offset+1;
 456:     }
 457:     prste(dsym);
 458: syntax:
 459:     return(elsize);
 460: }
 461: 
 462: /*
 463:  * Push down an outer-block declaration
 464:  * after redeclaration in an inner block.
 465:  */
 466: pushdecl(asp)
 467: struct phshtab *asp;
 468: {
 469:     register struct phshtab *sp, *nsp;
 470: 
 471:     sp = asp;
 472:     nsp = gblock(sizeof(*nsp));
 473:     maxdecl = funcbase = curbase;
 474:     cpysymb(nsp, sp);
 475:     sp->hclass = 0;
 476:     sp->hflag =& (FKEYW|FMOS);
 477:     sp->htype = 0;
 478:     sp->hoffset = 0;
 479:     sp->hblklev = blklev;
 480:     sp->hpdown = nsp;
 481: }
 482: 
 483: /*
 484:  * Copy the non-name part of a symbol
 485:  */
 486: cpysymb(s1, s2)
 487: struct phshtab *s1, *s2;
 488: {
 489:     register struct phshtab *rs1, *rs2;
 490: 
 491:     rs1 = s1;
 492:     rs2 = s2;
 493:     rs1->hclass = rs2->hclass;
 494:     rs1->hflag = rs2->hflag;
 495:     rs1->htype = rs2->htype;
 496:     rs1->hoffset = rs2->hoffset;
 497:     rs1->hsubsp = rs2->hsubsp;
 498:     rs1->hstrp = rs2->hstrp;
 499:     rs1->hblklev = rs2->hblklev;
 500:     rs1->hpdown = rs2->hpdown;
 501: }
 502: 
 503: 
 504: /*
 505:  * Read a declarator and get the implied type
 506:  */
 507: getype(adimp, absname)
 508: struct tdim *adimp;
 509: struct hshtab *absname;
 510: {
 511:     static struct hshtab argtype;
 512:     int type;
 513:     register int o;
 514:     register struct hshtab *ds;
 515:     register struct tdim *dimp;
 516: 
 517:     ds = defsym;
 518:     dimp = adimp;
 519:     type = 0;
 520:     switch(o=symbol()) {
 521: 
 522:     case TIMES:
 523:         type = getype(dimp, absname);
 524:         if (type==-1)
 525:             return(type);
 526:         if (type&BIGTYPE) {
 527:             typov();
 528:             type = 0;
 529:         }
 530:         return(type<<TYLEN | PTR);
 531: 
 532:     case LPARN:
 533:         if (absname==NULL || nextchar()!=')') {
 534:             type = getype(dimp, absname);
 535:             if (type==-1)
 536:                 return(type);
 537:             ds = defsym;
 538:             if ((o=symbol()) != RPARN)
 539:                 goto syntax;
 540:             goto getf;
 541:         }
 542: 
 543:     default:
 544:         peeksym = o;
 545:         if (absname) {
 546:             defsym = ds = absname;
 547:             absname = NULL;
 548:             goto getf;
 549:         }
 550:         break;
 551: 
 552:     case NAME:
 553:         defsym = ds = csym;
 554:     getf:
 555:         switch(o=symbol()) {
 556: 
 557:         case LPARN:
 558:             if (blklev==0) {
 559:                 blklev++;
 560:                 ds = defsym;
 561:                 declare(ARG1, &argtype, 0);
 562:                 defsym = ds;
 563:                 blklev--;
 564:             } else
 565:                 if ((o=symbol()) != RPARN)
 566:                     goto syntax;
 567:             if (type&BIGTYPE) {
 568:                 typov();
 569:                 type = 0;
 570:             }
 571:             type = type<<TYLEN | FUNC;
 572:             goto getf;
 573: 
 574:         case LBRACK:
 575:             if (dimp->rank>=5) {
 576:                 error("Rank too large");
 577:                 dimp->rank = 4;
 578:             }
 579:             if ((o=symbol()) != RBRACK) {
 580:                 peeksym = o;
 581:                 cval = conexp();
 582:                 defsym = ds;
 583:                 if ((o=symbol())!=RBRACK)
 584:                     goto syntax;
 585:             } else {
 586:                 if (dimp->rank!=0)
 587:                     error("Null dimension");
 588:                 cval = 0;
 589:             }
 590:             dimp->dimens[dimp->rank++] = cval;
 591:             if (type&BIGTYPE) {
 592:                 typov();
 593:                 type = 0;
 594:             }
 595:             type = type<<TYLEN | ARRAY;
 596:             goto getf;
 597:         }
 598:         peeksym = o;
 599:         return(type);
 600:     }
 601: syntax:
 602:     decsyn(o);
 603:     return(-1);
 604: }
 605: 
 606: /*
 607:  * More bits required for type than allowed.
 608:  */
 609: typov()
 610: {
 611:     error("Type is too complicated");
 612: }
 613: 
 614: /*
 615:  * Enforce alignment restrictions in structures,
 616:  * including bit-field considerations.
 617:  */
 618: align(type, offset, aflen)
 619: {
 620:     register a, t, flen;
 621:     char *ftl;
 622: 
 623:     flen = aflen;
 624:     a = offset;
 625:     t = type;
 626:     ftl = "Field too long";
 627:     if (flen==0) {
 628:         a =+ (NBPC+bitoffs-1) / NBPC;
 629:         bitoffs = 0;
 630:     }
 631:     while ((t&XTYPE)==ARRAY)
 632:         t = decref(t);
 633:     if (t!=CHAR) {
 634:         a = (a+ALIGN) & ~ALIGN;
 635:         if (a>offset)
 636:             bitoffs = 0;
 637:     }
 638:     if (flen) {
 639:         if (type==INT || type==UNSIGN) {
 640:             if (flen > NBPW)
 641:                 error(ftl);
 642:             if (flen+bitoffs > NBPW) {
 643:                 bitoffs = 0;
 644:                 a =+ NCPW;
 645:             }
 646:         } else if (type==CHAR) {
 647:             if (flen > NBPC)
 648:                 error(ftl);
 649:             if (flen+bitoffs > NBPC) {
 650:                 bitoffs = 0;
 651:                 a =+ 1;
 652:             }
 653:         } else
 654:             error("Bad type for field");
 655:     }
 656:     return(a-offset);
 657: }
 658: 
 659: /*
 660:  * Complain about syntax error in declaration
 661:  */
 662: decsyn(o)
 663: {
 664:     error("Declaration syntax");
 665:     errflush(o);
 666: }
 667: 
 668: /*
 669:  * Complain about a redeclaration
 670:  */
 671: redec()
 672: {
 673:     error("%.8s redeclared", defsym->name);
 674: }
 675: 
 676: /*
 677:  * Determine if a variable is suitable for storage in
 678:  * a register; if so return the register number
 679:  */
 680: goodreg(hp)
 681: struct hshtab *hp;
 682: {
 683:     int type;
 684: 
 685:     type = hp->htype;
 686:     /*
 687: 	 * Special dispensation for unions
 688: 	 */
 689:     if (type==STRUCT && length(hp)<=SZINT)
 690:         type = INT;
 691:     if ((type!=INT && type!=CHAR && type!=UNSIGN && (type&XTYPE)==0)
 692:      || (type&XTYPE)>PTR || regvar<3)
 693:         return(-1);
 694:     return(--regvar);
 695: }

Defined functions

align defined in line 618; used 5 times
cpysymb defined in line 486; used 4 times
decl1 defined in line 269; used 4 times
declare defined in line 225; used 3 times
declist defined in line 16; used 3 times
decsyn defined in line 662; used 3 times
getkeywords defined in line 35; used 3 times
getype defined in line 507; used 3 times
goodreg defined in line 680; used 2 times
pushdecl defined in line 466; used 4 times
redec defined in line 671; used 6 times
strdec defined in line 137; used 3 times
typov defined in line 609; used 4 times
Last modified: 1979-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1325
Valid CSS Valid XHTML 1.0 Strict