home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / decl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-13  |  36.6 KB  |  1,489 lines

  1. #include "c.h"
  2. #pragma warning(disable:4100)
  3. char *fname;
  4. #define add(x,n) (x > INT_MAX-(n) ? (overflow=1,x) : x+(n))
  5. #define chkoverflow(x,n) ((void)add(x,n))
  6. #define bits2bytes(n) (((n) + 7)/8)
  7.  
  8. int DefaultAlignment = 16;
  9.  
  10. static int regcount;
  11.  
  12. static List autos, registers;
  13. Symbol cfunc;           /* current function */
  14. FunctionDescriptor FunctionInfo;
  15. typedef struct tagDefinedFunctions {
  16.     struct tagDefinedFunctions *Next;
  17.     Symbol func;
  18. } DefinedFunctionsList;
  19.  
  20. static DefinedFunctionsList *DefinedFunctions=NULL;
  21.  
  22. Symbol retv;            /* return value location for structs */
  23.  
  24. static void checkref ARGS((Symbol, void *));
  25. static Symbol dclglobal ARGS((int, char *, Type, Coordinate *, int callAttributes));
  26. static Symbol dcllocal (int, char *, Type, Coordinate *,int);
  27. static Symbol dclparam (int, char *, Type, Coordinate *,int);
  28. static Type dclr ARGS((Type, char **, Symbol **, int, int *));
  29. static Type dclr1 ARGS((char **, Symbol **, int, int *));
  30. static void decl ARGS((Symbol(*) (int, char *, Type, Coordinate *,int)));
  31. extern void doconst ARGS((Symbol, void *));
  32. static void doglobal ARGS((Symbol, void *));
  33. static void doextern ARGS((Symbol, void *));
  34. static void exitparams ARGS((Symbol[]));
  35. static void fields ARGS((Type));
  36. static void funcdefn ARGS((int, char *, Type, Symbol[], Coordinate, int));
  37. static void initglobal ARGS((Symbol, int));
  38. static void oldparam ARGS((Symbol, void *));
  39. static Symbol *parameters ARGS((Type));
  40. static Type specifier ARGS((int *, int *, int *));
  41. static Type structdcl ARGS((int));
  42. static Type tnode ARGS((int, Type));
  43.  
  44. static void AddToFunctionsList(Symbol s)
  45. {
  46.     DefinedFunctionsList *rvp;
  47.     if (DefinedFunctions == NULL) {
  48.         DefinedFunctions = allocate(sizeof(DefinedFunctionsList),PERM);
  49.         rvp = DefinedFunctions;
  50.     }
  51.     else {
  52.         rvp = DefinedFunctions;
  53.         while (rvp->Next) {
  54.             rvp = rvp->Next;
  55.         }
  56.         rvp->Next = allocate(sizeof(DefinedFunctionsList),PERM);
  57.         rvp = rvp->Next;
  58.     }
  59.     rvp->func = s;
  60.     rvp->Next = NULL;
  61. }
  62.  
  63. void program()
  64. {
  65.     int n;
  66.  
  67.     level = GLOBAL;
  68.     for (n = 0; t != EOI; n++)
  69.         if (kind[t] == CHAR || kind[t] == STATIC
  70.                 || t == ID || t == '*' || t == '(') {
  71.             decl(dclglobal);
  72.             deallocate(STMT);
  73.             if (!(glevel >= 3 || xref))
  74.                 deallocate(FUNC);
  75.         }
  76.         else if (t == ';') {
  77.             warning("empty declaration\n");
  78.             t = gettok();
  79.         }
  80.         else {
  81.             error("unrecognized declaration\n");
  82.             t = gettok();
  83.         }
  84.     if (n == 0)
  85.         warning("empty input file\n");
  86. }
  87. static Type specifier(int *sclass, int *isRedeclaration, int *attributes)
  88. {
  89.     int cls, cons, sign, size, type, vol;
  90.     int qualifierseen=0;
  91.     Type ty = NULL;
  92.     int isPascal = 0;
  93.  
  94.     if (isRedeclaration)
  95.         *isRedeclaration = 0;
  96.     *attributes = 0;
  97.     cls = vol = cons = sign = size = type = 0;
  98.     if (sclass == NULL)
  99.         cls = AUTO;
  100.     for (;;) {
  101.         int *p, tt = t;
  102. restart:
  103.         switch (t) {
  104.         case AUTO:
  105.         case REGISTER:
  106.             if (level <= GLOBAL && cls == 0)
  107.                 error("invalid use of `%k'\n", t);
  108.             p = &cls;
  109.             t = gettok();
  110.             qualifierseen = 1;
  111.             break;
  112.         case STATIC:
  113.         case EXTERN:
  114.         case TYPEDEF:
  115.             p = &cls;
  116.             t = gettok();
  117.             break;
  118.         case CONST:
  119.             p = &cons;
  120.             t = gettok();
  121.             break;
  122.         case VOLATILE:
  123.             p = &vol;
  124.             t = gettok();
  125.             break;
  126.         case SIGNED:
  127.         case UNSIGNED:
  128.             p = &sign;
  129.             t = gettok();
  130.             qualifierseen = 1;
  131.             break;
  132.         case LONG:
  133.         case SHORT:
  134.             p = &size;
  135.             t = gettok();
  136.             qualifierseen = 1;
  137.             break;
  138.         case VOID:
  139.         case CHAR:
  140.         case INT:
  141.         case FLOAT:
  142.         case DOUBLE:
  143.         case LONGLONG:
  144.             p = &type;
  145.             ty = tsym->type;
  146.             t = gettok();
  147.             qualifierseen = 1;
  148.             break;
  149.         case ENUM:
  150.             p = &type;
  151.             ty = enumdcl();
  152.             break;
  153.         case STRUCT:
  154.         case UNION:
  155.             p = &type;
  156.             ty = structdcl(t);
  157.             break;
  158.         case PASCALKEYW:
  159.             p = &isPascal;
  160.             t = gettok();
  161.             break;
  162.         case STDCALL:
  163.             *attributes = 1;
  164.             t = gettok();
  165.             goto restart;
  166.         case ID:
  167.             if (istypename(t, tsym) && type == 0) {
  168.                 use(tsym, src);
  169.                 ty = tsym->type;
  170.                 p = &type;
  171.                 t = gettok();
  172.             }
  173.             else
  174.                 p = NULL;
  175.             break;
  176.         default:
  177.             p = NULL;
  178.         }
  179.         if (p == NULL)
  180.             break;
  181.         if (*p)
  182.             error("invalid use of `%k'\n", tt);
  183.         *p = tt;
  184.     }
  185.     if (sclass)
  186.         *sclass = cls;
  187.     if (type == 0) {
  188.         if (!qualifierseen && Aflag > 1)
  189.         warning("no type specified. Defaulting to int\n");
  190.         type = INT;
  191.         ty = inttype;
  192.     }
  193.     if (size == SHORT && type != INT
  194.             || size == LONG && type != INT && type != DOUBLE
  195.             || sign && type != INT && type != CHAR && type != LONGLONG) {
  196.         if (isRedeclaration && type == ID) {
  197.             Symbol sy;
  198.  
  199.             sy = lookup(tsym->name, identifiers);
  200.             if (sy == NULL)
  201.                 goto err;
  202.             if (sy->sclass != TYPEDEF)
  203.                 goto err;
  204.             if (sy->type == NULL)
  205.                 goto err;
  206.             if (sy->type->op != size) {
  207.                 if (sy->type->op != ty->op && sy->type->op != sign)
  208.                     goto err;
  209.             }
  210.             warning("redefinition of %s\n", sy->name);
  211.             *isRedeclaration = 1;
  212.             return (sy->type);
  213.         }
  214. err:
  215.         error("invalid type specification\n");
  216.     }
  217.     if (type == CHAR && sign)
  218.         ty = sign == UNSIGNED ? unsignedchar : signedchar;
  219.     else if (type == LONGLONG && sign)
  220.         ty = sign == UNSIGNED ? ulonglongtype : longlongtype;
  221.     else if (size == SHORT)
  222.         ty = sign == UNSIGNED ? unsignedshort : shorttype;
  223.     else if (size == LONG && type == DOUBLE)
  224.         ty = longdouble;
  225.     else if (size == LONG)
  226.         ty = sign == UNSIGNED ? unsignedlong : longtype;
  227.     else if (sign == UNSIGNED && type == INT)
  228.         ty = unsignedtype;
  229.     if (cons == CONST)
  230.         ty = qual(CONST, ty);
  231.     if (vol == VOLATILE)
  232.         ty = qual(VOLATILE, ty);
  233.     if (isPascal == PASCALKEYW)
  234.         ty = qual(PASCALKEYW, ty);
  235.     return ty;
  236. }
  237. static void decl(Symbol(*dcl)(int, char *, Type, Coordinate *, int callAttribute))
  238. {
  239.     int sclass, redeclaration, callAttributes;
  240.     Type ty, ty1;
  241.     static char stop[] = {CHAR, STATIC, ID, 0};
  242.  
  243.     ty = specifier(&sclass, &redeclaration, &callAttributes);
  244.     if (redeclaration) {
  245.         test(';', stop);
  246.         return;
  247.     }
  248.     if (t == ID || t == '*' || t == '(' || t == '[') {
  249.         char *id;
  250.         int dummy;
  251.         Coordinate pos;
  252.         id = NULL;
  253.         pos = src;
  254.         if (level == GLOBAL) {
  255.             Symbol *params = NULL;
  256.             ty1 = dclr(ty, &id, ¶ms, 0, &dummy);
  257.             if (dummy) callAttributes = dummy;
  258.             if (params && id && isfunc(ty1)
  259.                     && (t == '{' || istypename(t, tsym)
  260.                         || (kind[t] == STATIC && t != TYPEDEF))) {
  261.                 if (sclass == TYPEDEF) {
  262.                     error("invalid use of `typedef'\n");
  263.                     sclass = EXTERN;
  264.                 }
  265.                 if (ty1->u.f.oldstyle)
  266.                     exitscope();
  267.                 if (callAttributes) {
  268.                     if (ty1->op != FUNCTION)
  269.                         error("Incorrect usage of _stdcall");
  270.                     else
  271.                         ty1->u.f.isStdCall = 1;
  272.                 }
  273.                 funcdefn(sclass,fname = id, ty1, params, pos, callAttributes);
  274.                 fname = NULL;
  275.                 return;
  276.             }
  277.             else if (params)
  278.                 exitparams(params);
  279.         }
  280.         else {
  281.             int oldAttrib = callAttributes;
  282.             ty1 = dclr(ty, &id, NULL, 0, &callAttributes);
  283.             if (oldAttrib) callAttributes = oldAttrib;
  284.         }
  285.         for (;;) {
  286.             if (Aflag >= 1 && !hasproto(ty1))
  287.                 warning("missing prototype\n");
  288.             if (id == NULL)
  289.                 error("missing identifier\n");
  290.             else if (sclass == TYPEDEF) {
  291.                 Symbol p = lookup(id, identifiers);
  292.                 if (p && p->scope == level) {
  293.                     if (p->type->op == POINTER &&
  294.                             ty1->op == POINTER) {
  295.                         warning("redeclaration of '%s'\n", id);
  296.                     }
  297.                     else if (p->type->op != ty1->op)
  298.                         error("redeclaration of `%s'\n", id);
  299.                 }
  300.                 p = install(id, &identifiers, level,
  301.                             level < LOCAL ? PERM : FUNC);
  302.                 p->type = ty1;
  303.                 p->sclass = TYPEDEF;
  304.                 p->src = pos;
  305.                 if (callAttributes)
  306.                     p->Flags = 1;
  307.             }
  308.             else
  309.                 (void) (*dcl) (sclass, id, ty1, &pos, callAttributes);
  310.             if (t != ',')
  311.                 break;
  312.             t = gettok();
  313.             id = NULL;
  314.             pos = src;
  315.             ty1 = dclr(ty, &id, NULL, 0, &callAttributes);
  316.         }
  317.     }
  318.     else if (ty == NULL
  319.             || !(isenum(ty) ||
  320.                 isstruct(ty) && (*unqual(ty)->u.sym->name < '1' || *unqual(ty)->u.sym->name > '9')))
  321.         error("empty declaration\n");
  322.     test(';', stop);
  323. }
  324. static Symbol dclglobal(int sclass, char *id, Type ty, Coordinate * pos, int callAttributes)
  325. {
  326.     Symbol p;
  327.  
  328.     if (sclass == 0)
  329.         sclass = AUTO;
  330.     else if (sclass != EXTERN && sclass != STATIC) {
  331.         error("invalid storage class `%k' for `%t %s'\n",
  332.             sclass, ty, id);
  333.         sclass = AUTO;
  334.     }
  335.     p = lookup(id, identifiers);
  336.     if (p && p->scope == GLOBAL) {
  337.         if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1))
  338.             ty = compose(ty, p->type);
  339.         else
  340.             error("redeclaration of `%s' previously declared at %w\n", p->name, &p->src);
  341.  
  342.         if (!isfunc(ty) && p->defined && t == '=')
  343.             error("redefinition of `%s' previously defined at %w\n", p->name, &p->src);
  344.  
  345.         if (p->sclass == EXTERN && sclass == STATIC
  346.                 || p->sclass == STATIC && sclass == AUTO
  347.                 || p->sclass == AUTO && sclass == STATIC)
  348.             warning("inconsistent linkage for `%s' previously declared at %w\n", p->name, &p->src);
  349.  
  350.     }
  351.     if (p == NULL || p->scope != GLOBAL) {
  352.         p = install(id, &globals, GLOBAL, PERM);
  353.         p->sclass = sclass;
  354.         if (p->sclass != STATIC) {
  355.             static int nglobals;
  356.             nglobals++;
  357.             if (Aflag >= 2 && nglobals == 512)
  358.                 warning("more than 511 external identifiers\n");
  359.         }
  360.         if (callAttributes)
  361.             p->Flags = 1;
  362.         p->type = ty;
  363.         (*IR->defsymbol) (p);
  364.     }
  365.     else if (p->sclass == EXTERN)
  366.         p->sclass = sclass;
  367.     p->type = ty;
  368.     p->src = *pos;
  369.     if (callAttributes)
  370.         p->Flags = 1;
  371.     {
  372.         Symbol q = lookup(p->name, externals);
  373.         if (q && (p->sclass == STATIC
  374.                 || !eqtype(p->type, q->type, 1)))
  375.             warning("declaration of `%s' does not match previous declaration at %w\n", p->name, &q->src);
  376.  
  377.     }
  378.     if (t == '=' && isfunc(p->type)) {
  379.         error("illegal initialization for `%s'\n", p->name);
  380.         t = gettok();
  381.         initializer(p->type, 0);
  382.     }
  383.     else if (t == '=')
  384.         initglobal(p, 0);
  385.     else if (p->sclass == STATIC && !isfunc(p->type)
  386.             && p->type->size == 0)
  387.         error("undefined size for `%t %s'\n", p->type, p->name);
  388.     return p;
  389. }
  390. static void initglobal(Symbol p, int flag)
  391. {
  392.     Type ty;
  393.  
  394.     if (t == '=' || flag) {
  395.         p->assigned = 1;
  396.         p->references++;
  397.         p->firstuse = StatementCount;
  398.         if (p->sclass == STATIC) {
  399.             for (ty = p->type; isarray(ty); ty = ty->type);
  400.             defglobal(p, isconst(ty) ? LIT : DATA);
  401.         }
  402.         else
  403.             defglobal(p, DATA);
  404.         if (t == '=')
  405.             t = gettok();
  406.         ty = initializer(p->type, 0);
  407.         if (isarray(p->type) && p->type->size == 0)
  408.             p->type = ty;
  409.         if (p->sclass == EXTERN)
  410.             p->sclass = AUTO;
  411.         p->defined = 1;
  412.     }
  413. }
  414. void defglobal(Symbol p, int seg)
  415. {
  416.     p->u.seg = seg;
  417.     swtoseg(p->u.seg);
  418.     if (p->sclass != STATIC)
  419.         (*IR->export) (p);
  420.     if (level == GLOBAL && glevel > 0 && IR->stabsym) {
  421.         (*IR->stabsym) (p);
  422.         swtoseg(p->u.seg);
  423.     }
  424.     (*IR->global) (p);
  425. }
  426.  
  427. static Type dclr(Type basety, char **id, Symbol ** params, int abstract, int *attributes)
  428. {
  429.  
  430.     Type ty;
  431.  
  432.     *attributes = 0;
  433.     ty = dclr1(id, params, abstract, attributes);
  434.     for (; ty; ty = ty->type)
  435.         switch (ty->op) {
  436.         case POINTER:
  437.             basety = ptr(basety);
  438.             break;
  439.         case FUNCTION:
  440.             basety = func(basety, ty->u.f.proto, ty->u.f.oldstyle);
  441.             break;
  442.         case ARRAY:
  443.             basety = array(basety, ty->size, 0);
  444.             break;
  445.         case CONST:
  446.         case VOLATILE:
  447.             basety = qual(ty->op, basety);
  448.             break;
  449.         default:
  450.             assert(0);
  451.         }
  452.     if (Aflag >= 2 && basety->size > 32767)
  453.         warning("more than 32767 bytes in `%t'\n", basety);
  454.     return basety;
  455. }
  456. static Type tnode(int op, Type type)
  457. {
  458.     Type ty;
  459.  
  460.     NEW0(ty, STMT);
  461.     ty->op = op;
  462.     ty->type = type;
  463.     return ty;
  464. }
  465. static Type dclr1(char **id, Symbol ** params, int abstract, int *attributes)
  466. {
  467.     Type ty = NULL;
  468.     Type ty1;
  469.  
  470. restart:
  471.     switch (t) {
  472.     case ID:
  473.         if (id)
  474.             *id = token;
  475.         else
  476.             error("extraneous identifier `%s'\n", token);
  477.         t = gettok();
  478.         break;
  479.     case '*':
  480.         t = gettok();
  481.         if (t == CONST || t == VOLATILE) {
  482.             ty1 = ty = tnode(t, NULL);
  483.             while ((t = gettok()) == CONST || t == VOLATILE)
  484.                 ty1 = tnode(t, ty1);
  485.             ty->type = dclr1(id, params, abstract, attributes);
  486.             ty = ty1;
  487.         }
  488.         else
  489.             ty = dclr1(id, params, abstract, attributes);
  490.         ty = tnode(POINTER, ty);
  491.         break;
  492.     case STDCALL:
  493.         t = gettok();
  494.         *attributes = 1;
  495.         goto restart;
  496.     case '(':
  497.         t = gettok();
  498.         if (t == STDCALL) {
  499.             t = gettok();
  500.             *attributes = 1;
  501.         }
  502.         if (abstract
  503.                 && (t == REGISTER || istypename(t, tsym) || t == ')')) {
  504.             Symbol *args;
  505.             ty = tnode(FUNCTION, ty);
  506.             enterscope();
  507.             if (level > PARAM)
  508.                 enterscope();
  509.             args = parameters(ty);
  510.             exitparams(args);
  511.         }
  512.         else {
  513.             ty = dclr1(id, params, abstract, attributes);
  514.             expect(')');
  515.             if (abstract && ty == NULL
  516.                     && (id == NULL || *id == NULL))
  517.                 return tnode(FUNCTION, NULL);
  518.         } break;
  519.     case '[':
  520.         break;
  521.     default:
  522.         return ty;
  523.     }
  524.     while (t == '(' || t == '[')
  525.         switch (t) {
  526.         case '(':
  527.             t = gettok(); {
  528.                 Symbol *args;
  529.                 ty = tnode(FUNCTION, ty);
  530.                 enterscope();
  531.                 if (level > PARAM)
  532.                     enterscope();
  533.                 args = parameters(ty);
  534.                 if (params && *params == NULL)
  535.                     *params = args;
  536.                 else
  537.                     exitparams(args);
  538.             }
  539.             break;
  540.         case '[':
  541.             t = gettok(); {
  542.                 int n = 0;
  543.                 if (kind[t] == ID) {
  544.                     n = intexpr(']', 1);
  545.                     if (n <= 0) {
  546.                         error("`%d' is an illegal array size\n", n);
  547.                         n = 1;
  548.                     }
  549.                 }
  550.                 else
  551.                     expect(']');
  552.                 ty = tnode(ARRAY, ty);
  553.                 ty->size = n;
  554.             } break;
  555.         default:
  556.             assert(0);
  557.         }
  558.     return ty;
  559. }
  560. static Symbol *parameters(Type fty)
  561. {
  562.     List list = NULL;
  563.     Symbol *params;
  564.     int callAttributes, dummy;
  565.     Type tmpType;
  566.  
  567.     if (kind[t] == STATIC || istypename(t, tsym)) {
  568.         int n = 0;
  569.         Type ty1 = NULL;
  570.         for (;;) {
  571.             Type ty;
  572.             int sclass = 0;
  573.             char *id = NULL;
  574.             if (ty1 && t == ELLIPSIS) {
  575.                 static struct symbol sentinel;
  576.                 if (sentinel.type == NULL) {
  577.                     sentinel.type = voidtype;
  578.                     sentinel.defined = 1;
  579.                 }
  580.                 if (ty1 == voidtype)
  581.                     error("illegal formal parameter types\n");
  582.                 list = append(&sentinel, list);
  583.                 t = gettok();
  584.                 break;
  585.             }
  586.             if (!istypename(t, tsym) && t != REGISTER)
  587.                 error("missing parameter type\n");
  588.             n++;
  589.             tmpType = specifier(&sclass, NULL, &dummy);
  590.             ty = dclr(tmpType, &id, NULL, 1, &callAttributes);
  591.             if (ty == voidtype && (ty1 || id)
  592.                     || ty1 == voidtype)
  593.                 error("illegal formal parameter types\n");
  594.             if (id == NULL)
  595.                 id = stringd(n);
  596.             if (ty != voidtype)
  597.                 list = append(dclparam(sclass, id, ty, &src,callAttributes), list);
  598.             if (Aflag >= 1 && !hasproto(ty))
  599.                 warning("missing prototype\n");
  600.             if (ty1 == NULL)
  601.                 ty1 = ty;
  602.             if (t != ',')
  603.                 break;
  604.             t = gettok();
  605.         }
  606.         fty->u.f.proto = newarray(length(list) + 1,
  607.                                 sizeof(Type *), PERM);
  608.         params = ltov(&list, FUNC);
  609.         for (n = 0; params[n]; n++)
  610.             fty->u.f.proto[n] = params[n]->type;
  611.         fty->u.f.proto[n] = NULL;
  612.         fty->u.f.oldstyle = 0;
  613.     }
  614.     else {
  615.         if (t == ID)
  616.             for (;;) {
  617.                 Symbol p;
  618.  
  619.                 if (t != ID) {
  620.                     error("expecting an identifier\n");
  621.                     break;
  622.                 }
  623.                 p = dclparam(0, token, inttype, &src,callAttributes);
  624.                 p->defined = 0;
  625.                 list = append(p, list);
  626.                 t = gettok();
  627.                 if (t != ',')
  628.                     break;
  629.                 t = gettok();
  630.             }
  631.         params = ltov(&list, FUNC);
  632.         fty->u.f.proto = NULL;
  633.         fty->u.f.oldstyle = 1;
  634.     }
  635.     if (t != ')') {
  636.         static char stop[] = {CHAR, STATIC, IF, ')', 0};
  637.         expect(')');
  638.         skipto('{', stop);
  639.     }
  640.     if (t == ')')
  641.         t = gettok();
  642.     return params;
  643. }
  644. static void exitparams(Symbol params[])
  645. {
  646.     assert(params);
  647.     if (params[0] && !params[0]->defined)
  648.         error("extraneous old-style parameter list\n");
  649.     if (level > PARAM)
  650.         exitscope();
  651.     exitscope();
  652. }
  653.  
  654. static Symbol dclparam(int sclass, char *id, Type ty, Coordinate * pos,int callAttributes)
  655. {
  656.     Symbol p;
  657.  
  658.     if (isfunc(ty))
  659.         ty = ptr(ty);
  660.     else if (isarray(ty))
  661.         ty = atop(ty);
  662.     if (sclass == 0)
  663.         sclass = AUTO;
  664.     else if (sclass != REGISTER) {
  665.         error("invalid storage class `%k' for `%t%s\n",
  666.             sclass, ty, stringf(id ? " %s'" : "' parameter", id));
  667.         sclass = AUTO;
  668.     }
  669.     else if (isvolatile(ty) || isstruct(ty)) {
  670.         warning("register declaration ignored for `%t%s\n",
  671.                 ty, stringf(id ? " %s'" : "' parameter", id));
  672.         sclass = AUTO;
  673.     }
  674.  
  675.     p = lookup(id, identifiers);
  676.     if (p && p->scope == level)
  677.         error("duplicate declaration for `%s' previously declared at %w\n", id, &p->src);
  678.  
  679.     else
  680.         p = install(id, &identifiers, level, FUNC);
  681.     p->sclass = sclass;
  682.     p->src = *pos;
  683.     p->type = ty;
  684.     p->defined = 1;
  685.     if (t == '=') {
  686.         error("illegal initialization for parameter `%s'\n", id);
  687.         t = gettok();
  688.         (void) expr1(0);
  689.     }
  690.     return p;
  691. }
  692. static Type structdcl(int op)
  693. {
  694.     char *tag;
  695.     Type ty;
  696.     Symbol p;
  697.     Coordinate pos;
  698.  
  699.     t = gettok();
  700.     pos = src;
  701.     if (t == ID) {
  702.         tag = token;
  703.         t = gettok();
  704.     }
  705.     else
  706.         tag = "";
  707.     if (t == '{') {
  708.         static char stop[] = {IF, ',', 0};
  709.         ty = newstruct(op, tag);
  710.         ty->u.sym->src = pos;
  711.         ty->u.sym->defined = 1;
  712.         t = gettok();
  713.         if (istypename(t, tsym))
  714.             fields(ty);
  715.         else
  716.             error("invalid %k field declarations\n", op);
  717.         test('}', stop);
  718.     }
  719.     else if (*tag && (p = lookup(tag, types)) != NULL
  720.             && p->type->op == op) {
  721.         ty = p->type;
  722.         if (t == ';' && p->scope < level)
  723.             ty = newstruct(op, tag);
  724.     }
  725.     else {
  726.         if (*tag == 0)
  727.             error("missing %k tag\n", op);
  728.         ty = newstruct(op, tag);
  729.     }
  730.     if (*tag && xref)
  731.         use(ty->u.sym, pos);
  732.     return ty;
  733. }
  734. static void fields(Type ty)
  735. {
  736.     {
  737.         int n = 0;
  738.         int callAttributes;
  739.         int dummy;
  740.  
  741.         while (istypename(t, tsym)) {
  742.             static char stop[] = {IF, CHAR, '}', 0};
  743.             Type ty1 = specifier(NULL, NULL, &callAttributes);
  744.             for (;;) {
  745.                 Field p;
  746.                 char *id = NULL;
  747.  
  748.                 Type fty = dclr(ty1, &id, NULL, 0, &dummy);
  749.                 p = newfield(id, ty, fty);
  750.                 if (Aflag >= 1 && !hasproto(p->type)) {
  751.                     if (id)
  752.                         warning("missing prototype for %s\n", id);
  753.                     else
  754.                         warning("missing prototype\n");
  755.                 }
  756.                 if (t == ':') {
  757.                     if (unqual(p->type) != inttype
  758.                             && unqual(p->type) != unsignedtype) {
  759.                         if (unqual(p->type) != unsignedshort
  760.                                 && unqual(p->type) != unsignedlong)
  761.                             error("`%t' is an illegal bit-field type\n",
  762.                                 p->type);
  763.                         else if (Aflag > 1)
  764.                             warning("promoting %t to int\n", p->type);
  765.                         p->type = inttype;
  766.                     }
  767.                     t = gettok();
  768.                     p->bitsize = (short)intexpr(0, 0);
  769.                     if (p->bitsize > 8 * inttype->size || p->bitsize < 0) {
  770.                         error("`%d' is an illegal bit-field size\n",
  771.                             p->bitsize);
  772.                         p->bitsize = (short)(8 * inttype->size);
  773.                     }
  774.                     else if (p->bitsize == 0 && id) {
  775.                         warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id);
  776.  
  777.                         p->name = stringd(genlabel(1));
  778.                     }
  779.                     p->lsb = 1;
  780.                 }
  781.                 else if (id == NULL && Xflag && isstruct(p->type)) {
  782.                     if (Aflag >= 2)
  783.                         warning("non-ANSI unnamed substructure in `%t'\n", ty);
  784.                     if (p->type->size == 0)
  785.                         error("undefined size for field `%t'\n", p->type);
  786.                     p->name = NULL;
  787.                     break;
  788.                 }
  789.                 else {
  790.                     if (id == 0 && isstruct(p->type)) {
  791.                         if (Aflag >= 2)
  792.                             warning("non-ANSI unnamed substructure\n");
  793.                         if (p->type->size == 0)
  794.                             error("undefined size for field '%t'\n",p->type);
  795.                         p->name = 0;
  796.                         break;
  797.                     }
  798.                     else if (isfunc(p->type))
  799.                         error("`%t' is an illegal field type\n", p->type);
  800.                     else if (p->type->size == 0) {
  801.  
  802.                         warning("undefined size for field `%t %s'\n", p->type, id);
  803.                         p->type->size = p->type->align;
  804.                     }
  805.                 }
  806.                 if (isconst(p->type))
  807.                     ty->u.sym->u.s.cfields = 1;
  808.                 if (isvolatile(p->type))
  809.                     ty->u.sym->u.s.vfields = 1;
  810.                 if (dummy) {
  811.                     if (fty->op == POINTER) {
  812.                         if (fty->type->op != FUNCTION)
  813.                             error("incorrect _stdcall usage");
  814.                         else
  815.                             fty->type->u.f.isStdCall = 1;
  816.                     }
  817.                     else
  818.                         fty->u.f.isStdCall = 1;
  819.                 }
  820.                 n++;
  821.                 if (Aflag >= 2 && n == 128)
  822.                     warning("more than 127 fields in `%t'\n", ty);
  823.                 if (t != ',')
  824.                     break;
  825.                 t = gettok();
  826.             }
  827.             test(';', stop);
  828.         }
  829.     }
  830.     {
  831.         int bits = 0, off = 0, overflow = 0;
  832.         Field p, *q = &ty->u.sym->u.s.flist;
  833.         ty->align = IR->structmetric.align;
  834.         for (p = *q; p; p = p->link) {
  835.             int a = p->type->align ? p->type->align : 1;
  836.             if (a > DefaultAlignment) a = DefaultAlignment;
  837.             if (p->lsb)
  838.                 a = unsignedtype->align;
  839.             if (ty->op == UNION)
  840.                 off = bits = 0;
  841.             else if (p->bitsize == 0 || bits == 0
  842.                     || bits - 1 + p->bitsize > 8 * unsignedtype->size) {
  843.                 off = add(off, bits2bytes(bits - 1));
  844.                 bits = 0;
  845.                 chkoverflow(off, a - 1);
  846.                 off = roundup(off, a);
  847.             }
  848.             if (a > ty->align)
  849.                 ty->align = a;
  850.             p->offset = off;
  851.  
  852.             if (p->lsb) {
  853.                 if (bits == 0)
  854.                     bits = 1;
  855.                 if (IR->little_endian)
  856.                     p->lsb = (short)bits;
  857.                 else
  858.                     p->lsb = (short)(8 * unsignedtype->size - bits + 1 - p->bitsize + 1);
  859.                 bits += p->bitsize;
  860.             }
  861.             else
  862.                 off = add(off, p->type->size);
  863.             if (off + bits2bytes(bits - 1) > ty->size)
  864.                 ty->size = off + bits2bytes(bits - 1);
  865.             if (p->name == NULL
  866.                     || !('1' <= *p->name && *p->name <= '9')) {
  867.                 *q = p;
  868.                 q = &p->link;
  869.             }
  870.         }
  871.         *q = NULL;
  872.         chkoverflow(ty->size, ty->align - 1);
  873.         ty->size = roundup(ty->size, ty->align);
  874.         if (overflow) {
  875.             error("size of `%t' exceeds %d bytes\n", ty, INT_MAX);
  876.             ty->size = INT_MAX & (~(ty->align - 1));
  877.         }
  878.         if (Xflag)
  879.             checkfields(ty);
  880.     }
  881. }
  882. static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt, int callAttributes)
  883. {
  884.     int i, n;
  885.     Symbol *callee, *caller, p;
  886.     Type rty = freturn(ty);
  887.     Code cp;
  888.  
  889.     if (isstruct(rty) && rty->size == 0)
  890.         error("illegal use of incomplete type `%t'\n", rty);
  891.     memset(&FunctionInfo,0,sizeof(FunctionInfo));
  892.     StatementCount = 1;
  893.     for (n = 0; params[n]; n++);
  894.     if (n > 0 && params[n - 1]->name == NULL)
  895.         params[--n] = NULL;
  896.     if (Aflag >= 2 && n > 31)
  897.         warning("more than 31 parameters in function `%s'\n", id);
  898.     for (i=0; i<n;i++) {
  899.         params[i]->firstuse = StatementCount;
  900.         params[i]->x.isArgument = 1;
  901.     }
  902.     StatementCount++;
  903.     if (ty->u.f.oldstyle) {
  904.         caller = params;
  905.         callee = newarray(n + 1, sizeof *callee, FUNC);
  906.         memcpy(callee, caller, (n + 1) * sizeof *callee);
  907.         enterscope();
  908.         assert(level == PARAM);
  909.         while (kind[t] == STATIC || istypename(t, tsym))
  910.             decl(dclparam);
  911.         foreach(identifiers, PARAM, oldparam, callee);
  912.  
  913.         for (i = 0; (p = callee[i]) != NULL; i++) {
  914.             if (!p->defined)
  915.                 callee[i] = dclparam(0, p->name, inttype, &p->src,0);
  916.             *caller[i] = *p;
  917.             caller[i]->sclass = AUTO;
  918.             if (unqual(p->type) == floattype)
  919.                 caller[i]->type = doubletype;
  920.             else
  921.                 caller[i]->type = promote(p->type);
  922.         }
  923.         p = lookup(id, identifiers);
  924.         if (p && p->scope == GLOBAL && isfunc(p->type)
  925.                 && p->type->u.f.proto) {
  926.             Type *proto = p->type->u.f.proto;
  927.             for (i = 0; caller[i] && proto[i]; i++)
  928.                 if (eqtype(unqual(proto[i]),
  929.                         unqual(caller[i]->type), 1) == 0)
  930.                     break;
  931.             if (proto[i] || caller[i])
  932.                 error("conflicting argument declarations for function `%s'\n", id);
  933.  
  934.         }
  935.         else {
  936.             Type *proto = newarray(n + 1, sizeof *proto, PERM);
  937.             if (Aflag >= 1)
  938.                 warning("missing prototype for `%s'\n", id);
  939.             for (i = 0; i < n; i++)
  940.                 proto[i] = caller[i]->type;
  941.             proto[i] = NULL;
  942.             ty = func(rty, proto, 1);
  943.         }
  944.         for (i=0; i < n; i++) {
  945.             callee[i]->x.isArgument = 1;
  946.         }
  947.     }
  948.     else {
  949.         callee = params;
  950.         caller = newarray(n + 1, sizeof *caller, FUNC);
  951.         for (i = 0; (p = callee[i]) != NULL && p->name; i++) {
  952.             NEW(caller[i], FUNC);
  953.             *caller[i] = *p;
  954.             caller[i]->type = promote(p->type);
  955.             caller[i]->sclass = AUTO;
  956.             if ('1' <= *p->name && *p->name <= '9')
  957.                 error("missing name for parameter %d to function `%s'\n", i + 1, id);
  958.  
  959.         }
  960.         caller[i] = NULL;
  961.     }
  962.     for (i = 0; (p = callee[i]) != NULL; i++)
  963.         if (p->type->size == 0) {
  964.             error("undefined size for parameter `%t %s'\n",
  965.                 p->type, p->name);
  966.             caller[i]->type = p->type = inttype;
  967.         }
  968.     p = lookup(id, identifiers);
  969.     if (p && isfunc(p->type) && p->defined)
  970.         error("redefinition of `%s' previously defined at %w\n",
  971.             p->name, &p->src);
  972.     cfunc = dclglobal(sclass, id, ty, &pt, callAttributes);
  973.     cfunc->u.f.label = genlabel(1);
  974.     cfunc->u.f.callee = callee;
  975.     cfunc->u.f.pt = src;
  976.     cfunc->defined = 1;
  977.     cfunc->Flags = (unsigned char)callAttributes;
  978.     if (xref)
  979.         use(cfunc, cfunc->src);
  980.     if (Pflag)
  981.         printproto(cfunc, cfunc->u.f.callee);
  982.     if (ncalled >= 0)
  983.         ncalled = findfunc(cfunc->name, pt.file);
  984.     labels = table(NULL, LABELS);
  985.     stmtlabs = table(NULL, LABELS);
  986.     refinc = (float) 1.0;
  987.     regcount = 0;
  988.     codelist = &codehead;
  989.     codelist->next = NULL;
  990.     definept(NULL);
  991.     if (!IR->wants_callb && isstruct(rty))
  992.         retv = genident(AUTO, ptr(rty), PARAM);
  993.     cp = compound(0, NULL, 0);
  994.     FunctionInfo.cp = cp;
  995.     for (cp = codelist; cp->kind < Label; cp = cp->prev);
  996.     if (cp->kind != Jump) {
  997.         if (rty != voidtype
  998.                 && (rty != inttype || Aflag >= 1))
  999.             warning("missing return value\n");
  1000.         retcode(NULL);
  1001.     }
  1002.     definelab(cfunc->u.f.label);
  1003.     definept(NULL);
  1004.     if (events.exit)
  1005.         apply(events.exit, cfunc, NULL);
  1006.     walk(NULL, 0, 0);
  1007.     exitscope();
  1008.     assert(level == PARAM);
  1009.     foreach(identifiers, level, checkref, NULL);
  1010.     if (!IR->wants_callb && isstruct(rty)) {
  1011.         Symbol *a;
  1012.         a = newarray(n + 2, sizeof *a, FUNC);
  1013.         a[0] = retv;
  1014.         memcpy(&a[1], callee, (n + 1) * sizeof *callee);
  1015.         callee = a;
  1016.         a = newarray(n + 2, sizeof *a, FUNC);
  1017.         NEW(a[0], FUNC);
  1018.         *a[0] = *retv;
  1019.         memcpy(&a[1], caller, (n + 1) * sizeof *callee);
  1020.         caller = a;
  1021.     }
  1022.     if (!IR->wants_argb)
  1023.         for (i = 0; caller[i]; i++)
  1024.             if (isstruct(caller[i]->type)) {
  1025.                 caller[i]->type = ptr(caller[i]->type);
  1026.                 callee[i]->type = ptr(callee[i]->type);
  1027.                 caller[i]->structarg = callee[i]->structarg = 1;
  1028.             }
  1029.     if (glevel > 1)
  1030.         for (i = 0; callee[i]; i++)
  1031.             callee[i]->sclass = AUTO;
  1032. #if 0
  1033.     if (cfunc->sclass != STATIC)
  1034.         (*IR->export) (cfunc);
  1035. #endif
  1036.     if (glevel) {
  1037.         swtoseg(CODE);
  1038.         (*IR->stabsym) (cfunc);
  1039.     }
  1040.     swtoseg(CODE);
  1041.     if (cfunc->u.f.ncalls)
  1042.         FunctionHasCalls = 1;
  1043.     else
  1044.         FunctionHasCalls = 0;
  1045.  
  1046.     (*IR->function) (cfunc, caller, callee, cfunc->u.f.ncalls);
  1047. #if 1
  1048.     if (cfunc->sclass != STATIC)
  1049.         (*IR->export) (cfunc);
  1050. #endif
  1051.     if (glevel && IR->stabfend)
  1052.         (*IR->stabfend) (cfunc, lineno);
  1053.     outflush();
  1054.     foreach(stmtlabs, LABELS, checklab, NULL);
  1055.     exitscope();
  1056.     expect('}');
  1057.     AddToFunctionsList(cfunc);
  1058.     labels = stmtlabs = NULL;
  1059.     retv = NULL;
  1060.     cfunc = NULL;
  1061.     ResetExceptions();
  1062. }
  1063. static void oldparam(Symbol p, void *cl)
  1064. {
  1065.     int i;
  1066.     Symbol *callee = cl;
  1067.  
  1068.     for (i = 0; callee[i]; i++)
  1069.         if (p->name == callee[i]->name) {
  1070.             callee[i] = p;
  1071.             return;
  1072.         }
  1073.     error("declared parameter `%s' is missing\n", p->name);
  1074. }
  1075. Code compound(int loop, struct swtch * swp, int lev)
  1076. {
  1077.     Code cp;
  1078.     int nregs;
  1079.  
  1080.     walk(NULL, 0, 0);
  1081.     cp = code(Blockbeg);
  1082.     enterscope();
  1083.     assert(level >= LOCAL);
  1084.     autos = registers = NULL;
  1085.     if (level == LOCAL && IR->wants_callb
  1086.             && isstruct(freturn(cfunc->type))) {
  1087.         retv = genident(AUTO, ptr(freturn(cfunc->type)), level);
  1088.         retv->defined = 1;
  1089.         retv->ref = (float) 1.0;
  1090.         registers = append(retv, registers);
  1091.     }
  1092.     if (level == LOCAL && events.entry)
  1093.         apply(events.entry, cfunc, NULL);
  1094.     expect('{');
  1095.     while (kind[t] == CHAR || kind[t] == STATIC
  1096.             || istypename(t, tsym) && getchr() != ':')
  1097.         decl(dcllocal);
  1098.     {
  1099.         int i;
  1100.         Symbol *a = ltov(&autos, STMT);
  1101.         nregs = length(registers);
  1102.         for (i = 0; a[i]; i++)
  1103.             registers = append(a[i], registers);
  1104.         cp->u.block.locals = ltov(®isters, FUNC);
  1105.     }
  1106.     while (kind[t] == IF || kind[t] == ID)
  1107.         statement(loop, swp, lev);
  1108.     walk(NULL, 0, 0);
  1109.     foreach(identifiers, level, checkref, NULL);
  1110.     {
  1111.         int i = nregs, j;
  1112.         Symbol p;
  1113.         for (; (p = cp->u.block.locals[i]) != NULL; i++) {
  1114.             for (j = i; j > nregs
  1115.                     && cp->u.block.locals[j - 1]->ref < p->ref; j--)
  1116.                 cp->u.block.locals[j] = cp->u.block.locals[j - 1];
  1117.             cp->u.block.locals[j] = p;
  1118.         }
  1119.     }
  1120.     cp->u.block.level = level;
  1121.     cp->u.block.identifiers = identifiers;
  1122.     cp->u.block.types = types;
  1123.     code(Blockend)->u.begin = cp;
  1124.     if (level > LOCAL) {
  1125.         exitscope();
  1126.         expect('}');
  1127.     }
  1128.     return cp;
  1129. }
  1130. static void checkref(Symbol p, void *cl)
  1131. {
  1132.     if (p->scope >= PARAM
  1133.             && (isvolatile(p->type) || isfunc(p->type)))
  1134.         p->addressed = 1;
  1135.     if (/*Aflag >= 2 &&*/ p->defined && p->ref == 0) {
  1136.         if (p->sclass == STATIC)
  1137.             warning("static `%t %s' is not referenced\n",
  1138.                     p->type, p->name);
  1139.         else if (p->scope == PARAM && Aflag > 1)
  1140.             warning("parameter `%t %s' is not referenced\n",
  1141.                     p->type, p->name);
  1142.         else if (p->scope >= LOCAL && p->sclass != EXTERN)
  1143.             warning("local `%t %s' is not referenced\n",
  1144.                     p->type, p->name);
  1145.     }
  1146. #if 0
  1147.     if (p->sclass == AUTO
  1148.             && (p->scope == PARAM && regcount == 0
  1149.                 || p->scope >= LOCAL)
  1150.             && !p->addressed && isscalar(p->type) && p->ref >= 3.0)
  1151.         p->sclass = REGISTER;
  1152. #endif
  1153.     if (p->scope >= LOCAL && p->sclass == EXTERN) {
  1154.         Symbol q = lookup(p->name, externals);
  1155.         assert(q);
  1156.         q->ref += p->ref;
  1157.     }
  1158.     if (p->scope >= LOCAL && p->sclass != EXTERN ) {
  1159.  
  1160.         if (Aflag &&
  1161.             p->assigned == 1 && p->references == 1 && p->addressed == 0) {
  1162.             warning(" %s is assigned a value that is never used\n",p->name);
  1163.         }
  1164.         else if (p->assigned == 0 && p->references > 0) {
  1165.             if (p->type && p->type->op != ARRAY && p->type->op != STRUCT)
  1166.             warning(" possible usage of %s before definition\n",p->name);
  1167.         }
  1168.     }
  1169.     if (level == GLOBAL && p->sclass == STATIC && !p->defined
  1170.             && isfunc(p->type) && p->ref)
  1171.         error("undefined static `%t %s'\n", p->type, p->name);
  1172.     assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));
  1173. }
  1174. static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate * pos,int callAttributes)
  1175. {
  1176.     Symbol p, q;
  1177.  
  1178.     if (sclass == 0)
  1179.         sclass = isfunc(ty) ? EXTERN : AUTO;
  1180.     else if (isfunc(ty) && sclass != EXTERN) {
  1181.         error("invalid storage class `%k' for `%t %s'\n",
  1182.             sclass, ty, id);
  1183.         sclass = EXTERN;
  1184.     }
  1185.     else if (sclass == REGISTER
  1186.             && (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
  1187.         warning("register declaration ignored for `%t %s'\n",
  1188.                 ty, id);
  1189.         sclass = AUTO;
  1190.     }
  1191.     q = lookup(id, identifiers);
  1192.     if (q && q->scope >= level
  1193.             || q && q->scope == PARAM && level == LOCAL)
  1194.         if (sclass == EXTERN && q->sclass == EXTERN
  1195.                 && eqtype(q->type, ty, 1))
  1196.             ty = compose(ty, q->type);
  1197.         else
  1198.             error("redeclaration of `%s' previously declared at %w\n", q->name, &q->src);
  1199.  
  1200.     assert(level >= LOCAL);
  1201.     p = install(id, &identifiers, level, FUNC);
  1202.     p->type = ty;
  1203.     p->sclass = sclass;
  1204.     p->src = *pos;
  1205.     p->Flags = callAttributes;
  1206.     switch (sclass) {
  1207.     case EXTERN:
  1208.         if (q && q->scope == GLOBAL && q->sclass == STATIC) {
  1209.             p->sclass = STATIC;
  1210.             p->scope = GLOBAL;
  1211.             (*IR->defsymbol) (p);
  1212.             p->sclass = EXTERN;
  1213.             p->scope = level;
  1214.         }
  1215.         else
  1216.             (*IR->defsymbol) (p);
  1217.         {
  1218.             Symbol r = lookup(id, externals);
  1219.             if (r == NULL) {
  1220.                 r = install(p->name, &externals, GLOBAL, PERM);
  1221.                 r->src = p->src;
  1222.                 r->type = p->type;
  1223.                 r->sclass = p->sclass;
  1224.                 q = lookup(id, globals);
  1225.                 if (q && q->sclass != TYPEDEF && q->sclass != ENUM)
  1226.                     r = q;
  1227.             }
  1228.             if (r && !eqtype(r->type, p->type, 1))
  1229.                 warning("declaration of `%s' does not match previous declaration at %w\n", r->name, &r->src);
  1230.  
  1231.         } break;
  1232.     case STATIC:
  1233.         (*IR->defsymbol) (p);
  1234.         initglobal(p, 0);
  1235.         if (!p->defined)
  1236.             if (p->type->size > 0) {
  1237.                 defglobal(p, BSS);
  1238.                 (*IR->space) (p->type->size);
  1239.             }
  1240.             else
  1241.                 error("undefined size for `%t %s'\n",
  1242.                     p->type, p->name);
  1243.         p->defined = 1;
  1244.         break;
  1245.     case REGISTER:
  1246.         registers = append(p, registers);
  1247.         regcount++;
  1248.         p->defined = 1;
  1249.         break;
  1250.     case AUTO:
  1251.         autos = append(p, autos);
  1252.         p->defined = 1;
  1253.         break;
  1254.     default:
  1255.         assert(0);
  1256.     }
  1257.     if (t == '=') {
  1258.         Tree e;
  1259.         if (sclass == EXTERN)
  1260.             error("illegal initialization of `extern %s'\n", id);
  1261.         t = gettok();
  1262.         definept(NULL);
  1263.         if (isscalar(p->type)
  1264.                 || isstruct(p->type) && t != '{') {
  1265.             if (t == '{') {
  1266.                 t = gettok();
  1267.                 e = expr1(0);
  1268.                 expect('}');
  1269.             }
  1270.             else
  1271.                 e = expr1(0);
  1272.         }
  1273.         else {
  1274.             Symbol t1;
  1275.             Type ty = p->type, ty1 = ty;
  1276.             while (isarray(ty1))
  1277.                 ty1 = ty1->type;
  1278.             if (!isconst(ty) && (!isarray(ty) || !isconst(ty1)))
  1279.                 ty = qual(CONST, ty);
  1280.             t1 = genident(STATIC, ty, GLOBAL);
  1281.             initglobal(t1, 1);
  1282.             if (isarray(p->type) && p->type->size == 0
  1283.                     && t1->type->size > 0)
  1284.                 p->type = array(p->type->type,
  1285.                                 t1->type->size / t1->type->type->size, 0);
  1286.             e = idtree(t1);
  1287.         }
  1288.         walk(root(asgn(p, e)), 0, 0);
  1289.         p->ref = (float) 1.0;
  1290.         p->firstuse = p->lastuse = StatementCount;
  1291.     }
  1292.     if (!isfunc(p->type) && p->defined && p->type->size <= 0)
  1293.         error("undefined size for `%t %s'\n", p->type, id);
  1294.     return p;
  1295. }
  1296. void finalize(void)
  1297. {
  1298.     foreach(externals, GLOBAL, doextern, NULL);
  1299.     foreach(identifiers, GLOBAL, doglobal, NULL);
  1300.     foreach(identifiers, GLOBAL, checkref, NULL);
  1301.     foreach(constants, CONSTANTS, doconst, NULL);
  1302. }
  1303. static void doextern(Symbol p, void *cl)
  1304. {
  1305.     Symbol q = lookup(p->name, identifiers);
  1306.  
  1307.     if (q)
  1308.         q->ref += p->ref;
  1309.     else {
  1310.         (*IR->defsymbol) (p);
  1311.         (*IR->import) (p);
  1312.     }
  1313. }
  1314. static void doglobal(Symbol p,void *cl)
  1315. {
  1316.     if (!p->defined && (p->sclass == EXTERN
  1317.                         || isfunc(p->type) && p->sclass == AUTO))
  1318.         (*IR->import) (p);
  1319.     else if (!p->defined && !isfunc(p->type)
  1320.             && (p->sclass == AUTO || p->sclass == STATIC)) {
  1321.         if (isarray(p->type)
  1322.                 && p->type->size == 0 && p->type->type->size > 0)
  1323.             p->type = array(p->type->type, 1, 0);
  1324.         if (p->type->size > 0) {
  1325.             defglobal(p, BSS);
  1326.             (*IR->space) (p->type->size);
  1327.         }
  1328.         else
  1329.             error("undefined size for `%t %s'\n",
  1330.                 p->type, p->name);
  1331.         p->defined = 1;
  1332.     }
  1333.     if (Pflag
  1334.             && !isfunc(p->type)
  1335.             && !p->generated && p->sclass != EXTERN)
  1336.         printdecl(p, p->type);
  1337. }
  1338. void doconst(Symbol p,void * cl)
  1339. {
  1340.     if (p->u.c.loc) {
  1341.         assert(p->u.c.loc->u.seg == 0);
  1342.         defglobal(p->u.c.loc, LIT);
  1343.         if (isarray(p->type))
  1344.             (*IR->defstring) (p->type->size, p->u.c.v.p);
  1345.         else
  1346.             (*IR->defconst) (ttob(p->type), p->u.c.v);
  1347.         p->u.c.loc->defined = 1;
  1348.         p->u.c.loc = NULL;
  1349.     }
  1350. }
  1351. void checklab(Symbol p, void *cl)
  1352. {
  1353.     if (!p->defined)
  1354.         error("undefined label `%s'\n", p->name);
  1355.     p->defined = 1;
  1356. }
  1357.  
  1358. Type enumdcl(void)
  1359. {
  1360.     char *tag;
  1361.     Type ty;
  1362.     Symbol p;
  1363.     Coordinate pos;
  1364.  
  1365.     t = gettok();
  1366.     pos = src;
  1367.     p = NULL;           /* Better be sure that p is initialized before use */
  1368.     if (t == ID) {
  1369.         tag = token;
  1370.         t = gettok();
  1371.     }
  1372.     else
  1373.         tag = "";
  1374.     if (t == '{') {
  1375.         static char follow[] = {IF, 0};
  1376.         int n = 0, k = -1;
  1377.         List idlist = 0;
  1378.         ty = newstruct(ENUM, tag);
  1379.         t = gettok();
  1380.         if (t != ID)
  1381.             error("expecting an enumerator identifier\n");
  1382.         while (t == ID) {
  1383.             char *id = token;
  1384.             Coordinate s;
  1385.             if (tsym && tsym->scope == level)
  1386.                 error("redeclaration of `%s' previously declared at %w\n",
  1387.                     token, &tsym->src);
  1388.             s = src;
  1389.             t = gettok();
  1390.             if (t == '=') {
  1391.                 t = gettok();
  1392.                 k = intexpr(0, 0);
  1393.             }
  1394.             else {
  1395.                 if (k == INT_MAX)
  1396.                     error("overflow in value for enumeration constant `%s'\n", id);
  1397.                 k++;
  1398.             }
  1399.             p = install(id, &identifiers, level, level < LOCAL ? PERM : FUNC);
  1400.             p->src = s;
  1401.             p->type = ty;
  1402.             p->sclass = ENUM;
  1403.             p->u.value = k;
  1404.             idlist = append(p, idlist);
  1405.             n++;
  1406.             if (Aflag >= 2 && n == 128)
  1407.                 warning("more than 127 enumeration constants in `%t'\n", ty);
  1408.             if (t != ',')
  1409.                 break;
  1410.             t = gettok();
  1411.             if (Aflag >= 2 && t == '}')
  1412.                 warning("non-ANSI trailing comma in enumerator list\n");
  1413.         }
  1414.         test('}', follow);
  1415.         ty->type = inttype;
  1416.         ty->size = ty->type->size;
  1417.         ty->align = ty->type->align;
  1418.         ty->u.sym->u.idlist = ltov(&idlist, PERM);
  1419.         ty->u.sym->defined = 1;
  1420.     }
  1421.     else if ((p = lookup(tag, types)) != NULL && p->type->op == ENUM) {
  1422.         ty = p->type;
  1423.         if (t == ';')
  1424.             error("empty declaration\n");
  1425.     }
  1426.     else {
  1427.         error("unknown enumeration `%s'\n", tag);
  1428.         ty = newstruct(ENUM, tag);
  1429.         ty->type = inttype;
  1430.     }
  1431.     if (*tag && xref)
  1432.         use(p, pos);
  1433.     return ty;
  1434. }
  1435.  
  1436. Type typename(void)
  1437. {
  1438.     int callAttributes = 0;
  1439.     Type ty = specifier(NULL, NULL, &callAttributes);
  1440.  
  1441.     if (t == '*' || t == '(' || t == '[') {
  1442.         ty = dclr(ty, NULL, NULL, 1, &callAttributes);
  1443.         if (Aflag >= 1 && !hasproto(ty))
  1444.             warning("missing prototype\n");
  1445.     }
  1446.     return ty;
  1447. }
  1448.  
  1449. void DumpDefinedFunctions(void)
  1450. {
  1451.     DefinedFunctionsList *rvp;
  1452.  
  1453.     rvp = DefinedFunctions;
  1454.     while (rvp) {
  1455.         if (rvp->func->scope == GLOBAL && rvp->func->sclass != STATIC) 
  1456.             fprintf(xrefFile,"e %s %d\n",rvp->func->name,rvp->func->src.y);
  1457.         rvp = rvp->Next;
  1458.     }
  1459.     rvp = DefinedFunctions;
  1460.     while (rvp) {
  1461.         if (rvp->func->sclass == STATIC) 
  1462.             fprintf(xrefFile,"s %s %d\n",rvp->func->name,rvp->func->src.y);
  1463.         rvp = rvp->Next;
  1464.     }
  1465. }
  1466.  
  1467. void CheckStaticUses(void)
  1468. {
  1469.  
  1470.     DefinedFunctionsList *rvp;
  1471.  
  1472.     rvp = DefinedFunctions;
  1473.     return;
  1474.     while (rvp) {
  1475.         if (rvp->func->sclass == STATIC) {
  1476.             if (rvp->func->x.callused == 0 && rvp->func->ref == 0.0) {
  1477.                 warning("static function %s is never used\n",rvp->func->name);
  1478.             }
  1479.         }
  1480.         rvp = rvp->Next;
  1481.     }    
  1482. }
  1483.  
  1484. int GetLastFunctionLabel(void)
  1485. {
  1486.     return cfunc->u.f.label;
  1487. }
  1488.  
  1489.