|
|
1.1 ! root 1: /* C compiler: declaration parsing */ ! 2: ! 3: #include "c.h" ! 4: ! 5: ! 6: Symbol cfunc = 0; /* current function */ ! 7: char *fname = 0; /* current function name */ ! 8: Symbol retv; /* return value location for structs */ ! 9: ! 10: static List autos; /* auto locals for current block */ ! 11: static int nglobals; /* number of external ids */ ! 12: static int regcount; /* number of explicit register declarations */ ! 13: static List registers; /* register locals for current block */ ! 14: ! 15: dclproto(static void checklab,(Symbol, Generic)); ! 16: dclproto(static void checkref,(Symbol, Generic)); ! 17: dclproto(static Symbol dclglobal,(int, char *, Type, Coordinate *)); ! 18: dclproto(static Symbol dcllocal,(int, char *, Type, Coordinate *)); ! 19: dclproto(static Symbol dclparam,(int, char *, Type, Coordinate *)); ! 20: dclproto(static void decl,(Symbol (*)(int, char *, Type, Coordinate *))); ! 21: dclproto(static void doglobal,(Symbol, Generic)); ! 22: dclproto(static void doextern,(Symbol, Generic)); ! 23: dclproto(static Type enumdecl,(void)); ! 24: dclproto(static void fields,(Type)); ! 25: dclproto(static Type structdcl,(int)); ! 26: dclproto(static Type tnode,(int, Type)); ! 27: dclproto(static Type type,(int, int *)); ! 28: dclproto(static Type dclr,(Type, char **, Symbol **)); ! 29: dclproto(static Type dclr1,(char **, Symbol **)); ! 30: dclproto(static void funcdecl,(int, char *, Type, Symbol [], Coordinate)); ! 31: dclproto(static void oldparam,(Symbol, Generic)); ! 32: dclproto(static Symbol *parameters,(Type)); ! 33: dclproto(static void exitparams,(Symbol [])); ! 34: /* checklab - check for undefined labels; called at ends of functions */ ! 35: static void checklab(p, cl) Symbol p; Generic cl; { ! 36: if (!p->defined) ! 37: error("undefined label `%s'\n", p->name); ! 38: p->defined = 1; ! 39: } ! 40: ! 41: /* checkref - check for unreferenced variables; called at ends of blocks */ ! 42: static void checkref(p, cl) Symbol p; Generic cl; { ! 43: Symbol q; ! 44: ! 45: if (p->scope >= PARAM && isvolatile(p->type)) ! 46: p->addressed = 1; ! 47: if (Aflag >= 2 && p->defined && p->ref == 0) { ! 48: if (p->sclass == STATIC) ! 49: warning("static `%t %s' is not referenced\n", p->type, p->name); ! 50: else if (p->scope == PARAM) ! 51: warning("parameter `%t %s' is not referenced\n", p->type, p->name); ! 52: else if (p->scope > PARAM && p->sclass != EXTERN) ! 53: warning("local `%t %s' is not referenced\n", p->type, p->name); ! 54: } else if (p->scope >= PARAM + (regcount > 0) && p->sclass == AUTO ! 55: && !p->addressed && isscalar(p->type) && p->ref >= 3.0) ! 56: p->sclass = REGISTER; ! 57: if (p->scope > PARAM && (q = lookup(p->name, externals))) { ! 58: q->ref += p->ref; ! 59: } else if (p->sclass == STATIC && !p->defined) ! 60: if (p->ref) ! 61: error("undefined static `%t %s'\n", p->type, p->name); ! 62: else if (isfunc(p->type)) ! 63: warning("undefined static `%t %s'\n", p->type, p->name); ! 64: } ! 65: ! 66: /* compound - { ( decl ; )* statement* } */ ! 67: void compound(loop, swp, lev) struct swtch *swp; { ! 68: Symbol p; ! 69: Code cp; ! 70: int i, j, nregs; ! 71: ! 72: walk(0, 0, 0); ! 73: cp = code(Blockbeg); ! 74: enterscope(); ! 75: cp->u.block.bnumber = ++bnumber; ! 76: cp->u.block.level = level; ! 77: autos = registers = 0; ! 78: if (level == LOCAL && isstruct(freturn(cfunc->type))) { ! 79: retv = genident(AUTO, ptr(freturn(cfunc->type)), level); ! 80: retv->defined = 1; ! 81: retv->ref = 1; ! 82: registers = append(retv, registers); /* insures that retv is the 1st local */ ! 83: } ! 84: if (level == LOCAL && events.entry) ! 85: apply(events.entry, (Generic)cfunc, (Generic)0); ! 86: expect('{'); ! 87: while (kind[t] == CHAR || kind[t] == STATIC ! 88: || t == ID && tsym && tsym->sclass == TYPEDEF && (level < LOCAL || getchr() != ':')) ! 89: decl(dcllocal); ! 90: nregs = length(registers); ! 91: cp->u.block.locals = (Symbol *)ltoa(registers, (Generic *)talloc((nregs + length(autos) + 1)*sizeof(Symbol))); ! 92: ltoa(autos, (Generic *)&cp->u.block.locals[nregs]); ! 93: while (kind[t] == IF || kind[t] == ID) ! 94: statement(loop, swp, lev); ! 95: walk(0, 0, 0); ! 96: foreach(identifiers, level, checkref, (Generic)0); ! 97: for (i = nregs; p = cp->u.block.locals[i]; i++) { ! 98: for (j = i; j > nregs && cp->u.block.locals[j-1]->ref < p->ref; j--) ! 99: cp->u.block.locals[j] = cp->u.block.locals[j-1]; ! 100: cp->u.block.locals[j] = p; ! 101: } ! 102: cp->u.block.identifiers = identifiers; ! 103: cp->u.block.types = types; ! 104: code(Blockend); ! 105: if (level > LOCAL) { ! 106: exitscope(); ! 107: expect('}'); ! 108: } ! 109: } ! 110: ! 111: /* dclglobal - called from decl to declare a global */ ! 112: static Symbol dclglobal(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; { ! 113: Symbol p, q; ! 114: ! 115: if (!(sclass == 0 || sclass == EXTERN || sclass == STATIC)) { ! 116: error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id); ! 117: sclass = 0; ! 118: } ! 119: if (sclass == 0) ! 120: sclass = AUTO; ! 121: if ((p = lookup(id, identifiers)) && p->scope == GLOBAL) { ! 122: if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1)) ! 123: ty = composite(ty, p->type); ! 124: else ! 125: error("redeclaration of `%s' previously declared at %w\n", ! 126: p->name, &p->src); ! 127: if (!isfunc(ty) && p->defined && t == '=') ! 128: error("redefinition of `%s' previously defined at %w\n", ! 129: p->name, &p->src); ! 130: if (p->sclass == STATIC && sclass == AUTO ! 131: || p->sclass != STATIC && sclass == STATIC) ! 132: warning("inconsistent linkage for `%s' previously declared at %w\n", ! 133: p->name, &p->src); ! 134: } ! 135: if (p == 0 || p->scope != GLOBAL) ! 136: p = install(id, &globals, 1); ! 137: p->type = ty; ! 138: if (p->sclass == 0 || sclass != EXTERN && p->sclass != STATIC) ! 139: p->sclass = sclass; ! 140: if (p->sclass != STATIC) { ! 141: nglobals++; ! 142: if (Aflag >= 2 && nglobals == 512) ! 143: warning("more than 511 external identifiers\n"); ! 144: } ! 145: p->src = *pos; ! 146: if (!p->defined) ! 147: (*IR->defsymbol)(p); ! 148: if (q = lookup(p->name, externals)) { ! 149: if ((p->sclass == AUTO ? EXTERN : p->sclass) != q->sclass ! 150: || !eqtype(p->type, q->type, 1)) ! 151: warning("declaration of `%s' does not match previous declaration at %w\n", ! 152: p->name, &q->src); ! 153: p->ref += q->ref; ! 154: } ! 155: if (!isfunc(p->type)) ! 156: initglobal(p, 0); ! 157: else if (t == '=') { ! 158: error("illegal initialization for `%s'\n", p->name); ! 159: t = gettok(); ! 160: initializer(p->type, 0); ! 161: } ! 162: return p; ! 163: } ! 164: ! 165: /* dcllocal - called from decl to declare a local */ ! 166: static Symbol dcllocal(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; { ! 167: Symbol p, q; ! 168: ! 169: if (isfunc(ty)) { ! 170: if (!(sclass == 0 || sclass == EXTERN)) ! 171: error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id); ! 172: sclass = EXTERN; ! 173: } else if (sclass == 0) ! 174: sclass = AUTO; ! 175: if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty) || isarray(ty))) { ! 176: warning("register declaration ignored for `%t %s'\n", ty, id); ! 177: sclass = AUTO; ! 178: } ! 179: if ((q = lookup(id, identifiers)) ! 180: && (q->scope >= level || q->scope == PARAM && level == PARAM+1)) ! 181: if (sclass == EXTERN && q->sclass == EXTERN && eqtype(q->type, ty, 1)) ! 182: ty = composite(ty, q->type); ! 183: else ! 184: error("redeclaration of `%s' previously declared at %w\n", ! 185: q->name, &q->src); ! 186: assert(level >= LOCAL); ! 187: p = install(id, &identifiers, 0); ! 188: p->type = ty; ! 189: p->sclass = sclass; ! 190: p->src = *pos; ! 191: switch (sclass) { ! 192: case EXTERN: { ! 193: Symbol r; ! 194: if (q && q->scope == GLOBAL && q->sclass == STATIC) { ! 195: p->sclass = STATIC; ! 196: p->scope = GLOBAL; ! 197: (*IR->defsymbol)(p); ! 198: p->scope = level; ! 199: } else ! 200: (*IR->defsymbol)(p); ! 201: if ((r = lookup(id, externals)) == 0) { ! 202: r = install(p->name, &externals, 1); ! 203: r->src = p->src; ! 204: r->type = p->type; ! 205: r->sclass = p->sclass; ! 206: if ((q = lookup(id, globals)) && q->sclass != TYPEDEF && q->sclass != ENUM) ! 207: r = q; ! 208: } ! 209: if (r && ((r->sclass == AUTO ? EXTERN : r->sclass) != p->sclass ! 210: || !eqtype(r->type, p->type, 1))) ! 211: warning("declaration of `%s' does not match previous declaration at %w\n", ! 212: r->name, &r->src); ! 213: break; ! 214: } ! 215: case STATIC: ! 216: (*IR->defsymbol)(p); ! 217: initglobal(p, 0); ! 218: if (!p->defined) ! 219: if (p->type->size > 0) { ! 220: defglobal(p, BSS); ! 221: (*IR->space)(p->type->size); ! 222: } else ! 223: error("undefined size for `%t %s'\n", p->type, p->name); ! 224: p->defined = 1; ! 225: break; ! 226: case REGISTER: ! 227: registers = append(p, registers); ! 228: regcount++; ! 229: p->defined = 1; ! 230: break; ! 231: case AUTO: ! 232: autos = append(p, autos); ! 233: p->defined = 1; ! 234: break; ! 235: default: assert(0); ! 236: } ! 237: if (t == '=') { ! 238: Tree e; ! 239: if (sclass == EXTERN) ! 240: error("illegal initialization of `extern %s'\n", id); ! 241: t = gettok(); ! 242: definept(0); ! 243: if (isscalar(p->type) || isstruct(p->type) && t != '{') { ! 244: if (t == '{') { ! 245: t = gettok(); ! 246: e = constexpr(0); ! 247: genconst(e, 0); ! 248: expect('}'); ! 249: } else ! 250: e = expr1(0); ! 251: } else { ! 252: Type ty = p->type; ! 253: if (!isconst(ty) && (!isarray(ty) || !isconst(ty->type))) ! 254: ty = qual(CONST, ty); ! 255: q = genident(STATIC, ty, GLOBAL); ! 256: initglobal(q, 1); ! 257: if (isarray(p->type) && p->type->size == 0 && q->type->size > 0) ! 258: p->type = array(p->type->type, q->type->size/q->type->type->size, 0); ! 259: e = idnode(q); ! 260: } ! 261: walk(root(asgn(p, e)), 0, 0); ! 262: p->ref = 1; ! 263: } ! 264: if (p->sclass == AUTO && isarray(p->type) && p->type->type->size > 0 ! 265: && p->type->align < IR->structmetric.align) ! 266: p->type = array(p->type->type, ! 267: p->type->size/p->type->type->size, IR->structmetric.align); ! 268: if (!isfunc(p->type) && p->defined && p->type->size <= 0) ! 269: error("undefined size for `%t %s'\n", p->type, id); ! 270: return p; ! 271: } ! 272: ! 273: /* dclparam - called from decl to declare a parameter */ ! 274: static Symbol dclparam(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; { ! 275: Symbol p; ! 276: ! 277: if ((p = lookup(id, identifiers)) && p->scope == level) ! 278: error("duplicate declaration for `%s' previously declared at %w\n", ! 279: id, &p->src); ! 280: else if (p == 0 || p->scope < level) ! 281: p = install(id, &identifiers, 0); ! 282: if (isfunc(ty)) ! 283: ty = ptr(ty); ! 284: else if (isarray(ty)) ! 285: ty = atop(ty); ! 286: if (!(sclass == 0 || sclass == AUTO || sclass == REGISTER)) { ! 287: error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id); ! 288: sclass = AUTO; ! 289: } ! 290: if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty))) { ! 291: warning("register declaration ignored for `%t%s\n", ty, ! 292: stringf(id ? " %s'" : "' parameter", id)); ! 293: sclass = AUTO; ! 294: } ! 295: if (sclass == 0) ! 296: sclass = AUTO; ! 297: p->sclass = sclass; ! 298: p->src = *pos; ! 299: p->type = ty; ! 300: p->defined = 1; ! 301: if (t == '=') { ! 302: error("illegal initialization for parameter `%s'\n", id); ! 303: t = gettok(); ! 304: expr1(0); ! 305: } ! 306: return p; ! 307: } ! 308: /* dclr - declarator */ ! 309: static Type dclr(basety, id, params) Type basety; char **id; Symbol **params; { ! 310: Type ty; ! 311: ! 312: for (ty = dclr1(id, params); ty; ty = ty->type) ! 313: switch (ty->op) { ! 314: case POINTER: ! 315: basety = ptr(basety); ! 316: break; ! 317: case FUNCTION: ! 318: basety = func(basety, ty->u.f.proto, ty->u.f.oldstyle); ! 319: break; ! 320: case ARRAY: ! 321: basety = array(basety, ty->size, 0); ! 322: break; ! 323: case CONST: case VOLATILE: ! 324: basety = qual(ty->op, basety); ! 325: break; ! 326: default: ! 327: assert(0); ! 328: } ! 329: if (Aflag >= 2 && basety->size > 32767) ! 330: warning("more than 32767 bytes in `%t'\n", basety); ! 331: return basety; ! 332: } ! 333: ! 334: /* dclr1 - ( id | * ( const | volatile )* | '(' dclr1 ')' ) ( (...) | [...] )* */ ! 335: static Type dclr1(id, params) char **id; Symbol **params; { ! 336: Type ty = 0; ! 337: ! 338: switch (t) { ! 339: case ID: ! 340: if (id) ! 341: *id = token; ! 342: else ! 343: error("extraneous identifier `%s'\n", token); ! 344: t = gettok(); ! 345: break; ! 346: case '*': ! 347: t = gettok(); ! 348: if (t == CONST || t == VOLATILE) { ! 349: Type ty1; ! 350: ty1 = ty = tnode(t, (Type)0); ! 351: while ((t = gettok()) == CONST || t == VOLATILE) ! 352: ty1 = tnode(t, ty1); ! 353: ty->type = dclr1(id, params); ! 354: ty = ty1; ! 355: } else ! 356: ty = dclr1(id, params); ! 357: ty = tnode(POINTER, ty); ! 358: break; ! 359: case '(': ! 360: t = gettok(); ! 361: if (kind[t] == CHAR || t == ID && tsym && tsym->sclass == TYPEDEF) { ! 362: Symbol *args; ! 363: ty = tnode(FUNCTION, ty); ! 364: enterscope(); ! 365: args = parameters(ty); ! 366: exitparams(args); ! 367: } else { ! 368: ty = dclr1(id, params); ! 369: expect(')'); ! 370: if (ty == 0 && id == 0) ! 371: return tnode(FUNCTION, ty); ! 372: } ! 373: break; ! 374: case '[': ! 375: break; ! 376: default: ! 377: return ty; ! 378: } ! 379: while (t == '(' || t == '[') ! 380: if (t == '(') { ! 381: Symbol *args; ! 382: t = gettok(); ! 383: ty = tnode(FUNCTION, ty); ! 384: enterscope(); ! 385: args = parameters(ty); ! 386: if (params && *params == 0) ! 387: *params = args; ! 388: else ! 389: exitparams(args); ! 390: } else { ! 391: int n = 0; ! 392: t = gettok(); ! 393: if (kind[t] == ID) { ! 394: n = intexpr(']', 1); ! 395: if (n <= 0) { ! 396: error("`%d' is an illegal array size\n", n); ! 397: n = 1; ! 398: } ! 399: } else ! 400: expect(']'); ! 401: ty = tnode(ARRAY, ty); ! 402: ty->size = n; ! 403: } ! 404: return ty; ! 405: } ! 406: ! 407: /* decl - type [ dclr ( , dclr )* ] ; */ ! 408: static void decl(dcl) ! 409: dclproto(Symbol (*dcl),(int, char *, Type, Coordinate *)); { ! 410: int sclass; ! 411: char *id = 0; ! 412: Type ty, ty1; ! 413: Coordinate pt; ! 414: static char follow[] = { CHAR, STATIC, ID, 0 }; ! 415: ! 416: pt = src; ! 417: ty = type(level, &sclass); ! 418: if (t == ID || t == '*' || t == '(' || t == '[') { ! 419: Coordinate pos; ! 420: pos = src; ! 421: if (level == GLOBAL) { ! 422: Symbol *params = 0; ! 423: ty1 = dclr(ty, &id, ¶ms); ! 424: if (params && id && isfunc(ty1) ! 425: && (t == '{' || kind[t] == CHAR ! 426: || (kind[t] == STATIC && t != TYPEDEF) ! 427: || t == ID && tsym && tsym->sclass == TYPEDEF)) { ! 428: if (sclass == TYPEDEF) { ! 429: error("invalid use of `typedef'\n"); ! 430: sclass = EXTERN; ! 431: } ! 432: if (ty1->u.f.oldstyle) ! 433: exitscope(); ! 434: funcdecl(sclass, fname = id, ty1, params, pt); ! 435: fname = 0; ! 436: return; ! 437: } else if (params) ! 438: exitparams(params); ! 439: } else ! 440: ty1 = dclr(ty, &id, (Symbol **)0); ! 441: for (;;) { ! 442: if (Aflag >= 1 && !hasproto(ty1)) ! 443: warning("missing prototype\n"); ! 444: if (id == 0) ! 445: error("missing identifier\n"); ! 446: else if (sclass == TYPEDEF) ! 447: deftype(id, ty1, &pos); ! 448: else ! 449: (*dcl)(sclass, id, ty1, &pos); ! 450: if (level == GLOBAL) ! 451: tfree(); ! 452: if (t != ',') ! 453: break; ! 454: t = gettok(); ! 455: id = 0; ! 456: pos = src; ! 457: ty1 = dclr(ty, &id, (Symbol **)0); ! 458: } ! 459: } else if (ty == 0 || !(isenum(ty) ! 460: || isstruct(ty) && (*ty->u.sym->name < '1' || *ty->u.sym->name > '9'))) ! 461: error("empty declaration\n"); ! 462: test(';', follow); ! 463: } ! 464: ! 465: /* doextern - import external declared in a block, if necessary, propagate flags */ ! 466: static void doextern(p, cl) Symbol p; Generic cl; { ! 467: Symbol q; ! 468: ! 469: if (q = lookup(p->name, identifiers)) ! 470: q->ref += p->ref; ! 471: else { ! 472: (*IR->defsymbol)(p); ! 473: (*IR->import)(p); ! 474: } ! 475: } ! 476: ! 477: /* doglobal - finalize tentative definitions, check for imported symbols */ ! 478: static void doglobal(p, cl) Symbol p; Generic cl; { ! 479: if (p->sclass == TYPEDEF || p->sclass == ENUM || p->defined) { ! 480: if (Pflag && !isfunc(p->type) && !p->generated) ! 481: printdecl(p, p->type); ! 482: return; ! 483: } ! 484: if (p->sclass == EXTERN || isfunc(p->type)) ! 485: (*IR->import)(p); ! 486: else if (!isfunc(p->type)) { ! 487: if (isarray(p->type) && p->type->size == 0 ! 488: && p->type->type->size > 0) ! 489: p->type = array(p->type->type, 1, 0); ! 490: if (p->type->size > 0) { ! 491: defglobal(p, BSS); ! 492: (*IR->space)(p->type->size); ! 493: } else ! 494: error("undefined size for `%t %s'\n", p->type, p->name); ! 495: p->defined = 1; ! 496: if (Pflag && !p->generated) ! 497: printdecl(p, p->type); ! 498: } ! 499: } ! 500: ! 501: /* enumdecl - enum [ id ] [ { id [ = cexpr ] ( , id [ = cexpr ] )* } ] */ ! 502: static Type enumdecl() { ! 503: char *tag; ! 504: Type ty; ! 505: Symbol p; ! 506: Coordinate pos; ! 507: ! 508: t = gettok(); ! 509: if (t == ID) { ! 510: tag = token; ! 511: pos = src; ! 512: t = gettok(); ! 513: } else ! 514: tag = string(""); ! 515: if (t == '{') { ! 516: static char follow[] = { IF, 0 }; ! 517: int n = 0, k = -1; ! 518: List idlist = 0; ! 519: ty = newstruct(ENUM, tag); ! 520: t = gettok(); ! 521: if (t != ID) ! 522: error("expecting an enumerator identifier\n"); ! 523: while (t == ID) { ! 524: char *id = token; ! 525: Coordinate s; ! 526: if (tsym && tsym->scope == level) ! 527: error("redeclaration of `%s' previously declared at %w\n", ! 528: token, &tsym->src); ! 529: s = src; ! 530: t = gettok(); ! 531: if (t == '=') { ! 532: t = gettok(); ! 533: k = intexpr(0, 0); ! 534: } else { ! 535: if (k == INT_MAX) ! 536: error("overflow in value for enumeration constant `%s'\n", p->name); ! 537: k++; ! 538: } ! 539: p = install(id, &identifiers, level < LOCAL); ! 540: p->src = s; ! 541: p->type = ty; ! 542: p->sclass = ENUM; ! 543: p->u.value = k; ! 544: idlist = append(p, idlist); ! 545: n++; ! 546: if (Aflag >= 2 && n == 128) ! 547: warning("more than 127 enumeration constants in `%t'\n", ty); ! 548: if (t != ',') ! 549: break; ! 550: t = gettok(); ! 551: if (Aflag >= 2 && t == '}') ! 552: warning("non-ANSI trailing comma in enumerator list\n"); ! 553: } ! 554: test('}', follow); ! 555: ty->type = inttype; ! 556: ty->size = ty->type->size; ! 557: ty->align = ty->type->align; ! 558: ty->u.sym->u.idlist = (Symbol *)ltoa(idlist, (Generic *)alloc((length(idlist) + 1)*sizeof(Symbol))); ! 559: ty->u.sym->defined = 1; ! 560: } else if ((p = lookup(tag, types)) && p->type->op == ENUM) { ! 561: if (*tag && xref) ! 562: use(p, pos); ! 563: ty = p->type; ! 564: } else { ! 565: error("unknown enumeration `%s'\n", tag); ! 566: ty = newstruct(ENUM, tag); ! 567: ty->type = inttype; ! 568: } ! 569: return ty; ! 570: } ! 571: ! 572: /* fields - ( type dclr ( , dclr )* ; )* */ ! 573: static void fields(ty) Type ty; { ! 574: int n = 0, bits, off, overflow = 0; ! 575: Field p, *q; ! 576: ! 577: while (kind[t] == CHAR ! 578: || t == ID && tsym && tsym->sclass == TYPEDEF) { ! 579: static char follow[] = { IF, CHAR, '}', 0 }; ! 580: Type ty1 = type(0, (int *)0); ! 581: do { ! 582: char *id = 0; ! 583: Type fty; ! 584: if ((fty = dclr(ty1, &id, (Symbol **)0)) == 0) ! 585: fty = ty1; ! 586: if (Aflag >= 1 && !hasproto(fty)) ! 587: warning("missing prototype\n"); ! 588: p = newfield(id, ty, fty); /* refme */ ! 589: if (t == ':') { ! 590: fty = unqual(fty); ! 591: if (isenum(fty)) ! 592: fty = fty->type; ! 593: if (fty != inttype && fty != unsignedtype) { ! 594: error("`%t' is an illegal bit field type\n", p->type); ! 595: p->type = inttype; ! 596: } ! 597: t = gettok(); ! 598: p->bitsize = intexpr(0, 0); ! 599: if (p->bitsize > 8*inttype->size || p->bitsize < 0) { ! 600: error("`%d' is an illegal bit field size\n", p->bitsize); ! 601: p->bitsize = 8*inttype->size; ! 602: } else if (p->bitsize == 0 && id) { ! 603: warning("extraneous 0-width bit field `%t %s' ignored\n", ! 604: p->type, id); ! 605: p->name = stringd(genlabel(1)); ! 606: } ! 607: p->lsb = 1; ! 608: } else if (id == 0 && isstruct(p->type)) { ! 609: if (Aflag >= 2) ! 610: warning("non-ANSI unnamed substructure in `%t'\n", ty); ! 611: if (p->type->size == 0) ! 612: error("undefined size for field `%t'\n", p->type); ! 613: p->name = 0; ! 614: break; ! 615: } else { ! 616: if (id == 0) ! 617: error("field name missing\n"); ! 618: else if (p->type->size == 0) ! 619: error("undefined size for field `%t %s'\n", p->type, id); ! 620: } ! 621: n++; ! 622: if (Aflag >= 2 && n == 128) ! 623: warning("more than 127 fields in `%t'\n", ty); ! 624: } while (t == ',' && (t = gettok())); ! 625: test(';', follow); ! 626: } ! 627: ty->align = IR->structmetric.align; ! 628: off = bits = 0; ! 629: #define add(x,n) (x > INT_MAX - (n) ? (overflow = 1, x) : x + n) ! 630: q = &ty->u.sym->u.s.flist; ! 631: for (p = *q; p; p = p->link) { ! 632: int a = p->type->align ? p->type->align : 1; ! 633: if (ty->op == UNION) { ! 634: if (p->lsb) ! 635: a = unsignedtype->align; ! 636: bits = 0; ! 637: } else if (bits == 0 || p->bitsize == 0 ! 638: || bits - 1 + p->bitsize > 8*unsignedtype->size) { ! 639: if (bits) ! 640: off = add(off, (bits + 6)/8); ! 641: if (p->lsb) ! 642: a = unsignedtype->align; ! 643: add(off, a - 1); ! 644: off = roundup(off, a); ! 645: bits = 0; ! 646: } ! 647: if (a > ty->align) ! 648: ty->align = a; ! 649: p->offset = off; ! 650: if (p->lsb) { ! 651: if (bits == 0) ! 652: bits = 1; ! 653: if (IR->little_endian) ! 654: p->lsb = bits; ! 655: else ! 656: p->lsb = 8*unsignedtype->size - bits - p->bitsize + 2; ! 657: bits += p->bitsize; ! 658: if (ty->op == UNION && (bits + 6)/8 > ty->size) ! 659: ty->size = (bits + 6)/8; ! 660: } else if (ty->op == STRUCT) ! 661: off = add(off, p->type->size); ! 662: else if (p->type->size > ty->size) ! 663: ty->size = p->type->size; ! 664: if (isconst(p->type)) ! 665: ty->u.sym->u.s.cfields = 1; ! 666: if (isvolatile(p->type)) ! 667: ty->u.sym->u.s.vfields = 1; ! 668: if (p->name == 0 || *p->name > '9') { ! 669: *q = p; ! 670: q = &p->link; ! 671: } ! 672: } ! 673: *q = 0; ! 674: if (bits) ! 675: off = add(off, (bits + 6)/8); ! 676: if (ty->op == STRUCT) ! 677: ty->size = off; ! 678: else if (off > ty->size) ! 679: ty->size = off; ! 680: add(ty->size, ty->align - 1); ! 681: ty->size = roundup(ty->size, ty->align); ! 682: if (overflow) { ! 683: error("size of `%t' exceeds %d bytes\n", ty, INT_MAX); ! 684: ty->size = INT_MAX&(~(ty->align - 1)); ! 685: } ! 686: checkfields(ty); ! 687: } ! 688: ! 689: /* finalize - finalize tentative definitions, constants, check unref'd statics */ ! 690: void finalize() { ! 691: if (xref) { ! 692: setuses(identifiers); ! 693: foreach(types, level, fielduses, (Generic)0); ! 694: setuses(types); ! 695: } ! 696: foreach(identifiers, GLOBAL, doglobal, (Generic)0); ! 697: foreach(externals, GLOBAL, doextern, (Generic)0); ! 698: foreach(identifiers, GLOBAL, checkref, (Generic)0); ! 699: foreach(constants, CONSTANTS, doconst, (Generic)0); ! 700: } ! 701: /* funcdecl - ... ( ... ) decl* compound */ ! 702: static void funcdecl(sclass, id, ty, params, pt) char *id; Type ty; Symbol params[]; Coordinate pt; { ! 703: int i, n; ! 704: Code rp; ! 705: Symbol *callee, *caller, p; ! 706: ! 707: regcount = 0; ! 708: if (isstruct(freturn(ty)) && freturn(ty)->size == 0) ! 709: error("illegal use of incomplete type `%t'\n", freturn(ty)); ! 710: for (n = 0; params[n]; n++) ! 711: ; ! 712: if (n > 0 && params[n-1]->name == 0) ! 713: params[--n] = 0; ! 714: if (Aflag >= 2 && n > 31) ! 715: warning("more than 31 parameters in function `%s'\n", id); ! 716: if (!ty->u.f.oldstyle) { ! 717: callee = params; ! 718: caller = (Symbol *)talloc((n + 1)*sizeof *caller); ! 719: for (i = 0; (p = callee[i]) && p->name; i++) { ! 720: caller[i] = (Symbol)talloc(sizeof *caller[i]); ! 721: *caller[i] = *p; ! 722: caller[i]->type = promote(callee[i]->type); ! 723: if (callee[i]->sclass == REGISTER) { ! 724: caller[i]->sclass = AUTO; ! 725: ++regcount; ! 726: } ! 727: if (*p->name >= '1' && *p->name <= '9') ! 728: error("missing parameter name to function `%s'\n", id); ! 729: } ! 730: caller[i] = 0; ! 731: ! 732: } else { ! 733: Type *proto; ! 734: enterscope(); ! 735: caller = params; ! 736: while (kind[t] == CHAR || kind[t] == STATIC ! 737: || t == ID && tsym && tsym->sclass == TYPEDEF) ! 738: decl(dclparam); ! 739: callee = (Symbol *)talloc((n + 1)*sizeof *callee); ! 740: for (i = 0; i < n; i++) ! 741: callee[i] = caller[i]; ! 742: callee[i] = 0; ! 743: foreach(identifiers, PARAM, oldparam, (Generic)callee); ! 744: for (i = 0; p = callee[i]; i++) { ! 745: if (!p->defined) ! 746: callee[i] = dclparam(AUTO, p->name, inttype, &p->src); ! 747: *caller[i] = *p; ! 748: if (p->sclass == REGISTER) { ! 749: caller[i]->sclass = AUTO; ! 750: ++regcount; ! 751: } ! 752: if (unqual(p->type) == floattype) ! 753: caller[i]->type = doubletype; ! 754: else ! 755: caller[i]->type = promote(p->type); ! 756: } ! 757: if ((p = lookup(id, identifiers)) && p->scope == GLOBAL ! 758: && isfunc(p->type) && p->type->u.f.proto) { ! 759: proto = p->type->u.f.proto; ! 760: for (i = 0; caller[i] && proto[i]; i++) ! 761: if (eqtype(unqual(proto[i]), unqual(caller[i]->type), 1) == 0) ! 762: break; ! 763: if (proto[i] || caller[i]) ! 764: error("conflicting argument declarations for function `%s'\n", id); ! 765: ty = func(freturn(ty), proto, 0); ! 766: } else { ! 767: proto = (Type *)alloc((n + 1)*sizeof *proto); ! 768: for (i = 0; i < n; i++) ! 769: if (callee[i]->type == floattype) ! 770: proto[i] = doubletype; ! 771: else ! 772: proto[i] = promote(callee[i]->type); ! 773: proto[i] = 0; ! 774: ty = func(freturn(ty), proto, 1); ! 775: } ! 776: } ! 777: if (Aflag >= 1 && !hasproto(ty)) ! 778: warning("missing prototype\n"); ! 779: for (i = 0; p = callee[i]; i++) ! 780: if (p->type->size == 0) { ! 781: error("undefined size for parameter `%t %s'\n", p->type, p->name); ! 782: caller[i]->type = p->type = inttype; ! 783: } ! 784: if ((p = lookup(id, identifiers)) && isfunc(p->type)) { ! 785: if (p->defined) ! 786: error("redefinition of `%s' previously defined at %w\n", ! 787: p->name, &p->src); ! 788: if (xref) ! 789: use(p, p->src); ! 790: } ! 791: cfunc = dclglobal(sclass, id, ty, &pt); ! 792: cfunc->u.f.pt[0] = pt; ! 793: if (IR->jump_on_return || glevel > 1) ! 794: cfunc->u.f.label = genlabel(1); ! 795: cfunc->u.f.callee = callee; ! 796: cfunc->defined = 1; ! 797: if (Pflag) ! 798: printproto(cfunc, cfunc->u.f.callee); ! 799: labels[0] = table(0, LABELS); ! 800: labels[1] = table(0, LABELS); ! 801: refinc = 1.0; ! 802: bnumber = -1; ! 803: codelist = &codehead; ! 804: codelist->next = 0; ! 805: if (ncalled >= 0) ! 806: ncalled = findfunc(cfunc->name, pt.file); ! 807: cfunc->u.f.pt[2] = definept(0)->u.point.src; ! 808: compound(0, (struct swtch *)0, 0); ! 809: for (rp = codelist; rp->kind < Label; rp = rp->prev) ! 810: ; ! 811: if (rp->kind != Jump) { ! 812: if (cfunc->u.f.label == 0) ! 813: definept(0); ! 814: if (freturn(cfunc->type) != voidtype ! 815: && (freturn(cfunc->type) != inttype || Aflag >= 1)) ! 816: warning("missing return value\n"); ! 817: retcode(0, 0); ! 818: } ! 819: if (cfunc->u.f.label) { ! 820: definelab(cfunc->u.f.label); ! 821: definept(0); ! 822: walk(0, 0, 0); ! 823: } ! 824: exitscope(); ! 825: foreach(identifiers, level, checkref, (Generic)0); ! 826: flushequ(); ! 827: swtoseg(CODE); ! 828: if (cfunc->sclass != STATIC) ! 829: (*IR->export)(cfunc); ! 830: if (glevel && IR->stabsym) { ! 831: (*IR->stabsym)(cfunc); ! 832: swtoseg(CODE); ! 833: } ! 834: for (i = 0; caller[i]; i++) { ! 835: if (glevel > 1) ! 836: callee[i]->sclass = AUTO; ! 837: if (IR->no_argb && isstruct(caller[i]->type)) { ! 838: caller[i]->type = ptr(caller[i]->type); ! 839: callee[i]->type = ptr(callee[i]->type); ! 840: caller[i]->structarg = callee[i]->structarg = 1; ! 841: } ! 842: } ! 843: (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls); ! 844: if (glevel && IR->stabfend) ! 845: (*IR->stabfend)(cfunc, lineno); ! 846: outflush(); ! 847: cfunc->u.f.pt[1] = src; ! 848: expect('}'); ! 849: setuses(labels[0]); ! 850: foreach(labels[0], LABELS, checklab, (Generic)0); ! 851: if (events.exit) ! 852: apply(events.exit, (Generic)cfunc, (Generic)0); ! 853: exitscope(); ! 854: retv = 0; ! 855: tfree(); ! 856: cfunc = 0; ! 857: } ! 858: /* oldparam - check that p is an old-style parameter, and patch callee[i] */ ! 859: static void oldparam(p, cl) Symbol p; Generic cl; { ! 860: Symbol *callee = (Symbol *)cl; ! 861: int i; ! 862: ! 863: for (i = 0; callee[i]; i++) ! 864: if (p->name == callee[i]->name) { ! 865: callee[i] = p; ! 866: return; ! 867: } ! 868: error("declared parameter `%s' is missing\n", p->name); ! 869: } ! 870: /* parameters - [id ( , id )* | type dclr ( , type dclr )*] */ ! 871: static Symbol *parameters(fty) Type fty; { ! 872: List list = 0; ! 873: Symbol *params; ! 874: ! 875: if (kind[t] == CHAR || kind[t] == STATIC ! 876: || t == ID && tsym && tsym->sclass == TYPEDEF) { ! 877: int n = 0, sclass; ! 878: Type last = 0, ty; ! 879: static struct symbol sentinel; ! 880: if (sentinel.type == 0) { ! 881: sentinel.type = voidtype; ! 882: sentinel.defined = 1; ! 883: } ! 884: for (;;) { ! 885: char *id = 0; ! 886: if (last && t == ELLIPSIS) { ! 887: if (last == voidtype) ! 888: error("illegal formal parameter types\n"); ! 889: list = append(&sentinel, list); ! 890: t = gettok(); ! 891: break; ! 892: } ! 893: if (t == ID && (tsym == 0 || tsym->sclass != TYPEDEF) ! 894: || t != ID && t != REGISTER && kind[t] != CHAR) ! 895: error("missing parameter type\n"); ! 896: n++; ! 897: ty = dclr(type(PARAM, &sclass), &id, (Symbol **)0); ! 898: if (Aflag >= 1 && !hasproto(ty)) ! 899: warning("missing prototype\n"); ! 900: if (ty == voidtype && (last || id)) ! 901: error("illegal formal parameter types\n"); ! 902: if (id == 0) ! 903: id = stringd(n); ! 904: if (ty != voidtype) ! 905: list = append(dclparam(sclass, id, ty, &src), list); ! 906: last = ty; ! 907: if (t != ',') ! 908: break; ! 909: t = gettok(); ! 910: } ! 911: fty->u.f.proto = (Type *)alloc((length(list) + 1)*sizeof (Type *)); ! 912: params = (Symbol *)ltoa(list, (Generic *)0); ! 913: for (n = 0; params[n]; n++) ! 914: fty->u.f.proto[n] = params[n]->type; ! 915: fty->u.f.proto[n] = 0; ! 916: fty->u.f.oldstyle = 0; ! 917: } else { ! 918: if (t == ID) ! 919: for (;;) { ! 920: Symbol p; ! 921: if (t != ID) { ! 922: error("expecting an identifier\n"); ! 923: break; ! 924: } ! 925: p = dclparam(AUTO, token, inttype, &src); ! 926: p->defined = 0; ! 927: list = append(p, list); ! 928: t = gettok(); ! 929: if (t != ',') ! 930: break; ! 931: t = gettok(); ! 932: } ! 933: params = (Symbol *)ltoa(list, (Generic *)0); ! 934: fty->u.f.proto = 0; ! 935: fty->u.f.oldstyle = 1; ! 936: } ! 937: if (t != ')') { ! 938: static char follow[] = { CHAR, STATIC, IF, ')', 0 }; ! 939: expect(')'); ! 940: skipto('{', follow); ! 941: } ! 942: if (t == ')') ! 943: t = gettok(); ! 944: return params; ! 945: } ! 946: static void exitparams(params) Symbol params[]; { ! 947: if (params[0] && !params[0]->defined) ! 948: error("extraneous old-style parameter list\n"); ! 949: exitscope(); ! 950: } ! 951: ! 952: /* program - decl* */ ! 953: void program() { ! 954: int n; ! 955: ! 956: level = GLOBAL; ! 957: for (n= 0; t != EOI; n++) ! 958: if (kind[t] == CHAR || kind[t] == STATIC || t == ID) ! 959: decl(dclglobal); ! 960: else { ! 961: if (t == ';') ! 962: warning("empty declaration\n"); ! 963: else ! 964: error("unrecognized declaration\n"); ! 965: t = gettok(); ! 966: } ! 967: if (n == 0) ! 968: warning("empty input file\n"); ! 969: } ! 970: ! 971: /* structdcl - ( struct | union ) ( [ id ] { ( field; )+ } | id ) */ ! 972: static Type structdcl(op) { ! 973: char *tag; ! 974: Type ty; ! 975: Symbol p; ! 976: Coordinate pos; ! 977: ! 978: t = gettok(); ! 979: if (t == ID) { ! 980: tag = token; ! 981: pos = src; ! 982: t = gettok(); ! 983: } else ! 984: tag = string(""); ! 985: if (t == '{') { ! 986: static char follow[] = { IF, ',', 0 }; ! 987: ty = newstruct(op, tag); ! 988: if (*tag) ! 989: ty->u.sym->src = pos; ! 990: t = gettok(); ! 991: if (kind[t] == CHAR || t == ID && tsym ! 992: && tsym->sclass == TYPEDEF) ! 993: fields(ty); ! 994: else ! 995: error("invalid %k field declarations\n", op); ! 996: test('}', follow); ! 997: ty->u.sym->defined = 1; ! 998: } else if (*tag && (p = lookup(tag, types)) && p->type->op == op) { ! 999: if (t == ';' && p->scope < level) ! 1000: ty = newstruct(op, tag); ! 1001: if (xref) ! 1002: use(p, pos); ! 1003: ty = p->type; ! 1004: } else { ! 1005: if (*tag == 0) ! 1006: error("missing %k tag\n", op); ! 1007: ty = newstruct(op, tag); ! 1008: if (*tag && xref) ! 1009: use(ty->u.sym, pos); ! 1010: } ! 1011: return ty; ! 1012: } ! 1013: ! 1014: /* tnode - allocate a type node */ ! 1015: static Type tnode(op, type) Type type; { ! 1016: Type ty = (Type) talloc(sizeof *ty); ! 1017: ! 1018: BZERO(ty, struct tynode); ! 1019: ty->op = op; ! 1020: ty->type = type; ! 1021: return ty; ! 1022: } ! 1023: ! 1024: /* type - parse basic storage class and type specification */ ! 1025: static Type type(lev, sclass) int *sclass; { ! 1026: int cls, cons, *p, sign, size, tt, type, vol; ! 1027: Type ty = 0; ! 1028: ! 1029: if (sclass == 0) ! 1030: cls = AUTO; ! 1031: else ! 1032: *sclass = 0; ! 1033: for (vol = cons = sign = size = type = 0;;) { ! 1034: p = &type; ! 1035: tt = t; ! 1036: switch (t) { ! 1037: case AUTO: case REGISTER: case STATIC: ! 1038: case EXTERN: case TYPEDEF: ! 1039: p = sclass ? sclass : &cls; ! 1040: break; ! 1041: case CONST: ! 1042: p = &cons; ! 1043: break; ! 1044: case VOLATILE: ! 1045: p = &vol; ! 1046: break; ! 1047: case SIGNED: case UNSIGNED: ! 1048: p = &sign; ! 1049: break; ! 1050: case LONG: case SHORT: ! 1051: p = &size; ! 1052: break; ! 1053: case VOID: case CHAR: case INT: case FLOAT: case DOUBLE: ! 1054: ty = tsym->type; ! 1055: break; ! 1056: case ENUM: ! 1057: ty = enumdecl(); ! 1058: break; ! 1059: case STRUCT: case UNION: ! 1060: ty = structdcl(t); ! 1061: break; ! 1062: case ID: ! 1063: if (tsym && tsym->sclass == TYPEDEF ! 1064: && type == 0 && size == 0 && sign == 0) { ! 1065: use(tsym, src); ! 1066: ty = tsym->type; ! 1067: t = tt = ty->op; ! 1068: break; ! 1069: } ! 1070: /* fall through */ ! 1071: default: ! 1072: p = 0; ! 1073: } ! 1074: if (p == 0) ! 1075: break; ! 1076: if (*p) ! 1077: error("invalid use of `%k'\n", tt); ! 1078: *p = tt; ! 1079: if (t == tt) ! 1080: t = gettok(); ! 1081: } ! 1082: if (type == 0) { ! 1083: type = INT; ! 1084: ty = inttype; ! 1085: } ! 1086: if (size == SHORT && type != INT ! 1087: || size == LONG && type != INT && type != DOUBLE ! 1088: || sign && type != INT && type != CHAR) ! 1089: error("invalid type specification\n"); ! 1090: if (type == CHAR && sign) ! 1091: ty = sign == UNSIGNED ? unsignedchar : signedchar; ! 1092: else if (size == SHORT) ! 1093: ty = sign == UNSIGNED ? unsignedshort : shorttype; ! 1094: else if (size == LONG && type == DOUBLE) ! 1095: ty = longdouble; ! 1096: else if (size == LONG) ! 1097: ty = sign == UNSIGNED ? unsignedlong : longtype; ! 1098: else if (sign == UNSIGNED && type == INT) ! 1099: ty = unsignedtype; ! 1100: if (cons == CONST) ! 1101: ty = qual(CONST, ty); ! 1102: if (vol == VOLATILE) ! 1103: ty = qual(VOLATILE, ty); ! 1104: return ty; ! 1105: } ! 1106: ! 1107: /* typename - type dclr */ ! 1108: Type typename() { ! 1109: Type ty = type(0, (int *)0); ! 1110: ! 1111: if (t == '*' || t == '(' || t == '[') { ! 1112: ty = dclr(ty, (char **)0, (Symbol **)0); ! 1113: if (Aflag >= 1 && !hasproto(ty)) ! 1114: warning("missing prototype\n"); ! 1115: } ! 1116: return ty; ! 1117: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.