]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/dcl.c
cc: use UTFmax not 4 (djc)
[plan9front.git] / sys / src / cmd / cc / dcl.c
1 #include "cc.h"
2
3 Node*
4 dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n)
5 {
6         Sym *s;
7         Node *n1;
8         long v;
9
10         nearln = lineno;
11         lastfield = 0;
12
13 loop:
14         if(n != Z)
15         switch(n->op) {
16         default:
17                 diag(n, "unknown declarator: %O", n->op);
18                 break;
19
20         case OARRAY:
21                 t = typ(TARRAY, t);
22                 t->width = 0;
23                 n1 = n->right;
24                 n = n->left;
25                 if(n1 != Z) {
26                         complex(n1);
27                         v = -1;
28                         if(n1->op == OCONST)
29                                 v = n1->vconst;
30                         if(v <= 0) {
31                                 diag(n, "array size must be a positive constant");
32                                 v = 1;
33                         }
34                         t->width = v * t->link->width;
35                 }
36                 goto loop;
37
38         case OIND:
39                 t = typ(TIND, t);
40                 t->garb = n->garb;
41                 n = n->left;
42                 goto loop;
43
44         case OFUNC:
45                 t = typ(TFUNC, t);
46                 t->down = fnproto(n);
47                 n = n->left;
48                 goto loop;
49
50         case OBIT:
51                 n1 = n->right;
52                 complex(n1);
53                 lastfield = -1;
54                 if(n1->op == OCONST)
55                         lastfield = n1->vconst;
56                 if(lastfield < 0) {
57                         diag(n, "field width must be non-negative constant");
58                         lastfield = 1;
59                 }
60                 if(lastfield == 0) {
61                         lastbit = 0;
62                         firstbit = 1;
63                         if(n->left != Z) {
64                                 diag(n, "zero width named field");
65                                 lastfield = 1;
66                         }
67                 }
68                 if(!typei[t->etype]) {
69                         diag(n, "field type must be int-like");
70                         t = types[TINT];
71                         lastfield = 1;
72                 }
73                 if(lastfield > tfield->width*8) {
74                         diag(n, "field width larger than field unit");
75                         lastfield = 1;
76                 }
77                 lastbit += lastfield;
78                 if(lastbit > tfield->width*8) {
79                         lastbit = lastfield;
80                         firstbit = 1;
81                 }
82                 n = n->left;
83                 goto loop;
84
85         case ONAME:
86                 if(f == NODECL)
87                         break;
88                 s = n->sym;
89                 (*f)(c, t, s);
90                 if(s->class == CLOCAL)
91                         s = mkstatic(s);
92                 firstbit = 0;
93                 n->sym = s;
94                 n->type = s->type;
95                 n->xoffset = s->offset;
96                 n->class = s->class;
97                 n->etype = TVOID;
98                 if(n->type != T)
99                         n->etype = n->type->etype;
100                 if(debug['d'])
101                         dbgdecl(s);
102                 acidvar(s);
103                 s->varlineno = lineno;
104                 break;
105         }
106         lastdcl = t;
107         return n;
108 }
109
110 Sym*
111 mkstatic(Sym *s)
112 {
113         Sym *s1;
114
115         if(s->class != CLOCAL)
116                 return s;
117         snprint(symb, NSYMB, "%s$%d", s->name, s->block);
118         s1 = lookup();
119         if(s1->class != CSTATIC) {
120                 s1->type = s->type;
121                 s1->offset = s->offset;
122                 s1->block = s->block;
123                 s1->class = CSTATIC;
124         }
125         return s1;
126 }
127
128 /*
129  * make a copy of a typedef
130  * the problem is to split out incomplete
131  * arrays so that it is in the variable
132  * rather than the typedef.
133  */
134 Type*
135 tcopy(Type *t)
136 {
137         Type *tl, *tx;
138         int et;
139
140         if(t == T)
141                 return t;
142         et = t->etype;
143         if(typesu[et])
144                 return t;
145         tl = tcopy(t->link);
146         if(tl != t->link ||
147           (et == TARRAY && t->width == 0)) {
148                 tx = copytyp(t);
149                 tx->link = tl;
150                 return tx;
151         }
152         return t;
153 }
154
155 Node*
156 doinit(Sym *s, Type *t, long o, Node *a)
157 {
158         Node *n;
159
160         if(t == T)
161                 return Z;
162         if(s->class == CEXTERN) {
163                 s->class = CGLOBL;
164                 if(debug['d'])
165                         dbgdecl(s);
166         }
167         if(debug['i']) {
168                 print("t = %T; o = %ld; n = %s\n", t, o, s->name);
169                 prtree(a, "doinit value");
170         }
171
172
173         n = initlist;
174         if(a->op == OINIT)
175                 a = a->left;
176         initlist = a;
177
178         a = init1(s, t, o, 0);
179         if(initlist != Z)
180                 diag(initlist, "more initializers than structure: %s",
181                         s->name);
182         initlist = n;
183
184         return a;
185 }
186
187 /*
188  * get next major operator,
189  * dont advance initlist.
190  */
191 Node*
192 peekinit(void)
193 {
194         Node *a;
195
196         a = initlist;
197
198 loop:
199         if(a == Z)
200                 return a;
201         if(a->op == OLIST) {
202                 a = a->left;
203                 goto loop;
204         }
205         return a;
206 }
207
208 /*
209  * consume and return next element on
210  * initlist. expand strings.
211  */
212 Node*
213 nextinit(void)
214 {
215         Node *a, *b, *n;
216
217         a = initlist;
218         n = Z;
219
220         if(a == Z)
221                 return a;
222         if(a->op == OLIST) {
223                 n = a->right;
224                 a = a->left;
225         }
226         if(a->op == OUSED) {
227                 a = a->left;
228                 b = new(OCONST, Z, Z);
229                 b->type = a->type->link;
230                 if(a->op == OSTRING) {
231                         b->vconst = convvtox(*a->cstring, TCHAR);
232                         a->cstring++;
233                 }
234                 if(a->op == OLSTRING) {
235                         b->vconst = convvtox(*a->rstring, TRUNE);
236                         a->rstring++;
237                 }
238                 a->type->width -= b->type->width;
239                 if(a->type->width <= 0)
240                         initlist = n;
241                 return b;
242         }
243         initlist = n;
244         return a;
245 }
246
247 int
248 isstruct(Node *a, Type *t)
249 {
250         Node *n;
251
252         switch(a->op) {
253         case ODOTDOT:
254                 n = a->left;
255                 if(n && n->type && sametype(n->type, t))
256                         return 1;
257         case OSTRING:
258         case OLSTRING:
259         case OCONST:
260         case OINIT:
261         case OELEM:
262                 return 0;
263         }
264
265         n = new(ODOTDOT, Z, Z);
266         *n = *a;
267
268         /*
269          * ODOTDOT is a flag for tcom
270          * a second tcom will not be performed
271          */
272         a->op = ODOTDOT;
273         a->left = n;
274         a->right = Z;
275
276         if(tcom(n))
277                 return 0;
278
279         if(sametype(n->type, t))
280                 return 1;
281         return 0;
282 }
283
284 Node*
285 init1(Sym *s, Type *t, long o, int exflag)
286 {
287         Node *a, *l, *r, nod;
288         Type *t1;
289         long e, w, so, mw;
290
291         a = peekinit();
292         if(a == Z)
293                 return Z;
294
295         if(debug['i']) {
296                 print("t = %T; o = %ld; n = %s\n", t, o, s->name);
297                 prtree(a, "init1 value");
298         }
299
300         if(exflag && a->op == OINIT)
301                 return doinit(s, t, o, nextinit());
302
303         switch(t->etype) {
304         default:
305                 diag(Z, "unknown type in initialization: %T to: %s", t, s->name);
306                 return Z;
307
308         case TCHAR:
309         case TUCHAR:
310         case TINT:
311         case TUINT:
312         case TSHORT:
313         case TUSHORT:
314         case TLONG:
315         case TULONG:
316         case TVLONG:
317         case TUVLONG:
318         case TFLOAT:
319         case TDOUBLE:
320         case TIND:
321         single:
322                 if(a->op == OARRAY || a->op == OELEM)
323                         return Z;
324
325                 a = nextinit();
326                 if(a == Z)
327                         return Z;
328
329                 if(t->nbits)
330                         diag(Z, "cannot initialize bitfields");
331                 if(s->class == CAUTO) {
332                         l = new(ONAME, Z, Z);
333                         l->sym = s;
334                         l->type = t;
335                         l->etype = TVOID;
336                         if(s->type)
337                                 l->etype = s->type->etype;
338                         l->xoffset = s->offset + o;
339                         l->class = s->class;
340
341                         l = new(OASI, l, a);
342                         return l;
343                 }
344
345                 complex(a);
346                 if(a->type == T)
347                         return Z;
348
349                 if(a->op == OCONST) {
350                         if(vconst(a) && t->etype == TIND && a->type && a->type->etype != TIND){
351                                 diag(a, "initialize pointer to an integer: %s", s->name);
352                                 return Z;
353                         }
354                         if(!sametype(a->type, t)) {
355                                 /* hoop jumping to save malloc */
356                                 if(nodcast == Z)
357                                         nodcast = new(OCAST, Z, Z);
358                                 nod = *nodcast;
359                                 nod.left = a;
360                                 nod.type = t;
361                                 nod.lineno = a->lineno;
362                                 complex(&nod);
363                                 if(nod.type)
364                                         *a = nod;
365                         }
366                         if(a->op != OCONST) {
367                                 diag(a, "initializer is not a constant: %s",
368                                         s->name);
369                                 return Z;
370                         }
371                         if(vconst(a) == 0)
372                                 return Z;
373                         goto gext;
374                 }
375                 if(t->etype == TIND) {
376                         while(a->op == OCAST) {
377                                 warn(a, "CAST in initialization ignored");
378                                 a = a->left;
379                         }
380                         if(!sametype(t, a->type)) {
381                                 diag(a, "initialization of incompatible pointers: %s\n%T and %T",
382                                         s->name, t, a->type);
383                         }
384                         switch(a->op) {
385                         case OADDR:
386                                 a = a->left;
387                                 break;
388                         case ONAME:
389                         case OIND:
390                                 diag(a, "initializer is not a constant: %s", s->name);
391                                 return Z;
392                         }
393                         goto gext;
394                 }
395
396                 while(a->op == OCAST)
397                         a = a->left;
398                 if(a->op == OADDR) {
399                         warn(a, "initialize pointer to an integer: %s", s->name);
400                         a = a->left;
401                         goto gext;
402                 }
403                 diag(a, "initializer is not a constant: %s", s->name);
404                 return Z;
405
406         gext:
407                 gextern(s, a, o, t->width);
408
409                 return Z;
410
411         case TARRAY:
412                 w = t->link->width;
413                 if(a->op == OSTRING || a->op == OLSTRING)
414                 if(typei[t->link->etype]) {
415                         /*
416                          * get rid of null if sizes match exactly
417                          */
418                         a = nextinit();
419                         mw = t->width/w;
420                         so = a->type->width/a->type->link->width;
421                         if(mw && so > mw) {
422                                 if(so != mw+1)
423                                         diag(a, "string initialization larger than array");
424                                 a->type->width -= a->type->link->width;
425                         }
426
427                         /*
428                          * arrange strings to be expanded
429                          * inside OINIT braces.
430                          */
431                         a = new(OUSED, a, Z);
432                         return doinit(s, t, o, a);
433                 }
434
435                 mw = -w;
436                 l = Z;
437                 for(e=0;;) {
438                         /*
439                          * peek ahead for element initializer
440                          */
441                         a = peekinit();
442                         if(a == Z)
443                                 break;
444                         if(a->op == OELEM && t->link->etype != TSTRUCT)
445                                 break;
446                         if(a->op == OARRAY) {
447                                 if(e && exflag)
448                                         break;
449                                 a = nextinit();
450                                 r = a->left;
451                                 complex(r);
452                                 if(r->op != OCONST) {
453                                         diag(r, "initializer subscript must be constant");
454                                         return Z;
455                                 }
456                                 e = r->vconst;
457                                 if(t->width != 0)
458                                         if(e < 0 || e*w >= t->width) {
459                                                 diag(a, "initialization index out of range: %ld", e);
460                                                 continue;
461                                         }
462                         }
463
464                         so = e*w;
465                         if(so > mw)
466                                 mw = so;
467                         if(t->width != 0)
468                                 if(mw >= t->width)
469                                         break;
470                         r = init1(s, t->link, o+so, 1);
471                         l = newlist(l, r);
472                         e++;
473                 }
474                 if(t->width == 0)
475                         t->width = mw+w;
476                 return l;
477
478         case TUNION:
479         case TSTRUCT:
480                 /*
481                  * peek ahead to find type of rhs.
482                  * if its a structure, then treat
483                  * this element as a variable
484                  * rather than an aggregate.
485                  */
486                 if(isstruct(a, t))
487                         goto single;
488
489                 if(t->width <= 0) {
490                         diag(Z, "incomplete structure: %s", s->name);
491                         return Z;
492                 }
493                 l = Z;
494
495         again:
496                 for(t1 = t->link; t1 != T; t1 = t1->down) {
497                         if(a->op == OARRAY && t1->etype != TARRAY)
498                                 break;
499                         if(a->op == OELEM) {
500                                 if(t1->sym != a->sym)
501                                         continue;
502                                 nextinit();
503                         }
504                         r = init1(s, t1, o+t1->offset, 1);
505                         l = newlist(l, r);
506                         a = peekinit();
507                         if(a == Z)
508                                 break;
509                         if(a->op == OELEM)
510                                 goto again;
511                 }
512                 if(a && a->op == OELEM)
513                         diag(a, "structure element not found %F", a);
514                 return l;
515         }
516 }
517
518 Node*
519 newlist(Node *l, Node *r)
520 {
521         if(r == Z)
522                 return l;
523         if(l == Z)
524                 return r;
525         return new(OLIST, l, r);
526 }
527
528 void
529 sualign(Type *t)
530 {
531         Type *l;
532         long o, w;
533
534         o = 0;
535         switch(t->etype) {
536
537         case TSTRUCT:
538                 t->offset = 0;
539                 w = 0;
540                 for(l = t->link; l != T; l = l->down) {
541                         if(l->nbits) {
542                                 if(l->shift <= 0) {
543                                         l->shift = -l->shift;
544                                         w = round(w, tfield->width);
545                                         o = w;
546                                         w += tfield->width;
547                                 }
548                                 l->offset = o;
549                         } else {
550                                 if(l->width < 0 ||
551                                    l->width == 0 && l->down != T)
552                                         if(l->sym)
553                                                 diag(Z, "incomplete structure element: %s",
554                                                         l->sym->name);
555                                         else
556                                                 diag(Z, "incomplete structure element");
557                                 w = align(w, l, Ael1);
558                                 l->offset = w;
559                                 w = align(w, l, Ael2);
560                         }
561                 }
562                 w = align(w, t, Asu2);
563                 t->width = w;
564                 acidtype(t);
565                 pickletype(t);
566                 return;
567
568         case TUNION:
569                 t->offset = 0;
570                 w = 0;
571                 for(l = t->link; l != T; l = l->down) {
572                         if(l->width <= 0)
573                                 if(l->sym)
574                                         diag(Z, "incomplete union element: %s",
575                                                 l->sym->name);
576                                 else
577                                         diag(Z, "incomplete union element");
578                         l->offset = 0;
579                         l->shift = 0;
580                         o = align(align(0, l, Ael1), l, Ael2);
581                         if(o > w)
582                                 w = o;
583                 }
584                 w = align(w, t, Asu2);
585                 t->width = w;
586                 acidtype(t);
587                 pickletype(t);
588                 return;
589
590         default:
591                 diag(Z, "unknown type in sualign: %T", t);
592                 break;
593         }
594 }
595
596 long
597 round(long v, int w)
598 {
599         int r;
600
601         if(w <= 0 || w > 8) {
602                 diag(Z, "rounding by %d", w);
603                 w = 1;
604         }
605         r = v%w;
606         if(r)
607                 v += w-r;
608         return v;
609 }
610
611 Type*
612 ofnproto(Node *n)
613 {
614         Type *tl, *tr, *t;
615
616         if(n == Z)
617                 return T;
618         switch(n->op) {
619         case OLIST:
620                 tl = ofnproto(n->left);
621                 tr = ofnproto(n->right);
622                 if(tl == T)
623                         return tr;
624                 tl->down = tr;
625                 return tl;
626
627         case ONAME:
628                 t = copytyp(n->sym->type);
629                 t->down = T;
630                 return t;
631         }
632         return T;
633 }
634
635 #define ANSIPROTO       1
636 #define OLDPROTO        2
637
638 void
639 argmark(Node *n, int pass)
640 {
641         Type *t;
642
643         autoffset = align(0, thisfn->link, Aarg0);
644         stkoff = 0;
645         for(; n->left != Z; n = n->left) {
646                 if(n->op != OFUNC || n->left->op != ONAME)
647                         continue;
648                 walkparam(n->right, pass);
649                 if(pass != 0 && anyproto(n->right) == OLDPROTO) {
650                         t = typ(TFUNC, n->left->sym->type->link);
651                         t->down = typ(TOLD, T);
652                         t->down->down = ofnproto(n->right);
653                         tmerge(t, n->left->sym);
654                         n->left->sym->type = t;
655                 }
656                 break;
657         }
658         autoffset = 0;
659         stkoff = 0;
660 }
661
662 void
663 walkparam(Node *n, int pass)
664 {
665         Sym *s;
666         Node *n1;
667
668         if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
669                 return;
670
671 loop:
672         if(n == Z)
673                 return;
674         switch(n->op) {
675         default:
676                 diag(n, "argument not a name/prototype: %O", n->op);
677                 break;
678
679         case OLIST:
680                 walkparam(n->left, pass);
681                 n = n->right;
682                 goto loop;
683
684         case OPROTO:
685                 for(n1 = n; n1 != Z; n1=n1->left)
686                         if(n1->op == ONAME) {
687                                 if(pass == 0) {
688                                         s = n1->sym;
689                                         push1(s);
690                                         s->offset = -1;
691                                         break;
692                                 }
693                                 dodecl(pdecl, CPARAM, n->type, n->left);
694                                 break;
695                         }
696                 if(n1)
697                         break;
698                 if(pass == 0) {
699                         /*
700                          * extension:
701                          *      allow no name in argument declaration
702                         diag(Z, "no name in argument declaration");
703                          */
704                         break;
705                 }
706                 dodecl(NODECL, CPARAM, n->type, n->left);
707                 pdecl(CPARAM, lastdcl, S);
708                 break;
709
710         case ODOTDOT:
711                 break;
712         
713         case ONAME:
714                 s = n->sym;
715                 if(pass == 0) {
716                         push1(s);
717                         s->offset = -1;
718                         break;
719                 }
720                 if(s->offset != -1) {
721                         if(autoffset == 0) {
722                                 firstarg = s;
723                                 firstargtype = s->type;
724                         }
725                         autoffset = align(autoffset, s->type, Aarg1);
726                         s->offset = autoffset;
727                         autoffset = align(autoffset, s->type, Aarg2);
728                 } else
729                         dodecl(pdecl, CXXX, types[TINT], n);
730                 break;
731         }
732 }
733
734 void
735 markdcl(void)
736 {
737         Decl *d;
738
739         blockno++;
740         d = push();
741         d->val = DMARK;
742         d->offset = autoffset;
743         d->block = autobn;
744         autobn = blockno;
745 }
746
747 Node*
748 revertdcl(void)
749 {
750         Decl *d;
751         Sym *s;
752         Node *n, *n1;
753
754         n = Z;
755         for(;;) {
756                 d = dclstack;
757                 if(d == D) {
758                         diag(Z, "pop off dcl stack");
759                         break;
760                 }
761                 dclstack = d->link;
762                 s = d->sym;
763                 switch(d->val) {
764                 case DMARK:
765                         autoffset = d->offset;
766                         autobn = d->block;
767                         return n;
768
769                 case DAUTO:
770                         if(debug['d'])
771                                 print("revert1 \"%s\"\n", s->name);
772                         if(s->aused == 0) {
773                                 nearln = s->varlineno;
774                                 if(s->class == CAUTO)
775                                         warn(Z, "auto declared and not used: %s", s->name);
776                                 if(s->class == CPARAM)
777                                         warn(Z, "param declared and not used: %s", s->name);
778                         }
779                         if(s->type && (s->type->garb & GVOLATILE)) {
780                                 n1 = new(ONAME, Z, Z);
781                                 n1->sym = s;
782                                 n1->type = s->type;
783                                 n1->etype = TVOID;
784                                 if(n1->type != T)
785                                         n1->etype = n1->type->etype;
786                                 n1->xoffset = s->offset;
787                                 n1->class = s->class;
788
789                                 n1 = new(OADDR, n1, Z);
790                                 n1 = new(OUSED, n1, Z);
791                                 if(n == Z)
792                                         n = n1;
793                                 else
794                                         n = new(OLIST, n1, n);
795                         }
796                         s->type = d->type;
797                         s->class = d->class;
798                         s->offset = d->offset;
799                         s->block = d->block;
800                         s->varlineno = d->varlineno;
801                         s->aused = d->aused;
802                         break;
803
804                 case DSUE:
805                         if(debug['d'])
806                                 print("revert2 \"%s\"\n", s->name);
807                         s->suetag = d->type;
808                         s->sueblock = d->block;
809                         break;
810
811                 case DLABEL:
812                         if(debug['d'])
813                                 print("revert3 \"%s\"\n", s->name);
814                         if(s->label && s->label->addable == 0)
815                                 warn(s->label, "label declared and not used \"%s\"", s->name);
816                         s->label = Z;
817                         break;
818                 }
819         }
820         return n;
821 }
822
823 Type*
824 fnproto(Node *n)
825 {
826         int r;
827
828         r = anyproto(n->right);
829         if(r == 0 || (r & OLDPROTO)) {
830                 if(r & ANSIPROTO)
831                         diag(n, "mixed ansi/old function declaration: %F", n->left);
832                 return T;
833         }
834         return fnproto1(n->right);
835 }
836
837 int
838 anyproto(Node *n)
839 {
840         int r;
841
842         r = 0;
843
844 loop:
845         if(n == Z)
846                 return r;
847         switch(n->op) {
848         case OLIST:
849                 r |= anyproto(n->left);
850                 n = n->right;
851                 goto loop;
852
853         case ODOTDOT:
854         case OPROTO:
855                 return r | ANSIPROTO;
856         }
857         return r | OLDPROTO;
858 }
859
860 Type*
861 fnproto1(Node *n)
862 {
863         Type *t;
864
865         if(n == Z)
866                 return T;
867         switch(n->op) {
868         case OLIST:
869                 t = fnproto1(n->left);
870                 if(t != T)
871                         t->down = fnproto1(n->right);
872                 return t;
873
874         case OPROTO:
875                 lastdcl = T;
876                 dodecl(NODECL, CXXX, n->type, n->left);
877                 t = typ(TXXX, T);
878                 if(lastdcl != T)
879                         *t = *paramconv(lastdcl, 1);
880                 return t;
881
882         case ONAME:
883                 diag(n, "incomplete argument prototype");
884                 return typ(TINT, T);
885
886         case ODOTDOT:
887                 return typ(TDOT, T);
888         }
889         diag(n, "unknown op in fnproto");
890         return T;
891 }
892
893 void
894 dbgdecl(Sym *s)
895 {
896         print("decl \"%s\": C=%s [B=%d:O=%ld] T=%T\n",
897                 s->name, cnames[s->class], s->block, s->offset, s->type);
898 }
899
900 Decl*
901 push(void)
902 {
903         Decl *d;
904
905         d = alloc(sizeof(*d));
906         d->link = dclstack;
907         dclstack = d;
908         return d;
909 }
910
911 Decl*
912 push1(Sym *s)
913 {
914         Decl *d;
915
916         d = push();
917         d->sym = s;
918         d->val = DAUTO;
919         d->type = s->type;
920         d->class = s->class;
921         d->offset = s->offset;
922         d->block = s->block;
923         d->varlineno = s->varlineno;
924         d->aused = s->aused;
925         return d;
926 }
927
928 int
929 sametype(Type *t1, Type *t2)
930 {
931
932         if(t1 == t2)
933                 return 1;
934         return rsametype(t1, t2, 5, 1);
935 }
936
937 int
938 rsametype(Type *t1, Type *t2, int n, int f)
939 {
940         int et;
941
942         n--;
943         for(;;) {
944                 if(t1 == t2)
945                         return 1;
946                 if(t1 == T || t2 == T)
947                         return 0;
948                 if(n <= 0)
949                         return 1;
950                 et = t1->etype;
951                 if(et != t2->etype)
952                         return 0;
953                 if(et == TFUNC) {
954                         if(!rsametype(t1->link, t2->link, n, 0))
955                                 return 0;
956                         t1 = t1->down;
957                         t2 = t2->down;
958                         while(t1 != T && t2 != T) {
959                                 if(t1->etype == TOLD) {
960                                         t1 = t1->down;
961                                         continue;
962                                 }
963                                 if(t2->etype == TOLD) {
964                                         t2 = t2->down;
965                                         continue;
966                                 }
967                                 while(t1 != T || t2 != T) {
968                                         if(!rsametype(t1, t2, n, 0))
969                                                 return 0;
970                                         t1 = t1->down;
971                                         t2 = t2->down;
972                                 }
973                                 break;
974                         }
975                         return 1;
976                 }
977                 if(et == TARRAY)
978                         if(t1->width != t2->width && t1->width != 0 && t2->width != 0)
979                                 return 0;
980                 if(typesu[et]) {
981                         if(t1->link == T)
982                                 snap(t1);
983                         if(t2->link == T)
984                                 snap(t2);
985                         if(t1 != t2 && t1->link == T && t2->link == T){
986                                 /* structs with missing or different tag names aren't considered equal */
987                                 if(t1->tag == nil || t2->tag == nil ||
988                                    strcmp(t1->tag->name, t2->tag->name) != 0)
989                                         return 0;
990                         }
991                         t1 = t1->link;
992                         t2 = t2->link;
993                         for(;;) {
994                                 if(t1 == t2)
995                                         return 1;
996                                 if(!rsametype(t1, t2, n, 0))
997                                         return 0;
998                                 t1 = t1->down;
999                                 t2 = t2->down;
1000                         }
1001                 }
1002                 t1 = t1->link;
1003                 t2 = t2->link;
1004                 if((f || !debug['V']) && et == TIND) {
1005                         if(t1 != T && t1->etype == TVOID)
1006                                 return 1;
1007                         if(t2 != T && t2->etype == TVOID)
1008                                 return 1;
1009                 }
1010         }
1011 }
1012
1013 typedef struct Typetab Typetab;
1014
1015 struct Typetab{
1016         int n;
1017         Type **a;
1018 };
1019
1020 static int
1021 sigind(Type *t, Typetab *tt)
1022 {
1023         int n;
1024         Type **a, **na, **p, **e;
1025
1026         n = tt->n;
1027         a = tt->a;
1028         e = a+n;
1029         /* linear search seems ok */
1030         for(p = a ; p < e; p++)
1031                 if(sametype(*p, t))
1032                         return p-a;
1033         if((n&15) == 0){
1034                 na = malloc((n+16)*sizeof(Type*));
1035                 memmove(na, a, n*sizeof(Type*));
1036                 free(a);
1037                 a = tt->a = na;
1038         }
1039         a[tt->n++] = t;
1040         return -1;
1041 }
1042
1043 static ulong
1044 signat(Type *t, Typetab *tt)
1045 {
1046         int i;
1047         Type *t1;
1048         long s;
1049
1050         s = 0;
1051         for(; t; t=t->link) {
1052                 s = s*thash1 + thash[t->etype];
1053                 if(t->garb&GINCOMPLETE)
1054                         return s;
1055                 switch(t->etype) {
1056                 default:
1057                         return s;
1058                 case TARRAY:
1059                         s = s*thash2 + 0;       /* was t->width */
1060                         break;
1061                 case TFUNC:
1062                         for(t1=t->down; t1; t1=t1->down)
1063                                 s = s*thash3 + signat(t1, tt);
1064                         break;
1065                 case TSTRUCT:
1066                 case TUNION:
1067                         if((i = sigind(t, tt)) >= 0){
1068                                 s = s*thash2 + i;
1069                                 return s;
1070                         }
1071                         for(t1=t->link; t1; t1=t1->down)
1072                                 s = s*thash3 + signat(t1, tt);
1073                         return s;
1074                 case TIND:
1075                         break;
1076                 }
1077         }
1078         return s;
1079 }
1080
1081 ulong
1082 signature(Type *t)
1083 {
1084         ulong s;
1085         Typetab tt;
1086
1087         tt.n = 0;
1088         tt.a = nil;
1089         s = signat(t, &tt);
1090         free(tt.a);
1091         return s;
1092 }
1093
1094 ulong
1095 sign(Sym *s)
1096 {
1097         ulong v;
1098         Type *t;
1099
1100         if(s->sig == SIGINTERN)
1101                 return SIGNINTERN;
1102         if((t = s->type) == T)
1103                 return 0;
1104         v = signature(t);
1105         if(v == 0)
1106                 v = SIGNINTERN;
1107         return v;
1108 }
1109
1110 void
1111 snap(Type *t)
1112 {
1113         if(typesu[t->etype])
1114         if(t->link == T && t->tag && t->tag->suetag) {
1115                 t->link = t->tag->suetag->link;
1116                 t->width = t->tag->suetag->width;
1117         }
1118 }
1119
1120 Type*
1121 dotag(Sym *s, int et, int bn)
1122 {
1123         Decl *d;
1124
1125         if(bn != 0 && bn != s->sueblock) {
1126                 d = push();
1127                 d->sym = s;
1128                 d->val = DSUE;
1129                 d->type = s->suetag;
1130                 d->block = s->sueblock;
1131                 s->suetag = T;
1132         }
1133         if(s->suetag == T) {
1134                 s->suetag = typ(et, T);
1135                 s->sueblock = autobn;
1136         }
1137         if(s->suetag->etype != et)
1138                 diag(Z, "tag used for more than one type: %s",
1139                         s->name);
1140         if(s->suetag->tag == S)
1141                 s->suetag->tag = s;
1142         return s->suetag;
1143 }
1144
1145 Node*
1146 dcllabel(Sym *s, int f)
1147 {
1148         Decl *d, d1;
1149         Node *n;
1150
1151         n = s->label;
1152         if(n != Z) {
1153                 if(f) {
1154                         if(n->complex)
1155                                 diag(Z, "label reused: %s", s->name);
1156                         n->complex = 1; // declared
1157                 } else
1158                         n->addable = 1; // used
1159                 return n;
1160         }
1161
1162         d = push();
1163         d->sym = s;
1164         d->val = DLABEL;
1165         dclstack = d->link;
1166
1167         d1 = *firstdcl;
1168         *firstdcl = *d;
1169         *d = d1;
1170
1171         firstdcl->link = d;
1172         firstdcl = d;
1173
1174         n = new(OXXX, Z, Z);
1175         n->sym = s;
1176         n->complex = f;
1177         n->addable = !f;
1178         s->label = n;
1179
1180         if(debug['d'])
1181                 dbgdecl(s);
1182         return n;
1183 }
1184
1185 Type*
1186 paramconv(Type *t, int f)
1187 {
1188
1189         switch(t->etype) {
1190         case TARRAY:
1191                 t = typ(TIND, t->link);
1192                 t->width = types[TIND]->width;
1193                 break;
1194
1195         case TFUNC:
1196                 t = typ(TIND, t);
1197                 t->width = types[TIND]->width;
1198                 break;
1199
1200         case TFLOAT:
1201                 if(!f)
1202                         t = types[TDOUBLE];
1203                 break;
1204
1205         case TCHAR:
1206         case TSHORT:
1207                 if(!f)
1208                         t = types[TINT];
1209                 break;
1210
1211         case TUCHAR:
1212         case TUSHORT:
1213                 if(!f)
1214                         t = types[TUINT];
1215                 break;
1216         }
1217         return t;
1218 }
1219
1220 void
1221 adecl(int c, Type *t, Sym *s)
1222 {
1223
1224         if(c == CSTATIC)
1225                 c = CLOCAL;
1226         if(t->etype == TFUNC) {
1227                 if(c == CXXX)
1228                         c = CEXTERN;
1229                 if(c == CLOCAL)
1230                         c = CSTATIC;
1231                 if(c == CAUTO || c == CEXREG)
1232                         diag(Z, "function cannot be %s %s", cnames[c], s->name);
1233         }
1234         if(c == CXXX)
1235                 c = CAUTO;
1236         if(s) {
1237                 if(s->class == CSTATIC)
1238                         if(c == CEXTERN || c == CGLOBL) {
1239                                 warn(Z, "just say static: %s", s->name);
1240                                 c = CSTATIC;
1241                         }
1242                 if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
1243                 if(s->block == autobn)
1244                         diag(Z, "auto redeclaration of: %s", s->name);
1245                 if(c != CPARAM)
1246                         push1(s);
1247                 s->block = autobn;
1248                 s->offset = 0;
1249                 s->type = t;
1250                 s->class = c;
1251                 s->aused = 0;
1252         }
1253         switch(c) {
1254         case CAUTO:
1255                 autoffset = align(autoffset, t, Aaut3);
1256                 stkoff = maxround(stkoff, autoffset);
1257                 s->offset = -autoffset;
1258                 break;
1259
1260         case CPARAM:
1261                 if(autoffset == 0) {
1262                         firstarg = s;
1263                         firstargtype = t;
1264                 }
1265                 autoffset = align(autoffset, t, Aarg1);
1266                 if(s)
1267                         s->offset = autoffset;
1268                 autoffset = align(autoffset, t, Aarg2);
1269                 break;
1270         }
1271 }
1272
1273 void
1274 pdecl(int c, Type *t, Sym *s)
1275 {
1276         if(s && s->offset != -1) {
1277                 diag(Z, "not a parameter: %s", s->name);
1278                 return;
1279         }
1280         t = paramconv(t, c==CPARAM);
1281         if(c == CXXX)
1282                 c = CPARAM;
1283         if(c != CPARAM) {
1284                 diag(Z, "parameter cannot have class: %s", s->name);
1285                 c = CPARAM;
1286         }
1287         if(typesu[t->etype] && t->width <= 0)
1288                 diag(Z, "incomplete structure: %s", t->tag->name);
1289         adecl(c, t, s);
1290 }
1291
1292 void
1293 xdecl(int c, Type *t, Sym *s)
1294 {
1295         long o;
1296
1297         o = 0;
1298         switch(c) {
1299         case CEXREG:
1300                 o = exreg(t);
1301                 if(o == 0)
1302                         c = CEXTERN;
1303                 if(s->class == CGLOBL)
1304                         c = CGLOBL;
1305                 break;
1306
1307         case CEXTERN:
1308                 if(s->class == CGLOBL)
1309                         c = CGLOBL;
1310                 break;
1311
1312         case CXXX:
1313                 c = CGLOBL;
1314                 if(s->class == CEXTERN)
1315                         s->class = CGLOBL;
1316                 break;
1317
1318         case CAUTO:
1319                 diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
1320                 c = CEXTERN;
1321                 break;
1322
1323         case CTYPESTR:
1324                 if(!typesuv[t->etype]) {
1325                         diag(Z, "typestr must be struct/union: %s", s->name);
1326                         break;
1327                 }
1328                 dclfunct(t, s);
1329                 break;
1330         }
1331
1332         if(s->class == CSTATIC)
1333                 if(c == CEXTERN || c == CGLOBL) {
1334                         warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
1335                         c = CSTATIC;
1336                 }
1337         if(s->type != T)
1338                 if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
1339                         diag(Z, "external redeclaration of: %s", s->name);
1340                         Bprint(&diagbuf, "      %s %T %L\n", cnames[c], t, nearln);
1341                         Bprint(&diagbuf, "      %s %T %L\n", cnames[s->class], s->type, s->varlineno);
1342                 }
1343         tmerge(t, s);
1344         s->type = t;
1345         s->class = c;
1346         s->block = 0;
1347         s->offset = o;
1348 }
1349
1350 void
1351 tmerge(Type *t1, Sym *s)
1352 {
1353         Type *ta, *tb, *t2;
1354
1355         t2 = s->type;
1356 /*print("merge  %T; %T\n", t1, t2);/**/
1357         for(;;) {
1358                 if(t1 == T || t2 == T || t1 == t2)
1359                         break;
1360                 if(t1->etype != t2->etype)
1361                         break;
1362                 switch(t1->etype) {
1363                 case TFUNC:
1364                         ta = t1->down;
1365                         tb = t2->down;
1366                         if(ta == T) {
1367                                 t1->down = tb;
1368                                 break;
1369                         }
1370                         if(tb == T)
1371                                 break;
1372                         while(ta != T && tb != T) {
1373                                 if(ta == tb)
1374                                         break;
1375                                 /* ignore old-style flag */
1376                                 if(ta->etype == TOLD) {
1377                                         ta = ta->down;
1378                                         continue;
1379                                 }
1380                                 if(tb->etype == TOLD) {
1381                                         tb = tb->down;
1382                                         continue;
1383                                 }
1384                                 /* checking terminated by ... */
1385                                 if(ta->etype == TDOT && tb->etype == TDOT) {
1386                                         ta = T;
1387                                         tb = T;
1388                                         break;
1389                                 }
1390                                 if(!sametype(ta, tb))
1391                                         break;
1392                                 ta = ta->down;
1393                                 tb = tb->down;
1394                         }
1395                         if(ta != tb)
1396                                 diag(Z, "function inconsistently declared: %s", s->name);
1397
1398                         /* take new-style over old-style */
1399                         ta = t1->down;
1400                         tb = t2->down;
1401                         if(ta != T && ta->etype == TOLD)
1402                                 if(tb != T && tb->etype != TOLD)
1403                                         t1->down = tb;
1404                         break;
1405
1406                 case TARRAY:
1407                         /* should we check array size change? */
1408                         if(t2->width > t1->width)
1409                                 t1->width = t2->width;
1410                         break;
1411
1412                 case TUNION:
1413                 case TSTRUCT:
1414                         return;
1415                 }
1416                 t1 = t1->link;
1417                 t2 = t2->link;
1418         }
1419 }
1420
1421 void
1422 edecl(int c, Type *t, Sym *s)
1423 {
1424         Type *t1;
1425
1426         if(s == S) {
1427                 if(!typesu[t->etype])
1428                         diag(Z, "unnamed structure element must be struct/union");
1429                 if(c != CXXX)
1430                         diag(Z, "unnamed structure element cannot have class");
1431         } else
1432                 if(c != CXXX)
1433                         diag(Z, "structure element cannot have class: %s", s->name);
1434         t1 = t;
1435         t = copytyp(t1);
1436         t->sym = s;
1437         t->down = T;
1438         if(lastfield) {
1439                 t->shift = lastbit - lastfield;
1440                 t->nbits = lastfield;
1441                 if(firstbit)
1442                         t->shift = -t->shift;
1443                 if(typeu[t->etype])
1444                         t->etype = tufield->etype;
1445                 else
1446                         t->etype = tfield->etype;
1447         }
1448         if(strf == T)
1449                 strf = t;
1450         else
1451                 strl->down = t;
1452         strl = t;
1453 }
1454
1455 /*
1456  * this routine is very suspect.
1457  * ansi requires the enum type to
1458  * be represented as an 'int'
1459  * this means that 0x81234567
1460  * would be illegal. this routine
1461  * makes signed and unsigned go
1462  * to unsigned.
1463  */
1464 Type*
1465 maxtype(Type *t1, Type *t2)
1466 {
1467
1468         if(t1 == T)
1469                 return t2;
1470         if(t2 == T)
1471                 return t1;
1472         if(t1->etype > t2->etype)
1473                 return t1;
1474         return t2;
1475 }
1476
1477 void
1478 doenum(Sym *s, Node *n)
1479 {
1480
1481         if(n) {
1482                 complex(n);
1483                 if(n->op != OCONST) {
1484                         diag(n, "enum not a constant: %s", s->name);
1485                         return;
1486                 }
1487                 en.cenum = n->type;
1488                 en.tenum = maxtype(en.cenum, en.tenum);
1489
1490                 if(!typefd[en.cenum->etype])
1491                         en.lastenum = n->vconst;
1492                 else
1493                         en.floatenum = n->fconst;
1494         }
1495         if(dclstack)
1496                 push1(s);
1497         xdecl(CXXX, types[TENUM], s);
1498
1499         if(en.cenum == T) {
1500                 en.tenum = types[TINT];
1501                 en.cenum = types[TINT];
1502                 en.lastenum = 0;
1503         }
1504         s->tenum = en.cenum;
1505
1506         if(!typefd[s->tenum->etype]) {
1507                 s->vconst = convvtox(en.lastenum, s->tenum->etype);
1508                 en.lastenum++;
1509         } else {
1510                 s->fconst = en.floatenum;
1511                 en.floatenum++;
1512         }
1513
1514         if(debug['d'])
1515                 dbgdecl(s);
1516         acidvar(s);
1517 }
1518
1519 void
1520 symadjust(Sym *s, Node *n, long del)
1521 {
1522
1523         switch(n->op) {
1524         default:
1525                 if(n->left)
1526                         symadjust(s, n->left, del);
1527                 if(n->right)
1528                         symadjust(s, n->right, del);
1529                 return;
1530
1531         case ONAME:
1532                 if(n->sym == s)
1533                         n->xoffset -= del;
1534                 return;
1535
1536         case OCONST:
1537         case OSTRING:
1538         case OLSTRING:
1539         case OINDREG:
1540         case OREGISTER:
1541                 return;
1542         }
1543 }
1544
1545 static int
1546 covered1(long o, Node *n)
1547 {
1548         if(n->op == OLIST)
1549                 return covered1(o, n->left) || covered1(o, n->right);
1550         if(n->op == OASI)
1551                 return covered1(o, n->left);
1552         if(n->op != ONAME)
1553                 return 0;
1554         return o >= n->xoffset && o < n->xoffset+n->type->width;
1555 }
1556
1557 static int
1558 covered(long o, long w, Node *n)
1559 {
1560         while(w > 0 && covered1(o, n)) {
1561                 o++;
1562                 w--;
1563         }
1564         return w == 0;
1565 }
1566
1567 static Node*
1568 initz(Node *q, Type *t, long o, Node *n)
1569 {
1570         Node *p;
1571
1572         if(covered(o, t->width, n))
1573                 return n;
1574
1575         p = new(ONAME, Z, Z);
1576         *p = *q;
1577         p->type = t;
1578         p->xoffset = o;
1579
1580         q = new(OCONST, Z, Z);
1581         q->vconst = 0;
1582         q->type = t;
1583
1584         return new(OLIST, new(OASI, p, q), n);
1585 }
1586
1587 Node*
1588 contig(Sym *s, Node *n, long v)
1589 {
1590         Node *p, *r, *q, *m;
1591         long w;
1592         Type *zt;
1593
1594         if(debug['i']) {
1595                 print("contig v = %ld; s = %s\n", v, s->name);
1596                 prtree(n, "doinit value");
1597         }
1598
1599         if(n == Z)
1600                 goto no;
1601         w = s->type->width;
1602
1603         /*
1604          * nightmare: an automatic array whose size
1605          * increases when it is initialized
1606          */
1607         if(v != w) {
1608                 if(v != 0)
1609                         diag(n, "automatic adjustable array: %s", s->name);
1610                 v = s->offset;
1611                 autoffset = align(autoffset, s->type, Aaut3);
1612                 s->offset = -autoffset;
1613                 stkoff = maxround(stkoff, autoffset);
1614                 symadjust(s, n, v - s->offset);
1615         }
1616         if(n->op == OAS)
1617                 diag(Z, "oops in contig");
1618         if(n->op == OASI)
1619                 if(n->left->type)
1620                 if(n->left->type->width == w)
1621                         goto no;
1622
1623         for(q=n; q->op != ONAME; q=q->left)
1624                 ;
1625
1626         v = s->offset;
1627
1628         /* unaligned front */
1629         while(w > 0 && (v % ewidth[TIND]) != 0) {
1630                 zt = types[TCHAR];
1631                 if(w >= ewidth[TLONG] && (v % ewidth[TLONG]) == 0)
1632                         zt = types[TLONG];
1633                 n = initz(q, zt, v, n);
1634                 v += zt->width;
1635                 w -= zt->width;
1636         }
1637
1638         /* skip initialized words */
1639         while(w >= ewidth[TIND] && covered(v, ewidth[TIND], n)) {
1640                 v += ewidth[TIND];
1641                 w -= ewidth[TIND];
1642         }
1643
1644         /* unaligned (or small) back */
1645         while(w > 0 && ((w % ewidth[TIND]) != 0 || w <= 16)) {
1646                 zt = types[TCHAR];
1647                 if(w >= ewidth[TLONG] && (w % ewidth[TLONG]) == 0)
1648                         zt = types[TLONG];
1649                 w -= zt->width;
1650                 n = initz(q, zt, v + w, n);
1651         }
1652
1653         if(w == 0)
1654                 goto no;
1655
1656 /*
1657  * insert the following code, where long becomes vlong if pointers are fat
1658  *
1659         *(long**)&X = (long*)((char*)X + sizeof(X));
1660         do {
1661                 *(long**)&X -= 1;
1662                 **(long**)&X = 0;
1663         } while(*(long**)&X);
1664  */
1665
1666         zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
1667
1668         p = new(ONAME, Z, Z);
1669         *p = *q;
1670         p->type = typ(TIND, zt);
1671         p->xoffset = v;
1672
1673         r = new(ONAME, Z, Z);
1674         *r = *p;
1675         r = new(OPOSTDEC, r, Z);
1676
1677         q = new(ONAME, Z, Z);
1678         *q = *p;
1679         q = new(OIND, q, Z);
1680
1681         m = new(OCONST, Z, Z);
1682         m->vconst = 0;
1683         m->type = zt;
1684
1685         q = new(OAS, q, m);
1686
1687         r = new(OLIST, r, q);
1688
1689         q = new(ONAME, Z, Z);
1690         *q = *p;
1691         r = new(ODWHILE, q, r);
1692
1693         q = new(ONAME, Z, Z);
1694         *q = *p;
1695         q->type = q->type->link;
1696         q->xoffset += w;
1697         q = new(OADDR, q, 0);
1698
1699         q = new(OASI, p, q);
1700         r = new(OLIST, q, r);
1701
1702         n = new(OLIST, r, n);
1703
1704 no:
1705         return n;
1706 }