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 "c0h.c" 12: 13: /* 14: * Process a sequence of declaration statements 15: */ 16: declist(sclass) 17: { 18: register sc, elsize, offset; 19: int type; 20: 21: offset = 0; 22: sc = sclass; 23: while ((elsize = getkeywords(&sclass, &type)) != -1) { 24: offset = declare(sclass, type, offset, elsize); 25: sclass = sc; 26: } 27: return(offset+align(INT, offset, 0)); 28: } 29: 30: /* 31: * Read the keywords introducing a declaration statement 32: */ 33: getkeywords(scptr, tptr) 34: int *scptr, *tptr; 35: { 36: register skw, tkw, longf; 37: int o, elsize, isadecl, ismos; 38: 39: isadecl = 0; 40: longf = 0; 41: tkw = -1; 42: skw = *scptr; 43: elsize = 0; 44: ismos = skw==MOS; 45: for (;;) { 46: mosflg = ismos; 47: switch ((o=symbol())==KEYW? cval: -1) { 48: 49: case AUTO: 50: case STATIC: 51: case EXTERN: 52: case REG: 53: if (skw && skw!=cval) 54: error("Conflict in storage class"); 55: skw = cval; 56: break; 57: 58: case LONG: 59: longf++; 60: break; 61: 62: case STRUCT: 63: o = STRUCT; 64: elsize = strdec(&o, ismos); 65: cval = o; 66: case INT: 67: case CHAR: 68: case FLOAT: 69: case DOUBLE: 70: if (tkw>=0) 71: error("Type clash"); 72: tkw = cval; 73: break; 74: 75: default: 76: peeksym = o; 77: if (isadecl==0) 78: return(-1); 79: if (tkw<0) 80: tkw = INT; 81: if (skw==0) 82: skw = AUTO; 83: if (longf) { 84: if (tkw==FLOAT) 85: tkw = DOUBLE; 86: else if (tkw==INT) 87: tkw = LONG; 88: else 89: error("Misplaced 'long'"); 90: } 91: *scptr = skw; 92: *tptr = tkw; 93: return(elsize); 94: } 95: isadecl++; 96: } 97: } 98: 99: /* 100: * Process a structure declaration; a subroutine 101: * of getkeywords. 102: */ 103: strdec(tkwp, mosf) 104: int *tkwp; 105: { 106: register elsize, o; 107: register struct hshtab *ssym; 108: int savebits; 109: struct hshtab *ds; 110: 111: mosflg = 1; 112: ssym = 0; 113: if ((o=symbol())==NAME) { 114: ssym = csym; 115: if (ssym->hclass==0) { 116: ssym->hclass = STRTAG; 117: ssym->lenp = dimp; 118: chkdim(); 119: dimtab[dimp++] = 0; 120: } 121: if (ssym->hclass != STRTAG) 122: redec(); 123: mosflg = mosf; 124: o = symbol(); 125: } 126: mosflg = 0; 127: if (o != LBRACE) { 128: if (ssym==0) { 129: syntax: 130: decsyn(o); 131: return(0); 132: } 133: if (ssym->hclass!=STRTAG) 134: error("Bad structure name"); 135: if ((elsize = dimtab[ssym->lenp&0377])==0) { 136: *tkwp = RSTRUCT; 137: elsize = ssym; 138: } 139: peeksym = o; 140: } else { 141: ds = defsym; 142: mosflg = 0; 143: savebits = bitoffs; 144: bitoffs = 0; 145: elsize = declist(MOS); 146: bitoffs = savebits; 147: defsym = ds; 148: if ((o = symbol()) != RBRACE) 149: goto syntax; 150: if (ssym) { 151: if (dimtab[ssym->lenp&0377]) 152: error("%.8s redeclared", ssym->name); 153: dimtab[ssym->lenp&0377] = elsize; 154: } 155: } 156: return(elsize); 157: } 158: 159: /* 160: * Check that the dimension table has not overflowed 161: */ 162: chkdim() 163: { 164: if (dimp >= dimsiz) { 165: error("Dimension/struct table overflow"); 166: exit(1); 167: } 168: } 169: 170: /* 171: * Process a comma-separated list of declarators 172: */ 173: declare(askw, tkw, offset, elsize) 174: { 175: register int o; 176: register int skw; 177: 178: skw = askw; 179: do { 180: offset =+ decl1(skw, tkw, offset, elsize); 181: } while ((o=symbol()) == COMMA); 182: if (o==SEMI || o==RPARN && skw==ARG1) 183: return(offset); 184: decsyn(o); 185: } 186: 187: /* 188: * Process a single declarator 189: */ 190: decl1(askw, tkw, offset, elsize) 191: { 192: int t1, chkoff, a; 193: register int type, skw; 194: register struct hshtab *dsym; 195: 196: skw = askw; 197: chkoff = 0; 198: mosflg = skw==MOS; 199: if ((peeksym=symbol())==SEMI || peeksym==RPARN) 200: return(0); 201: /* 202: * Filler field 203: */ 204: if (peeksym==COLON && skw==MOS) { 205: peeksym = -1; 206: t1 = conexp(); 207: elsize = align(tkw, offset, t1); 208: bitoffs =+ t1; 209: return(elsize); 210: } 211: if ((t1=getype()) < 0) 212: goto syntax; 213: type = 0; 214: do 215: type = type<<TYLEN | (t1 & XTYPE); 216: while (((t1=>>TYLEN) & XTYPE)!=0); 217: type =| tkw; 218: dsym = defsym; 219: if (!(dsym->hclass==0 220: || (skw==ARG && dsym->hclass==ARG1) 221: || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type))) 222: if (skw==MOS && dsym->hclass==MOS && dsym->htype==type) 223: chkoff = 1; 224: else { 225: redec(); 226: goto syntax; 227: } 228: dsym->htype = type; 229: if (skw) 230: dsym->hclass = skw; 231: if (skw==ARG1) { 232: if (paraml==0) 233: paraml = dsym; 234: else 235: parame->hoffset = dsym; 236: parame = dsym; 237: } 238: if (elsize && ((type&TYPE)==RSTRUCT || (type&TYPE)==STRUCT)) { 239: dsym->lenp = dimp; 240: chkdim(); 241: dimtab[dimp++] = elsize; 242: } 243: elsize = 0; 244: if (skw==MOS) { 245: elsize = length(dsym); 246: t1 = 0; 247: if ((peeksym = symbol())==COLON) { 248: elsize = 0; 249: peeksym = -1; 250: t1 = conexp(); 251: dsym->hflag =| FFIELD; 252: } 253: a = align(type, offset, t1); 254: elsize =+ a; 255: offset =+ a; 256: if (t1) { 257: if (chkoff && (dsym->bitoffs!=bitoffs 258: || dsym->flen!=t1)) 259: redec(); 260: dsym->bitoffs = bitoffs; 261: dsym->flen = t1; 262: bitoffs =+ t1; 263: } 264: if (chkoff && dsym->hoffset != offset) 265: redec(); 266: dsym->hoffset = offset; 267: } 268: if ((dsym->htype&XTYPE)==FUNC) { 269: if (dsym->hclass!=EXTERN && dsym->hclass!=AUTO) 270: error("Bad function"); 271: dsym->hclass = EXTERN; 272: } 273: if (dsym->hclass==AUTO) { 274: autolen =+ rlength(dsym); 275: dsym->hoffset = -autolen; 276: } else if (dsym->hclass==STATIC) { 277: dsym->hoffset = isn; 278: outcode("BBNBNB", BSS, LABEL, isn++, 279: SSPACE, rlength(dsym), PROG); 280: } else if (dsym->hclass==REG) { 281: if ((type&TYPE)>CHAR && (type&XTYPE)==0 282: || (type&XTYPE)>PTR || regvar<3) 283: error("Bad register %o", type); 284: dsym->hoffset = --regvar; 285: } 286: syntax: 287: return(elsize); 288: } 289: 290: /* 291: * Read a declarator and get the implied type 292: */ 293: getype() 294: { 295: register int o, type; 296: register struct hshtab *ds; 297: 298: switch(o=symbol()) { 299: 300: case TIMES: 301: return(getype()<<TYLEN | PTR); 302: 303: case LPARN: 304: type = getype(); 305: if ((o=symbol()) != RPARN) 306: goto syntax; 307: goto getf; 308: 309: case NAME: 310: defsym = ds = csym; 311: type = 0; 312: ds->ssp = dimp; 313: getf: 314: switch(o=symbol()) { 315: 316: case LPARN: 317: if (xdflg) { 318: xdflg = 0; 319: ds = defsym; 320: declare(ARG1, 0, 0, 0); 321: defsym = ds; 322: xdflg++; 323: } else 324: if ((o=symbol()) != RPARN) 325: goto syntax; 326: type = type<<TYLEN | FUNC; 327: goto getf; 328: 329: case LBRACK: 330: chkdim(); 331: if ((o=symbol()) != RBRACK) { 332: peeksym = o; 333: cval = conexp(); 334: for (o=ds->ssp&0377; o<dimp; o++) 335: dimtab[o] =* cval; 336: dimtab[dimp++] = cval; 337: if ((o=symbol())!=RBRACK) 338: goto syntax; 339: } else 340: dimtab[dimp++] = 1; 341: type = type<<TYLEN | ARRAY; 342: goto getf; 343: } 344: peeksym = o; 345: return(type); 346: } 347: syntax: 348: decsyn(o); 349: return(-1); 350: } 351: 352: /* 353: * Enforce alignment restrictions in structures, 354: * including bit-field considerations. 355: */ 356: align(type, offset, aflen) 357: { 358: register a, t, flen; 359: char *ftl; 360: 361: flen = aflen; 362: a = offset; 363: t = type; 364: ftl = "Field too long"; 365: if (flen==0 && bitoffs) { 366: a =+ (bitoffs-1) / NBPC; 367: bitoffs = 0; 368: } 369: while ((t&XTYPE)==ARRAY) 370: t = decref(t); 371: if (t!=CHAR) { 372: a = (a+ALIGN) & ~ALIGN; 373: if (a>offset) 374: bitoffs = 0; 375: } 376: if (flen) { 377: if (type==INT) { 378: if (flen > NBPW) 379: error(ftl); 380: if (flen+bitoffs > NBPW) { 381: bitoffs = 0; 382: a =+ NCPW; 383: } 384: } else if (type==CHAR) { 385: if (flen > NBPC) 386: error(ftl); 387: if (flen+bitoffs > NCPW) { 388: bitoffs = 0; 389: a =+ 1; 390: } 391: } else 392: error("Bad type for field"); 393: } 394: return(a-offset); 395: } 396: 397: /* 398: * Complain about syntax error in declaration 399: */ 400: decsyn(o) 401: { 402: error("Declaration syntax"); 403: errflush(o); 404: } 405: 406: /* 407: * Complain about a redeclaration 408: */ 409: redec() 410: { 411: error("%.8s redeclared", defsym->name); 412: }