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 if(a->op == OADDR)
385 a = a->left;
386 goto gext;
387 }
388
389 while(a->op == OCAST)
390 a = a->left;
391 if(a->op == OADDR) {
392 warn(a, "initialize pointer to an integer: %s", s->name);
393 a = a->left;
394 goto gext;
395 }
396 diag(a, "initializer is not a constant: %s", s->name);
397 return Z;
398
399 gext:
400 gextern(s, a, o, t->width);
401
402 return Z;
403
404 case TARRAY:
405 w = t->link->width;
406 if(a->op == OSTRING || a->op == OLSTRING)
407 if(typei[t->link->etype]) {
408 /*
409 * get rid of null if sizes match exactly
410 */
411 a = nextinit();
412 mw = t->width/w;
413 so = a->type->width/a->type->link->width;
414 if(mw && so > mw) {
415 if(so != mw+1)
416 diag(a, "string initialization larger than array");
417 a->type->width -= a->type->link->width;
418 }
419
420 /*
421 * arrange strings to be expanded
422 * inside OINIT braces.
423 */
424 a = new(OUSED, a, Z);
425 return doinit(s, t, o, a);
426 }
427
428 mw = -w;
429 l = Z;
430 for(e=0;;) {
431 /*
432 * peek ahead for element initializer
433 */
434 a = peekinit();
435 if(a == Z)
436 break;
437 if(a->op == OELEM && t->link->etype != TSTRUCT)
438 break;
439 if(a->op == OARRAY) {
440 if(e && exflag)
441 break;
442 a = nextinit();
443 r = a->left;
444 complex(r);
445 if(r->op != OCONST) {
446 diag(r, "initializer subscript must be constant");
447 return Z;
448 }
449 e = r->vconst;
450 if(t->width != 0)
451 if(e < 0 || e*w >= t->width) {
452 diag(a, "initialization index out of range: %ld", e);
453 continue;
454 }
455 }
456
457 so = e*w;
458 if(so > mw)
459 mw = so;
460 if(t->width != 0)
461 if(mw >= t->width)
462 break;
463 r = init1(s, t->link, o+so, 1);
464 l = newlist(l, r);
465 e++;
466 }
467 if(t->width == 0)
468 t->width = mw+w;
469 return l;
470
471 case TUNION:
472 case TSTRUCT:
473 /*
474 * peek ahead to find type of rhs.
475 * if its a structure, then treat
476 * this element as a variable
477 * rather than an aggregate.
478 */
479 if(isstruct(a, t))
480 goto single;
481
482 if(t->width <= 0) {
483 diag(Z, "incomplete structure: %s", s->name);
484 return Z;
485 }
486 l = Z;
487
488 again:
489 for(t1 = t->link; t1 != T; t1 = t1->down) {
490 if(a->op == OARRAY && t1->etype != TARRAY)
491 break;
492 if(a->op == OELEM) {
493 if(t1->sym != a->sym)
494 continue;
495 nextinit();
496 }
497 r = init1(s, t1, o+t1->offset, 1);
498 l = newlist(l, r);
499 a = peekinit();
500 if(a == Z)
501 break;
502 if(a->op == OELEM)
503 goto again;
504 }
505 if(a && a->op == OELEM)
506 diag(a, "structure element not found %F", a);
507 return l;
508 }
509 }
510
511 Node*
newlist(Node * l,Node * r)512 newlist(Node *l, Node *r)
513 {
514 if(r == Z)
515 return l;
516 if(l == Z)
517 return r;
518 return new(OLIST, l, r);
519 }
520
521 void
sualign(Type * t)522 sualign(Type *t)
523 {
524 Type *l;
525 long o, w;
526
527 o = 0;
528 switch(t->etype) {
529
530 case TSTRUCT:
531 t->offset = 0;
532 w = 0;
533 for(l = t->link; l != T; l = l->down) {
534 if(l->nbits) {
535 if(l->shift <= 0) {
536 l->shift = -l->shift;
537 w = round(w, tfield->width);
538 o = w;
539 w += tfield->width;
540 }
541 l->offset = o;
542 } else {
543 if(l->width < 0 ||
544 l->width == 0 && l->down != T)
545 if(l->sym)
546 diag(Z, "incomplete structure element: %s",
547 l->sym->name);
548 else
549 diag(Z, "incomplete structure element");
550 w = align(w, l, Ael1);
551 l->offset = w;
552 w = align(w, l, Ael2);
553 }
554 }
555 w = align(w, t, Asu2);
556 t->width = w;
557 acidtype(t);
558 pickletype(t);
559 return;
560
561 case TUNION:
562 t->offset = 0;
563 w = 0;
564 for(l = t->link; l != T; l = l->down) {
565 if(l->width <= 0)
566 if(l->sym)
567 diag(Z, "incomplete union element: %s",
568 l->sym->name);
569 else
570 diag(Z, "incomplete union element");
571 l->offset = 0;
572 l->shift = 0;
573 o = align(align(0, l, Ael1), l, Ael2);
574 if(o > w)
575 w = o;
576 }
577 w = align(w, t, Asu2);
578 t->width = w;
579 acidtype(t);
580 pickletype(t);
581 return;
582
583 default:
584 diag(Z, "unknown type in sualign: %T", t);
585 break;
586 }
587 }
588
589 long
round(long v,int w)590 round(long v, int w)
591 {
592 int r;
593
594 if(w <= 0 || w > 8) {
595 diag(Z, "rounding by %d", w);
596 w = 1;
597 }
598 r = v%w;
599 if(r)
600 v += w-r;
601 return v;
602 }
603
604 Type*
ofnproto(Node * n)605 ofnproto(Node *n)
606 {
607 Type *tl, *tr, *t;
608
609 if(n == Z)
610 return T;
611 switch(n->op) {
612 case OLIST:
613 tl = ofnproto(n->left);
614 tr = ofnproto(n->right);
615 if(tl == T)
616 return tr;
617 tl->down = tr;
618 return tl;
619
620 case ONAME:
621 t = copytyp(n->sym->type);
622 t->down = T;
623 return t;
624 }
625 return T;
626 }
627
628 #define ANSIPROTO 1
629 #define OLDPROTO 2
630
631 void
argmark(Node * n,int pass)632 argmark(Node *n, int pass)
633 {
634 Type *t;
635
636 autoffset = align(0, thisfn->link, Aarg0);
637 stkoff = 0;
638 for(; n->left != Z; n = n->left) {
639 if(n->op != OFUNC || n->left->op != ONAME)
640 continue;
641 walkparam(n->right, pass);
642 if(pass != 0 && anyproto(n->right) == OLDPROTO) {
643 t = typ(TFUNC, n->left->sym->type->link);
644 t->down = typ(TOLD, T);
645 t->down->down = ofnproto(n->right);
646 tmerge(t, n->left->sym);
647 n->left->sym->type = t;
648 }
649 break;
650 }
651 autoffset = 0;
652 stkoff = 0;
653 }
654
655 void
walkparam(Node * n,int pass)656 walkparam(Node *n, int pass)
657 {
658 Sym *s;
659 Node *n1;
660
661 if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
662 return;
663
664 loop:
665 if(n == Z)
666 return;
667 switch(n->op) {
668 default:
669 diag(n, "argument not a name/prototype: %O", n->op);
670 break;
671
672 case OLIST:
673 walkparam(n->left, pass);
674 n = n->right;
675 goto loop;
676
677 case OPROTO:
678 for(n1 = n; n1 != Z; n1=n1->left)
679 if(n1->op == ONAME) {
680 if(pass == 0) {
681 s = n1->sym;
682 push1(s);
683 s->offset = -1;
684 break;
685 }
686 dodecl(pdecl, CPARAM, n->type, n->left);
687 break;
688 }
689 if(n1)
690 break;
691 if(pass == 0) {
692 /*
693 * extension:
694 * allow no name in argument declaration
695 diag(Z, "no name in argument declaration");
696 */
697 break;
698 }
699 dodecl(NODECL, CPARAM, n->type, n->left);
700 pdecl(CPARAM, lastdcl, S);
701 break;
702
703 case ODOTDOT:
704 break;
705
706 case ONAME:
707 s = n->sym;
708 if(pass == 0) {
709 push1(s);
710 s->offset = -1;
711 break;
712 }
713 if(s->offset != -1) {
714 if(autoffset == 0) {
715 firstarg = s;
716 firstargtype = s->type;
717 }
718 autoffset = align(autoffset, s->type, Aarg1);
719 s->offset = autoffset;
720 autoffset = align(autoffset, s->type, Aarg2);
721 } else
722 dodecl(pdecl, CXXX, types[TINT], n);
723 break;
724 }
725 }
726
727 void
markdcl(void)728 markdcl(void)
729 {
730 Decl *d;
731
732 blockno++;
733 d = push();
734 d->val = DMARK;
735 d->offset = autoffset;
736 d->block = autobn;
737 autobn = blockno;
738 }
739
740 Node*
revertdcl(void)741 revertdcl(void)
742 {
743 Decl *d;
744 Sym *s;
745 Node *n, *n1;
746
747 n = Z;
748 for(;;) {
749 d = dclstack;
750 if(d == D) {
751 diag(Z, "pop off dcl stack");
752 break;
753 }
754 dclstack = d->link;
755 s = d->sym;
756 switch(d->val) {
757 case DMARK:
758 autoffset = d->offset;
759 autobn = d->block;
760 return n;
761
762 case DAUTO:
763 if(debug['d'])
764 print("revert1 \"%s\"\n", s->name);
765 if(s->aused == 0) {
766 nearln = s->varlineno;
767 if(s->class == CAUTO)
768 warn(Z, "auto declared and not used: %s", s->name);
769 if(s->class == CPARAM)
770 warn(Z, "param declared and not used: %s", s->name);
771 }
772 if(s->type && (s->type->garb & GVOLATILE)) {
773 n1 = new(ONAME, Z, Z);
774 n1->sym = s;
775 n1->type = s->type;
776 n1->etype = TVOID;
777 if(n1->type != T)
778 n1->etype = n1->type->etype;
779 n1->xoffset = s->offset;
780 n1->class = s->class;
781
782 n1 = new(OADDR, n1, Z);
783 n1 = new(OUSED, n1, Z);
784 if(n == Z)
785 n = n1;
786 else
787 n = new(OLIST, n1, n);
788 }
789 s->type = d->type;
790 s->class = d->class;
791 s->offset = d->offset;
792 s->block = d->block;
793 s->varlineno = d->varlineno;
794 s->aused = d->aused;
795 break;
796
797 case DSUE:
798 if(debug['d'])
799 print("revert2 \"%s\"\n", s->name);
800 s->suetag = d->type;
801 s->sueblock = d->block;
802 break;
803
804 case DLABEL:
805 if(debug['d'])
806 print("revert3 \"%s\"\n", s->name);
807 if(s->label && s->label->addable == 0)
808 warn(s->label, "label declared and not used \"%s\"", s->name);
809 s->label = Z;
810 break;
811 }
812 }
813 return n;
814 }
815
816 Type*
fnproto(Node * n)817 fnproto(Node *n)
818 {
819 int r;
820
821 r = anyproto(n->right);
822 if(r == 0 || (r & OLDPROTO)) {
823 if(r & ANSIPROTO)
824 diag(n, "mixed ansi/old function declaration: %F", n->left);
825 return T;
826 }
827 return fnproto1(n->right);
828 }
829
830 int
anyproto(Node * n)831 anyproto(Node *n)
832 {
833 int r;
834
835 r = 0;
836
837 loop:
838 if(n == Z)
839 return r;
840 switch(n->op) {
841 case OLIST:
842 r |= anyproto(n->left);
843 n = n->right;
844 goto loop;
845
846 case ODOTDOT:
847 case OPROTO:
848 return r | ANSIPROTO;
849 }
850 return r | OLDPROTO;
851 }
852
853 Type*
fnproto1(Node * n)854 fnproto1(Node *n)
855 {
856 Type *t;
857
858 if(n == Z)
859 return T;
860 switch(n->op) {
861 case OLIST:
862 t = fnproto1(n->left);
863 if(t != T)
864 t->down = fnproto1(n->right);
865 return t;
866
867 case OPROTO:
868 lastdcl = T;
869 dodecl(NODECL, CXXX, n->type, n->left);
870 t = typ(TXXX, T);
871 if(lastdcl != T)
872 *t = *paramconv(lastdcl, 1);
873 return t;
874
875 case ONAME:
876 diag(n, "incomplete argument prototype");
877 return typ(TINT, T);
878
879 case ODOTDOT:
880 return typ(TDOT, T);
881 }
882 diag(n, "unknown op in fnproto");
883 return T;
884 }
885
886 void
dbgdecl(Sym * s)887 dbgdecl(Sym *s)
888 {
889 print("decl \"%s\": C=%s [B=%d:O=%ld] T=%T\n",
890 s->name, cnames[s->class], s->block, s->offset, s->type);
891 }
892
893 Decl*
push(void)894 push(void)
895 {
896 Decl *d;
897
898 d = alloc(sizeof(*d));
899 d->link = dclstack;
900 dclstack = d;
901 return d;
902 }
903
904 Decl*
push1(Sym * s)905 push1(Sym *s)
906 {
907 Decl *d;
908
909 d = push();
910 d->sym = s;
911 d->val = DAUTO;
912 d->type = s->type;
913 d->class = s->class;
914 d->offset = s->offset;
915 d->block = s->block;
916 d->varlineno = s->varlineno;
917 d->aused = s->aused;
918 return d;
919 }
920
921 int
sametype(Type * t1,Type * t2)922 sametype(Type *t1, Type *t2)
923 {
924
925 if(t1 == t2)
926 return 1;
927 return rsametype(t1, t2, 5, 1);
928 }
929
930 int
rsametype(Type * t1,Type * t2,int n,int f)931 rsametype(Type *t1, Type *t2, int n, int f)
932 {
933 int et;
934
935 n--;
936 for(;;) {
937 if(t1 == t2)
938 return 1;
939 if(t1 == T || t2 == T)
940 return 0;
941 if(n <= 0)
942 return 1;
943 et = t1->etype;
944 if(et != t2->etype)
945 return 0;
946 if(et == TFUNC) {
947 if(!rsametype(t1->link, t2->link, n, 0))
948 return 0;
949 t1 = t1->down;
950 t2 = t2->down;
951 while(t1 != T && t2 != T) {
952 if(t1->etype == TOLD) {
953 t1 = t1->down;
954 continue;
955 }
956 if(t2->etype == TOLD) {
957 t2 = t2->down;
958 continue;
959 }
960 while(t1 != T || t2 != T) {
961 if(!rsametype(t1, t2, n, 0))
962 return 0;
963 t1 = t1->down;
964 t2 = t2->down;
965 }
966 break;
967 }
968 return 1;
969 }
970 if(et == TARRAY)
971 if(t1->width != t2->width && t1->width != 0 && t2->width != 0)
972 return 0;
973 if(typesu[et]) {
974 if(t1->link == T)
975 snap(t1);
976 if(t2->link == T)
977 snap(t2);
978 if(t1 != t2 && t1->link == T && t2->link == T){
979 /* structs with missing or different tag names aren't considered equal */
980 if(t1->tag == nil || t2->tag == nil ||
981 strcmp(t1->tag->name, t2->tag->name) != 0)
982 return 0;
983 }
984 t1 = t1->link;
985 t2 = t2->link;
986 for(;;) {
987 if(t1 == t2)
988 return 1;
989 if(!rsametype(t1, t2, n, 0))
990 return 0;
991 t1 = t1->down;
992 t2 = t2->down;
993 }
994 }
995 t1 = t1->link;
996 t2 = t2->link;
997 if((f || !debug['V']) && et == TIND) {
998 if(t1 != T && t1->etype == TVOID)
999 return 1;
1000 if(t2 != T && t2->etype == TVOID)
1001 return 1;
1002 }
1003 }
1004 }
1005
1006 typedef struct Typetab Typetab;
1007
1008 struct Typetab{
1009 int n;
1010 Type **a;
1011 };
1012
1013 static int
sigind(Type * t,Typetab * tt)1014 sigind(Type *t, Typetab *tt)
1015 {
1016 int n;
1017 Type **a, **na, **p, **e;
1018
1019 n = tt->n;
1020 a = tt->a;
1021 e = a+n;
1022 /* linear search seems ok */
1023 for(p = a ; p < e; p++)
1024 if(sametype(*p, t))
1025 return p-a;
1026 if((n&15) == 0){
1027 na = malloc((n+16)*sizeof(Type*));
1028 memmove(na, a, n*sizeof(Type*));
1029 free(a);
1030 a = tt->a = na;
1031 }
1032 a[tt->n++] = t;
1033 return -1;
1034 }
1035
1036 static ulong
signat(Type * t,Typetab * tt)1037 signat(Type *t, Typetab *tt)
1038 {
1039 int i;
1040 Type *t1;
1041 long s;
1042
1043 s = 0;
1044 for(; t; t=t->link) {
1045 s = s*thash1 + thash[t->etype];
1046 if(t->garb&GINCOMPLETE)
1047 return s;
1048 switch(t->etype) {
1049 default:
1050 return s;
1051 case TARRAY:
1052 s = s*thash2 + 0; /* was t->width */
1053 break;
1054 case TFUNC:
1055 for(t1=t->down; t1; t1=t1->down)
1056 s = s*thash3 + signat(t1, tt);
1057 break;
1058 case TSTRUCT:
1059 case TUNION:
1060 if((i = sigind(t, tt)) >= 0){
1061 s = s*thash2 + i;
1062 return s;
1063 }
1064 for(t1=t->link; t1; t1=t1->down)
1065 s = s*thash3 + signat(t1, tt);
1066 return s;
1067 case TIND:
1068 break;
1069 }
1070 }
1071 return s;
1072 }
1073
1074 ulong
signature(Type * t)1075 signature(Type *t)
1076 {
1077 ulong s;
1078 Typetab tt;
1079
1080 tt.n = 0;
1081 tt.a = nil;
1082 s = signat(t, &tt);
1083 free(tt.a);
1084 return s;
1085 }
1086
1087 ulong
sign(Sym * s)1088 sign(Sym *s)
1089 {
1090 ulong v;
1091 Type *t;
1092
1093 if(s->sig == SIGINTERN)
1094 return SIGNINTERN;
1095 if((t = s->type) == T)
1096 return 0;
1097 v = signature(t);
1098 if(v == 0)
1099 v = SIGNINTERN;
1100 return v;
1101 }
1102
1103 void
snap(Type * t)1104 snap(Type *t)
1105 {
1106 if(typesu[t->etype])
1107 if(t->link == T && t->tag && t->tag->suetag) {
1108 t->link = t->tag->suetag->link;
1109 t->width = t->tag->suetag->width;
1110 }
1111 }
1112
1113 Type*
dotag(Sym * s,int et,int bn)1114 dotag(Sym *s, int et, int bn)
1115 {
1116 Decl *d;
1117
1118 if(bn != 0 && bn != s->sueblock) {
1119 d = push();
1120 d->sym = s;
1121 d->val = DSUE;
1122 d->type = s->suetag;
1123 d->block = s->sueblock;
1124 s->suetag = T;
1125 }
1126 if(s->suetag == T) {
1127 s->suetag = typ(et, T);
1128 s->sueblock = autobn;
1129 }
1130 if(s->suetag->etype != et)
1131 diag(Z, "tag used for more than one type: %s",
1132 s->name);
1133 if(s->suetag->tag == S)
1134 s->suetag->tag = s;
1135 return s->suetag;
1136 }
1137
1138 Node*
dcllabel(Sym * s,int f)1139 dcllabel(Sym *s, int f)
1140 {
1141 Decl *d, d1;
1142 Node *n;
1143
1144 n = s->label;
1145 if(n != Z) {
1146 if(f) {
1147 if(n->complex)
1148 diag(Z, "label reused: %s", s->name);
1149 n->complex = 1; // declared
1150 } else
1151 n->addable = 1; // used
1152 return n;
1153 }
1154
1155 d = push();
1156 d->sym = s;
1157 d->val = DLABEL;
1158 dclstack = d->link;
1159
1160 d1 = *firstdcl;
1161 *firstdcl = *d;
1162 *d = d1;
1163
1164 firstdcl->link = d;
1165 firstdcl = d;
1166
1167 n = new(OXXX, Z, Z);
1168 n->sym = s;
1169 n->complex = f;
1170 n->addable = !f;
1171 s->label = n;
1172
1173 if(debug['d'])
1174 dbgdecl(s);
1175 return n;
1176 }
1177
1178 Type*
paramconv(Type * t,int f)1179 paramconv(Type *t, int f)
1180 {
1181
1182 switch(t->etype) {
1183 case TARRAY:
1184 t = typ(TIND, t->link);
1185 t->width = types[TIND]->width;
1186 break;
1187
1188 case TFUNC:
1189 t = typ(TIND, t);
1190 t->width = types[TIND]->width;
1191 break;
1192
1193 case TFLOAT:
1194 if(!f)
1195 t = types[TDOUBLE];
1196 break;
1197
1198 case TCHAR:
1199 case TSHORT:
1200 if(!f)
1201 t = types[TINT];
1202 break;
1203
1204 case TUCHAR:
1205 case TUSHORT:
1206 if(!f)
1207 t = types[TUINT];
1208 break;
1209 }
1210 return t;
1211 }
1212
1213 void
adecl(int c,Type * t,Sym * s)1214 adecl(int c, Type *t, Sym *s)
1215 {
1216
1217 if(c == CSTATIC)
1218 c = CLOCAL;
1219 if(t->etype == TFUNC) {
1220 if(c == CXXX)
1221 c = CEXTERN;
1222 if(c == CLOCAL)
1223 c = CSTATIC;
1224 if(c == CAUTO || c == CEXREG)
1225 diag(Z, "function cannot be %s %s", cnames[c], s->name);
1226 }
1227 if(c == CXXX)
1228 c = CAUTO;
1229 if(s) {
1230 if(s->class == CSTATIC)
1231 if(c == CEXTERN || c == CGLOBL) {
1232 warn(Z, "just say static: %s", s->name);
1233 c = CSTATIC;
1234 }
1235 if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
1236 if(s->block == autobn)
1237 diag(Z, "auto redeclaration of: %s", s->name);
1238 if(c != CPARAM)
1239 push1(s);
1240 s->block = autobn;
1241 s->offset = 0;
1242 s->type = t;
1243 s->class = c;
1244 s->aused = 0;
1245 }
1246 switch(c) {
1247 case CAUTO:
1248 autoffset = align(autoffset, t, Aaut3);
1249 stkoff = maxround(stkoff, autoffset);
1250 s->offset = -autoffset;
1251 break;
1252
1253 case CPARAM:
1254 if(autoffset == 0) {
1255 firstarg = s;
1256 firstargtype = t;
1257 }
1258 autoffset = align(autoffset, t, Aarg1);
1259 if(s)
1260 s->offset = autoffset;
1261 autoffset = align(autoffset, t, Aarg2);
1262 break;
1263 }
1264 }
1265
1266 void
pdecl(int c,Type * t,Sym * s)1267 pdecl(int c, Type *t, Sym *s)
1268 {
1269 if(s && s->offset != -1) {
1270 diag(Z, "not a parameter: %s", s->name);
1271 return;
1272 }
1273 t = paramconv(t, c==CPARAM);
1274 if(c == CXXX)
1275 c = CPARAM;
1276 if(c != CPARAM) {
1277 diag(Z, "parameter cannot have class: %s", s->name);
1278 c = CPARAM;
1279 }
1280 if(typesu[t->etype] && t->width <= 0)
1281 diag(Z, "incomplete structure: %s", t->tag->name);
1282 adecl(c, t, s);
1283 }
1284
1285 void
xdecl(int c,Type * t,Sym * s)1286 xdecl(int c, Type *t, Sym *s)
1287 {
1288 long o;
1289
1290 o = 0;
1291 switch(c) {
1292 case CEXREG:
1293 o = exreg(t);
1294 if(o == 0)
1295 c = CEXTERN;
1296 if(s->class == CGLOBL)
1297 c = CGLOBL;
1298 break;
1299
1300 case CEXTERN:
1301 if(s->class == CGLOBL)
1302 c = CGLOBL;
1303 break;
1304
1305 case CXXX:
1306 c = CGLOBL;
1307 if(s->class == CEXTERN)
1308 s->class = CGLOBL;
1309 break;
1310
1311 case CAUTO:
1312 diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
1313 c = CEXTERN;
1314 break;
1315
1316 case CTYPESTR:
1317 if(!typesuv[t->etype]) {
1318 diag(Z, "typestr must be struct/union: %s", s->name);
1319 break;
1320 }
1321 dclfunct(t, s);
1322 break;
1323 }
1324
1325 if(s->class == CSTATIC)
1326 if(c == CEXTERN || c == CGLOBL) {
1327 warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
1328 c = CSTATIC;
1329 }
1330 if(s->type != T)
1331 if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
1332 diag(Z, "external redeclaration of: %s", s->name);
1333 Bprint(&diagbuf, " %s %T %L\n", cnames[c], t, nearln);
1334 Bprint(&diagbuf, " %s %T %L\n", cnames[s->class], s->type, s->varlineno);
1335 }
1336 tmerge(t, s);
1337 s->type = t;
1338 s->class = c;
1339 s->block = 0;
1340 s->offset = o;
1341 }
1342
1343 void
tmerge(Type * t1,Sym * s)1344 tmerge(Type *t1, Sym *s)
1345 {
1346 Type *ta, *tb, *t2;
1347
1348 t2 = s->type;
1349 /*print("merge %T; %T\n", t1, t2);/**/
1350 for(;;) {
1351 if(t1 == T || t2 == T || t1 == t2)
1352 break;
1353 if(t1->etype != t2->etype)
1354 break;
1355 switch(t1->etype) {
1356 case TFUNC:
1357 ta = t1->down;
1358 tb = t2->down;
1359 if(ta == T) {
1360 t1->down = tb;
1361 break;
1362 }
1363 if(tb == T)
1364 break;
1365 while(ta != T && tb != T) {
1366 if(ta == tb)
1367 break;
1368 /* ignore old-style flag */
1369 if(ta->etype == TOLD) {
1370 ta = ta->down;
1371 continue;
1372 }
1373 if(tb->etype == TOLD) {
1374 tb = tb->down;
1375 continue;
1376 }
1377 /* checking terminated by ... */
1378 if(ta->etype == TDOT && tb->etype == TDOT) {
1379 ta = T;
1380 tb = T;
1381 break;
1382 }
1383 if(!sametype(ta, tb))
1384 break;
1385 ta = ta->down;
1386 tb = tb->down;
1387 }
1388 if(ta != tb)
1389 diag(Z, "function inconsistently declared: %s", s->name);
1390
1391 /* take new-style over old-style */
1392 ta = t1->down;
1393 tb = t2->down;
1394 if(ta != T && ta->etype == TOLD)
1395 if(tb != T && tb->etype != TOLD)
1396 t1->down = tb;
1397 break;
1398
1399 case TARRAY:
1400 /* should we check array size change? */
1401 if(t2->width > t1->width)
1402 t1->width = t2->width;
1403 break;
1404
1405 case TUNION:
1406 case TSTRUCT:
1407 return;
1408 }
1409 t1 = t1->link;
1410 t2 = t2->link;
1411 }
1412 }
1413
1414 void
edecl(int c,Type * t,Sym * s)1415 edecl(int c, Type *t, Sym *s)
1416 {
1417 Type *t1;
1418
1419 if(s == S) {
1420 if(!typesu[t->etype])
1421 diag(Z, "unnamed structure element must be struct/union");
1422 if(c != CXXX)
1423 diag(Z, "unnamed structure element cannot have class");
1424 } else
1425 if(c != CXXX)
1426 diag(Z, "structure element cannot have class: %s", s->name);
1427 t1 = t;
1428 t = copytyp(t1);
1429 t->sym = s;
1430 t->down = T;
1431 if(lastfield) {
1432 t->shift = lastbit - lastfield;
1433 t->nbits = lastfield;
1434 if(firstbit)
1435 t->shift = -t->shift;
1436 if(typeu[t->etype])
1437 t->etype = tufield->etype;
1438 else
1439 t->etype = tfield->etype;
1440 }
1441 if(strf == T)
1442 strf = t;
1443 else
1444 strl->down = t;
1445 strl = t;
1446 }
1447
1448 /*
1449 * this routine is very suspect.
1450 * ansi requires the enum type to
1451 * be represented as an 'int'
1452 * this means that 0x81234567
1453 * would be illegal. this routine
1454 * makes signed and unsigned go
1455 * to unsigned.
1456 */
1457 Type*
maxtype(Type * t1,Type * t2)1458 maxtype(Type *t1, Type *t2)
1459 {
1460
1461 if(t1 == T)
1462 return t2;
1463 if(t2 == T)
1464 return t1;
1465 if(t1->etype > t2->etype)
1466 return t1;
1467 return t2;
1468 }
1469
1470 void
doenum(Sym * s,Node * n)1471 doenum(Sym *s, Node *n)
1472 {
1473
1474 if(n) {
1475 complex(n);
1476 if(n->op != OCONST) {
1477 diag(n, "enum not a constant: %s", s->name);
1478 return;
1479 }
1480 en.cenum = n->type;
1481 en.tenum = maxtype(en.cenum, en.tenum);
1482
1483 if(!typefd[en.cenum->etype])
1484 en.lastenum = n->vconst;
1485 else
1486 en.floatenum = n->fconst;
1487 }
1488 if(dclstack)
1489 push1(s);
1490 xdecl(CXXX, types[TENUM], s);
1491
1492 if(en.cenum == T) {
1493 en.tenum = types[TINT];
1494 en.cenum = types[TINT];
1495 en.lastenum = 0;
1496 }
1497 s->tenum = en.cenum;
1498
1499 if(!typefd[s->tenum->etype]) {
1500 s->vconst = convvtox(en.lastenum, s->tenum->etype);
1501 en.lastenum++;
1502 } else {
1503 s->fconst = en.floatenum;
1504 en.floatenum++;
1505 }
1506
1507 if(debug['d'])
1508 dbgdecl(s);
1509 acidvar(s);
1510 }
1511
1512 void
symadjust(Sym * s,Node * n,long del)1513 symadjust(Sym *s, Node *n, long del)
1514 {
1515
1516 switch(n->op) {
1517 default:
1518 if(n->left)
1519 symadjust(s, n->left, del);
1520 if(n->right)
1521 symadjust(s, n->right, del);
1522 return;
1523
1524 case ONAME:
1525 if(n->sym == s)
1526 n->xoffset -= del;
1527 return;
1528
1529 case OCONST:
1530 case OSTRING:
1531 case OLSTRING:
1532 case OINDREG:
1533 case OREGISTER:
1534 return;
1535 }
1536 }
1537
1538 Node*
contig(Sym * s,Node * n,long v)1539 contig(Sym *s, Node *n, long v)
1540 {
1541 Node *p, *r, *q, *m;
1542 long w;
1543 Type *zt;
1544
1545 if(debug['i']) {
1546 print("contig v = %ld; s = %s\n", v, s->name);
1547 prtree(n, "doinit value");
1548 }
1549
1550 if(n == Z)
1551 goto no;
1552 w = s->type->width;
1553
1554 /*
1555 * nightmare: an automatic array whose size
1556 * increases when it is initialized
1557 */
1558 if(v != w) {
1559 if(v != 0)
1560 diag(n, "automatic adjustable array: %s", s->name);
1561 v = s->offset;
1562 autoffset = align(autoffset, s->type, Aaut3);
1563 s->offset = -autoffset;
1564 stkoff = maxround(stkoff, autoffset);
1565 symadjust(s, n, v - s->offset);
1566 }
1567 if(w <= ewidth[TIND])
1568 goto no;
1569 if(n->op == OAS)
1570 diag(Z, "oops in contig");
1571 /*ZZZ this appears incorrect
1572 need to check if the list completely covers the data.
1573 if not, bail
1574 */
1575 if(n->op == OLIST)
1576 goto no;
1577 if(n->op == OASI)
1578 if(n->left->type)
1579 if(n->left->type->width == w)
1580 goto no;
1581 while(w & (ewidth[TIND]-1))
1582 w++;
1583 /*
1584 * insert the following code, where long becomes vlong if pointers are fat
1585 *
1586 *(long**)&X = (long*)((char*)X + sizeof(X));
1587 do {
1588 *(long**)&X -= 1;
1589 **(long**)&X = 0;
1590 } while(*(long**)&X);
1591 */
1592
1593 for(q=n; q->op != ONAME; q=q->left)
1594 ;
1595
1596 zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
1597
1598 p = new(ONAME, Z, Z);
1599 *p = *q;
1600 p->type = typ(TIND, zt);
1601 p->xoffset = s->offset;
1602
1603 r = new(ONAME, Z, Z);
1604 *r = *p;
1605 r = new(OPOSTDEC, r, Z);
1606
1607 q = new(ONAME, Z, Z);
1608 *q = *p;
1609 q = new(OIND, q, Z);
1610
1611 m = new(OCONST, Z, Z);
1612 m->vconst = 0;
1613 m->type = zt;
1614
1615 q = new(OAS, q, m);
1616
1617 r = new(OLIST, r, q);
1618
1619 q = new(ONAME, Z, Z);
1620 *q = *p;
1621 r = new(ODWHILE, q, r);
1622
1623 q = new(ONAME, Z, Z);
1624 *q = *p;
1625 q->type = q->type->link;
1626 q->xoffset += w;
1627 q = new(OADDR, q, 0);
1628
1629 q = new(OASI, p, q);
1630 r = new(OLIST, q, r);
1631
1632 n = new(OLIST, r, n);
1633
1634 no:
1635 return n;
1636 }
1637