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