1 #include "cc.h"
2
3 Node*
dodecl(void (* f)(int,Type *,Sym *),int c,Type * t,Node * n)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*
mkstatic(Sym * s)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*
tcopy(Type * t)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*
doinit(Sym * s,Type * t,long o,Node * a)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*
peekinit(void)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*
nextinit(void)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
isstruct(Node * a,Type * t)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*
init1(Sym * s,Type * t,long o,int exflag)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*
newlist(Node * l,Node * r)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
sualign(Type * t)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
round(long v,int w)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*
ofnproto(Node * n)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
argmark(Node * n,int pass)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
walkparam(Node * n,int pass)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
markdcl(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*
revertdcl(void)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*
fnproto(Node * n)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
anyproto(Node * n)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*
fnproto1(Node * n)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
dbgdecl(Sym * s)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*
push(void)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*
push1(Sym * s)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
sametype(Type * t1,Type * t2)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
rsametype(Type * t1,Type * t2,int n,int f)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
sigind(Type * t,Typetab * tt)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
signat(Type * t,Typetab * tt)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
signature(Type * t)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
sign(Sym * s)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
snap(Type * t)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*
dotag(Sym * s,int et,int bn)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*
dcllabel(Sym * s,int f)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*
paramconv(Type * t,int f)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
adecl(int c,Type * t,Sym * s)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
pdecl(int c,Type * t,Sym * s)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
xdecl(int c,Type * t,Sym * s)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
tmerge(Type * t1,Sym * s)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
edecl(int c,Type * t,Sym * s)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*
maxtype(Type * t1,Type * t2)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
doenum(Sym * s,Node * n)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
symadjust(Sym * s,Node * n,long del)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 Node*
contig(Sym * s,Node * n,long v)1546 contig(Sym *s, Node *n, long v)
1547 {
1548 Node *p, *r, *q, *m;
1549 long w;
1550 Type *zt;
1551
1552 if(debug['i']) {
1553 print("contig v = %ld; s = %s\n", v, s->name);
1554 prtree(n, "doinit value");
1555 }
1556
1557 if(n == Z)
1558 goto no;
1559 w = s->type->width;
1560
1561 /*
1562 * nightmare: an automatic array whose size
1563 * increases when it is initialized
1564 */
1565 if(v != w) {
1566 if(v != 0)
1567 diag(n, "automatic adjustable array: %s", s->name);
1568 v = s->offset;
1569 autoffset = align(autoffset, s->type, Aaut3);
1570 s->offset = -autoffset;
1571 stkoff = maxround(stkoff, autoffset);
1572 symadjust(s, n, v - s->offset);
1573 }
1574 if(w <= ewidth[TIND])
1575 goto no;
1576 if(n->op == OAS)
1577 diag(Z, "oops in contig");
1578 /*ZZZ this appears incorrect
1579 need to check if the list completely covers the data.
1580 if not, bail
1581 */
1582 if(n->op == OLIST)
1583 goto no;
1584 if(n->op == OASI)
1585 if(n->left->type)
1586 if(n->left->type->width == w)
1587 goto no;
1588 while(w & (ewidth[TIND]-1))
1589 w++;
1590 /*
1591 * insert the following code, where long becomes vlong if pointers are fat
1592 *
1593 *(long**)&X = (long*)((char*)X + sizeof(X));
1594 do {
1595 *(long**)&X -= 1;
1596 **(long**)&X = 0;
1597 } while(*(long**)&X);
1598 */
1599
1600 for(q=n; q->op != ONAME; q=q->left)
1601 ;
1602
1603 zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
1604
1605 p = new(ONAME, Z, Z);
1606 *p = *q;
1607 p->type = typ(TIND, zt);
1608 p->xoffset = s->offset;
1609
1610 r = new(ONAME, Z, Z);
1611 *r = *p;
1612 r = new(OPOSTDEC, r, Z);
1613
1614 q = new(ONAME, Z, Z);
1615 *q = *p;
1616 q = new(OIND, q, Z);
1617
1618 m = new(OCONST, Z, Z);
1619 m->vconst = 0;
1620 m->type = zt;
1621
1622 q = new(OAS, q, m);
1623
1624 r = new(OLIST, r, q);
1625
1626 q = new(ONAME, Z, Z);
1627 *q = *p;
1628 r = new(ODWHILE, q, r);
1629
1630 q = new(ONAME, Z, Z);
1631 *q = *p;
1632 q->type = q->type->link;
1633 q->xoffset += w;
1634 q = new(OADDR, q, 0);
1635
1636 q = new(OASI, p, q);
1637 r = new(OLIST, q, r);
1638
1639 n = new(OLIST, r, n);
1640
1641 no:
1642 return n;
1643 }
1644