00001 #include "c.h"
00002
00003
00004 #define add(x,n) (x > inttype->u.sym->u.limits.max.i-(n) ? (overflow=1,x) : x+(n))
00005 #define chkoverflow(x,n) ((void)add(x,n))
00006 #define bits2bytes(n) (((n) + 7)/8)
00007 static int regcount;
00008
00009 static List autos, registers;
00010 Symbol cfunc;
00011 Symbol retv;
00012
00013 static void checkref(Symbol, void *);
00014 static Symbol dclglobal(int, char *, Type, Coordinate *);
00015 static Symbol dcllocal(int, char *, Type, Coordinate *);
00016 static Symbol dclparam(int, char *, Type, Coordinate *);
00017 static Type dclr(Type, char **, Symbol **, int);
00018 static Type dclr1(char **, Symbol **, int);
00019 static void decl(Symbol (*)(int, char *, Type, Coordinate *));
00020 extern void doconst(Symbol, void *);
00021 static void doglobal(Symbol, void *);
00022 static void doextern(Symbol, void *);
00023 static void exitparams(Symbol []);
00024 static void fields(Type);
00025 static void funcdefn(int, char *, Type, Symbol [], Coordinate);
00026 static void initglobal(Symbol, int);
00027 static void oldparam(Symbol, void *);
00028 static Symbol *parameters(Type);
00029 static Type specifier(int *);
00030 static Type structdcl(int);
00031 static Type tnode(int, Type);
00032 void program(void) {
00033 int n;
00034
00035 level = GLOBAL;
00036 for (n = 0; t != EOI; n++)
00037 if (kind[t] == CHAR || kind[t] == STATIC
00038 || t == ID || t == '*' || t == '(') {
00039 decl(dclglobal);
00040 deallocate(STMT);
00041 if (!(glevel >= 3 || xref))
00042 deallocate(FUNC);
00043 } else if (t == ';') {
00044 warning("empty declaration\n");
00045 t = gettok();
00046 } else {
00047 error("unrecognized declaration\n");
00048 t = gettok();
00049 }
00050 if (n == 0)
00051 warning("empty input file\n");
00052 }
00053 static Type specifier(int *sclass) {
00054 int cls, cons, sign, size, type, vol;
00055 Type ty = NULL;
00056
00057 cls = vol = cons = sign = size = type = 0;
00058 if (sclass == NULL)
00059 cls = AUTO;
00060 for (;;) {
00061 int *p, tt = t;
00062 switch (t) {
00063 case AUTO:
00064 case REGISTER: if (level <= GLOBAL && cls == 0)
00065 error("invalid use of `%k'\n", t);
00066 p = &cls; t = gettok(); break;
00067 case STATIC: case EXTERN:
00068 case TYPEDEF: p = &cls; t = gettok(); break;
00069 case CONST: p = &cons; t = gettok(); break;
00070 case VOLATILE: p = &vol; t = gettok(); break;
00071 case SIGNED:
00072 case UNSIGNED: p = &sign; t = gettok(); break;
00073 case LONG: if (size == LONG) {
00074 size = 0;
00075 tt = LONG+LONG;
00076 }
00077 p = &size; t = gettok(); break;
00078 case SHORT: p = &size; t = gettok(); break;
00079 case VOID: case CHAR: case INT: case FLOAT:
00080 case DOUBLE: p = &type; ty = tsym->type;
00081 t = gettok(); break;
00082 case ENUM: p = &type; ty = enumdcl(); break;
00083 case STRUCT:
00084 case UNION: p = &type; ty = structdcl(t); break;
00085 case ID:
00086 if (istypename(t, tsym) && type == 0
00087 && sign == 0 && size == 0) {
00088 use(tsym, src);
00089 ty = tsym->type;
00090 if (isqual(ty)
00091 && ty->size != ty->type->size) {
00092 ty = unqual(ty);
00093 if (isconst(tsym->type))
00094 ty = qual(CONST, ty);
00095 if (isvolatile(tsym->type))
00096 ty = qual(VOLATILE, ty);
00097 tsym->type = ty;
00098 }
00099 p = &type;
00100 t = gettok();
00101 } else
00102 p = NULL;
00103 break;
00104 default: p = NULL;
00105 }
00106 if (p == NULL)
00107 break;
00108 if (*p)
00109 error("invalid use of `%k'\n", tt);
00110 *p = tt;
00111 }
00112 if (sclass)
00113 *sclass = cls;
00114 if (type == 0) {
00115 type = INT;
00116 ty = inttype;
00117 }
00118 if (size == SHORT && type != INT
00119 || size == LONG+LONG && type != INT
00120 || size == LONG && type != INT && type != DOUBLE
00121 || sign && type != INT && type != CHAR)
00122 error("invalid type specification\n");
00123 if (type == CHAR && sign)
00124 ty = sign == UNSIGNED ? unsignedchar : signedchar;
00125 else if (size == SHORT)
00126 ty = sign == UNSIGNED ? unsignedshort : shorttype;
00127 else if (size == LONG && type == DOUBLE)
00128 ty = longdouble;
00129 else if (size == LONG+LONG) {
00130 ty = sign == UNSIGNED ? unsignedlonglong : longlong;
00131 if (Aflag >= 1)
00132 warning("`%t' is a non-ANSI type\n", ty);
00133 } else if (size == LONG)
00134 ty = sign == UNSIGNED ? unsignedlong : longtype;
00135 else if (sign == UNSIGNED && type == INT)
00136 ty = unsignedtype;
00137 if (cons == CONST)
00138 ty = qual(CONST, ty);
00139 if (vol == VOLATILE)
00140 ty = qual(VOLATILE, ty);
00141 return ty;
00142 }
00143 static void decl(Symbol (*dcl)(int, char *, Type, Coordinate *)) {
00144 int sclass;
00145 Type ty, ty1;
00146 static char stop[] = { CHAR, STATIC, ID, 0 };
00147
00148 ty = specifier(&sclass);
00149 if (t == ID || t == '*' || t == '(' || t == '[') {
00150 char *id;
00151 Coordinate pos;
00152 id = NULL;
00153 pos = src;
00154 if (level == GLOBAL) {
00155 Symbol *params = NULL;
00156 ty1 = dclr(ty, &id, ¶ms, 0);
00157 if (params && id && isfunc(ty1)
00158 && (t == '{' || istypename(t, tsym)
00159 || (kind[t] == STATIC && t != TYPEDEF))) {
00160 if (sclass == TYPEDEF) {
00161 error("invalid use of `typedef'\n");
00162 sclass = EXTERN;
00163 }
00164 if (ty1->u.f.oldstyle)
00165 exitscope();
00166 funcdefn(sclass, id, ty1, params, pos);
00167 return;
00168 } else if (params)
00169 exitparams(params);
00170 } else
00171 ty1 = dclr(ty, &id, NULL, 0);
00172 for (;;) {
00173 if (Aflag >= 1 && !hasproto(ty1))
00174 warning("missing prototype\n");
00175 if (id == NULL)
00176 error("missing identifier\n");
00177 else if (sclass == TYPEDEF)
00178 {
00179 Symbol p = lookup(id, identifiers);
00180 if (p && p->scope == level)
00181 error("redeclaration of `%s'\n", id);
00182 p = install(id, &identifiers, level,
00183 level < LOCAL ? PERM : FUNC);
00184 p->type = ty1;
00185 p->sclass = TYPEDEF;
00186 p->src = pos;
00187 }
00188 else
00189 (void)(*dcl)(sclass, id, ty1, &pos);
00190 if (t != ',')
00191 break;
00192 t = gettok();
00193 id = NULL;
00194 pos = src;
00195 ty1 = dclr(ty, &id, NULL, 0);
00196 }
00197 } else if (ty == NULL
00198 || !(isenum(ty) ||
00199 isstruct(ty) && (*unqual(ty)->u.sym->name < '1' || *unqual(ty)->u.sym->name > '9')))
00200 error("empty declaration\n");
00201 test(';', stop);
00202 }
00203 static Symbol dclglobal(int sclass, char *id, Type ty, Coordinate *pos) {
00204 Symbol p;
00205
00206 if (sclass == 0)
00207 sclass = AUTO;
00208 else if (sclass != EXTERN && sclass != STATIC) {
00209 error("invalid storage class `%k' for `%t %s'\n",
00210 sclass, ty, id);
00211 sclass = AUTO;
00212 }
00213 p = lookup(id, identifiers);
00214 if (p && p->scope == GLOBAL) {
00215 if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1))
00216 ty = compose(ty, p->type);
00217 else
00218 error("redeclaration of `%s' previously declared at %w\n", p->name, &p->src);
00219
00220 if (!isfunc(ty) && p->defined && t == '=')
00221 error("redefinition of `%s' previously defined at %w\n", p->name, &p->src);
00222
00223 if (p->sclass == EXTERN && sclass == STATIC
00224 || p->sclass == STATIC && sclass == AUTO
00225 || p->sclass == AUTO && sclass == STATIC)
00226 warning("inconsistent linkage for `%s' previously declared at %w\n", p->name, &p->src);
00227
00228 }
00229 if (p == NULL || p->scope != GLOBAL) {
00230 Symbol q = lookup(id, externals);
00231 if (q) {
00232 if (sclass == STATIC || !eqtype(ty, q->type, 1))
00233 warning("declaration of `%s' does not match previous declaration at %w\n", id, &q->src);
00234
00235 p = relocate(id, externals, globals);
00236 p->sclass = sclass;
00237 } else {
00238 p = install(id, &globals, GLOBAL, PERM);
00239 p->sclass = sclass;
00240 (*IR->defsymbol)(p);
00241 }
00242 if (p->sclass != STATIC) {
00243 static int nglobals;
00244 nglobals++;
00245 if (Aflag >= 2 && nglobals == 512)
00246 warning("more than 511 external identifiers\n");
00247 }
00248 } else if (p->sclass == EXTERN)
00249 p->sclass = sclass;
00250 p->type = ty;
00251 p->src = *pos;
00252 if (t == '=' && isfunc(p->type)) {
00253 error("illegal initialization for `%s'\n", p->name);
00254 t = gettok();
00255 initializer(p->type, 0);
00256 } else if (t == '=') {
00257 initglobal(p, 0);
00258 if (glevel > 0 && IR->stabsym) {
00259 (*IR->stabsym)(p); swtoseg(p->u.seg); }
00260 } else if (p->sclass == STATIC && !isfunc(p->type)
00261 && p->type->size == 0)
00262 error("undefined size for `%t %s'\n", p->type, p->name);
00263 return p;
00264 }
00265 static void initglobal(Symbol p, int flag) {
00266 Type ty;
00267
00268 if (t == '=' || flag) {
00269 if (p->sclass == STATIC) {
00270 for (ty = p->type; isarray(ty); ty = ty->type)
00271 ;
00272 defglobal(p, isconst(ty) ? LIT : DATA);
00273 } else
00274 defglobal(p, DATA);
00275 if (t == '=')
00276 t = gettok();
00277 ty = initializer(p->type, 0);
00278 if (isarray(p->type) && p->type->size == 0)
00279 p->type = ty;
00280 if (p->sclass == EXTERN)
00281 p->sclass = AUTO;
00282 }
00283 }
00284 void defglobal(Symbol p, int seg) {
00285 p->u.seg = seg;
00286 swtoseg(p->u.seg);
00287 if (p->sclass != STATIC)
00288 (*IR->export)(p);
00289 (*IR->global)(p);
00290 p->defined = 1;
00291 }
00292
00293 static Type dclr(Type basety, char **id, Symbol **params, int abstract) {
00294 Type ty = dclr1(id, params, abstract);
00295
00296 for ( ; ty; ty = ty->type)
00297 switch (ty->op) {
00298 case POINTER:
00299 basety = ptr(basety);
00300 break;
00301 case FUNCTION:
00302 basety = func(basety, ty->u.f.proto,
00303 ty->u.f.oldstyle);
00304 break;
00305 case ARRAY:
00306 basety = array(basety, ty->size, 0);
00307 break;
00308 case CONST: case VOLATILE:
00309 basety = qual(ty->op, basety);
00310 break;
00311 default: assert(0);
00312 }
00313 if (Aflag >= 2 && basety->size > 32767)
00314 warning("more than 32767 bytes in `%t'\n", basety);
00315 return basety;
00316 }
00317 static Type tnode(int op, Type type) {
00318 Type ty;
00319
00320 NEW0(ty, STMT);
00321 ty->op = op;
00322 ty->type = type;
00323 return ty;
00324 }
00325 static Type dclr1(char **id, Symbol **params, int abstract) {
00326 Type ty = NULL;
00327
00328 switch (t) {
00329 case ID: if (id)
00330 *id = token;
00331 else
00332 error("extraneous identifier `%s'\n", token);
00333 t = gettok(); break;
00334 case '*': t = gettok(); if (t == CONST || t == VOLATILE) {
00335 Type ty1;
00336 ty1 = ty = tnode(t, NULL);
00337 while ((t = gettok()) == CONST || t == VOLATILE)
00338 ty1 = tnode(t, ty1);
00339 ty->type = dclr1(id, params, abstract);
00340 ty = ty1;
00341 } else
00342 ty = dclr1(id, params, abstract);
00343 ty = tnode(POINTER, ty); break;
00344 case '(': t = gettok(); if (abstract
00345 && (t == REGISTER || istypename(t, tsym) || t == ')')) {
00346 Symbol *args;
00347 ty = tnode(FUNCTION, ty);
00348 enterscope();
00349 if (level > PARAM)
00350 enterscope();
00351 args = parameters(ty);
00352 exitparams(args);
00353 } else {
00354 ty = dclr1(id, params, abstract);
00355 expect(')');
00356 if (abstract && ty == NULL
00357 && (id == NULL || *id == NULL))
00358 return tnode(FUNCTION, NULL);
00359 } break;
00360 case '[': break;
00361 default: return ty;
00362 }
00363 while (t == '(' || t == '[')
00364 switch (t) {
00365 case '(': t = gettok(); { Symbol *args;
00366 ty = tnode(FUNCTION, ty);
00367 enterscope();
00368 if (level > PARAM)
00369 enterscope();
00370 args = parameters(ty);
00371 if (params && *params == NULL)
00372 *params = args;
00373 else
00374 exitparams(args);
00375 }
00376 break;
00377 case '[': t = gettok(); { int n = 0;
00378 if (kind[t] == ID) {
00379 n = intexpr(']', 1);
00380 if (n <= 0) {
00381 error("`%d' is an illegal array size\n", n);
00382 n = 1;
00383 }
00384 } else
00385 expect(']');
00386 ty = tnode(ARRAY, ty);
00387 ty->size = n; } break;
00388 default: assert(0);
00389 }
00390 return ty;
00391 }
00392 static Symbol *parameters(Type fty) {
00393 List list = NULL;
00394 Symbol *params;
00395
00396 if (kind[t] == STATIC || istypename(t, tsym)) {
00397 int n = 0;
00398 Type ty1 = NULL;
00399 for (;;) {
00400 Type ty;
00401 int sclass = 0;
00402 char *id = NULL;
00403 if (ty1 && t == ELLIPSIS) {
00404 static struct symbol sentinel;
00405 if (sentinel.type == NULL) {
00406 sentinel.type = voidtype;
00407 sentinel.defined = 1;
00408 }
00409 if (ty1 == voidtype)
00410 error("illegal formal parameter types\n");
00411 list = append(&sentinel, list);
00412 t = gettok();
00413 break;
00414 }
00415 if (!istypename(t, tsym) && t != REGISTER)
00416 error("missing parameter type\n");
00417 n++;
00418 ty = dclr(specifier(&sclass), &id, NULL, 1);
00419 if ( ty == voidtype && (ty1 || id)
00420 || ty1 == voidtype)
00421 error("illegal formal parameter types\n");
00422 if (id == NULL)
00423 id = stringd(n);
00424 if (ty != voidtype)
00425 list = append(dclparam(sclass, id, ty, &src), list);
00426 if (Aflag >= 1 && !hasproto(ty))
00427 warning("missing prototype\n");
00428 if (ty1 == NULL)
00429 ty1 = ty;
00430 if (t != ',')
00431 break;
00432 t = gettok();
00433 }
00434 fty->u.f.proto = newarray(length(list) + 1,
00435 sizeof (Type *), PERM);
00436 params = ltov(&list, FUNC);
00437 for (n = 0; params[n]; n++)
00438 fty->u.f.proto[n] = params[n]->type;
00439 fty->u.f.proto[n] = NULL;
00440 fty->u.f.oldstyle = 0;
00441 } else {
00442 if (t == ID)
00443 for (;;) {
00444 Symbol p;
00445 if (t != ID) {
00446 error("expecting an identifier\n");
00447 break;
00448 }
00449 p = dclparam(0, token, inttype, &src);
00450 p->defined = 0;
00451 list = append(p, list);
00452 t = gettok();
00453 if (t != ',')
00454 break;
00455 t = gettok();
00456 }
00457 params = ltov(&list, FUNC);
00458 fty->u.f.proto = NULL;
00459 fty->u.f.oldstyle = 1;
00460 }
00461 if (t != ')') {
00462 static char stop[] = { CHAR, STATIC, IF, ')', 0 };
00463 expect(')');
00464 skipto('{', stop);
00465 }
00466 if (t == ')')
00467 t = gettok();
00468 return params;
00469 }
00470 static void exitparams(Symbol params[]) {
00471 assert(params);
00472 if (params[0] && !params[0]->defined)
00473 error("extraneous old-style parameter list\n");
00474 if (level > PARAM)
00475 exitscope();
00476 exitscope();
00477 }
00478
00479 static Symbol dclparam(int sclass, char *id, Type ty, Coordinate *pos) {
00480 Symbol p;
00481
00482 if (isfunc(ty))
00483 ty = ptr(ty);
00484 else if (isarray(ty))
00485 ty = atop(ty);
00486 if (sclass == 0)
00487 sclass = AUTO;
00488 else if (sclass != REGISTER) {
00489 error("invalid storage class `%k' for `%t%s\n",
00490 sclass, ty, stringf(id ? " %s'" : "' parameter", id));
00491 sclass = AUTO;
00492 } else if (isvolatile(ty) || isstruct(ty)) {
00493 warning("register declaration ignored for `%t%s\n",
00494 ty, stringf(id ? " %s'" : "' parameter", id));
00495 sclass = AUTO;
00496 }
00497
00498 p = lookup(id, identifiers);
00499 if (p && p->scope == level)
00500 error("duplicate declaration for `%s' previously declared at %w\n", id, &p->src);
00501
00502 else
00503 p = install(id, &identifiers, level, FUNC);
00504 p->sclass = sclass;
00505 p->src = *pos;
00506 p->type = ty;
00507 p->defined = 1;
00508 if (t == '=') {
00509 error("illegal initialization for parameter `%s'\n", id);
00510 t = gettok();
00511 (void)expr1(0);
00512 }
00513 return p;
00514 }
00515 static Type structdcl(int op) {
00516 char *tag;
00517 Type ty;
00518 Symbol p;
00519 Coordinate pos;
00520
00521 t = gettok();
00522 pos = src;
00523 if (t == ID) {
00524 tag = token;
00525 t = gettok();
00526 } else
00527 tag = "";
00528 if (t == '{') {
00529 static char stop[] = { IF, ',', 0 };
00530 ty = newstruct(op, tag);
00531 ty->u.sym->src = pos;
00532 ty->u.sym->defined = 1;
00533 t = gettok();
00534 if (istypename(t, tsym))
00535 fields(ty);
00536 else
00537 error("invalid %k field declarations\n", op);
00538 test('}', stop);
00539 }
00540 else if (*tag && (p = lookup(tag, types)) != NULL
00541 && p->type->op == op) {
00542 ty = p->type;
00543 if (t == ';' && p->scope < level)
00544 ty = newstruct(op, tag);
00545 }
00546 else {
00547 if (*tag == 0)
00548 error("missing %k tag\n", op);
00549 ty = newstruct(op, tag);
00550 }
00551 if (*tag && xref)
00552 use(ty->u.sym, pos);
00553 return ty;
00554 }
00555 static void fields(Type ty) {
00556 { int n = 0;
00557 while (istypename(t, tsym)) {
00558 static char stop[] = { IF, CHAR, '}', 0 };
00559 Type ty1 = specifier(NULL);
00560 for (;;) {
00561 Field p;
00562 char *id = NULL;
00563 Type fty = dclr(ty1, &id, NULL, 0);
00564 p = newfield(id, ty, fty);
00565 if (Aflag >= 1 && !hasproto(p->type))
00566 warning("missing prototype\n");
00567 if (t == ':') {
00568 if (unqual(p->type) != inttype
00569 && unqual(p->type) != unsignedtype) {
00570 error("`%t' is an illegal bit-field type\n",
00571 p->type);
00572 p->type = inttype;
00573 }
00574 t = gettok();
00575 p->bitsize = intexpr(0, 0);
00576 if (p->bitsize > 8*inttype->size || p->bitsize < 0) {
00577 error("`%d' is an illegal bit-field size\n",
00578 p->bitsize);
00579 p->bitsize = 8*inttype->size;
00580 } else if (p->bitsize == 0 && id) {
00581 warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id);
00582
00583 p->name = stringd(genlabel(1));
00584 }
00585 p->lsb = 1;
00586 }
00587 else {
00588 if (id == NULL)
00589 error("field name missing\n");
00590 else if (isfunc(p->type))
00591 error("`%t' is an illegal field type\n", p->type);
00592 else if (p->type->size == 0)
00593 error("undefined size for field `%t %s'\n",
00594 p->type, id);
00595 }
00596 if (isconst(p->type))
00597 ty->u.sym->u.s.cfields = 1;
00598 if (isvolatile(p->type))
00599 ty->u.sym->u.s.vfields = 1;
00600 n++;
00601 if (Aflag >= 2 && n == 128)
00602 warning("more than 127 fields in `%t'\n", ty);
00603 if (t != ',')
00604 break;
00605 t = gettok();
00606 }
00607 test(';', stop);
00608 } }
00609 { int bits = 0, off = 0, overflow = 0;
00610 Field p, *q = &ty->u.sym->u.s.flist;
00611 ty->align = IR->structmetric.align;
00612 for (p = *q; p; p = p->link) {
00613 int a = p->type->align ? p->type->align : 1;
00614 if (p->lsb)
00615 a = unsignedtype->align;
00616 if (ty->op == UNION)
00617 off = bits = 0;
00618 else if (p->bitsize == 0 || bits == 0
00619 || bits - 1 + p->bitsize > 8*unsignedtype->size) {
00620 off = add(off, bits2bytes(bits-1));
00621 bits = 0;
00622 chkoverflow(off, a - 1);
00623 off = roundup(off, a);
00624 }
00625 if (a > ty->align)
00626 ty->align = a;
00627 p->offset = off;
00628
00629 if (p->lsb) {
00630 if (bits == 0)
00631 bits = 1;
00632 if (IR->little_endian)
00633 p->lsb = bits;
00634 else
00635 p->lsb = 8*unsignedtype->size - bits + 1
00636 - p->bitsize + 1;
00637 bits += p->bitsize;
00638 } else
00639 off = add(off, p->type->size);
00640 if (off + bits2bytes(bits-1) > ty->size)
00641 ty->size = off + bits2bytes(bits-1);
00642 if (p->name == NULL
00643 || !('1' <= *p->name && *p->name <= '9')) {
00644 *q = p;
00645 q = &p->link;
00646 }
00647 }
00648 *q = NULL;
00649 chkoverflow(ty->size, ty->align - 1);
00650 ty->size = roundup(ty->size, ty->align);
00651 if (overflow) {
00652 error("size of `%t' exceeds %d bytes\n", ty, inttype->u.sym->u.limits.max.i);
00653 ty->size = inttype->u.sym->u.limits.max.i&(~(ty->align - 1));
00654 } }
00655 }
00656 static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt) {
00657 int i, n;
00658 Symbol *callee, *caller, p;
00659 Type rty = freturn(ty);
00660
00661 if (isstruct(rty) && rty->size == 0)
00662 error("illegal use of incomplete type `%t'\n", rty);
00663 for (n = 0; params[n]; n++)
00664 ;
00665 if (n > 0 && params[n-1]->name == NULL)
00666 params[--n] = NULL;
00667 if (Aflag >= 2 && n > 31)
00668 warning("more than 31 parameters in function `%s'\n", id);
00669 if (ty->u.f.oldstyle) {
00670 if (Aflag >= 1)
00671 warning("old-style function definition for `%s'\n", id);
00672 caller = params;
00673 callee = newarray(n + 1, sizeof *callee, FUNC);
00674 memcpy(callee, caller, (n+1)*sizeof *callee);
00675 enterscope();
00676 assert(level == PARAM);
00677 while (kind[t] == STATIC || istypename(t, tsym))
00678 decl(dclparam);
00679 foreach(identifiers, PARAM, oldparam, callee);
00680
00681 for (i = 0; (p = callee[i]) != NULL; i++) {
00682 if (!p->defined)
00683 callee[i] = dclparam(0, p->name, inttype, &p->src);
00684 *caller[i] = *p;
00685 caller[i]->sclass = AUTO;
00686 caller[i]->type = promote(p->type);
00687 }
00688 p = lookup(id, identifiers);
00689 if (p && p->scope == GLOBAL && isfunc(p->type)
00690 && p->type->u.f.proto) {
00691 Type *proto = p->type->u.f.proto;
00692 for (i = 0; caller[i] && proto[i]; i++) {
00693 Type ty = unqual(proto[i]);
00694 if (eqtype(isenum(ty) ? ty->type : ty,
00695 unqual(caller[i]->type), 1) == 0)
00696 break;
00697 else if (isenum(ty) && !isenum(unqual(caller[i]->type)))
00698 warning("compatibility of `%t' and `%t' is compiler dependent\n",
00699 proto[i], caller[i]->type);
00700 }
00701 if (proto[i] || caller[i])
00702 error("conflicting argument declarations for function `%s'\n", id);
00703
00704 }
00705 else {
00706 Type *proto = newarray(n + 1, sizeof *proto, PERM);
00707 if (Aflag >= 1)
00708 warning("missing prototype for `%s'\n", id);
00709 for (i = 0; i < n; i++)
00710 proto[i] = caller[i]->type;
00711 proto[i] = NULL;
00712 ty = func(rty, proto, 1);
00713 }
00714 } else {
00715 callee = params;
00716 caller = newarray(n + 1, sizeof *caller, FUNC);
00717 for (i = 0; (p = callee[i]) != NULL && p->name; i++) {
00718 NEW(caller[i], FUNC);
00719 *caller[i] = *p;
00720 if (isint(p->type))
00721 caller[i]->type = promote(p->type);
00722 caller[i]->sclass = AUTO;
00723 if ('1' <= *p->name && *p->name <= '9')
00724 error("missing name for parameter %d to function `%s'\n", i + 1, id);
00725
00726 }
00727 caller[i] = NULL;
00728 }
00729 for (i = 0; (p = callee[i]) != NULL; i++)
00730 if (p->type->size == 0) {
00731 error("undefined size for parameter `%t %s'\n",
00732 p->type, p->name);
00733 caller[i]->type = p->type = inttype;
00734 }
00735 if (Aflag >= 2 && sclass != STATIC && strcmp(id, "main") == 0) {
00736 if (ty->u.f.oldstyle)
00737 warning("`%t %s()' is a non-ANSI definition\n", rty, id);
00738 else if (!(rty == inttype
00739 && (n == 0 && callee[0] == NULL
00740 || n == 2 && callee[0]->type == inttype
00741 && isptr(callee[1]->type) && callee[1]->type->type == charptype
00742 && !variadic(ty))))
00743 warning("`%s' is a non-ANSI definition\n", typestring(ty, id));
00744 }
00745 p = lookup(id, identifiers);
00746 if (p && isfunc(p->type) && p->defined)
00747 error("redefinition of `%s' previously defined at %w\n",
00748 p->name, &p->src);
00749 cfunc = dclglobal(sclass, id, ty, &pt);
00750 cfunc->u.f.label = genlabel(1);
00751 cfunc->u.f.callee = callee;
00752 cfunc->u.f.pt = src;
00753 cfunc->defined = 1;
00754 if (xref)
00755 use(cfunc, cfunc->src);
00756 if (Pflag)
00757 printproto(cfunc, cfunc->u.f.callee);
00758 if (ncalled >= 0)
00759 ncalled = findfunc(cfunc->name, pt.file);
00760 labels = table(NULL, LABELS);
00761 stmtlabs = table(NULL, LABELS);
00762 refinc = 1.0;
00763 regcount = 0;
00764 codelist = &codehead;
00765 codelist->next = NULL;
00766 if (!IR->wants_callb && isstruct(rty))
00767 retv = genident(AUTO, ptr(rty), PARAM);
00768 compound(0, NULL, 0);
00769
00770 {
00771 Code cp;
00772 for (cp = codelist; cp->kind < Label; cp = cp->prev)
00773 ;
00774 if (cp->kind != Jump) {
00775 if (rty != voidtype) {
00776 warning("missing return value\n");
00777 retcode(cnsttree(inttype, 0L));
00778 } else
00779 retcode(NULL);
00780 }
00781 }
00782 definelab(cfunc->u.f.label);
00783 if (events.exit)
00784 apply(events.exit, cfunc, NULL);
00785 walk(NULL, 0, 0);
00786 exitscope();
00787 assert(level == PARAM);
00788 foreach(identifiers, level, checkref, NULL);
00789 if (!IR->wants_callb && isstruct(rty)) {
00790 Symbol *a;
00791 a = newarray(n + 2, sizeof *a, FUNC);
00792 a[0] = retv;
00793 memcpy(&a[1], callee, (n+1)*sizeof *callee);
00794 callee = a;
00795 a = newarray(n + 2, sizeof *a, FUNC);
00796 NEW(a[0], FUNC);
00797 *a[0] = *retv;
00798 memcpy(&a[1], caller, (n+1)*sizeof *callee);
00799 caller = a;
00800 }
00801 if (!IR->wants_argb)
00802 for (i = 0; caller[i]; i++)
00803 if (isstruct(caller[i]->type)) {
00804 caller[i]->type = ptr(caller[i]->type);
00805 callee[i]->type = ptr(callee[i]->type);
00806 caller[i]->structarg = callee[i]->structarg = 1;
00807 }
00808 if (glevel > 1) for (i = 0; callee[i]; i++) callee[i]->sclass = AUTO;
00809 if (cfunc->sclass != STATIC)
00810 (*IR->export)(cfunc);
00811 if (glevel && IR->stabsym) {
00812 swtoseg(CODE); (*IR->stabsym)(cfunc); }
00813 swtoseg(CODE);
00814 (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);
00815 if (glevel && IR->stabfend)
00816 (*IR->stabfend)(cfunc, lineno);
00817 foreach(stmtlabs, LABELS, checklab, NULL);
00818 exitscope();
00819 expect('}');
00820 labels = stmtlabs = NULL;
00821 retv = NULL;
00822 cfunc = NULL;
00823 }
00824 static void oldparam(Symbol p, void *cl) {
00825 int i;
00826 Symbol *callee = cl;
00827
00828 for (i = 0; callee[i]; i++)
00829 if (p->name == callee[i]->name) {
00830 callee[i] = p;
00831 return;
00832 }
00833 error("declared parameter `%s' is missing\n", p->name);
00834 }
00835 void compound(int loop, struct swtch *swp, int lev) {
00836 Code cp;
00837 int nregs;
00838
00839 walk(NULL, 0, 0);
00840 cp = code(Blockbeg);
00841 enterscope();
00842 assert(level >= LOCAL);
00843 if (level == LOCAL && events.entry)
00844 apply(events.entry, cfunc, NULL);
00845 definept(NULL);
00846 expect('{');
00847 autos = registers = NULL;
00848 if (level == LOCAL && IR->wants_callb
00849 && isstruct(freturn(cfunc->type))) {
00850 retv = genident(AUTO, ptr(freturn(cfunc->type)), level);
00851 retv->defined = 1;
00852 retv->ref = 1;
00853 registers = append(retv, registers);
00854 }
00855 while (kind[t] == CHAR || kind[t] == STATIC
00856 || istypename(t, tsym) && getchr() != ':')
00857 decl(dcllocal);
00858 {
00859 int i;
00860 Symbol *a = ltov(&autos, STMT);
00861 nregs = length(registers);
00862 for (i = 0; a[i]; i++)
00863 registers = append(a[i], registers);
00864 cp->u.block.locals = ltov(®isters, FUNC);
00865 }
00866 if (events.blockentry)
00867 apply(events.blockentry, cp->u.block.locals, NULL);
00868 while (kind[t] == IF || kind[t] == ID)
00869 statement(loop, swp, lev);
00870 walk(NULL, 0, 0);
00871 foreach(identifiers, level, checkref, NULL);
00872 {
00873 int i = nregs, j;
00874 Symbol p;
00875 for ( ; (p = cp->u.block.locals[i]) != NULL; i++) {
00876 for (j = i; j > nregs
00877 && cp->u.block.locals[j-1]->ref < p->ref; j--)
00878 cp->u.block.locals[j] = cp->u.block.locals[j-1];
00879 cp->u.block.locals[j]