xref: /inferno-os/utils/cc/dcl.c (revision 50b0dbb170df61467e42c7ea4deb0b5692d15f4c)
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 			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*
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
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
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*
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
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
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
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*
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*
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
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*
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, 0);
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
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*
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*
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
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
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
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
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
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
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
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*
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*
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*
1179 paramconv(Type *t, int f, int defining)
1180 {
1181 
1182 	switch(t->etype) {
1183 	case TUNION:
1184 	case TSTRUCT:
1185 		if(t->width <= 0 && defining)
1186 			diag(Z, "incomplete structure: %s", t->tag->name);
1187 		break;
1188 
1189 	case TARRAY:
1190 		t = typ(TIND, t->link);
1191 		t->width = types[TIND]->width;
1192 		break;
1193 
1194 	case TFUNC:
1195 		t = typ(TIND, t);
1196 		t->width = types[TIND]->width;
1197 		break;
1198 
1199 	case TFLOAT:
1200 		if(!f)
1201 			t = types[TDOUBLE];
1202 		break;
1203 
1204 	case TCHAR:
1205 	case TSHORT:
1206 		if(!f)
1207 			t = types[TINT];
1208 		break;
1209 
1210 	case TUCHAR:
1211 	case TUSHORT:
1212 		if(!f)
1213 			t = types[TUINT];
1214 		break;
1215 	}
1216 	return t;
1217 }
1218 
1219 void
1220 adecl(int c, Type *t, Sym *s)
1221 {
1222 
1223 	if(c == CSTATIC)
1224 		c = CLOCAL;
1225 	if(t->etype == TFUNC) {
1226 		if(c == CXXX)
1227 			c = CEXTERN;
1228 		if(c == CLOCAL)
1229 			c = CSTATIC;
1230 		if(c == CAUTO || c == CEXREG)
1231 			diag(Z, "function cannot be %s %s", cnames[c], s->name);
1232 	}
1233 	if(c == CXXX)
1234 		c = CAUTO;
1235 	if(s) {
1236 		if(s->class == CSTATIC)
1237 			if(c == CEXTERN || c == CGLOBL) {
1238 				warn(Z, "just say static: %s", s->name);
1239 				c = CSTATIC;
1240 			}
1241 		if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
1242 		if(s->block == autobn)
1243 			diag(Z, "auto redeclaration of: %s", s->name);
1244 		if(c != CPARAM)
1245 			push1(s);
1246 		s->block = autobn;
1247 		s->offset = 0;
1248 		s->type = t;
1249 		s->class = c;
1250 		s->aused = 0;
1251 	}
1252 	switch(c) {
1253 	case CAUTO:
1254 		autoffset = align(autoffset, t, Aaut3);
1255 		stkoff = maxround(stkoff, autoffset);
1256 		s->offset = -autoffset;
1257 		break;
1258 
1259 	case CPARAM:
1260 		if(autoffset == 0) {
1261 			firstarg = s;
1262 			firstargtype = t;
1263 		}
1264 		autoffset = align(autoffset, t, Aarg1);
1265 		if(s)
1266 			s->offset = autoffset;
1267 		autoffset = align(autoffset, t, Aarg2);
1268 		break;
1269 	}
1270 }
1271 
1272 void
1273 pdecl(int c, Type *t, Sym *s)
1274 {
1275 	if(s && s->offset != -1) {
1276 		diag(Z, "not a parameter: %s", s->name);
1277 		return;
1278 	}
1279 	t = paramconv(t, c==CPARAM, 1);
1280 	if(c == CXXX)
1281 		c = CPARAM;
1282 	if(c != CPARAM) {
1283 		diag(Z, "parameter cannot have class: %s", s->name);
1284 		c = CPARAM;
1285 	}
1286 	adecl(c, t, s);
1287 }
1288 
1289 void
1290 xdecl(int c, Type *t, Sym *s)
1291 {
1292 	long o;
1293 
1294 	o = 0;
1295 	switch(c) {
1296 	case CEXREG:
1297 		o = exreg(t);
1298 		if(o == 0)
1299 			c = CEXTERN;
1300 		if(s->class == CGLOBL)
1301 			c = CGLOBL;
1302 		break;
1303 
1304 	case CEXTERN:
1305 		if(s->class == CGLOBL)
1306 			c = CGLOBL;
1307 		break;
1308 
1309 	case CXXX:
1310 		c = CGLOBL;
1311 		if(s->class == CEXTERN)
1312 			s->class = CGLOBL;
1313 		break;
1314 
1315 	case CAUTO:
1316 		diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
1317 		c = CEXTERN;
1318 		break;
1319 
1320 	case CTYPESTR:
1321 		if(!typesuv[t->etype]) {
1322 			diag(Z, "typestr must be struct/union: %s", s->name);
1323 			break;
1324 		}
1325 		dclfunct(t, s);
1326 		break;
1327 	}
1328 
1329 	if(s->class == CSTATIC)
1330 		if(c == CEXTERN || c == CGLOBL) {
1331 			warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
1332 			c = CSTATIC;
1333 		}
1334 	if(s->type != T)
1335 		if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
1336 			diag(Z, "external redeclaration of: %s", s->name);
1337 			Bprint(&diagbuf, "	%s %T %L\n", cnames[c], t, nearln);
1338 			Bprint(&diagbuf, "	%s %T %L\n", cnames[s->class], s->type, s->varlineno);
1339 		}
1340 	tmerge(t, s);
1341 	s->type = t;
1342 	s->class = c;
1343 	s->block = 0;
1344 	s->offset = o;
1345 }
1346 
1347 void
1348 tmerge(Type *t1, Sym *s)
1349 {
1350 	Type *ta, *tb, *t2;
1351 
1352 	t2 = s->type;
1353 /*print("merge	%T; %T\n", t1, t2);/**/
1354 	for(;;) {
1355 		if(t1 == T || t2 == T || t1 == t2)
1356 			break;
1357 		if(t1->etype != t2->etype)
1358 			break;
1359 		switch(t1->etype) {
1360 		case TFUNC:
1361 			ta = t1->down;
1362 			tb = t2->down;
1363 			if(ta == T) {
1364 				t1->down = tb;
1365 				break;
1366 			}
1367 			if(tb == T)
1368 				break;
1369 			while(ta != T && tb != T) {
1370 				if(ta == tb)
1371 					break;
1372 				/* ignore old-style flag */
1373 				if(ta->etype == TOLD) {
1374 					ta = ta->down;
1375 					continue;
1376 				}
1377 				if(tb->etype == TOLD) {
1378 					tb = tb->down;
1379 					continue;
1380 				}
1381 				/* checking terminated by ... */
1382 				if(ta->etype == TDOT && tb->etype == TDOT) {
1383 					ta = T;
1384 					tb = T;
1385 					break;
1386 				}
1387 				if(!sametype(ta, tb))
1388 					break;
1389 				ta = ta->down;
1390 				tb = tb->down;
1391 			}
1392 			if(ta != tb)
1393 				diag(Z, "function inconsistently declared: %s", s->name);
1394 
1395 			/* take new-style over old-style */
1396 			ta = t1->down;
1397 			tb = t2->down;
1398 			if(ta != T && ta->etype == TOLD)
1399 				if(tb != T && tb->etype != TOLD)
1400 					t1->down = tb;
1401 			break;
1402 
1403 		case TARRAY:
1404 			/* should we check array size change? */
1405 			if(t2->width > t1->width)
1406 				t1->width = t2->width;
1407 			break;
1408 
1409 		case TUNION:
1410 		case TSTRUCT:
1411 			return;
1412 		}
1413 		t1 = t1->link;
1414 		t2 = t2->link;
1415 	}
1416 }
1417 
1418 void
1419 edecl(int c, Type *t, Sym *s)
1420 {
1421 	Type *t1;
1422 
1423 	if(s == S) {
1424 		if(!typesu[t->etype])
1425 			diag(Z, "unnamed structure element must be struct/union");
1426 		if(c != CXXX)
1427 			diag(Z, "unnamed structure element cannot have class");
1428 	} else
1429 		if(c != CXXX)
1430 			diag(Z, "structure element cannot have class: %s", s->name);
1431 	t1 = t;
1432 	t = copytyp(t1);
1433 	t->sym = s;
1434 	t->down = T;
1435 	if(lastfield) {
1436 		t->shift = lastbit - lastfield;
1437 		t->nbits = lastfield;
1438 		if(firstbit)
1439 			t->shift = -t->shift;
1440 		if(typeu[t->etype])
1441 			t->etype = tufield->etype;
1442 		else
1443 			t->etype = tfield->etype;
1444 	}
1445 	if(strf == T)
1446 		strf = t;
1447 	else
1448 		strl->down = t;
1449 	strl = t;
1450 }
1451 
1452 /*
1453  * this routine is very suspect.
1454  * ansi requires the enum type to
1455  * be represented as an 'int'
1456  * this means that 0x81234567
1457  * would be illegal. this routine
1458  * makes signed and unsigned go
1459  * to unsigned.
1460  */
1461 Type*
1462 maxtype(Type *t1, Type *t2)
1463 {
1464 
1465 	if(t1 == T)
1466 		return t2;
1467 	if(t2 == T)
1468 		return t1;
1469 	if(t1->etype > t2->etype)
1470 		return t1;
1471 	return t2;
1472 }
1473 
1474 void
1475 doenum(Sym *s, Node *n)
1476 {
1477 
1478 	if(n) {
1479 		complex(n);
1480 		if(n->op != OCONST) {
1481 			diag(n, "enum not a constant: %s", s->name);
1482 			return;
1483 		}
1484 		en.cenum = n->type;
1485 		en.tenum = maxtype(en.cenum, en.tenum);
1486 
1487 		if(!typefd[en.cenum->etype])
1488 			en.lastenum = n->vconst;
1489 		else
1490 			en.floatenum = n->fconst;
1491 	}
1492 	if(dclstack)
1493 		push1(s);
1494 	xdecl(CXXX, types[TENUM], s);
1495 
1496 	if(en.cenum == T) {
1497 		en.tenum = types[TINT];
1498 		en.cenum = types[TINT];
1499 		en.lastenum = 0;
1500 	}
1501 	s->tenum = en.cenum;
1502 
1503 	if(!typefd[s->tenum->etype]) {
1504 		s->vconst = convvtox(en.lastenum, s->tenum->etype);
1505 		en.lastenum++;
1506 	} else {
1507 		s->fconst = en.floatenum;
1508 		en.floatenum++;
1509 	}
1510 
1511 	if(debug['d'])
1512 		dbgdecl(s);
1513 	acidvar(s);
1514 }
1515 
1516 void
1517 symadjust(Sym *s, Node *n, long del)
1518 {
1519 
1520 	switch(n->op) {
1521 	default:
1522 		if(n->left)
1523 			symadjust(s, n->left, del);
1524 		if(n->right)
1525 			symadjust(s, n->right, del);
1526 		return;
1527 
1528 	case ONAME:
1529 		if(n->sym == s)
1530 			n->xoffset -= del;
1531 		return;
1532 
1533 	case OCONST:
1534 	case OSTRING:
1535 	case OLSTRING:
1536 	case OINDREG:
1537 	case OREGISTER:
1538 		return;
1539 	}
1540 }
1541 
1542 Node*
1543 contig(Sym *s, Node *n, long v)
1544 {
1545 	Node *p, *r, *q, *m;
1546 	long w;
1547 	Type *zt;
1548 
1549 	if(debug['i']) {
1550 		print("contig v = %ld; s = %s\n", v, s->name);
1551 		prtree(n, "doinit value");
1552 	}
1553 
1554 	if(n == Z)
1555 		goto no;
1556 	w = s->type->width;
1557 
1558 	/*
1559 	 * nightmare: an automatic array whose size
1560 	 * increases when it is initialized
1561 	 */
1562 	if(v != w) {
1563 		if(v != 0)
1564 			diag(n, "automatic adjustable array: %s", s->name);
1565 		v = s->offset;
1566 		autoffset = align(autoffset, s->type, Aaut3);
1567 		s->offset = -autoffset;
1568 		stkoff = maxround(stkoff, autoffset);
1569 		symadjust(s, n, v - s->offset);
1570 	}
1571 	if(w <= ewidth[TIND])
1572 		goto no;
1573 	if(n->op == OAS)
1574 		diag(Z, "oops in contig");
1575 /*ZZZ this appears incorrect
1576 need to check if the list completely covers the data.
1577 if not, bail
1578  */
1579 	if(n->op == OLIST)
1580 		goto no;
1581 	if(n->op == OASI)
1582 		if(n->left->type)
1583 		if(n->left->type->width == w)
1584 			goto no;
1585 	while(w & (ewidth[TIND]-1))
1586 		w++;
1587 /*
1588  * insert the following code, where long becomes vlong if pointers are fat
1589  *
1590 	*(long**)&X = (long*)((char*)X + sizeof(X));
1591 	do {
1592 		*(long**)&X -= 1;
1593 		**(long**)&X = 0;
1594 	} while(*(long**)&X);
1595  */
1596 
1597 	for(q=n; q->op != ONAME; q=q->left)
1598 		;
1599 
1600 	zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
1601 
1602 	p = new(ONAME, Z, Z);
1603 	*p = *q;
1604 	p->type = typ(TIND, zt);
1605 	p->xoffset = s->offset;
1606 
1607 	r = new(ONAME, Z, Z);
1608 	*r = *p;
1609 	r = new(OPOSTDEC, r, Z);
1610 
1611 	q = new(ONAME, Z, Z);
1612 	*q = *p;
1613 	q = new(OIND, q, Z);
1614 
1615 	m = new(OCONST, Z, Z);
1616 	m->vconst = 0;
1617 	m->type = zt;
1618 
1619 	q = new(OAS, q, m);
1620 
1621 	r = new(OLIST, r, q);
1622 
1623 	q = new(ONAME, Z, Z);
1624 	*q = *p;
1625 	r = new(ODWHILE, q, r);
1626 
1627 	q = new(ONAME, Z, Z);
1628 	*q = *p;
1629 	q->type = q->type->link;
1630 	q->xoffset += w;
1631 	q = new(OADDR, q, 0);
1632 
1633 	q = new(OASI, p, q);
1634 	r = new(OLIST, q, r);
1635 
1636 	n = new(OLIST, r, n);
1637 
1638 no:
1639 	return n;
1640 }
1641