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

Defined functions

align defined in line 619; used 5 times
cpysymb defined in line 487; used 4 times
decl1 defined in line 270; used 4 times
declare defined in line 226; used 3 times
declist defined in line 17; used 3 times
decsyn defined in line 663; used 3 times
getkeywords defined in line 36; used 3 times
getype defined in line 508; used 3 times
goodreg defined in line 681; used 2 times
pushdecl defined in line 467; used 4 times
redec defined in line 672; used 6 times
strdec defined in line 138; used 3 times
typov defined in line 610; used 4 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1518
Valid CSS Valid XHTML 1.0 Strict