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