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