Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

decl.c

Go to the documentation of this file.
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;       /* current function */
00011 Symbol retv;        /* return value location for structs */
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, &params, 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(&registers, 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]