13e12c5d1SDavid du Colombier #include "cc.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier Node*
dodecl(void (* f)(int,Type *,Sym *),int c,Type * t,Node * n)43e12c5d1SDavid du Colombier dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier Sym *s;
73e12c5d1SDavid du Colombier Node *n1;
83e12c5d1SDavid du Colombier long v;
93e12c5d1SDavid du Colombier
103e12c5d1SDavid du Colombier nearln = lineno;
113e12c5d1SDavid du Colombier lastfield = 0;
123e12c5d1SDavid du Colombier
133e12c5d1SDavid du Colombier loop:
143e12c5d1SDavid du Colombier if(n != Z)
153e12c5d1SDavid du Colombier switch(n->op) {
163e12c5d1SDavid du Colombier default:
173e12c5d1SDavid du Colombier diag(n, "unknown declarator: %O", n->op);
183e12c5d1SDavid du Colombier break;
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier case OARRAY:
213e12c5d1SDavid du Colombier t = typ(TARRAY, t);
223e12c5d1SDavid du Colombier t->width = 0;
233e12c5d1SDavid du Colombier n1 = n->right;
243e12c5d1SDavid du Colombier n = n->left;
253e12c5d1SDavid du Colombier if(n1 != Z) {
263e12c5d1SDavid du Colombier complex(n1);
273e12c5d1SDavid du Colombier v = -1;
283e12c5d1SDavid du Colombier if(n1->op == OCONST)
29219b2ee8SDavid du Colombier v = n1->vconst;
303e12c5d1SDavid du Colombier if(v <= 0) {
313e12c5d1SDavid du Colombier diag(n, "array size must be a positive constant");
323e12c5d1SDavid du Colombier v = 1;
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier t->width = v * t->link->width;
353e12c5d1SDavid du Colombier }
363e12c5d1SDavid du Colombier goto loop;
373e12c5d1SDavid du Colombier
383e12c5d1SDavid du Colombier case OIND:
393e12c5d1SDavid du Colombier t = typ(TIND, t);
407dd7cddfSDavid du Colombier t->garb = n->garb;
413e12c5d1SDavid du Colombier n = n->left;
423e12c5d1SDavid du Colombier goto loop;
433e12c5d1SDavid du Colombier
443e12c5d1SDavid du Colombier case OFUNC:
453e12c5d1SDavid du Colombier t = typ(TFUNC, t);
463e12c5d1SDavid du Colombier t->down = fnproto(n);
473e12c5d1SDavid du Colombier n = n->left;
483e12c5d1SDavid du Colombier goto loop;
493e12c5d1SDavid du Colombier
503e12c5d1SDavid du Colombier case OBIT:
513e12c5d1SDavid du Colombier n1 = n->right;
523e12c5d1SDavid du Colombier complex(n1);
533e12c5d1SDavid du Colombier lastfield = -1;
543e12c5d1SDavid du Colombier if(n1->op == OCONST)
55219b2ee8SDavid du Colombier lastfield = n1->vconst;
563e12c5d1SDavid du Colombier if(lastfield < 0) {
573e12c5d1SDavid du Colombier diag(n, "field width must be non-negative constant");
583e12c5d1SDavid du Colombier lastfield = 1;
593e12c5d1SDavid du Colombier }
603e12c5d1SDavid du Colombier if(lastfield == 0) {
613e12c5d1SDavid du Colombier lastbit = 0;
623e12c5d1SDavid du Colombier firstbit = 1;
633e12c5d1SDavid du Colombier if(n->left != Z) {
643e12c5d1SDavid du Colombier diag(n, "zero width named field");
653e12c5d1SDavid du Colombier lastfield = 1;
663e12c5d1SDavid du Colombier }
673e12c5d1SDavid du Colombier }
68219b2ee8SDavid du Colombier if(!typei[t->etype]) {
693e12c5d1SDavid du Colombier diag(n, "field type must be int-like");
707dd7cddfSDavid du Colombier t = types[TINT];
713e12c5d1SDavid du Colombier lastfield = 1;
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier if(lastfield > tfield->width*8) {
743e12c5d1SDavid du Colombier diag(n, "field width larger than field unit");
753e12c5d1SDavid du Colombier lastfield = 1;
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier lastbit += lastfield;
783e12c5d1SDavid du Colombier if(lastbit > tfield->width*8) {
793e12c5d1SDavid du Colombier lastbit = lastfield;
803e12c5d1SDavid du Colombier firstbit = 1;
813e12c5d1SDavid du Colombier }
823e12c5d1SDavid du Colombier n = n->left;
833e12c5d1SDavid du Colombier goto loop;
843e12c5d1SDavid du Colombier
853e12c5d1SDavid du Colombier case ONAME:
863e12c5d1SDavid du Colombier if(f == NODECL)
873e12c5d1SDavid du Colombier break;
883e12c5d1SDavid du Colombier s = n->sym;
893e12c5d1SDavid du Colombier (*f)(c, t, s);
903e12c5d1SDavid du Colombier if(s->class == CLOCAL)
913e12c5d1SDavid du Colombier s = mkstatic(s);
923e12c5d1SDavid du Colombier firstbit = 0;
933e12c5d1SDavid du Colombier n->sym = s;
943e12c5d1SDavid du Colombier n->type = s->type;
95219b2ee8SDavid du Colombier n->xoffset = s->offset;
963e12c5d1SDavid du Colombier n->class = s->class;
973e12c5d1SDavid du Colombier n->etype = TVOID;
983e12c5d1SDavid du Colombier if(n->type != T)
993e12c5d1SDavid du Colombier n->etype = n->type->etype;
1003e12c5d1SDavid du Colombier if(debug['d'])
1013e12c5d1SDavid du Colombier dbgdecl(s);
102219b2ee8SDavid du Colombier acidvar(s);
1033e12c5d1SDavid du Colombier s->varlineno = lineno;
1043e12c5d1SDavid du Colombier break;
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier lastdcl = t;
1073e12c5d1SDavid du Colombier return n;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier
1103e12c5d1SDavid du Colombier Sym*
mkstatic(Sym * s)1113e12c5d1SDavid du Colombier mkstatic(Sym *s)
1123e12c5d1SDavid du Colombier {
1133e12c5d1SDavid du Colombier Sym *s1;
1143e12c5d1SDavid du Colombier
1153e12c5d1SDavid du Colombier if(s->class != CLOCAL)
1163e12c5d1SDavid du Colombier return s;
1179a747e4fSDavid du Colombier snprint(symb, NSYMB, "%s$%d", s->name, s->block);
1183e12c5d1SDavid du Colombier s1 = lookup();
1193e12c5d1SDavid du Colombier if(s1->class != CSTATIC) {
1203e12c5d1SDavid du Colombier s1->type = s->type;
1213e12c5d1SDavid du Colombier s1->offset = s->offset;
1223e12c5d1SDavid du Colombier s1->block = s->block;
1233e12c5d1SDavid du Colombier s1->class = CSTATIC;
1243e12c5d1SDavid du Colombier }
1253e12c5d1SDavid du Colombier return s1;
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier /*
1293e12c5d1SDavid du Colombier * make a copy of a typedef
130219b2ee8SDavid du Colombier * the problem is to split out incomplete
1313e12c5d1SDavid du Colombier * arrays so that it is in the variable
1323e12c5d1SDavid du Colombier * rather than the typedef.
1333e12c5d1SDavid du Colombier */
1343e12c5d1SDavid du Colombier Type*
tcopy(Type * t)1353e12c5d1SDavid du Colombier tcopy(Type *t)
1363e12c5d1SDavid du Colombier {
1373e12c5d1SDavid du Colombier Type *tl, *tx;
1383e12c5d1SDavid du Colombier int et;
1393e12c5d1SDavid du Colombier
1403e12c5d1SDavid du Colombier if(t == T)
1413e12c5d1SDavid du Colombier return t;
1423e12c5d1SDavid du Colombier et = t->etype;
1433e12c5d1SDavid du Colombier if(typesu[et])
1443e12c5d1SDavid du Colombier return t;
1453e12c5d1SDavid du Colombier tl = tcopy(t->link);
1463e12c5d1SDavid du Colombier if(tl != t->link ||
1473e12c5d1SDavid du Colombier (et == TARRAY && t->width == 0)) {
14880ee5cbfSDavid du Colombier tx = copytyp(t);
1493e12c5d1SDavid du Colombier tx->link = tl;
1503e12c5d1SDavid du Colombier return tx;
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier return t;
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier
1553e12c5d1SDavid du Colombier Node*
doinit(Sym * s,Type * t,long o,Node * a)1563e12c5d1SDavid du Colombier doinit(Sym *s, Type *t, long o, Node *a)
1573e12c5d1SDavid du Colombier {
1583e12c5d1SDavid du Colombier Node *n;
1593e12c5d1SDavid du Colombier
1603e12c5d1SDavid du Colombier if(t == T)
1613e12c5d1SDavid du Colombier return Z;
1623e12c5d1SDavid du Colombier if(s->class == CEXTERN) {
1633e12c5d1SDavid du Colombier s->class = CGLOBL;
1643e12c5d1SDavid du Colombier if(debug['d'])
1653e12c5d1SDavid du Colombier dbgdecl(s);
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier if(debug['i']) {
1683e12c5d1SDavid du Colombier print("t = %T; o = %ld; n = %s\n", t, o, s->name);
1693e12c5d1SDavid du Colombier prtree(a, "doinit value");
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier
1723e12c5d1SDavid du Colombier
1733e12c5d1SDavid du Colombier n = initlist;
1743e12c5d1SDavid du Colombier if(a->op == OINIT)
1753e12c5d1SDavid du Colombier a = a->left;
1763e12c5d1SDavid du Colombier initlist = a;
1773e12c5d1SDavid du Colombier
1783e12c5d1SDavid du Colombier a = init1(s, t, o, 0);
1793e12c5d1SDavid du Colombier if(initlist != Z)
1803e12c5d1SDavid du Colombier diag(initlist, "more initializers than structure: %s",
1813e12c5d1SDavid du Colombier s->name);
1823e12c5d1SDavid du Colombier initlist = n;
1833e12c5d1SDavid du Colombier
1843e12c5d1SDavid du Colombier return a;
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier
1873e12c5d1SDavid du Colombier /*
1883e12c5d1SDavid du Colombier * get next major operator,
1893e12c5d1SDavid du Colombier * dont advance initlist.
1903e12c5d1SDavid du Colombier */
1913e12c5d1SDavid du Colombier Node*
peekinit(void)1923e12c5d1SDavid du Colombier peekinit(void)
1933e12c5d1SDavid du Colombier {
1943e12c5d1SDavid du Colombier Node *a;
1953e12c5d1SDavid du Colombier
1963e12c5d1SDavid du Colombier a = initlist;
1973e12c5d1SDavid du Colombier
1983e12c5d1SDavid du Colombier loop:
1993e12c5d1SDavid du Colombier if(a == Z)
2003e12c5d1SDavid du Colombier return a;
2013e12c5d1SDavid du Colombier if(a->op == OLIST) {
2023e12c5d1SDavid du Colombier a = a->left;
2033e12c5d1SDavid du Colombier goto loop;
2043e12c5d1SDavid du Colombier }
2053e12c5d1SDavid du Colombier return a;
2063e12c5d1SDavid du Colombier }
2073e12c5d1SDavid du Colombier
2083e12c5d1SDavid du Colombier /*
2093e12c5d1SDavid du Colombier * consume and return next element on
2103e12c5d1SDavid du Colombier * initlist. expand strings.
2113e12c5d1SDavid du Colombier */
2123e12c5d1SDavid du Colombier Node*
nextinit(void)2133e12c5d1SDavid du Colombier nextinit(void)
2143e12c5d1SDavid du Colombier {
2153e12c5d1SDavid du Colombier Node *a, *b, *n;
2163e12c5d1SDavid du Colombier
2173e12c5d1SDavid du Colombier a = initlist;
2183e12c5d1SDavid du Colombier n = Z;
2193e12c5d1SDavid du Colombier
2203e12c5d1SDavid du Colombier if(a == Z)
2213e12c5d1SDavid du Colombier return a;
2223e12c5d1SDavid du Colombier if(a->op == OLIST) {
2233e12c5d1SDavid du Colombier n = a->right;
2243e12c5d1SDavid du Colombier a = a->left;
2253e12c5d1SDavid du Colombier }
2263e12c5d1SDavid du Colombier if(a->op == OUSED) {
2273e12c5d1SDavid du Colombier a = a->left;
2283e12c5d1SDavid du Colombier b = new(OCONST, Z, Z);
2293e12c5d1SDavid du Colombier b->type = a->type->link;
2303e12c5d1SDavid du Colombier if(a->op == OSTRING) {
231219b2ee8SDavid du Colombier b->vconst = convvtox(*a->cstring, TCHAR);
232219b2ee8SDavid du Colombier a->cstring++;
2333e12c5d1SDavid du Colombier }
2343e12c5d1SDavid du Colombier if(a->op == OLSTRING) {
235*82726826SDavid du Colombier b->vconst = convvtox(*a->rstring, TRUNE);
236219b2ee8SDavid du Colombier a->rstring++;
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier a->type->width -= b->type->width;
2393e12c5d1SDavid du Colombier if(a->type->width <= 0)
2403e12c5d1SDavid du Colombier initlist = n;
2413e12c5d1SDavid du Colombier return b;
2423e12c5d1SDavid du Colombier }
2433e12c5d1SDavid du Colombier initlist = n;
2443e12c5d1SDavid du Colombier return a;
2453e12c5d1SDavid du Colombier }
2463e12c5d1SDavid du Colombier
2473e12c5d1SDavid du Colombier int
isstruct(Node * a,Type * t)2483e12c5d1SDavid du Colombier isstruct(Node *a, Type *t)
2493e12c5d1SDavid du Colombier {
2503e12c5d1SDavid du Colombier Node *n;
2513e12c5d1SDavid du Colombier
2523e12c5d1SDavid du Colombier switch(a->op) {
2533e12c5d1SDavid du Colombier case ODOTDOT:
2543e12c5d1SDavid du Colombier n = a->left;
2553e12c5d1SDavid du Colombier if(n && n->type && sametype(n->type, t))
2563e12c5d1SDavid du Colombier return 1;
2573e12c5d1SDavid du Colombier case OSTRING:
2583e12c5d1SDavid du Colombier case OLSTRING:
2593e12c5d1SDavid du Colombier case OCONST:
2603e12c5d1SDavid du Colombier case OINIT:
261219b2ee8SDavid du Colombier case OELEM:
2623e12c5d1SDavid du Colombier return 0;
2633e12c5d1SDavid du Colombier }
2643e12c5d1SDavid du Colombier
2653e12c5d1SDavid du Colombier n = new(ODOTDOT, Z, Z);
2663e12c5d1SDavid du Colombier *n = *a;
2673e12c5d1SDavid du Colombier
2683e12c5d1SDavid du Colombier /*
2693e12c5d1SDavid du Colombier * ODOTDOT is a flag for tcom
2703e12c5d1SDavid du Colombier * a second tcom will not be performed
2713e12c5d1SDavid du Colombier */
2723e12c5d1SDavid du Colombier a->op = ODOTDOT;
2733e12c5d1SDavid du Colombier a->left = n;
2743e12c5d1SDavid du Colombier a->right = Z;
2753e12c5d1SDavid du Colombier
2763e12c5d1SDavid du Colombier if(tcom(n))
2773e12c5d1SDavid du Colombier return 0;
2783e12c5d1SDavid du Colombier
2793e12c5d1SDavid du Colombier if(sametype(n->type, t))
2803e12c5d1SDavid du Colombier return 1;
2813e12c5d1SDavid du Colombier return 0;
2823e12c5d1SDavid du Colombier }
2833e12c5d1SDavid du Colombier
2843e12c5d1SDavid du Colombier Node*
init1(Sym * s,Type * t,long o,int exflag)2853e12c5d1SDavid du Colombier init1(Sym *s, Type *t, long o, int exflag)
2863e12c5d1SDavid du Colombier {
2877dd7cddfSDavid du Colombier Node *a, *l, *r, nod;
288219b2ee8SDavid du Colombier Type *t1;
2893e12c5d1SDavid du Colombier long e, w, so, mw;
2903e12c5d1SDavid du Colombier
2913e12c5d1SDavid du Colombier a = peekinit();
2923e12c5d1SDavid du Colombier if(a == Z)
2933e12c5d1SDavid du Colombier return Z;
2943e12c5d1SDavid du Colombier
2953e12c5d1SDavid du Colombier if(debug['i']) {
2963e12c5d1SDavid du Colombier print("t = %T; o = %ld; n = %s\n", t, o, s->name);
2973e12c5d1SDavid du Colombier prtree(a, "init1 value");
2983e12c5d1SDavid du Colombier }
2993e12c5d1SDavid du Colombier
3003e12c5d1SDavid du Colombier if(exflag && a->op == OINIT)
3013e12c5d1SDavid du Colombier return doinit(s, t, o, nextinit());
3023e12c5d1SDavid du Colombier
3033e12c5d1SDavid du Colombier switch(t->etype) {
3043e12c5d1SDavid du Colombier default:
3053e12c5d1SDavid du Colombier diag(Z, "unknown type in initialization: %T to: %s", t, s->name);
3063e12c5d1SDavid du Colombier return Z;
3073e12c5d1SDavid du Colombier
3083e12c5d1SDavid du Colombier case TCHAR:
3093e12c5d1SDavid du Colombier case TUCHAR:
3107dd7cddfSDavid du Colombier case TINT:
3117dd7cddfSDavid du Colombier case TUINT:
3123e12c5d1SDavid du Colombier case TSHORT:
3133e12c5d1SDavid du Colombier case TUSHORT:
3143e12c5d1SDavid du Colombier case TLONG:
3153e12c5d1SDavid du Colombier case TULONG:
3163e12c5d1SDavid du Colombier case TVLONG:
3177dd7cddfSDavid du Colombier case TUVLONG:
3183e12c5d1SDavid du Colombier case TFLOAT:
3193e12c5d1SDavid du Colombier case TDOUBLE:
3203e12c5d1SDavid du Colombier case TIND:
3213e12c5d1SDavid du Colombier single:
322219b2ee8SDavid du Colombier if(a->op == OARRAY || a->op == OELEM)
3233e12c5d1SDavid du Colombier return Z;
3243e12c5d1SDavid du Colombier
3253e12c5d1SDavid du Colombier a = nextinit();
3263e12c5d1SDavid du Colombier if(a == Z)
3273e12c5d1SDavid du Colombier return Z;
3283e12c5d1SDavid du Colombier
3293e12c5d1SDavid du Colombier if(t->nbits)
3303e12c5d1SDavid du Colombier diag(Z, "cannot initialize bitfields");
3313e12c5d1SDavid du Colombier if(s->class == CAUTO) {
3323e12c5d1SDavid du Colombier l = new(ONAME, Z, Z);
3333e12c5d1SDavid du Colombier l->sym = s;
3343e12c5d1SDavid du Colombier l->type = t;
3353e12c5d1SDavid du Colombier l->etype = TVOID;
3363e12c5d1SDavid du Colombier if(s->type)
3373e12c5d1SDavid du Colombier l->etype = s->type->etype;
338219b2ee8SDavid du Colombier l->xoffset = s->offset + o;
3393e12c5d1SDavid du Colombier l->class = s->class;
3403e12c5d1SDavid du Colombier
3417dd7cddfSDavid du Colombier l = new(OASI, l, a);
3423e12c5d1SDavid du Colombier return l;
3433e12c5d1SDavid du Colombier }
3443e12c5d1SDavid du Colombier
3453e12c5d1SDavid du Colombier complex(a);
3463e12c5d1SDavid du Colombier if(a->type == T)
3473e12c5d1SDavid du Colombier return Z;
3483e12c5d1SDavid du Colombier
3493e12c5d1SDavid du Colombier if(a->op == OCONST) {
350b05f4f54SDavid du Colombier if(vconst(a) && t->etype == TIND && a->type && a->type->etype != TIND){
351b05f4f54SDavid du Colombier diag(a, "initialize pointer to an integer: %s", s->name);
352b05f4f54SDavid du Colombier return Z;
353b05f4f54SDavid du Colombier }
3543e12c5d1SDavid du Colombier if(!sametype(a->type, t)) {
3557dd7cddfSDavid du Colombier /* hoop jumping to save malloc */
3567dd7cddfSDavid du Colombier if(nodcast == Z)
3577dd7cddfSDavid du Colombier nodcast = new(OCAST, Z, Z);
3587dd7cddfSDavid du Colombier nod = *nodcast;
3597dd7cddfSDavid du Colombier nod.left = a;
3607dd7cddfSDavid du Colombier nod.type = t;
3617dd7cddfSDavid du Colombier nod.lineno = a->lineno;
3627dd7cddfSDavid du Colombier complex(&nod);
3637dd7cddfSDavid du Colombier if(nod.type)
3647dd7cddfSDavid du Colombier *a = nod;
3653e12c5d1SDavid du Colombier }
3663e12c5d1SDavid du Colombier if(a->op != OCONST) {
3673e12c5d1SDavid du Colombier diag(a, "initializer is not a constant: %s",
3683e12c5d1SDavid du Colombier s->name);
3693e12c5d1SDavid du Colombier return Z;
3703e12c5d1SDavid du Colombier }
3713e12c5d1SDavid du Colombier if(vconst(a) == 0)
3723e12c5d1SDavid du Colombier return Z;
3733e12c5d1SDavid du Colombier goto gext;
3743e12c5d1SDavid du Colombier }
3753e12c5d1SDavid du Colombier if(t->etype == TIND) {
3763e12c5d1SDavid du Colombier while(a->op == OCAST) {
3773e12c5d1SDavid du Colombier warn(a, "CAST in initialization ignored");
3783e12c5d1SDavid du Colombier a = a->left;
3793e12c5d1SDavid du Colombier }
3803e12c5d1SDavid du Colombier if(!sametype(t, a->type)) {
38173e742d7SDavid du Colombier diag(a, "initialization of incompatible pointers: %s\n%T and %T",
38273e742d7SDavid du Colombier s->name, t, a->type);
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier if(a->op == OADDR)
3853e12c5d1SDavid du Colombier a = a->left;
3863e12c5d1SDavid du Colombier goto gext;
3873e12c5d1SDavid du Colombier }
388219b2ee8SDavid du Colombier
3893e12c5d1SDavid du Colombier while(a->op == OCAST)
3903e12c5d1SDavid du Colombier a = a->left;
3913e12c5d1SDavid du Colombier if(a->op == OADDR) {
3927dd7cddfSDavid du Colombier warn(a, "initialize pointer to an integer: %s", s->name);
3933e12c5d1SDavid du Colombier a = a->left;
3943e12c5d1SDavid du Colombier goto gext;
3953e12c5d1SDavid du Colombier }
3963e12c5d1SDavid du Colombier diag(a, "initializer is not a constant: %s", s->name);
3973e12c5d1SDavid du Colombier return Z;
3983e12c5d1SDavid du Colombier
3993e12c5d1SDavid du Colombier gext:
4003e12c5d1SDavid du Colombier gextern(s, a, o, t->width);
4013e12c5d1SDavid du Colombier
4023e12c5d1SDavid du Colombier return Z;
4033e12c5d1SDavid du Colombier
4043e12c5d1SDavid du Colombier case TARRAY:
4053e12c5d1SDavid du Colombier w = t->link->width;
4063e12c5d1SDavid du Colombier if(a->op == OSTRING || a->op == OLSTRING)
407219b2ee8SDavid du Colombier if(typei[t->link->etype]) {
4083e12c5d1SDavid du Colombier /*
4093e12c5d1SDavid du Colombier * get rid of null if sizes match exactly
4103e12c5d1SDavid du Colombier */
4113e12c5d1SDavid du Colombier a = nextinit();
4123e12c5d1SDavid du Colombier mw = t->width/w;
4133e12c5d1SDavid du Colombier so = a->type->width/a->type->link->width;
4143e12c5d1SDavid du Colombier if(mw && so > mw) {
4153e12c5d1SDavid du Colombier if(so != mw+1)
4163e12c5d1SDavid du Colombier diag(a, "string initialization larger than array");
4173e12c5d1SDavid du Colombier a->type->width -= a->type->link->width;
4183e12c5d1SDavid du Colombier }
4193e12c5d1SDavid du Colombier
4203e12c5d1SDavid du Colombier /*
4213e12c5d1SDavid du Colombier * arrange strings to be expanded
4223e12c5d1SDavid du Colombier * inside OINIT braces.
4233e12c5d1SDavid du Colombier */
4243e12c5d1SDavid du Colombier a = new(OUSED, a, Z);
4253e12c5d1SDavid du Colombier return doinit(s, t, o, a);
4263e12c5d1SDavid du Colombier }
4273e12c5d1SDavid du Colombier
4283e12c5d1SDavid du Colombier mw = -w;
4293e12c5d1SDavid du Colombier l = Z;
4303e12c5d1SDavid du Colombier for(e=0;;) {
4313e12c5d1SDavid du Colombier /*
4323e12c5d1SDavid du Colombier * peek ahead for element initializer
4333e12c5d1SDavid du Colombier */
4343e12c5d1SDavid du Colombier a = peekinit();
4353e12c5d1SDavid du Colombier if(a == Z)
4363e12c5d1SDavid du Colombier break;
437219b2ee8SDavid du Colombier if(a->op == OELEM && t->link->etype != TSTRUCT)
438219b2ee8SDavid du Colombier break;
4393e12c5d1SDavid du Colombier if(a->op == OARRAY) {
4407dd7cddfSDavid du Colombier if(e && exflag)
4417dd7cddfSDavid du Colombier break;
4423e12c5d1SDavid du Colombier a = nextinit();
4433e12c5d1SDavid du Colombier r = a->left;
4443e12c5d1SDavid du Colombier complex(r);
4453e12c5d1SDavid du Colombier if(r->op != OCONST) {
4463e12c5d1SDavid du Colombier diag(r, "initializer subscript must be constant");
4473e12c5d1SDavid du Colombier return Z;
4483e12c5d1SDavid du Colombier }
449219b2ee8SDavid du Colombier e = r->vconst;
4503e12c5d1SDavid du Colombier if(t->width != 0)
4513e12c5d1SDavid du Colombier if(e < 0 || e*w >= t->width) {
4527dd7cddfSDavid du Colombier diag(a, "initialization index out of range: %ld", e);
4533e12c5d1SDavid du Colombier continue;
4543e12c5d1SDavid du Colombier }
4557dd7cddfSDavid du Colombier }
4563e12c5d1SDavid du Colombier
4573e12c5d1SDavid du Colombier so = e*w;
4583e12c5d1SDavid du Colombier if(so > mw)
4593e12c5d1SDavid du Colombier mw = so;
4603e12c5d1SDavid du Colombier if(t->width != 0)
4613e12c5d1SDavid du Colombier if(mw >= t->width)
4623e12c5d1SDavid du Colombier break;
4633e12c5d1SDavid du Colombier r = init1(s, t->link, o+so, 1);
4643e12c5d1SDavid du Colombier l = newlist(l, r);
4653e12c5d1SDavid du Colombier e++;
4663e12c5d1SDavid du Colombier }
4673e12c5d1SDavid du Colombier if(t->width == 0)
4683e12c5d1SDavid du Colombier t->width = mw+w;
4693e12c5d1SDavid du Colombier return l;
4703e12c5d1SDavid du Colombier
4713e12c5d1SDavid du Colombier case TUNION:
4723e12c5d1SDavid du Colombier case TSTRUCT:
4733e12c5d1SDavid du Colombier /*
4743e12c5d1SDavid du Colombier * peek ahead to find type of rhs.
4753e12c5d1SDavid du Colombier * if its a structure, then treat
4763e12c5d1SDavid du Colombier * this element as a variable
4773e12c5d1SDavid du Colombier * rather than an aggregate.
4783e12c5d1SDavid du Colombier */
4793e12c5d1SDavid du Colombier if(isstruct(a, t))
4803e12c5d1SDavid du Colombier goto single;
4813e12c5d1SDavid du Colombier
4823e12c5d1SDavid du Colombier if(t->width <= 0) {
4833e12c5d1SDavid du Colombier diag(Z, "incomplete structure: %s", s->name);
4843e12c5d1SDavid du Colombier return Z;
4853e12c5d1SDavid du Colombier }
4863e12c5d1SDavid du Colombier l = Z;
487219b2ee8SDavid du Colombier
488219b2ee8SDavid du Colombier again:
489219b2ee8SDavid du Colombier for(t1 = t->link; t1 != T; t1 = t1->down) {
490219b2ee8SDavid du Colombier if(a->op == OARRAY && t1->etype != TARRAY)
491219b2ee8SDavid du Colombier break;
492219b2ee8SDavid du Colombier if(a->op == OELEM) {
493219b2ee8SDavid du Colombier if(t1->sym != a->sym)
494219b2ee8SDavid du Colombier continue;
495219b2ee8SDavid du Colombier nextinit();
496219b2ee8SDavid du Colombier }
497219b2ee8SDavid du Colombier r = init1(s, t1, o+t1->offset, 1);
498219b2ee8SDavid du Colombier l = newlist(l, r);
4993e12c5d1SDavid du Colombier a = peekinit();
5003e12c5d1SDavid du Colombier if(a == Z)
5013e12c5d1SDavid du Colombier break;
502219b2ee8SDavid du Colombier if(a->op == OELEM)
503219b2ee8SDavid du Colombier goto again;
5043e12c5d1SDavid du Colombier }
505219b2ee8SDavid du Colombier if(a && a->op == OELEM)
506219b2ee8SDavid du Colombier diag(a, "structure element not found %F", a);
5073e12c5d1SDavid du Colombier return l;
5083e12c5d1SDavid du Colombier }
5093e12c5d1SDavid du Colombier }
5103e12c5d1SDavid du Colombier
5113e12c5d1SDavid du Colombier Node*
newlist(Node * l,Node * r)5123e12c5d1SDavid du Colombier newlist(Node *l, Node *r)
5133e12c5d1SDavid du Colombier {
5143e12c5d1SDavid du Colombier if(r == Z)
5153e12c5d1SDavid du Colombier return l;
5163e12c5d1SDavid du Colombier if(l == Z)
5173e12c5d1SDavid du Colombier return r;
5183e12c5d1SDavid du Colombier return new(OLIST, l, r);
5193e12c5d1SDavid du Colombier }
5203e12c5d1SDavid du Colombier
5213e12c5d1SDavid du Colombier void
sualign(Type * t)522d40255d8SDavid du Colombier sualign(Type *t)
5233e12c5d1SDavid du Colombier {
5243e12c5d1SDavid du Colombier Type *l;
5253e12c5d1SDavid du Colombier long o, w;
5263e12c5d1SDavid du Colombier
5273e12c5d1SDavid du Colombier o = 0;
5283e12c5d1SDavid du Colombier switch(t->etype) {
5293e12c5d1SDavid du Colombier
5303e12c5d1SDavid du Colombier case TSTRUCT:
5313e12c5d1SDavid du Colombier t->offset = 0;
5323e12c5d1SDavid du Colombier w = 0;
5333e12c5d1SDavid du Colombier for(l = t->link; l != T; l = l->down) {
5343e12c5d1SDavid du Colombier if(l->nbits) {
5353e12c5d1SDavid du Colombier if(l->shift <= 0) {
5363e12c5d1SDavid du Colombier l->shift = -l->shift;
5377dd7cddfSDavid du Colombier w = round(w, tfield->width);
5383e12c5d1SDavid du Colombier o = w;
5393e12c5d1SDavid du Colombier w += tfield->width;
5403e12c5d1SDavid du Colombier }
5413e12c5d1SDavid du Colombier l->offset = o;
5423e12c5d1SDavid du Colombier } else {
5437fd2696aSDavid du Colombier if(l->width < 0 ||
5447fd2696aSDavid du Colombier l->width == 0 && l->down != T)
5453e12c5d1SDavid du Colombier if(l->sym)
5463e12c5d1SDavid du Colombier diag(Z, "incomplete structure element: %s",
5473e12c5d1SDavid du Colombier l->sym->name);
5483e12c5d1SDavid du Colombier else
5493e12c5d1SDavid du Colombier diag(Z, "incomplete structure element");
5507dd7cddfSDavid du Colombier w = align(w, l, Ael1);
5513e12c5d1SDavid du Colombier l->offset = w;
5527dd7cddfSDavid du Colombier w = align(w, l, Ael2);
5533e12c5d1SDavid du Colombier }
5543e12c5d1SDavid du Colombier }
5557dd7cddfSDavid du Colombier w = align(w, t, Asu2);
5563e12c5d1SDavid du Colombier t->width = w;
557219b2ee8SDavid du Colombier acidtype(t);
55880ee5cbfSDavid du Colombier pickletype(t);
5593e12c5d1SDavid du Colombier return;
5603e12c5d1SDavid du Colombier
5613e12c5d1SDavid du Colombier case TUNION:
5623e12c5d1SDavid du Colombier t->offset = 0;
5633e12c5d1SDavid du Colombier w = 0;
5643e12c5d1SDavid du Colombier for(l = t->link; l != T; l = l->down) {
5653e12c5d1SDavid du Colombier if(l->width <= 0)
5663e12c5d1SDavid du Colombier if(l->sym)
5673e12c5d1SDavid du Colombier diag(Z, "incomplete union element: %s",
5683e12c5d1SDavid du Colombier l->sym->name);
5693e12c5d1SDavid du Colombier else
5703e12c5d1SDavid du Colombier diag(Z, "incomplete union element");
5713e12c5d1SDavid du Colombier l->offset = 0;
5723e12c5d1SDavid du Colombier l->shift = 0;
5737dd7cddfSDavid du Colombier o = align(align(0, l, Ael1), l, Ael2);
5747dd7cddfSDavid du Colombier if(o > w)
5757dd7cddfSDavid du Colombier w = o;
5763e12c5d1SDavid du Colombier }
5777dd7cddfSDavid du Colombier w = align(w, t, Asu2);
5783e12c5d1SDavid du Colombier t->width = w;
579219b2ee8SDavid du Colombier acidtype(t);
58080ee5cbfSDavid du Colombier pickletype(t);
5813e12c5d1SDavid du Colombier return;
5823e12c5d1SDavid du Colombier
5833e12c5d1SDavid du Colombier default:
584d40255d8SDavid du Colombier diag(Z, "unknown type in sualign: %T", t);
5853e12c5d1SDavid du Colombier break;
5863e12c5d1SDavid du Colombier }
5873e12c5d1SDavid du Colombier }
5883e12c5d1SDavid du Colombier
5897dd7cddfSDavid du Colombier long
round(long v,int w)5907dd7cddfSDavid du Colombier round(long v, int w)
5913e12c5d1SDavid du Colombier {
5923e12c5d1SDavid du Colombier int r;
5933e12c5d1SDavid du Colombier
5947dd7cddfSDavid du Colombier if(w <= 0 || w > 8) {
5953e12c5d1SDavid du Colombier diag(Z, "rounding by %d", w);
5963e12c5d1SDavid du Colombier w = 1;
5973e12c5d1SDavid du Colombier }
5983e12c5d1SDavid du Colombier r = v%w;
5993e12c5d1SDavid du Colombier if(r)
6007dd7cddfSDavid du Colombier v += w-r;
6017dd7cddfSDavid du Colombier return v;
6023e12c5d1SDavid du Colombier }
6033e12c5d1SDavid du Colombier
6043e12c5d1SDavid du Colombier Type*
ofnproto(Node * n)6053e12c5d1SDavid du Colombier ofnproto(Node *n)
6063e12c5d1SDavid du Colombier {
6073e12c5d1SDavid du Colombier Type *tl, *tr, *t;
6083e12c5d1SDavid du Colombier
6093e12c5d1SDavid du Colombier if(n == Z)
6103e12c5d1SDavid du Colombier return T;
6113e12c5d1SDavid du Colombier switch(n->op) {
6123e12c5d1SDavid du Colombier case OLIST:
6133e12c5d1SDavid du Colombier tl = ofnproto(n->left);
6143e12c5d1SDavid du Colombier tr = ofnproto(n->right);
6153e12c5d1SDavid du Colombier if(tl == T)
6163e12c5d1SDavid du Colombier return tr;
6173e12c5d1SDavid du Colombier tl->down = tr;
6183e12c5d1SDavid du Colombier return tl;
6193e12c5d1SDavid du Colombier
6203e12c5d1SDavid du Colombier case ONAME:
62180ee5cbfSDavid du Colombier t = copytyp(n->sym->type);
6223e12c5d1SDavid du Colombier t->down = T;
6233e12c5d1SDavid du Colombier return t;
6243e12c5d1SDavid du Colombier }
6253e12c5d1SDavid du Colombier return T;
6263e12c5d1SDavid du Colombier }
6273e12c5d1SDavid du Colombier
6283e12c5d1SDavid du Colombier #define ANSIPROTO 1
6293e12c5d1SDavid du Colombier #define OLDPROTO 2
6303e12c5d1SDavid du Colombier
6313e12c5d1SDavid du Colombier void
argmark(Node * n,int pass)6323e12c5d1SDavid du Colombier argmark(Node *n, int pass)
6333e12c5d1SDavid du Colombier {
6343e12c5d1SDavid du Colombier Type *t;
6353e12c5d1SDavid du Colombier
6367dd7cddfSDavid du Colombier autoffset = align(0, thisfn->link, Aarg0);
6373e12c5d1SDavid du Colombier stkoff = 0;
6383e12c5d1SDavid du Colombier for(; n->left != Z; n = n->left) {
6393e12c5d1SDavid du Colombier if(n->op != OFUNC || n->left->op != ONAME)
6403e12c5d1SDavid du Colombier continue;
6413e12c5d1SDavid du Colombier walkparam(n->right, pass);
6423e12c5d1SDavid du Colombier if(pass != 0 && anyproto(n->right) == OLDPROTO) {
6433e12c5d1SDavid du Colombier t = typ(TFUNC, n->left->sym->type->link);
6443e12c5d1SDavid du Colombier t->down = typ(TOLD, T);
6453e12c5d1SDavid du Colombier t->down->down = ofnproto(n->right);
6463e12c5d1SDavid du Colombier tmerge(t, n->left->sym);
6473e12c5d1SDavid du Colombier n->left->sym->type = t;
6483e12c5d1SDavid du Colombier }
6493e12c5d1SDavid du Colombier break;
6503e12c5d1SDavid du Colombier }
6513e12c5d1SDavid du Colombier autoffset = 0;
6523e12c5d1SDavid du Colombier stkoff = 0;
6533e12c5d1SDavid du Colombier }
6543e12c5d1SDavid du Colombier
6553e12c5d1SDavid du Colombier void
walkparam(Node * n,int pass)6563e12c5d1SDavid du Colombier walkparam(Node *n, int pass)
6573e12c5d1SDavid du Colombier {
6583e12c5d1SDavid du Colombier Sym *s;
659219b2ee8SDavid du Colombier Node *n1;
6603e12c5d1SDavid du Colombier
6613e12c5d1SDavid du Colombier if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
6623e12c5d1SDavid du Colombier return;
6633e12c5d1SDavid du Colombier
6643e12c5d1SDavid du Colombier loop:
6653e12c5d1SDavid du Colombier if(n == Z)
6663e12c5d1SDavid du Colombier return;
6673e12c5d1SDavid du Colombier switch(n->op) {
6683e12c5d1SDavid du Colombier default:
6693e12c5d1SDavid du Colombier diag(n, "argument not a name/prototype: %O", n->op);
6703e12c5d1SDavid du Colombier break;
6713e12c5d1SDavid du Colombier
6723e12c5d1SDavid du Colombier case OLIST:
6733e12c5d1SDavid du Colombier walkparam(n->left, pass);
6743e12c5d1SDavid du Colombier n = n->right;
6753e12c5d1SDavid du Colombier goto loop;
6763e12c5d1SDavid du Colombier
6773e12c5d1SDavid du Colombier case OPROTO:
678219b2ee8SDavid du Colombier for(n1 = n; n1 != Z; n1=n1->left)
679219b2ee8SDavid du Colombier if(n1->op == ONAME) {
6803e12c5d1SDavid du Colombier if(pass == 0) {
681219b2ee8SDavid du Colombier s = n1->sym;
6823e12c5d1SDavid du Colombier push1(s);
6833e12c5d1SDavid du Colombier s->offset = -1;
6843e12c5d1SDavid du Colombier break;
6853e12c5d1SDavid du Colombier }
686219b2ee8SDavid du Colombier dodecl(pdecl, CPARAM, n->type, n->left);
6873e12c5d1SDavid du Colombier break;
6883e12c5d1SDavid du Colombier }
689219b2ee8SDavid du Colombier if(n1)
690219b2ee8SDavid du Colombier break;
691219b2ee8SDavid du Colombier if(pass == 0) {
692219b2ee8SDavid du Colombier /*
693219b2ee8SDavid du Colombier * extension:
694219b2ee8SDavid du Colombier * allow no name in argument declaration
695219b2ee8SDavid du Colombier diag(Z, "no name in argument declaration");
696219b2ee8SDavid du Colombier */
697219b2ee8SDavid du Colombier break;
698219b2ee8SDavid du Colombier }
699219b2ee8SDavid du Colombier dodecl(NODECL, CPARAM, n->type, n->left);
700219b2ee8SDavid du Colombier pdecl(CPARAM, lastdcl, S);
7013e12c5d1SDavid du Colombier break;
7023e12c5d1SDavid du Colombier
7033e12c5d1SDavid du Colombier case ODOTDOT:
7043e12c5d1SDavid du Colombier break;
7053e12c5d1SDavid du Colombier
7063e12c5d1SDavid du Colombier case ONAME:
7073e12c5d1SDavid du Colombier s = n->sym;
7083e12c5d1SDavid du Colombier if(pass == 0) {
7093e12c5d1SDavid du Colombier push1(s);
7103e12c5d1SDavid du Colombier s->offset = -1;
7113e12c5d1SDavid du Colombier break;
7123e12c5d1SDavid du Colombier }
7133e12c5d1SDavid du Colombier if(s->offset != -1) {
7143e12c5d1SDavid du Colombier if(autoffset == 0) {
7153e12c5d1SDavid du Colombier firstarg = s;
7163e12c5d1SDavid du Colombier firstargtype = s->type;
7173e12c5d1SDavid du Colombier }
7187dd7cddfSDavid du Colombier autoffset = align(autoffset, s->type, Aarg1);
7193e12c5d1SDavid du Colombier s->offset = autoffset;
7207dd7cddfSDavid du Colombier autoffset = align(autoffset, s->type, Aarg2);
7213e12c5d1SDavid du Colombier } else
7227dd7cddfSDavid du Colombier dodecl(pdecl, CXXX, types[TINT], n);
7233e12c5d1SDavid du Colombier break;
7243e12c5d1SDavid du Colombier }
7253e12c5d1SDavid du Colombier }
7263e12c5d1SDavid du Colombier
7273e12c5d1SDavid du Colombier void
markdcl(void)7283e12c5d1SDavid du Colombier markdcl(void)
7293e12c5d1SDavid du Colombier {
7303e12c5d1SDavid du Colombier Decl *d;
7313e12c5d1SDavid du Colombier
7323e12c5d1SDavid du Colombier blockno++;
7333e12c5d1SDavid du Colombier d = push();
7343e12c5d1SDavid du Colombier d->val = DMARK;
7353e12c5d1SDavid du Colombier d->offset = autoffset;
7363e12c5d1SDavid du Colombier d->block = autobn;
7373e12c5d1SDavid du Colombier autobn = blockno;
7383e12c5d1SDavid du Colombier }
7393e12c5d1SDavid du Colombier
7407dd7cddfSDavid du Colombier Node*
revertdcl(void)7413e12c5d1SDavid du Colombier revertdcl(void)
7423e12c5d1SDavid du Colombier {
7433e12c5d1SDavid du Colombier Decl *d;
7443e12c5d1SDavid du Colombier Sym *s;
7457dd7cddfSDavid du Colombier Node *n, *n1;
7463e12c5d1SDavid du Colombier
7477dd7cddfSDavid du Colombier n = Z;
7483e12c5d1SDavid du Colombier for(;;) {
7493e12c5d1SDavid du Colombier d = dclstack;
7503e12c5d1SDavid du Colombier if(d == D) {
7513e12c5d1SDavid du Colombier diag(Z, "pop off dcl stack");
7523e12c5d1SDavid du Colombier break;
7533e12c5d1SDavid du Colombier }
7543e12c5d1SDavid du Colombier dclstack = d->link;
7553e12c5d1SDavid du Colombier s = d->sym;
7563e12c5d1SDavid du Colombier switch(d->val) {
7573e12c5d1SDavid du Colombier case DMARK:
7583e12c5d1SDavid du Colombier autoffset = d->offset;
7593e12c5d1SDavid du Colombier autobn = d->block;
7607dd7cddfSDavid du Colombier return n;
7613e12c5d1SDavid du Colombier
7623e12c5d1SDavid du Colombier case DAUTO:
7633e12c5d1SDavid du Colombier if(debug['d'])
7643e12c5d1SDavid du Colombier print("revert1 \"%s\"\n", s->name);
7653e12c5d1SDavid du Colombier if(s->aused == 0) {
7663e12c5d1SDavid du Colombier nearln = s->varlineno;
7673e12c5d1SDavid du Colombier if(s->class == CAUTO)
7683e12c5d1SDavid du Colombier warn(Z, "auto declared and not used: %s", s->name);
7693e12c5d1SDavid du Colombier if(s->class == CPARAM)
7703e12c5d1SDavid du Colombier warn(Z, "param declared and not used: %s", s->name);
7713e12c5d1SDavid du Colombier }
7727dd7cddfSDavid du Colombier if(s->type && (s->type->garb & GVOLATILE)) {
7737dd7cddfSDavid du Colombier n1 = new(ONAME, Z, Z);
7747dd7cddfSDavid du Colombier n1->sym = s;
7757dd7cddfSDavid du Colombier n1->type = s->type;
7767dd7cddfSDavid du Colombier n1->etype = TVOID;
7777dd7cddfSDavid du Colombier if(n1->type != T)
7787dd7cddfSDavid du Colombier n1->etype = n1->type->etype;
7797dd7cddfSDavid du Colombier n1->xoffset = s->offset;
7807dd7cddfSDavid du Colombier n1->class = s->class;
7817dd7cddfSDavid du Colombier
7827dd7cddfSDavid du Colombier n1 = new(OADDR, n1, Z);
7837dd7cddfSDavid du Colombier n1 = new(OUSED, n1, Z);
7847dd7cddfSDavid du Colombier if(n == Z)
7857dd7cddfSDavid du Colombier n = n1;
7867dd7cddfSDavid du Colombier else
7877dd7cddfSDavid du Colombier n = new(OLIST, n1, n);
7887dd7cddfSDavid du Colombier }
7893e12c5d1SDavid du Colombier s->type = d->type;
7903e12c5d1SDavid du Colombier s->class = d->class;
7913e12c5d1SDavid du Colombier s->offset = d->offset;
7923e12c5d1SDavid du Colombier s->block = d->block;
7933e12c5d1SDavid du Colombier s->varlineno = d->varlineno;
7943e12c5d1SDavid du Colombier s->aused = d->aused;
7953e12c5d1SDavid du Colombier break;
7963e12c5d1SDavid du Colombier
7973e12c5d1SDavid du Colombier case DSUE:
7983e12c5d1SDavid du Colombier if(debug['d'])
7993e12c5d1SDavid du Colombier print("revert2 \"%s\"\n", s->name);
8003e12c5d1SDavid du Colombier s->suetag = d->type;
8013e12c5d1SDavid du Colombier s->sueblock = d->block;
8023e12c5d1SDavid du Colombier break;
8033e12c5d1SDavid du Colombier
8043e12c5d1SDavid du Colombier case DLABEL:
8053e12c5d1SDavid du Colombier if(debug['d'])
8063e12c5d1SDavid du Colombier print("revert3 \"%s\"\n", s->name);
8077dd7cddfSDavid du Colombier if(s->label && s->label->addable == 0)
8087dd7cddfSDavid du Colombier warn(s->label, "label declared and not used \"%s\"", s->name);
8093e12c5d1SDavid du Colombier s->label = Z;
8103e12c5d1SDavid du Colombier break;
8113e12c5d1SDavid du Colombier }
8123e12c5d1SDavid du Colombier }
8137dd7cddfSDavid du Colombier return n;
8143e12c5d1SDavid du Colombier }
8153e12c5d1SDavid du Colombier
8163e12c5d1SDavid du Colombier Type*
fnproto(Node * n)8173e12c5d1SDavid du Colombier fnproto(Node *n)
8183e12c5d1SDavid du Colombier {
8193e12c5d1SDavid du Colombier int r;
8203e12c5d1SDavid du Colombier
8213e12c5d1SDavid du Colombier r = anyproto(n->right);
8223e12c5d1SDavid du Colombier if(r == 0 || (r & OLDPROTO)) {
8233e12c5d1SDavid du Colombier if(r & ANSIPROTO)
8243e12c5d1SDavid du Colombier diag(n, "mixed ansi/old function declaration: %F", n->left);
8253e12c5d1SDavid du Colombier return T;
8263e12c5d1SDavid du Colombier }
8273e12c5d1SDavid du Colombier return fnproto1(n->right);
8283e12c5d1SDavid du Colombier }
8293e12c5d1SDavid du Colombier
8303e12c5d1SDavid du Colombier int
anyproto(Node * n)8313e12c5d1SDavid du Colombier anyproto(Node *n)
8323e12c5d1SDavid du Colombier {
8333e12c5d1SDavid du Colombier int r;
8343e12c5d1SDavid du Colombier
8353e12c5d1SDavid du Colombier r = 0;
8363e12c5d1SDavid du Colombier
8373e12c5d1SDavid du Colombier loop:
8383e12c5d1SDavid du Colombier if(n == Z)
8393e12c5d1SDavid du Colombier return r;
8403e12c5d1SDavid du Colombier switch(n->op) {
8413e12c5d1SDavid du Colombier case OLIST:
8423e12c5d1SDavid du Colombier r |= anyproto(n->left);
8433e12c5d1SDavid du Colombier n = n->right;
8443e12c5d1SDavid du Colombier goto loop;
8453e12c5d1SDavid du Colombier
8463e12c5d1SDavid du Colombier case ODOTDOT:
8473e12c5d1SDavid du Colombier case OPROTO:
8483e12c5d1SDavid du Colombier return r | ANSIPROTO;
8493e12c5d1SDavid du Colombier }
8503e12c5d1SDavid du Colombier return r | OLDPROTO;
8513e12c5d1SDavid du Colombier }
8523e12c5d1SDavid du Colombier
8533e12c5d1SDavid du Colombier Type*
fnproto1(Node * n)8543e12c5d1SDavid du Colombier fnproto1(Node *n)
8553e12c5d1SDavid du Colombier {
8563e12c5d1SDavid du Colombier Type *t;
8573e12c5d1SDavid du Colombier
8583e12c5d1SDavid du Colombier if(n == Z)
8593e12c5d1SDavid du Colombier return T;
8603e12c5d1SDavid du Colombier switch(n->op) {
8613e12c5d1SDavid du Colombier case OLIST:
8623e12c5d1SDavid du Colombier t = fnproto1(n->left);
8633e12c5d1SDavid du Colombier if(t != T)
8643e12c5d1SDavid du Colombier t->down = fnproto1(n->right);
8653e12c5d1SDavid du Colombier return t;
8663e12c5d1SDavid du Colombier
8673e12c5d1SDavid du Colombier case OPROTO:
8683e12c5d1SDavid du Colombier lastdcl = T;
8693e12c5d1SDavid du Colombier dodecl(NODECL, CXXX, n->type, n->left);
8703e12c5d1SDavid du Colombier t = typ(TXXX, T);
8713e12c5d1SDavid du Colombier if(lastdcl != T)
8723e12c5d1SDavid du Colombier *t = *paramconv(lastdcl, 1);
8733e12c5d1SDavid du Colombier return t;
8743e12c5d1SDavid du Colombier
8753e12c5d1SDavid du Colombier case ONAME:
8763e12c5d1SDavid du Colombier diag(n, "incomplete argument prototype");
8777dd7cddfSDavid du Colombier return typ(TINT, T);
8783e12c5d1SDavid du Colombier
8793e12c5d1SDavid du Colombier case ODOTDOT:
8803e12c5d1SDavid du Colombier return typ(TDOT, T);
8813e12c5d1SDavid du Colombier }
8823e12c5d1SDavid du Colombier diag(n, "unknown op in fnproto");
8833e12c5d1SDavid du Colombier return T;
8843e12c5d1SDavid du Colombier }
8853e12c5d1SDavid du Colombier
8863e12c5d1SDavid du Colombier void
dbgdecl(Sym * s)8873e12c5d1SDavid du Colombier dbgdecl(Sym *s)
8883e12c5d1SDavid du Colombier {
8897dd7cddfSDavid du Colombier print("decl \"%s\": C=%s [B=%d:O=%ld] T=%T\n",
890219b2ee8SDavid du Colombier s->name, cnames[s->class], s->block, s->offset, s->type);
8913e12c5d1SDavid du Colombier }
8923e12c5d1SDavid du Colombier
8933e12c5d1SDavid du Colombier Decl*
push(void)8943e12c5d1SDavid du Colombier push(void)
8953e12c5d1SDavid du Colombier {
8963e12c5d1SDavid du Colombier Decl *d;
8973e12c5d1SDavid du Colombier
8987dd7cddfSDavid du Colombier d = alloc(sizeof(*d));
8993e12c5d1SDavid du Colombier d->link = dclstack;
9003e12c5d1SDavid du Colombier dclstack = d;
9013e12c5d1SDavid du Colombier return d;
9023e12c5d1SDavid du Colombier }
9033e12c5d1SDavid du Colombier
9043e12c5d1SDavid du Colombier Decl*
push1(Sym * s)9053e12c5d1SDavid du Colombier push1(Sym *s)
9063e12c5d1SDavid du Colombier {
9073e12c5d1SDavid du Colombier Decl *d;
9083e12c5d1SDavid du Colombier
9093e12c5d1SDavid du Colombier d = push();
9103e12c5d1SDavid du Colombier d->sym = s;
9113e12c5d1SDavid du Colombier d->val = DAUTO;
9123e12c5d1SDavid du Colombier d->type = s->type;
9133e12c5d1SDavid du Colombier d->class = s->class;
9143e12c5d1SDavid du Colombier d->offset = s->offset;
9153e12c5d1SDavid du Colombier d->block = s->block;
9163e12c5d1SDavid du Colombier d->varlineno = s->varlineno;
9173e12c5d1SDavid du Colombier d->aused = s->aused;
9183e12c5d1SDavid du Colombier return d;
9193e12c5d1SDavid du Colombier }
9203e12c5d1SDavid du Colombier
9213e12c5d1SDavid du Colombier int
sametype(Type * t1,Type * t2)9223e12c5d1SDavid du Colombier sametype(Type *t1, Type *t2)
9233e12c5d1SDavid du Colombier {
9243e12c5d1SDavid du Colombier
9253e12c5d1SDavid du Colombier if(t1 == t2)
9263e12c5d1SDavid du Colombier return 1;
9277dd7cddfSDavid du Colombier return rsametype(t1, t2, 5, 1);
9283e12c5d1SDavid du Colombier }
9293e12c5d1SDavid du Colombier
9303e12c5d1SDavid du Colombier int
rsametype(Type * t1,Type * t2,int n,int f)9317dd7cddfSDavid du Colombier rsametype(Type *t1, Type *t2, int n, int f)
9323e12c5d1SDavid du Colombier {
9333e12c5d1SDavid du Colombier int et;
9343e12c5d1SDavid du Colombier
9353e12c5d1SDavid du Colombier n--;
9363e12c5d1SDavid du Colombier for(;;) {
9373e12c5d1SDavid du Colombier if(t1 == t2)
9383e12c5d1SDavid du Colombier return 1;
9393e12c5d1SDavid du Colombier if(t1 == T || t2 == T)
9403e12c5d1SDavid du Colombier return 0;
9413e12c5d1SDavid du Colombier if(n <= 0)
9423e12c5d1SDavid du Colombier return 1;
9433e12c5d1SDavid du Colombier et = t1->etype;
9443e12c5d1SDavid du Colombier if(et != t2->etype)
9453e12c5d1SDavid du Colombier return 0;
9463e12c5d1SDavid du Colombier if(et == TFUNC) {
9477dd7cddfSDavid du Colombier if(!rsametype(t1->link, t2->link, n, 0))
9483e12c5d1SDavid du Colombier return 0;
9493e12c5d1SDavid du Colombier t1 = t1->down;
9503e12c5d1SDavid du Colombier t2 = t2->down;
9513e12c5d1SDavid du Colombier while(t1 != T && t2 != T) {
9523e12c5d1SDavid du Colombier if(t1->etype == TOLD) {
9533e12c5d1SDavid du Colombier t1 = t1->down;
9543e12c5d1SDavid du Colombier continue;
9553e12c5d1SDavid du Colombier }
9563e12c5d1SDavid du Colombier if(t2->etype == TOLD) {
9573e12c5d1SDavid du Colombier t2 = t2->down;
9583e12c5d1SDavid du Colombier continue;
9593e12c5d1SDavid du Colombier }
9603e12c5d1SDavid du Colombier while(t1 != T || t2 != T) {
9617dd7cddfSDavid du Colombier if(!rsametype(t1, t2, n, 0))
9623e12c5d1SDavid du Colombier return 0;
9633e12c5d1SDavid du Colombier t1 = t1->down;
9643e12c5d1SDavid du Colombier t2 = t2->down;
9653e12c5d1SDavid du Colombier }
9663e12c5d1SDavid du Colombier break;
9673e12c5d1SDavid du Colombier }
9683e12c5d1SDavid du Colombier return 1;
9693e12c5d1SDavid du Colombier }
9707dd7cddfSDavid du Colombier if(et == TARRAY)
9717dd7cddfSDavid du Colombier if(t1->width != t2->width && t1->width != 0 && t2->width != 0)
9727dd7cddfSDavid du Colombier return 0;
9737dd7cddfSDavid du Colombier if(typesu[et]) {
9747dd7cddfSDavid du Colombier if(t1->link == T)
9757dd7cddfSDavid du Colombier snap(t1);
9767dd7cddfSDavid du Colombier if(t2->link == T)
9777dd7cddfSDavid du Colombier snap(t2);
9786891d857SDavid du Colombier if(t1 != t2 && t1->link == T && t2->link == T){
9796891d857SDavid du Colombier /* structs with missing or different tag names aren't considered equal */
9806891d857SDavid du Colombier if(t1->tag == nil || t2->tag == nil ||
9816891d857SDavid du Colombier strcmp(t1->tag->name, t2->tag->name) != 0)
9826891d857SDavid du Colombier return 0;
9836891d857SDavid du Colombier }
9843e12c5d1SDavid du Colombier t1 = t1->link;
9853e12c5d1SDavid du Colombier t2 = t2->link;
9863e12c5d1SDavid du Colombier for(;;) {
9873e12c5d1SDavid du Colombier if(t1 == t2)
9883e12c5d1SDavid du Colombier return 1;
9897dd7cddfSDavid du Colombier if(!rsametype(t1, t2, n, 0))
9903e12c5d1SDavid du Colombier return 0;
9913e12c5d1SDavid du Colombier t1 = t1->down;
9923e12c5d1SDavid du Colombier t2 = t2->down;
9933e12c5d1SDavid du Colombier }
9947dd7cddfSDavid du Colombier }
9957dd7cddfSDavid du Colombier t1 = t1->link;
9967dd7cddfSDavid du Colombier t2 = t2->link;
9977dd7cddfSDavid du Colombier if((f || !debug['V']) && et == TIND) {
9987dd7cddfSDavid du Colombier if(t1 != T && t1->etype == TVOID)
9993e12c5d1SDavid du Colombier return 1;
10007dd7cddfSDavid du Colombier if(t2 != T && t2->etype == TVOID)
10017dd7cddfSDavid du Colombier return 1;
10027dd7cddfSDavid du Colombier }
10037dd7cddfSDavid du Colombier }
10047dd7cddfSDavid du Colombier }
10057dd7cddfSDavid du Colombier
1006375daca8SDavid du Colombier typedef struct Typetab Typetab;
1007375daca8SDavid du Colombier
1008375daca8SDavid du Colombier struct Typetab{
1009375daca8SDavid du Colombier int n;
1010375daca8SDavid du Colombier Type **a;
1011375daca8SDavid du Colombier };
1012375daca8SDavid du Colombier
1013375daca8SDavid du Colombier static int
sigind(Type * t,Typetab * tt)1014375daca8SDavid du Colombier sigind(Type *t, Typetab *tt)
10157dd7cddfSDavid du Colombier {
1016375daca8SDavid du Colombier int n;
1017375daca8SDavid du Colombier Type **a, **na, **p, **e;
1018375daca8SDavid du Colombier
1019375daca8SDavid du Colombier n = tt->n;
1020375daca8SDavid du Colombier a = tt->a;
1021375daca8SDavid du Colombier e = a+n;
1022375daca8SDavid du Colombier /* linear search seems ok */
1023375daca8SDavid du Colombier for(p = a ; p < e; p++)
1024375daca8SDavid du Colombier if(sametype(*p, t))
1025375daca8SDavid du Colombier return p-a;
1026375daca8SDavid du Colombier if((n&15) == 0){
1027375daca8SDavid du Colombier na = malloc((n+16)*sizeof(Type*));
1028375daca8SDavid du Colombier memmove(na, a, n*sizeof(Type*));
1029375daca8SDavid du Colombier free(a);
1030375daca8SDavid du Colombier a = tt->a = na;
1031375daca8SDavid du Colombier }
1032375daca8SDavid du Colombier a[tt->n++] = t;
1033375daca8SDavid du Colombier return -1;
1034375daca8SDavid du Colombier }
1035375daca8SDavid du Colombier
1036375daca8SDavid du Colombier static ulong
signat(Type * t,Typetab * tt)1037375daca8SDavid du Colombier signat(Type *t, Typetab *tt)
1038375daca8SDavid du Colombier {
1039375daca8SDavid du Colombier int i;
10407dd7cddfSDavid du Colombier Type *t1;
10417dd7cddfSDavid du Colombier long s;
10427dd7cddfSDavid du Colombier
10437dd7cddfSDavid du Colombier s = 0;
10447dd7cddfSDavid du Colombier for(; t; t=t->link) {
10457dd7cddfSDavid du Colombier s = s*thash1 + thash[t->etype];
1046375daca8SDavid du Colombier if(t->garb&GINCOMPLETE)
1047375daca8SDavid du Colombier return s;
10487dd7cddfSDavid du Colombier switch(t->etype) {
10497dd7cddfSDavid du Colombier default:
10507dd7cddfSDavid du Colombier return s;
10517dd7cddfSDavid du Colombier case TARRAY:
1052375daca8SDavid du Colombier s = s*thash2 + 0; /* was t->width */
10537dd7cddfSDavid du Colombier break;
10547dd7cddfSDavid du Colombier case TFUNC:
1055375daca8SDavid du Colombier for(t1=t->down; t1; t1=t1->down)
1056375daca8SDavid du Colombier s = s*thash3 + signat(t1, tt);
1057375daca8SDavid du Colombier break;
10587dd7cddfSDavid du Colombier case TSTRUCT:
10597dd7cddfSDavid du Colombier case TUNION:
1060375daca8SDavid du Colombier if((i = sigind(t, tt)) >= 0){
1061375daca8SDavid du Colombier s = s*thash2 + i;
1062375daca8SDavid du Colombier return s;
1063375daca8SDavid du Colombier }
1064375daca8SDavid du Colombier for(t1=t->link; t1; t1=t1->down)
1065375daca8SDavid du Colombier s = s*thash3 + signat(t1, tt);
1066375daca8SDavid du Colombier return s;
10677dd7cddfSDavid du Colombier case TIND:
10687dd7cddfSDavid du Colombier break;
10697dd7cddfSDavid du Colombier }
10707dd7cddfSDavid du Colombier }
10717dd7cddfSDavid du Colombier return s;
10727dd7cddfSDavid du Colombier }
10737dd7cddfSDavid du Colombier
1074375daca8SDavid du Colombier ulong
signature(Type * t)1075375daca8SDavid du Colombier signature(Type *t)
1076375daca8SDavid du Colombier {
1077375daca8SDavid du Colombier ulong s;
1078375daca8SDavid du Colombier Typetab tt;
1079375daca8SDavid du Colombier
1080375daca8SDavid du Colombier tt.n = 0;
1081375daca8SDavid du Colombier tt.a = nil;
1082375daca8SDavid du Colombier s = signat(t, &tt);
1083375daca8SDavid du Colombier free(tt.a);
1084375daca8SDavid du Colombier return s;
1085375daca8SDavid du Colombier }
1086375daca8SDavid du Colombier
1087375daca8SDavid du Colombier ulong
sign(Sym * s)1088375daca8SDavid du Colombier sign(Sym *s)
1089375daca8SDavid du Colombier {
1090375daca8SDavid du Colombier ulong v;
1091375daca8SDavid du Colombier Type *t;
1092375daca8SDavid du Colombier
1093375daca8SDavid du Colombier if(s->sig == SIGINTERN)
1094375daca8SDavid du Colombier return SIGNINTERN;
1095375daca8SDavid du Colombier if((t = s->type) == T)
1096375daca8SDavid du Colombier return 0;
1097375daca8SDavid du Colombier v = signature(t);
1098375daca8SDavid du Colombier if(v == 0)
1099375daca8SDavid du Colombier v = SIGNINTERN;
1100375daca8SDavid du Colombier return v;
1101375daca8SDavid du Colombier }
1102375daca8SDavid du Colombier
11037dd7cddfSDavid du Colombier void
snap(Type * t)11047dd7cddfSDavid du Colombier snap(Type *t)
11057dd7cddfSDavid du Colombier {
11067dd7cddfSDavid du Colombier if(typesu[t->etype])
11077dd7cddfSDavid du Colombier if(t->link == T && t->tag && t->tag->suetag) {
11087dd7cddfSDavid du Colombier t->link = t->tag->suetag->link;
11097dd7cddfSDavid du Colombier t->width = t->tag->suetag->width;
11103e12c5d1SDavid du Colombier }
11113e12c5d1SDavid du Colombier }
11123e12c5d1SDavid du Colombier
1113219b2ee8SDavid du Colombier Type*
dotag(Sym * s,int et,int bn)11143e12c5d1SDavid du Colombier dotag(Sym *s, int et, int bn)
11153e12c5d1SDavid du Colombier {
11163e12c5d1SDavid du Colombier Decl *d;
11173e12c5d1SDavid du Colombier
11183e12c5d1SDavid du Colombier if(bn != 0 && bn != s->sueblock) {
11193e12c5d1SDavid du Colombier d = push();
11203e12c5d1SDavid du Colombier d->sym = s;
11213e12c5d1SDavid du Colombier d->val = DSUE;
11223e12c5d1SDavid du Colombier d->type = s->suetag;
11233e12c5d1SDavid du Colombier d->block = s->sueblock;
11243e12c5d1SDavid du Colombier s->suetag = T;
11253e12c5d1SDavid du Colombier }
11263e12c5d1SDavid du Colombier if(s->suetag == T) {
11273e12c5d1SDavid du Colombier s->suetag = typ(et, T);
11283e12c5d1SDavid du Colombier s->sueblock = autobn;
11293e12c5d1SDavid du Colombier }
11303e12c5d1SDavid du Colombier if(s->suetag->etype != et)
11313e12c5d1SDavid du Colombier diag(Z, "tag used for more than one type: %s",
11323e12c5d1SDavid du Colombier s->name);
11333e12c5d1SDavid du Colombier if(s->suetag->tag == S)
11343e12c5d1SDavid du Colombier s->suetag->tag = s;
1135219b2ee8SDavid du Colombier return s->suetag;
11363e12c5d1SDavid du Colombier }
11373e12c5d1SDavid du Colombier
11383e12c5d1SDavid du Colombier Node*
dcllabel(Sym * s,int f)11393e12c5d1SDavid du Colombier dcllabel(Sym *s, int f)
11403e12c5d1SDavid du Colombier {
11413e12c5d1SDavid du Colombier Decl *d, d1;
11423e12c5d1SDavid du Colombier Node *n;
11433e12c5d1SDavid du Colombier
11443e12c5d1SDavid du Colombier n = s->label;
11453e12c5d1SDavid du Colombier if(n != Z) {
11463e12c5d1SDavid du Colombier if(f) {
11473e12c5d1SDavid du Colombier if(n->complex)
11483e12c5d1SDavid du Colombier diag(Z, "label reused: %s", s->name);
11497dd7cddfSDavid du Colombier n->complex = 1; // declared
11507dd7cddfSDavid du Colombier } else
11517dd7cddfSDavid du Colombier n->addable = 1; // used
11523e12c5d1SDavid du Colombier return n;
11533e12c5d1SDavid du Colombier }
11543e12c5d1SDavid du Colombier
11553e12c5d1SDavid du Colombier d = push();
11563e12c5d1SDavid du Colombier d->sym = s;
11573e12c5d1SDavid du Colombier d->val = DLABEL;
11583e12c5d1SDavid du Colombier dclstack = d->link;
11593e12c5d1SDavid du Colombier
11603e12c5d1SDavid du Colombier d1 = *firstdcl;
11613e12c5d1SDavid du Colombier *firstdcl = *d;
11623e12c5d1SDavid du Colombier *d = d1;
11633e12c5d1SDavid du Colombier
11643e12c5d1SDavid du Colombier firstdcl->link = d;
11653e12c5d1SDavid du Colombier firstdcl = d;
11663e12c5d1SDavid du Colombier
11673e12c5d1SDavid du Colombier n = new(OXXX, Z, Z);
11683e12c5d1SDavid du Colombier n->sym = s;
11693e12c5d1SDavid du Colombier n->complex = f;
11707dd7cddfSDavid du Colombier n->addable = !f;
11713e12c5d1SDavid du Colombier s->label = n;
11723e12c5d1SDavid du Colombier
11733e12c5d1SDavid du Colombier if(debug['d'])
11743e12c5d1SDavid du Colombier dbgdecl(s);
11753e12c5d1SDavid du Colombier return n;
11763e12c5d1SDavid du Colombier }
11773e12c5d1SDavid du Colombier
11783e12c5d1SDavid du Colombier Type*
paramconv(Type * t,int f)11793e12c5d1SDavid du Colombier paramconv(Type *t, int f)
11803e12c5d1SDavid du Colombier {
11813e12c5d1SDavid du Colombier
11823e12c5d1SDavid du Colombier switch(t->etype) {
11833e12c5d1SDavid du Colombier case TARRAY:
11843e12c5d1SDavid du Colombier t = typ(TIND, t->link);
11853e12c5d1SDavid du Colombier t->width = types[TIND]->width;
11863e12c5d1SDavid du Colombier break;
11873e12c5d1SDavid du Colombier
11883e12c5d1SDavid du Colombier case TFUNC:
11893e12c5d1SDavid du Colombier t = typ(TIND, t);
11903e12c5d1SDavid du Colombier t->width = types[TIND]->width;
11913e12c5d1SDavid du Colombier break;
11923e12c5d1SDavid du Colombier
11933e12c5d1SDavid du Colombier case TFLOAT:
11943e12c5d1SDavid du Colombier if(!f)
11953e12c5d1SDavid du Colombier t = types[TDOUBLE];
11963e12c5d1SDavid du Colombier break;
11973e12c5d1SDavid du Colombier
11983e12c5d1SDavid du Colombier case TCHAR:
11993e12c5d1SDavid du Colombier case TSHORT:
12003e12c5d1SDavid du Colombier if(!f)
12017dd7cddfSDavid du Colombier t = types[TINT];
12023e12c5d1SDavid du Colombier break;
12033e12c5d1SDavid du Colombier
12043e12c5d1SDavid du Colombier case TUCHAR:
12053e12c5d1SDavid du Colombier case TUSHORT:
12063e12c5d1SDavid du Colombier if(!f)
12077dd7cddfSDavid du Colombier t = types[TUINT];
12083e12c5d1SDavid du Colombier break;
12093e12c5d1SDavid du Colombier }
12103e12c5d1SDavid du Colombier return t;
12113e12c5d1SDavid du Colombier }
12123e12c5d1SDavid du Colombier
12133e12c5d1SDavid du Colombier void
adecl(int c,Type * t,Sym * s)12143e12c5d1SDavid du Colombier adecl(int c, Type *t, Sym *s)
12153e12c5d1SDavid du Colombier {
12163e12c5d1SDavid du Colombier
12173e12c5d1SDavid du Colombier if(c == CSTATIC)
12183e12c5d1SDavid du Colombier c = CLOCAL;
12193e12c5d1SDavid du Colombier if(t->etype == TFUNC) {
12203e12c5d1SDavid du Colombier if(c == CXXX)
12213e12c5d1SDavid du Colombier c = CEXTERN;
12223e12c5d1SDavid du Colombier if(c == CLOCAL)
12233e12c5d1SDavid du Colombier c = CSTATIC;
12243e12c5d1SDavid du Colombier if(c == CAUTO || c == CEXREG)
12253e12c5d1SDavid du Colombier diag(Z, "function cannot be %s %s", cnames[c], s->name);
12263e12c5d1SDavid du Colombier }
12273e12c5d1SDavid du Colombier if(c == CXXX)
12283e12c5d1SDavid du Colombier c = CAUTO;
1229219b2ee8SDavid du Colombier if(s) {
1230219b2ee8SDavid du Colombier if(s->class == CSTATIC)
12317dd7cddfSDavid du Colombier if(c == CEXTERN || c == CGLOBL) {
12327dd7cddfSDavid du Colombier warn(Z, "just say static: %s", s->name);
1233219b2ee8SDavid du Colombier c = CSTATIC;
12347dd7cddfSDavid du Colombier }
12353e12c5d1SDavid du Colombier if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
12363e12c5d1SDavid du Colombier if(s->block == autobn)
12373e12c5d1SDavid du Colombier diag(Z, "auto redeclaration of: %s", s->name);
12383e12c5d1SDavid du Colombier if(c != CPARAM)
12393e12c5d1SDavid du Colombier push1(s);
12403e12c5d1SDavid du Colombier s->block = autobn;
12413e12c5d1SDavid du Colombier s->offset = 0;
12423e12c5d1SDavid du Colombier s->type = t;
12433e12c5d1SDavid du Colombier s->class = c;
12443e12c5d1SDavid du Colombier s->aused = 0;
1245219b2ee8SDavid du Colombier }
12467dd7cddfSDavid du Colombier switch(c) {
12477dd7cddfSDavid du Colombier case CAUTO:
12487dd7cddfSDavid du Colombier autoffset = align(autoffset, t, Aaut3);
12497dd7cddfSDavid du Colombier stkoff = maxround(stkoff, autoffset);
12507dd7cddfSDavid du Colombier s->offset = -autoffset;
12517dd7cddfSDavid du Colombier break;
12523e12c5d1SDavid du Colombier
12537dd7cddfSDavid du Colombier case CPARAM:
12547dd7cddfSDavid du Colombier if(autoffset == 0) {
12553e12c5d1SDavid du Colombier firstarg = s;
12563e12c5d1SDavid du Colombier firstargtype = t;
12573e12c5d1SDavid du Colombier }
12587dd7cddfSDavid du Colombier autoffset = align(autoffset, t, Aarg1);
1259219b2ee8SDavid du Colombier if(s)
12603e12c5d1SDavid du Colombier s->offset = autoffset;
12617dd7cddfSDavid du Colombier autoffset = align(autoffset, t, Aarg2);
12627dd7cddfSDavid du Colombier break;
12633e12c5d1SDavid du Colombier }
12643e12c5d1SDavid du Colombier }
12653e12c5d1SDavid du Colombier
12663e12c5d1SDavid du Colombier void
pdecl(int c,Type * t,Sym * s)12673e12c5d1SDavid du Colombier pdecl(int c, Type *t, Sym *s)
12683e12c5d1SDavid du Colombier {
1269219b2ee8SDavid du Colombier if(s && s->offset != -1) {
12703e12c5d1SDavid du Colombier diag(Z, "not a parameter: %s", s->name);
12713e12c5d1SDavid du Colombier return;
12723e12c5d1SDavid du Colombier }
12733e12c5d1SDavid du Colombier t = paramconv(t, c==CPARAM);
12743e12c5d1SDavid du Colombier if(c == CXXX)
12753e12c5d1SDavid du Colombier c = CPARAM;
12763e12c5d1SDavid du Colombier if(c != CPARAM) {
12773e12c5d1SDavid du Colombier diag(Z, "parameter cannot have class: %s", s->name);
12783e12c5d1SDavid du Colombier c = CPARAM;
12793e12c5d1SDavid du Colombier }
1280d40255d8SDavid du Colombier if(typesu[t->etype] && t->width <= 0)
1281d40255d8SDavid du Colombier diag(Z, "incomplete structure: %s", t->tag->name);
12823e12c5d1SDavid du Colombier adecl(c, t, s);
12833e12c5d1SDavid du Colombier }
12843e12c5d1SDavid du Colombier
12853e12c5d1SDavid du Colombier void
xdecl(int c,Type * t,Sym * s)12863e12c5d1SDavid du Colombier xdecl(int c, Type *t, Sym *s)
12873e12c5d1SDavid du Colombier {
12883e12c5d1SDavid du Colombier long o;
12893e12c5d1SDavid du Colombier
12903e12c5d1SDavid du Colombier o = 0;
129180ee5cbfSDavid du Colombier switch(c) {
129280ee5cbfSDavid du Colombier case CEXREG:
12933e12c5d1SDavid du Colombier o = exreg(t);
12943e12c5d1SDavid du Colombier if(o == 0)
12953e12c5d1SDavid du Colombier c = CEXTERN;
12963e12c5d1SDavid du Colombier if(s->class == CGLOBL)
12973e12c5d1SDavid du Colombier c = CGLOBL;
129880ee5cbfSDavid du Colombier break;
129980ee5cbfSDavid du Colombier
130080ee5cbfSDavid du Colombier case CEXTERN:
130180ee5cbfSDavid du Colombier if(s->class == CGLOBL)
130280ee5cbfSDavid du Colombier c = CGLOBL;
130380ee5cbfSDavid du Colombier break;
130480ee5cbfSDavid du Colombier
130580ee5cbfSDavid du Colombier case CXXX:
130680ee5cbfSDavid du Colombier c = CGLOBL;
130780ee5cbfSDavid du Colombier if(s->class == CEXTERN)
130880ee5cbfSDavid du Colombier s->class = CGLOBL;
130980ee5cbfSDavid du Colombier break;
131080ee5cbfSDavid du Colombier
131180ee5cbfSDavid du Colombier case CAUTO:
13127dd7cddfSDavid du Colombier diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
13133e12c5d1SDavid du Colombier c = CEXTERN;
131480ee5cbfSDavid du Colombier break;
131580ee5cbfSDavid du Colombier
131680ee5cbfSDavid du Colombier case CTYPESTR:
131780ee5cbfSDavid du Colombier if(!typesuv[t->etype]) {
131880ee5cbfSDavid du Colombier diag(Z, "typestr must be struct/union: %s", s->name);
131980ee5cbfSDavid du Colombier break;
13203e12c5d1SDavid du Colombier }
132180ee5cbfSDavid du Colombier dclfunct(t, s);
132280ee5cbfSDavid du Colombier break;
132380ee5cbfSDavid du Colombier }
132480ee5cbfSDavid du Colombier
13253e12c5d1SDavid du Colombier if(s->class == CSTATIC)
13267dd7cddfSDavid du Colombier if(c == CEXTERN || c == CGLOBL) {
13277dd7cddfSDavid du Colombier warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
13283e12c5d1SDavid du Colombier c = CSTATIC;
13297dd7cddfSDavid du Colombier }
13303e12c5d1SDavid du Colombier if(s->type != T)
13313e12c5d1SDavid du Colombier if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
13323e12c5d1SDavid du Colombier diag(Z, "external redeclaration of: %s", s->name);
1333eb2d877eSDavid du Colombier Bprint(&diagbuf, " %s %T %L\n", cnames[c], t, nearln);
1334eb2d877eSDavid du Colombier Bprint(&diagbuf, " %s %T %L\n", cnames[s->class], s->type, s->varlineno);
13353e12c5d1SDavid du Colombier }
13363e12c5d1SDavid du Colombier tmerge(t, s);
13373e12c5d1SDavid du Colombier s->type = t;
13383e12c5d1SDavid du Colombier s->class = c;
13393e12c5d1SDavid du Colombier s->block = 0;
13403e12c5d1SDavid du Colombier s->offset = o;
13413e12c5d1SDavid du Colombier }
13423e12c5d1SDavid du Colombier
13433e12c5d1SDavid du Colombier void
tmerge(Type * t1,Sym * s)13443e12c5d1SDavid du Colombier tmerge(Type *t1, Sym *s)
13453e12c5d1SDavid du Colombier {
13463e12c5d1SDavid du Colombier Type *ta, *tb, *t2;
13473e12c5d1SDavid du Colombier
13483e12c5d1SDavid du Colombier t2 = s->type;
13493e12c5d1SDavid du Colombier /*print("merge %T; %T\n", t1, t2);/**/
13503e12c5d1SDavid du Colombier for(;;) {
13513e12c5d1SDavid du Colombier if(t1 == T || t2 == T || t1 == t2)
13523e12c5d1SDavid du Colombier break;
13533e12c5d1SDavid du Colombier if(t1->etype != t2->etype)
13543e12c5d1SDavid du Colombier break;
13553e12c5d1SDavid du Colombier switch(t1->etype) {
13563e12c5d1SDavid du Colombier case TFUNC:
13573e12c5d1SDavid du Colombier ta = t1->down;
13583e12c5d1SDavid du Colombier tb = t2->down;
13593e12c5d1SDavid du Colombier if(ta == T) {
13603e12c5d1SDavid du Colombier t1->down = tb;
13613e12c5d1SDavid du Colombier break;
13623e12c5d1SDavid du Colombier }
13633e12c5d1SDavid du Colombier if(tb == T)
13643e12c5d1SDavid du Colombier break;
13653e12c5d1SDavid du Colombier while(ta != T && tb != T) {
13663e12c5d1SDavid du Colombier if(ta == tb)
13673e12c5d1SDavid du Colombier break;
13683e12c5d1SDavid du Colombier /* ignore old-style flag */
13693e12c5d1SDavid du Colombier if(ta->etype == TOLD) {
13703e12c5d1SDavid du Colombier ta = ta->down;
13713e12c5d1SDavid du Colombier continue;
13723e12c5d1SDavid du Colombier }
13733e12c5d1SDavid du Colombier if(tb->etype == TOLD) {
13743e12c5d1SDavid du Colombier tb = tb->down;
13753e12c5d1SDavid du Colombier continue;
13763e12c5d1SDavid du Colombier }
13773e12c5d1SDavid du Colombier /* checking terminated by ... */
13783e12c5d1SDavid du Colombier if(ta->etype == TDOT && tb->etype == TDOT) {
13793e12c5d1SDavid du Colombier ta = T;
13803e12c5d1SDavid du Colombier tb = T;
13813e12c5d1SDavid du Colombier break;
13823e12c5d1SDavid du Colombier }
13833e12c5d1SDavid du Colombier if(!sametype(ta, tb))
13843e12c5d1SDavid du Colombier break;
13853e12c5d1SDavid du Colombier ta = ta->down;
13863e12c5d1SDavid du Colombier tb = tb->down;
13873e12c5d1SDavid du Colombier }
13883e12c5d1SDavid du Colombier if(ta != tb)
13893e12c5d1SDavid du Colombier diag(Z, "function inconsistently declared: %s", s->name);
13903e12c5d1SDavid du Colombier
13913e12c5d1SDavid du Colombier /* take new-style over old-style */
13923e12c5d1SDavid du Colombier ta = t1->down;
13933e12c5d1SDavid du Colombier tb = t2->down;
13943e12c5d1SDavid du Colombier if(ta != T && ta->etype == TOLD)
13953e12c5d1SDavid du Colombier if(tb != T && tb->etype != TOLD)
13963e12c5d1SDavid du Colombier t1->down = tb;
13973e12c5d1SDavid du Colombier break;
13983e12c5d1SDavid du Colombier
13993e12c5d1SDavid du Colombier case TARRAY:
14003e12c5d1SDavid du Colombier /* should we check array size change? */
14013e12c5d1SDavid du Colombier if(t2->width > t1->width)
14023e12c5d1SDavid du Colombier t1->width = t2->width;
14033e12c5d1SDavid du Colombier break;
14043e12c5d1SDavid du Colombier
14053e12c5d1SDavid du Colombier case TUNION:
14063e12c5d1SDavid du Colombier case TSTRUCT:
14073e12c5d1SDavid du Colombier return;
14083e12c5d1SDavid du Colombier }
14093e12c5d1SDavid du Colombier t1 = t1->link;
14103e12c5d1SDavid du Colombier t2 = t2->link;
14113e12c5d1SDavid du Colombier }
14123e12c5d1SDavid du Colombier }
14133e12c5d1SDavid du Colombier
14143e12c5d1SDavid du Colombier void
edecl(int c,Type * t,Sym * s)14153e12c5d1SDavid du Colombier edecl(int c, Type *t, Sym *s)
14163e12c5d1SDavid du Colombier {
14173e12c5d1SDavid du Colombier Type *t1;
14183e12c5d1SDavid du Colombier
14193e12c5d1SDavid du Colombier if(s == S) {
14203e12c5d1SDavid du Colombier if(!typesu[t->etype])
14213e12c5d1SDavid du Colombier diag(Z, "unnamed structure element must be struct/union");
14223e12c5d1SDavid du Colombier if(c != CXXX)
14233e12c5d1SDavid du Colombier diag(Z, "unnamed structure element cannot have class");
14243e12c5d1SDavid du Colombier } else
14253e12c5d1SDavid du Colombier if(c != CXXX)
14263e12c5d1SDavid du Colombier diag(Z, "structure element cannot have class: %s", s->name);
14273e12c5d1SDavid du Colombier t1 = t;
142880ee5cbfSDavid du Colombier t = copytyp(t1);
14293e12c5d1SDavid du Colombier t->sym = s;
14303e12c5d1SDavid du Colombier t->down = T;
14313e12c5d1SDavid du Colombier if(lastfield) {
14323e12c5d1SDavid du Colombier t->shift = lastbit - lastfield;
14333e12c5d1SDavid du Colombier t->nbits = lastfield;
14343e12c5d1SDavid du Colombier if(firstbit)
14353e12c5d1SDavid du Colombier t->shift = -t->shift;
14367dd7cddfSDavid du Colombier if(typeu[t->etype])
14377dd7cddfSDavid du Colombier t->etype = tufield->etype;
14387dd7cddfSDavid du Colombier else
14397dd7cddfSDavid du Colombier t->etype = tfield->etype;
14403e12c5d1SDavid du Colombier }
14413e12c5d1SDavid du Colombier if(strf == T)
14423e12c5d1SDavid du Colombier strf = t;
14433e12c5d1SDavid du Colombier else
14443e12c5d1SDavid du Colombier strl->down = t;
14453e12c5d1SDavid du Colombier strl = t;
14463e12c5d1SDavid du Colombier }
14473e12c5d1SDavid du Colombier
14483e12c5d1SDavid du Colombier /*
1449219b2ee8SDavid du Colombier * this routine is very suspect.
1450219b2ee8SDavid du Colombier * ansi requires the enum type to
1451219b2ee8SDavid du Colombier * be represented as an 'int'
1452219b2ee8SDavid du Colombier * this means that 0x81234567
1453219b2ee8SDavid du Colombier * would be illegal. this routine
1454219b2ee8SDavid du Colombier * makes signed and unsigned go
1455219b2ee8SDavid du Colombier * to unsigned.
14563e12c5d1SDavid du Colombier */
1457219b2ee8SDavid du Colombier Type*
maxtype(Type * t1,Type * t2)1458219b2ee8SDavid du Colombier maxtype(Type *t1, Type *t2)
1459219b2ee8SDavid du Colombier {
1460219b2ee8SDavid du Colombier
1461219b2ee8SDavid du Colombier if(t1 == T)
1462219b2ee8SDavid du Colombier return t2;
1463219b2ee8SDavid du Colombier if(t2 == T)
1464219b2ee8SDavid du Colombier return t1;
1465219b2ee8SDavid du Colombier if(t1->etype > t2->etype)
1466219b2ee8SDavid du Colombier return t1;
1467219b2ee8SDavid du Colombier return t2;
14683e12c5d1SDavid du Colombier }
14693e12c5d1SDavid du Colombier
14703e12c5d1SDavid du Colombier void
doenum(Sym * s,Node * n)14713e12c5d1SDavid du Colombier doenum(Sym *s, Node *n)
14723e12c5d1SDavid du Colombier {
14733e12c5d1SDavid du Colombier
14743e12c5d1SDavid du Colombier if(n) {
14753e12c5d1SDavid du Colombier complex(n);
1476219b2ee8SDavid du Colombier if(n->op != OCONST) {
1477219b2ee8SDavid du Colombier diag(n, "enum not a constant: %s", s->name);
14783e12c5d1SDavid du Colombier return;
14793e12c5d1SDavid du Colombier }
1480219b2ee8SDavid du Colombier en.cenum = n->type;
1481219b2ee8SDavid du Colombier en.tenum = maxtype(en.cenum, en.tenum);
1482219b2ee8SDavid du Colombier
1483219b2ee8SDavid du Colombier if(!typefd[en.cenum->etype])
1484219b2ee8SDavid du Colombier en.lastenum = n->vconst;
1485219b2ee8SDavid du Colombier else
1486219b2ee8SDavid du Colombier en.floatenum = n->fconst;
14873e12c5d1SDavid du Colombier }
14883e12c5d1SDavid du Colombier if(dclstack)
14893e12c5d1SDavid du Colombier push1(s);
14903e12c5d1SDavid du Colombier xdecl(CXXX, types[TENUM], s);
1491219b2ee8SDavid du Colombier
1492219b2ee8SDavid du Colombier if(en.cenum == T) {
14937dd7cddfSDavid du Colombier en.tenum = types[TINT];
14947dd7cddfSDavid du Colombier en.cenum = types[TINT];
1495219b2ee8SDavid du Colombier en.lastenum = 0;
1496219b2ee8SDavid du Colombier }
1497219b2ee8SDavid du Colombier s->tenum = en.cenum;
1498219b2ee8SDavid du Colombier
1499219b2ee8SDavid du Colombier if(!typefd[s->tenum->etype]) {
1500219b2ee8SDavid du Colombier s->vconst = convvtox(en.lastenum, s->tenum->etype);
1501219b2ee8SDavid du Colombier en.lastenum++;
1502219b2ee8SDavid du Colombier } else {
1503219b2ee8SDavid du Colombier s->fconst = en.floatenum;
1504219b2ee8SDavid du Colombier en.floatenum++;
1505219b2ee8SDavid du Colombier }
1506219b2ee8SDavid du Colombier
15073e12c5d1SDavid du Colombier if(debug['d'])
15083e12c5d1SDavid du Colombier dbgdecl(s);
15097dd7cddfSDavid du Colombier acidvar(s);
15103e12c5d1SDavid du Colombier }
15113e12c5d1SDavid du Colombier
15123e12c5d1SDavid du Colombier void
symadjust(Sym * s,Node * n,long del)15133e12c5d1SDavid du Colombier symadjust(Sym *s, Node *n, long del)
15143e12c5d1SDavid du Colombier {
15153e12c5d1SDavid du Colombier
15163e12c5d1SDavid du Colombier switch(n->op) {
15173e12c5d1SDavid du Colombier default:
15183e12c5d1SDavid du Colombier if(n->left)
15193e12c5d1SDavid du Colombier symadjust(s, n->left, del);
15203e12c5d1SDavid du Colombier if(n->right)
15213e12c5d1SDavid du Colombier symadjust(s, n->right, del);
15223e12c5d1SDavid du Colombier return;
15233e12c5d1SDavid du Colombier
15243e12c5d1SDavid du Colombier case ONAME:
15253e12c5d1SDavid du Colombier if(n->sym == s)
1526219b2ee8SDavid du Colombier n->xoffset -= del;
15273e12c5d1SDavid du Colombier return;
15283e12c5d1SDavid du Colombier
15293e12c5d1SDavid du Colombier case OCONST:
15303e12c5d1SDavid du Colombier case OSTRING:
15313e12c5d1SDavid du Colombier case OLSTRING:
15323e12c5d1SDavid du Colombier case OINDREG:
15333e12c5d1SDavid du Colombier case OREGISTER:
15343e12c5d1SDavid du Colombier return;
15353e12c5d1SDavid du Colombier }
15363e12c5d1SDavid du Colombier }
15373e12c5d1SDavid du Colombier
15383e12c5d1SDavid du Colombier Node*
contig(Sym * s,Node * n,long v)15393e12c5d1SDavid du Colombier contig(Sym *s, Node *n, long v)
15403e12c5d1SDavid du Colombier {
15413e12c5d1SDavid du Colombier Node *p, *r, *q, *m;
15423e12c5d1SDavid du Colombier long w;
154373e742d7SDavid du Colombier Type *zt;
15443e12c5d1SDavid du Colombier
15459a747e4fSDavid du Colombier if(debug['i']) {
15469a747e4fSDavid du Colombier print("contig v = %ld; s = %s\n", v, s->name);
15479a747e4fSDavid du Colombier prtree(n, "doinit value");
15489a747e4fSDavid du Colombier }
15499a747e4fSDavid du Colombier
15503e12c5d1SDavid du Colombier if(n == Z)
15513e12c5d1SDavid du Colombier goto no;
15523e12c5d1SDavid du Colombier w = s->type->width;
15533e12c5d1SDavid du Colombier
15543e12c5d1SDavid du Colombier /*
15553e12c5d1SDavid du Colombier * nightmare: an automatic array whose size
15563e12c5d1SDavid du Colombier * increases when it is initialized
15573e12c5d1SDavid du Colombier */
15583e12c5d1SDavid du Colombier if(v != w) {
15593e12c5d1SDavid du Colombier if(v != 0)
15603e12c5d1SDavid du Colombier diag(n, "automatic adjustable array: %s", s->name);
15613e12c5d1SDavid du Colombier v = s->offset;
15627dd7cddfSDavid du Colombier autoffset = align(autoffset, s->type, Aaut3);
15633e12c5d1SDavid du Colombier s->offset = -autoffset;
15647dd7cddfSDavid du Colombier stkoff = maxround(stkoff, autoffset);
15653e12c5d1SDavid du Colombier symadjust(s, n, v - s->offset);
15663e12c5d1SDavid du Colombier }
156773e742d7SDavid du Colombier if(w <= ewidth[TIND])
15683e12c5d1SDavid du Colombier goto no;
15693e12c5d1SDavid du Colombier if(n->op == OAS)
15707dd7cddfSDavid du Colombier diag(Z, "oops in contig");
15719a747e4fSDavid du Colombier /*ZZZ this appears incorrect
15729a747e4fSDavid du Colombier need to check if the list completely covers the data.
15739a747e4fSDavid du Colombier if not, bail
15749a747e4fSDavid du Colombier */
15757dd7cddfSDavid du Colombier if(n->op == OLIST)
15767dd7cddfSDavid du Colombier goto no;
15777dd7cddfSDavid du Colombier if(n->op == OASI)
15783e12c5d1SDavid du Colombier if(n->left->type)
15793e12c5d1SDavid du Colombier if(n->left->type->width == w)
15803e12c5d1SDavid du Colombier goto no;
1581b8d70f5aSDavid du Colombier while(w & (ewidth[TIND]-1))
1582b8d70f5aSDavid du Colombier w++;
15833e12c5d1SDavid du Colombier /*
158473e742d7SDavid du Colombier * insert the following code, where long becomes vlong if pointers are fat
15853e12c5d1SDavid du Colombier *
15863e12c5d1SDavid du Colombier *(long**)&X = (long*)((char*)X + sizeof(X));
15873e12c5d1SDavid du Colombier do {
15883e12c5d1SDavid du Colombier *(long**)&X -= 1;
15893e12c5d1SDavid du Colombier **(long**)&X = 0;
15903e12c5d1SDavid du Colombier } while(*(long**)&X);
15913e12c5d1SDavid du Colombier */
15923e12c5d1SDavid du Colombier
15933e12c5d1SDavid du Colombier for(q=n; q->op != ONAME; q=q->left)
15943e12c5d1SDavid du Colombier ;
15953e12c5d1SDavid du Colombier
159673e742d7SDavid du Colombier zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
159773e742d7SDavid du Colombier
15983e12c5d1SDavid du Colombier p = new(ONAME, Z, Z);
15993e12c5d1SDavid du Colombier *p = *q;
160073e742d7SDavid du Colombier p->type = typ(TIND, zt);
1601219b2ee8SDavid du Colombier p->xoffset = s->offset;
16023e12c5d1SDavid du Colombier
16033e12c5d1SDavid du Colombier r = new(ONAME, Z, Z);
16043e12c5d1SDavid du Colombier *r = *p;
16053e12c5d1SDavid du Colombier r = new(OPOSTDEC, r, Z);
16063e12c5d1SDavid du Colombier
16073e12c5d1SDavid du Colombier q = new(ONAME, Z, Z);
16083e12c5d1SDavid du Colombier *q = *p;
16093e12c5d1SDavid du Colombier q = new(OIND, q, Z);
16103e12c5d1SDavid du Colombier
16113e12c5d1SDavid du Colombier m = new(OCONST, Z, Z);
1612219b2ee8SDavid du Colombier m->vconst = 0;
161373e742d7SDavid du Colombier m->type = zt;
16143e12c5d1SDavid du Colombier
16153e12c5d1SDavid du Colombier q = new(OAS, q, m);
16163e12c5d1SDavid du Colombier
16173e12c5d1SDavid du Colombier r = new(OLIST, r, q);
16183e12c5d1SDavid du Colombier
16193e12c5d1SDavid du Colombier q = new(ONAME, Z, Z);
16203e12c5d1SDavid du Colombier *q = *p;
16213e12c5d1SDavid du Colombier r = new(ODWHILE, q, r);
16223e12c5d1SDavid du Colombier
16233e12c5d1SDavid du Colombier q = new(ONAME, Z, Z);
16243e12c5d1SDavid du Colombier *q = *p;
16253e12c5d1SDavid du Colombier q->type = q->type->link;
1626219b2ee8SDavid du Colombier q->xoffset += w;
16273e12c5d1SDavid du Colombier q = new(OADDR, q, 0);
16283e12c5d1SDavid du Colombier
16297dd7cddfSDavid du Colombier q = new(OASI, p, q);
16303e12c5d1SDavid du Colombier r = new(OLIST, q, r);
16313e12c5d1SDavid du Colombier
16323e12c5d1SDavid du Colombier n = new(OLIST, r, n);
16333e12c5d1SDavid du Colombier
16343e12c5d1SDavid du Colombier no:
16353e12c5d1SDavid du Colombier return n;
16363e12c5d1SDavid du Colombier }
1637