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: }