xref: /plan9-contrib/sys/src/cmd/cc/dcl.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 		n = n->left;
41 		goto loop;
42 
43 	case OFUNC:
44 		t = typ(TFUNC, t);
45 		t->down = fnproto(n);
46 		n = n->left;
47 		goto loop;
48 
49 	case OBIT:
50 		n1 = n->right;
51 		complex(n1);
52 		lastfield = -1;
53 		if(n1->op == OCONST)
54 			lastfield = n1->vconst;
55 		if(lastfield < 0) {
56 			diag(n, "field width must be non-negative constant");
57 			lastfield = 1;
58 		}
59 		if(lastfield == 0) {
60 			lastbit = 0;
61 			firstbit = 1;
62 			if(n->left != Z) {
63 				diag(n, "zero width named field");
64 				lastfield = 1;
65 			}
66 		}
67 		if(!typei[t->etype]) {
68 			diag(n, "field type must be int-like");
69 			t = tint;
70 			lastfield = 1;
71 		}
72 		if(lastfield > tfield->width*8) {
73 			diag(n, "field width larger than field unit");
74 			lastfield = 1;
75 		}
76 		lastbit += lastfield;
77 		if(lastbit > tfield->width*8) {
78 			lastbit = lastfield;
79 			firstbit = 1;
80 		}
81 		n = n->left;
82 		goto loop;
83 
84 	case ONAME:
85 		if(f == NODECL)
86 			break;
87 		s = n->sym;
88 		(*f)(c, t, s);
89 		if(s->class == CLOCAL)
90 			s = mkstatic(s);
91 		firstbit = 0;
92 		n->sym = s;
93 		n->type = s->type;
94 		n->xoffset = s->offset;
95 		n->class = s->class;
96 		n->etype = TVOID;
97 		if(n->type != T)
98 			n->etype = n->type->etype;
99 		if(debug['d'])
100 			dbgdecl(s);
101 		acidvar(s);
102 		s->varlineno = lineno;
103 		break;
104 	}
105 	lastdcl = t;
106 	return n;
107 }
108 
109 Sym*
110 mkstatic(Sym *s)
111 {
112 	Sym *s1;
113 
114 	if(s->class != CLOCAL)
115 		return s;
116 	snprint(symb, NSYMB, "%s$%d", s->name, s->block);
117 	s1 = lookup();
118 	if(s1->class != CSTATIC) {
119 		s1->type = s->type;
120 		s1->offset = s->offset;
121 		s1->block = s->block;
122 		s1->class = CSTATIC;
123 	}
124 	return s1;
125 }
126 
127 /*
128  * make a copy of a typedef
129  * the problem is to split out incomplete
130  * arrays so that it is in the variable
131  * rather than the typedef.
132  */
133 Type*
134 tcopy(Type *t)
135 {
136 	Type *tl, *tx;
137 	int et;
138 
139 	if(t == T)
140 		return t;
141 	et = t->etype;
142 	if(typesu[et])
143 		return t;
144 	tl = tcopy(t->link);
145 	if(tl != t->link ||
146 	  (et == TARRAY && t->width == 0)) {
147 		tx = typ(TXXX, 0);
148 		*tx = *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 loop:
221 	if(a == Z)
222 		return a;
223 	if(a->op == OLIST) {
224 		n = a->right;
225 		a = a->left;
226 	}
227 	if(a->op == OUSED) {
228 		a = a->left;
229 		b = new(OCONST, Z, Z);
230 		b->type = a->type->link;
231 		if(a->op == OSTRING) {
232 			b->vconst = convvtox(*a->cstring, TCHAR);
233 			a->cstring++;
234 		}
235 		if(a->op == OLSTRING) {
236 			b->vconst = convvtox(*a->rstring, TUSHORT);
237 			a->rstring++;
238 		}
239 		a->type->width -= b->type->width;
240 		if(a->type->width <= 0)
241 			initlist = n;
242 		return b;
243 	}
244 	initlist = n;
245 	return a;
246 }
247 
248 int
249 isstruct(Node *a, Type *t)
250 {
251 	Node *n;
252 
253 	switch(a->op) {
254 	case ODOTDOT:
255 		n = a->left;
256 		if(n && n->type && sametype(n->type, t))
257 			return 1;
258 	case OSTRING:
259 	case OLSTRING:
260 	case OCONST:
261 	case OINIT:
262 	case OELEM:
263 		return 0;
264 	}
265 
266 	n = new(ODOTDOT, Z, Z);
267 	*n = *a;
268 
269 	/*
270 	 * ODOTDOT is a flag for tcom
271 	 * a second tcom will not be performed
272 	 */
273 	a->op = ODOTDOT;
274 	a->left = n;
275 	a->right = Z;
276 
277 	if(tcom(n))
278 		return 0;
279 
280 	if(sametype(n->type, t))
281 		return 1;
282 	return 0;
283 }
284 
285 Node*
286 init1(Sym *s, Type *t, long o, int exflag)
287 {
288 	Node *a, *l, *r;
289 	Type *t1;
290 	long e, w, so, mw;
291 
292 	a = peekinit();
293 	if(a == Z)
294 		return Z;
295 
296 	if(debug['i']) {
297 		print("t = %T; o = %ld; n = %s\n", t, o, s->name);
298 		prtree(a, "init1 value");
299 	}
300 
301 	if(exflag && a->op == OINIT)
302 		return doinit(s, t, o, nextinit());
303 
304 	switch(t->etype) {
305 	default:
306 		diag(Z, "unknown type in initialization: %T to: %s", t, s->name);
307 		return Z;
308 
309 	case TCHAR:
310 	case TUCHAR:
311 	case TSHORT:
312 	case TUSHORT:
313 	case TLONG:
314 	case TULONG:
315 	case TVLONG:
316 	case TFLOAT:
317 	case TDOUBLE:
318 	case TIND:
319 	single:
320 		if(a->op == OARRAY || a->op == OELEM)
321 			return Z;
322 
323 		a = nextinit();
324 		if(a == Z)
325 			return Z;
326 
327 		if(t->nbits)
328 			diag(Z, "cannot initialize bitfields");
329 		if(s->class == CAUTO) {
330 			l = new(ONAME, Z, Z);
331 			l->sym = s;
332 			l->type = t;
333 			l->etype = TVOID;
334 			if(s->type)
335 				l->etype = s->type->etype;
336 			l->xoffset = s->offset + o;
337 			l->class = s->class;
338 
339 			l = new(OAS, l, a);
340 			return l;
341 		}
342 
343 		complex(a);
344 		if(a->type == T)
345 			return Z;
346 
347 		if(a->op == OCONST) {
348 			if(!sametype(a->type, t)) {
349 				e = a->lineno;
350 				a = new(OCAST, a, Z);
351 				a->lineno = e;
352 				a->type = t;
353 				complex(a);
354 			}
355 			if(a->op != OCONST) {
356 				diag(a, "initializer is not a constant: %s",
357 					s->name);
358 				return Z;
359 			}
360 			if(vconst(a) == 0)
361 				return Z;
362 			goto gext;
363 		}
364 		if(t->etype == TIND) {
365 			while(a->op == OCAST) {
366 				warn(a, "CAST in initialization ignored");
367 				a = a->left;
368 			}
369 			if(!sametype(t, a->type)) {
370 				diag(a, "initialization of incompatible pointers: %s",
371 					s->name);
372 				print("%T and %T\n", t, a->type);
373 			}
374 			if(a->op == OADDR)
375 				a = a->left;
376 			goto gext;
377 		}
378 
379 		while(a->op == OCAST)
380 			a = a->left;
381 		if(a->op == OADDR) {
382 			warn(a, "initialize pointer to an integer", s->name);
383 			a = a->left;
384 			goto gext;
385 		}
386 		diag(a, "initializer is not a constant: %s", s->name);
387 		return Z;
388 
389 	gext:
390 		gextern(s, a, o, t->width);
391 
392 		return Z;
393 
394 	case TARRAY:
395 		w = t->link->width;
396 		if(a->op == OSTRING || a->op == OLSTRING)
397 		if(typei[t->link->etype]) {
398 			/*
399 			 * get rid of null if sizes match exactly
400 			 */
401 			a = nextinit();
402 			mw = t->width/w;
403 			so = a->type->width/a->type->link->width;
404 			if(mw && so > mw) {
405 				if(so != mw+1)
406 					diag(a, "string initialization larger than array");
407 				a->type->width -= a->type->link->width;
408 			}
409 
410 			/*
411 			 * arrange strings to be expanded
412 			 * inside OINIT braces.
413 			 */
414 			a = new(OUSED, a, Z);
415 			return doinit(s, t, o, a);
416 		}
417 
418 		mw = -w;
419 		l = Z;
420 		for(e=0;;) {
421 			/*
422 			 * peek ahead for element initializer
423 			 */
424 			a = peekinit();
425 			if(a == Z)
426 				break;
427 			if(a->op == OELEM && t->link->etype != TSTRUCT)
428 				break;
429 			if(a->op == OARRAY) {
430 				a = nextinit();
431 				r = a->left;
432 				complex(r);
433 				if(r->op != OCONST) {
434 					diag(r, "initializer subscript must be constant");
435 					return Z;
436 				}
437 				e = r->vconst;
438 				if(t->width != 0)
439 					if(e < 0 || e*w >= t->width) {
440 						diag(a, "initilization index out of range: %ld", e);
441 						e = 0;
442 					}
443 				continue;
444 			}
445 
446 			so = e*w;
447 			if(so > mw)
448 				mw = so;
449 			if(t->width != 0)
450 				if(mw >= t->width)
451 					break;
452 			r = init1(s, t->link, o+so, 1);
453 			l = newlist(l, r);
454 			e++;
455 		}
456 		if(t->width == 0)
457 			t->width = mw+w;
458 		return l;
459 
460 	case TUNION:
461 	case TSTRUCT:
462 		/*
463 		 * peek ahead to find type of rhs.
464 		 * if its a structure, then treat
465 		 * this element as a variable
466 		 * rather than an aggregate.
467 		 */
468 		if(isstruct(a, t))
469 			goto single;
470 
471 		if(t->width <= 0) {
472 			diag(Z, "incomplete structure: %s", s->name);
473 			return Z;
474 		}
475 		l = Z;
476 
477 	again:
478 		for(t1 = t->link; t1 != T; t1 = t1->down) {
479 			if(a->op == OARRAY && t1->etype != TARRAY)
480 				break;
481 			if(a->op == OELEM) {
482 				if(t1->sym != a->sym)
483 					continue;
484 				nextinit();
485 			}
486 			r = init1(s, t1, o+t1->offset, 1);
487 			l = newlist(l, r);
488 			a = peekinit();
489 			if(a == Z)
490 				break;
491 			if(a->op == OELEM)
492 				goto again;
493 		}
494 		if(a && a->op == OELEM)
495 			diag(a, "structure element not found %F", a);
496 		return l;
497 	}
498 }
499 
500 Node*
501 newlist(Node *l, Node *r)
502 {
503 	if(r == Z)
504 		return l;
505 	if(l == Z)
506 		return r;
507 	return new(OLIST, l, r);
508 }
509 
510 void
511 suallign(Type *t)
512 {
513 	Type *l;
514 	long o, w;
515 
516 	o = 0;
517 	switch(t->etype) {
518 
519 	case TSTRUCT:
520 		t->offset = 0;
521 		w = 0;
522 		for(l = t->link; l != T; l = l->down) {
523 			if(l->nbits) {
524 				if(l->shift <= 0) {
525 					l->shift = -l->shift;
526 					w += round(w, tfield->width);
527 					o = w;
528 					w += tfield->width;
529 				}
530 				l->offset = o;
531 			} else {
532 				if(l->width <= 0)
533 					if(l->sym)
534 						diag(Z, "incomplete structure element: %s",
535 							l->sym->name);
536 					else
537 						diag(Z, "incomplete structure element");
538 				w += round(w, allign(l));
539 				l->offset = w;
540 				w += l->width;
541 			}
542 		}
543 		w += round(w, supad);
544 		t->width = w;
545 		acidtype(t);
546 		return;
547 
548 	case TUNION:
549 		t->offset = 0;
550 		w = 0;
551 		for(l = t->link; l != T; l = l->down) {
552 			if(l->width <= 0)
553 				if(l->sym)
554 					diag(Z, "incomplete union element: %s",
555 						l->sym->name);
556 				else
557 					diag(Z, "incomplete union element");
558 			l->offset = 0;
559 			l->shift = 0;
560 			if(l->width > w)
561 				w = l->width;
562 		}
563 		w += round(w, supad);
564 		t->width = w;
565 		acidtype(t);
566 		return;
567 
568 	default:
569 		diag(Z, "unknown type in suallign: %T", t);
570 		break;
571 	}
572 }
573 
574 int
575 allign(Type *t)
576 {
577 	int w;
578 
579 	while(t->etype == TARRAY)
580 		t = t->link;
581 	w = ewidth[t->etype];
582 	if(w <= 0 || w > suround)
583 		w = suround;
584 	return w;
585 }
586 
587 int
588 round(long v, long w)
589 {
590 	int r;
591 
592 	if(w <= 0) {
593 		diag(Z, "rounding by %d", w);
594 		w = 1;
595 	}
596 	if(w > types[TVLONG]->width)
597 		w = types[TVLONG]->width;
598 	r = v%w;
599 	if(r)
600 		r = w-r;
601 	return r;
602 }
603 
604 Type*
605 ofnproto(Node *n)
606 {
607 	Type *tl, *tr, *t;
608 
609 loop:
610 	if(n == Z)
611 		return T;
612 	switch(n->op) {
613 	case OLIST:
614 		tl = ofnproto(n->left);
615 		tr = ofnproto(n->right);
616 		if(tl == T)
617 			return tr;
618 		tl->down = tr;
619 		return tl;
620 
621 	case ONAME:
622 		t = typ(TXXX, T);
623 		*t = *n->sym->type;
624 		t->down = T;
625 		return t;
626 	}
627 	return T;
628 }
629 
630 #define	ANSIPROTO	1
631 #define	OLDPROTO	2
632 
633 void
634 argmark(Node *n, int pass)
635 {
636 	Type *t;
637 
638 	autoffset = 0;
639 	if(passbypointer(thisfn->link->etype)) {
640 		autoffset += types[TIND]->width;
641 		autoffset += round(autoffset, tint->width);
642 	}
643 	stkoff = 0;
644 	for(; n->left != Z; n = n->left) {
645 		if(n->op != OFUNC || n->left->op != ONAME)
646 			continue;
647 		walkparam(n->right, pass);
648 		if(pass != 0 && anyproto(n->right) == OLDPROTO) {
649 			t = typ(TFUNC, n->left->sym->type->link);
650 			t->down = typ(TOLD, T);
651 			t->down->down = ofnproto(n->right);
652 			tmerge(t, n->left->sym);
653 			n->left->sym->type = t;
654 		}
655 		break;
656 	}
657 	autoffset = 0;
658 	stkoff = 0;
659 }
660 
661 void
662 walkparam(Node *n, int pass)
663 {
664 	Sym *s;
665 	Node *n1;
666 
667 	if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
668 		return;
669 
670 loop:
671 	if(n == Z)
672 		return;
673 	switch(n->op) {
674 	default:
675 		diag(n, "argument not a name/prototype: %O", n->op);
676 		break;
677 
678 	case OLIST:
679 		walkparam(n->left, pass);
680 		n = n->right;
681 		goto loop;
682 
683 	case OPROTO:
684 		for(n1 = n; n1 != Z; n1=n1->left)
685 			if(n1->op == ONAME) {
686 				if(pass == 0) {
687 					s = n1->sym;
688 					push1(s);
689 					s->offset = -1;
690 					break;
691 				}
692 				dodecl(pdecl, CPARAM, n->type, n->left);
693 				break;
694 			}
695 		if(n1)
696 			break;
697 		if(pass == 0) {
698 			/*
699 			 * extension:
700 			 *	allow no name in argument declaration
701 			diag(Z, "no name in argument declaration");
702 			 */
703 			break;
704 		}
705 		dodecl(NODECL, CPARAM, n->type, n->left);
706 		pdecl(CPARAM, lastdcl, S);
707 		break;
708 
709 	case ODOTDOT:
710 		break;
711 
712 	case ONAME:
713 		s = n->sym;
714 		if(pass == 0) {
715 			push1(s);
716 			s->offset = -1;
717 			break;
718 		}
719 		if(s->offset != -1) {
720 			if(autoffset == 0) {
721 				firstarg = s;
722 				firstargtype = s->type;
723 			}
724 			s->offset = autoffset;
725 			autoffset += s->type->width;
726 			autoffset += round(autoffset, tint->width);
727 		} else
728 			dodecl(pdecl, CXXX, tint, n);
729 		break;
730 	}
731 }
732 
733 void
734 markdcl(void)
735 {
736 	Decl *d;
737 
738 	blockno++;
739 	d = push();
740 	d->val = DMARK;
741 	d->offset = autoffset;
742 	d->block = autobn;
743 	autobn = blockno;
744 }
745 
746 void
747 revertdcl(void)
748 {
749 	Decl *d;
750 	Sym *s;
751 
752 	for(;;) {
753 		d = dclstack;
754 		if(d == D) {
755 			diag(Z, "pop off dcl stack");
756 			break;
757 		}
758 		dclstack = d->link;
759 		s = d->sym;
760 		switch(d->val) {
761 		case DMARK:
762 			autoffset = d->offset;
763 			autobn = d->block;
764 			return;
765 
766 		case DAUTO:
767 			if(debug['d'])
768 				print("revert1 \"%s\"\n", s->name);
769 			if(s->aused == 0) {
770 				nearln = s->varlineno;
771 				if(s->class == CAUTO)
772 					warn(Z, "auto declared and not used: %s", s->name);
773 				if(s->class == CPARAM)
774 					warn(Z, "param declared and not used: %s", s->name);
775 			}
776 			s->type = d->type;
777 			s->class = d->class;
778 			s->offset = d->offset;
779 			s->block = d->block;
780 			s->varlineno = d->varlineno;
781 			s->aused = d->aused;
782 			break;
783 
784 		case DSUE:
785 			if(debug['d'])
786 				print("revert2 \"%s\"\n", s->name);
787 			s->suetag = d->type;
788 			s->sueblock = d->block;
789 			break;
790 
791 		case DLABEL:
792 			if(debug['d'])
793 				print("revert3 \"%s\"\n", s->name);
794 			s->label = Z;
795 			break;
796 		}
797 	}
798 }
799 
800 Type*
801 fnproto(Node *n)
802 {
803 	int r;
804 
805 	r = anyproto(n->right);
806 	if(r == 0 || (r & OLDPROTO)) {
807 		if(r & ANSIPROTO)
808 			diag(n, "mixed ansi/old function declaration: %F", n->left);
809 		return T;
810 	}
811 	return fnproto1(n->right);
812 }
813 
814 int
815 anyproto(Node *n)
816 {
817 	int r;
818 
819 	r = 0;
820 
821 loop:
822 	if(n == Z)
823 		return r;
824 	switch(n->op) {
825 	case OLIST:
826 		r |= anyproto(n->left);
827 		n = n->right;
828 		goto loop;
829 
830 	case ODOTDOT:
831 	case OPROTO:
832 		return r | ANSIPROTO;
833 	}
834 	return r | OLDPROTO;
835 }
836 
837 Type*
838 fnproto1(Node *n)
839 {
840 	Type *t;
841 
842 	if(n == Z)
843 		return T;
844 	switch(n->op) {
845 	case OLIST:
846 		t = fnproto1(n->left);
847 		if(t != T)
848 			t->down = fnproto1(n->right);
849 		return t;
850 
851 	case OPROTO:
852 		lastdcl = T;
853 		dodecl(NODECL, CXXX, n->type, n->left);
854 		t = typ(TXXX, T);
855 		if(lastdcl != T)
856 			*t = *paramconv(lastdcl, 1);
857 		return t;
858 
859 	case ONAME:
860 		diag(n, "incomplete argument prototype");
861 		return typ(tint->etype, T);
862 
863 	case ODOTDOT:
864 		return typ(TDOT, T);
865 	}
866 	diag(n, "unknown op in fnproto");
867 	return T;
868 }
869 
870 void
871 dbgdecl(Sym *s)
872 {
873 
874 	if(s->class == CAUTO)
875 		print("decl \"%s\": %s [%d:%ld] %T",
876 			s->name, cnames[s->class], s->block, s->offset, s->type);
877 	else
878 		print("decl \"%s\": %s [%d] %T\n",
879 			s->name, cnames[s->class], s->block, s->type);
880 }
881 
882 Decl*
883 push(void)
884 {
885 	Decl *d;
886 
887 	ALLOC(d, Decl);
888 	d->link = dclstack;
889 	dclstack = d;
890 	return d;
891 }
892 
893 Decl*
894 push1(Sym *s)
895 {
896 	Decl *d;
897 
898 	d = push();
899 	d->sym = s;
900 	d->val = DAUTO;
901 	d->type = s->type;
902 	d->class = s->class;
903 	d->offset = s->offset;
904 	d->block = s->block;
905 	d->varlineno = s->varlineno;
906 	d->aused = s->aused;
907 	return d;
908 }
909 
910 int
911 sametype(Type *t1, Type *t2)
912 {
913 
914 	if(t1 == t2)
915 		return 1;
916 	return rsametype(t1, t2, 5);
917 }
918 
919 int
920 rsametype(Type *t1, Type *t2, int n)
921 {
922 	int et;
923 
924 	n--;
925 	for(;;) {
926 		if(t1 == t2)
927 			return 1;
928 		if(t1 == T || t2 == T)
929 			return 0;
930 		if(n <= 0)
931 			return 1;
932 		et = t1->etype;
933 		if(et != t2->etype)
934 			return 0;
935 		if(et == TFUNC) {
936 			if(!rsametype(t1->link, t2->link, n))
937 				return 0;
938 			t1 = t1->down;
939 			t2 = t2->down;
940 			while(t1 != T && t2 != T) {
941 				if(t1->etype == TOLD) {
942 					t1 = t1->down;
943 					continue;
944 				}
945 				if(t2->etype == TOLD) {
946 					t2 = t2->down;
947 					continue;
948 				}
949 				while(t1 != T || t2 != T) {
950 					if(!rsametype(t1, t2, n))
951 						return 0;
952 					t1 = t1->down;
953 					t2 = t2->down;
954 				}
955 				break;
956 			}
957 			return 1;
958 		}
959 		t1 = t1->link;
960 		t2 = t2->link;
961 		if(typesu[et])
962 			for(;;) {
963 				if(t1 == t2)
964 					return 1;
965 				if(!rsametype(t1, t2, n))
966 					return 0;
967 				t1 = t1->down;
968 				t2 = t2->down;
969 			}
970 		if(et == TIND)
971 			if(t1->etype == TVOID || t2->etype == TVOID)
972 				return 1;
973 	}
974 }
975 
976 Type*
977 dotag(Sym *s, int et, int bn)
978 {
979 	Decl *d;
980 
981 	if(bn != 0 && bn != s->sueblock) {
982 		d = push();
983 		d->sym = s;
984 		d->val = DSUE;
985 		d->type = s->suetag;
986 		d->block = s->sueblock;
987 		s->suetag = T;
988 	}
989 	if(s->suetag == T) {
990 		s->suetag = typ(et, T);
991 		s->sueblock = autobn;
992 	}
993 	if(s->suetag->etype != et)
994 		diag(Z, "tag used for more than one type: %s",
995 			s->name);
996 	if(s->suetag->tag == S)
997 		s->suetag->tag = s;
998 	return s->suetag;
999 }
1000 
1001 Node*
1002 dcllabel(Sym *s, int f)
1003 {
1004 	Decl *d, d1;
1005 	Node *n;
1006 
1007 	n = s->label;
1008 	if(n != Z) {
1009 		if(f) {
1010 			if(n->complex)
1011 				diag(Z, "label reused: %s", s->name);
1012 			n->complex = 1;
1013 		}
1014 		return n;
1015 	}
1016 
1017 	d = push();
1018 	d->sym = s;
1019 	d->val = DLABEL;
1020 	dclstack = d->link;
1021 
1022 	d1 = *firstdcl;
1023 	*firstdcl = *d;
1024 	*d = d1;
1025 
1026 	firstdcl->link = d;
1027 	firstdcl = d;
1028 
1029 	n = new(OXXX, Z, Z);
1030 	n->sym = s;
1031 	n->complex = f;
1032 	s->label = n;
1033 
1034 	if(debug['d'])
1035 		dbgdecl(s);
1036 	return n;
1037 }
1038 
1039 Type*
1040 paramconv(Type *t, int f)
1041 {
1042 
1043 	switch(t->etype) {
1044 	case TARRAY:
1045 		t = typ(TIND, t->link);
1046 		t->width = types[TIND]->width;
1047 		break;
1048 
1049 	case TFUNC:
1050 		t = typ(TIND, t);
1051 		t->width = types[TIND]->width;
1052 		break;
1053 
1054 	case TFLOAT:
1055 		if(!f)
1056 			t = types[TDOUBLE];
1057 		break;
1058 
1059 	case TCHAR:
1060 	case TSHORT:
1061 		if(!f)
1062 			t = tint;
1063 		break;
1064 
1065 	case TUCHAR:
1066 	case TUSHORT:
1067 		if(!f)
1068 			t = tuint;
1069 		break;
1070 	}
1071 	return t;
1072 }
1073 
1074 void
1075 adecl(int c, Type *t, Sym *s)
1076 {
1077 
1078 	if(c == CSTATIC)
1079 		c = CLOCAL;
1080 	if(t->etype == TFUNC) {
1081 		if(c == CXXX)
1082 			c = CEXTERN;
1083 		if(c == CLOCAL)
1084 			c = CSTATIC;
1085 		if(c == CAUTO || c == CEXREG)
1086 			diag(Z, "function cannot be %s %s", cnames[c], s->name);
1087 	}
1088 	if(c == CXXX)
1089 		c = CAUTO;
1090 	if(s) {
1091 		if(s->class == CSTATIC)
1092 			if(c == CEXTERN || c == CGLOBL)
1093 				c = CSTATIC;
1094 		if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
1095 		if(s->block == autobn)
1096 			diag(Z, "auto redeclaration of: %s", s->name);
1097 		if(c != CPARAM)
1098 			push1(s);
1099 		s->block = autobn;
1100 		s->offset = 0;
1101 		s->type = t;
1102 		s->class = c;
1103 		s->aused = 0;
1104 	}
1105 
1106 	if(c != CAUTO && c != CPARAM)
1107 		return;
1108 	if(c == CPARAM && autoffset == 0) {
1109 		firstarg = s;
1110 		firstargtype = t;
1111 	}
1112 	if(t->width < tint->width)
1113 		autoffset += endian(t->width);
1114 	if(s)
1115 		s->offset = autoffset;
1116 	autoffset += t->width;
1117 	autoffset += round(autoffset, tint->width);
1118 	if(c == CAUTO)
1119 		s->offset = -autoffset;
1120 	if(autoffset > stkoff) {
1121 		stkoff = autoffset;
1122 		stkoff += round(stkoff, types[TLONG]->width);
1123 	}
1124 }
1125 
1126 void
1127 pdecl(int c, Type *t, Sym *s)
1128 {
1129 	if(s && s->offset != -1) {
1130 		diag(Z, "not a parameter: %s", s->name);
1131 		return;
1132 	}
1133 	t = paramconv(t, c==CPARAM);
1134 	if(c == CXXX)
1135 		c = CPARAM;
1136 	if(c != CPARAM) {
1137 		diag(Z, "parameter cannot have class: %s", s->name);
1138 		c = CPARAM;
1139 	}
1140 	adecl(c, t, s);
1141 }
1142 
1143 void
1144 xdecl(int c, Type *t, Sym *s)
1145 {
1146 	long o;
1147 
1148 	o = 0;
1149 	if(c == CEXREG) {
1150 		o = exreg(t);
1151 		if(o == 0)
1152 			c = CEXTERN;
1153 	}
1154 	if(c == CXXX) {
1155 		c = CGLOBL;
1156 		if(s->class == CEXTERN)
1157 			s->class = c;
1158 	}
1159 	if(c == CEXTERN)
1160 		if(s->class == CGLOBL)
1161 			c = CGLOBL;
1162 	if(c == CAUTO) {
1163 		diag(Z, "external declaration cannot be auto: %s", s->name);
1164 		c = CEXTERN;
1165 	}
1166 	if(s->class == CSTATIC)
1167 		if(c == CEXTERN || c == CGLOBL)
1168 			c = CSTATIC;
1169 	if(s->type != T)
1170 		if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
1171 			diag(Z, "external redeclaration of: %s", s->name);
1172 			print("	%T; %T\n", t, s->type);
1173 		}
1174 	tmerge(t, s);
1175 	s->type = t;
1176 	s->class = c;
1177 	s->block = 0;
1178 	s->offset = o;
1179 }
1180 
1181 void
1182 tmerge(Type *t1, Sym *s)
1183 {
1184 	Type *ta, *tb, *t2;
1185 
1186 	t2 = s->type;
1187 /*print("merge	%T; %T\n", t1, t2);/**/
1188 	for(;;) {
1189 		if(t1 == T || t2 == T || t1 == t2)
1190 			break;
1191 		if(t1->etype != t2->etype)
1192 			break;
1193 		switch(t1->etype) {
1194 		case TFUNC:
1195 			ta = t1->down;
1196 			tb = t2->down;
1197 			if(ta == T) {
1198 				t1->down = tb;
1199 				break;
1200 			}
1201 			if(tb == T)
1202 				break;
1203 			while(ta != T && tb != T) {
1204 				if(ta == tb)
1205 					break;
1206 				/* ignore old-style flag */
1207 				if(ta->etype == TOLD) {
1208 					ta = ta->down;
1209 					continue;
1210 				}
1211 				if(tb->etype == TOLD) {
1212 					tb = tb->down;
1213 					continue;
1214 				}
1215 				/* checking terminated by ... */
1216 				if(ta->etype == TDOT && tb->etype == TDOT) {
1217 					ta = T;
1218 					tb = T;
1219 					break;
1220 				}
1221 				if(!sametype(ta, tb))
1222 					break;
1223 				ta = ta->down;
1224 				tb = tb->down;
1225 			}
1226 			if(ta != tb)
1227 				diag(Z, "function inconsistently declared: %s", s->name);
1228 
1229 			/* take new-style over old-style */
1230 			ta = t1->down;
1231 			tb = t2->down;
1232 			if(ta != T && ta->etype == TOLD)
1233 				if(tb != T && tb->etype != TOLD)
1234 					t1->down = tb;
1235 			break;
1236 
1237 		case TARRAY:
1238 			/* should we check array size change? */
1239 			if(t2->width > t1->width)
1240 				t1->width = t2->width;
1241 			break;
1242 
1243 		case TUNION:
1244 		case TSTRUCT:
1245 			return;
1246 		}
1247 		t1 = t1->link;
1248 		t2 = t2->link;
1249 	}
1250 }
1251 
1252 void
1253 edecl(int c, Type *t, Sym *s)
1254 {
1255 	Type *t1;
1256 
1257 	if(s == S) {
1258 		if(!typesu[t->etype])
1259 			diag(Z, "unnamed structure element must be struct/union");
1260 		if(c != CXXX)
1261 			diag(Z, "unnamed structure element cannot have class");
1262 	} else
1263 		if(c != CXXX)
1264 			diag(Z, "structure element cannot have class: %s", s->name);
1265 	t1 = t;
1266 	t = typ(TXXX, T);
1267 	*t = *t1;
1268 	t->sym = s;
1269 	t->down = T;
1270 	if(lastfield) {
1271 		t->shift = lastbit - lastfield;
1272 		t->nbits = lastfield;
1273 		if(firstbit)
1274 			t->shift = -t->shift;
1275 	}
1276 	if(strf == T)
1277 		strf = t;
1278 	else
1279 		strl->down = t;
1280 	strl = t;
1281 }
1282 
1283 /*
1284  * this routine is very suspect.
1285  * ansi requires the enum type to
1286  * be represented as an 'int'
1287  * this means that 0x81234567
1288  * would be illegal. this routine
1289  * makes signed and unsigned go
1290  * to unsigned.
1291  */
1292 Type*
1293 maxtype(Type *t1, Type *t2)
1294 {
1295 
1296 	if(t1 == T)
1297 		return t2;
1298 	if(t2 == T)
1299 		return t1;
1300 	if(t1->etype > t2->etype)
1301 		return t1;
1302 	return t2;
1303 }
1304 
1305 void
1306 doenum(Sym *s, Node *n)
1307 {
1308 
1309 	if(n) {
1310 		complex(n);
1311 		if(n->op != OCONST) {
1312 			diag(n, "enum not a constant: %s", s->name);
1313 			return;
1314 		}
1315 		en.cenum = n->type;
1316 		en.tenum = maxtype(en.cenum, en.tenum);
1317 
1318 		if(!typefd[en.cenum->etype])
1319 			en.lastenum = n->vconst;
1320 		else
1321 			en.floatenum = n->fconst;
1322 	}
1323 	if(dclstack)
1324 		push1(s);
1325 	xdecl(CXXX, types[TENUM], s);
1326 
1327 	if(en.cenum == T) {
1328 		en.tenum = tint;
1329 		en.cenum = tint;
1330 		en.lastenum = 0;
1331 	}
1332 	s->tenum = en.cenum;
1333 
1334 	if(!typefd[s->tenum->etype]) {
1335 		s->vconst = convvtox(en.lastenum, s->tenum->etype);
1336 		en.lastenum++;
1337 	} else {
1338 		s->fconst = en.floatenum;
1339 		en.floatenum++;
1340 	}
1341 
1342 	if(debug['d'])
1343 		dbgdecl(s);
1344 }
1345 
1346 void
1347 symadjust(Sym *s, Node *n, long del)
1348 {
1349 
1350 	switch(n->op) {
1351 	default:
1352 		if(n->left)
1353 			symadjust(s, n->left, del);
1354 		if(n->right)
1355 			symadjust(s, n->right, del);
1356 		return;
1357 
1358 	case ONAME:
1359 		if(n->sym == s)
1360 			n->xoffset -= del;
1361 		return;
1362 
1363 	case OCONST:
1364 	case OSTRING:
1365 	case OLSTRING:
1366 	case OINDREG:
1367 	case OREGISTER:
1368 		return;
1369 	}
1370 }
1371 
1372 Node*
1373 contig(Sym *s, Node *n, long v)
1374 {
1375 	Node *p, *r, *q, *m;
1376 	long w;
1377 
1378 	if(n == Z)
1379 		goto no;
1380 	w = s->type->width;
1381 
1382 	/*
1383 	 * nightmare: an automatic array whose size
1384 	 * increases when it is initialized
1385 	 */
1386 	if(v != w) {
1387 		if(v != 0)
1388 			diag(n, "automatic adjustable array: %s", s->name);
1389 		v = s->offset;
1390 		autoffset += w;
1391 		autoffset += round(autoffset, tint->width);
1392 		s->offset = -autoffset;
1393 		if(autoffset > stkoff) {
1394 			stkoff = autoffset;
1395 			stkoff += round(stkoff, types[TLONG]->width);
1396 		}
1397 		symadjust(s, n, v - s->offset);
1398 	}
1399 	if(w <= 4)
1400 		goto no;
1401 	if(n->op == OAS)
1402 		if(n->left->type)
1403 		if(n->left->type->width == w)
1404 			goto no;
1405 	while(w & 3)
1406 		w++;	/* is this a bug?? */
1407 /*
1408  * insert the following code
1409  *
1410 	*(long**)&X = (long*)((char*)X + sizeof(X));
1411 	do {
1412 		*(long**)&X -= 1;
1413 		**(long**)&X = 0;
1414 	} while(*(long**)&X);
1415  */
1416 
1417 	for(q=n; q->op != ONAME; q=q->left)
1418 		;
1419 
1420 	p = new(ONAME, Z, Z);
1421 	*p = *q;
1422 	p->type = typ(TIND, types[TLONG]);
1423 	p->xoffset = s->offset;
1424 
1425 	r = new(ONAME, Z, Z);
1426 	*r = *p;
1427 	r = new(OPOSTDEC, r, Z);
1428 
1429 	q = new(ONAME, Z, Z);
1430 	*q = *p;
1431 	q = new(OIND, q, Z);
1432 
1433 	m = new(OCONST, Z, Z);
1434 	m->vconst = 0;
1435 	m->type = types[TLONG];
1436 
1437 	q = new(OAS, q, m);
1438 
1439 	r = new(OLIST, r, q);
1440 
1441 	q = new(ONAME, Z, Z);
1442 	*q = *p;
1443 	r = new(ODWHILE, q, r);
1444 
1445 	q = new(ONAME, Z, Z);
1446 	*q = *p;
1447 	q->type = q->type->link;
1448 	q->xoffset += w;
1449 	q = new(OADDR, q, 0);
1450 
1451 	q = new(OAS, p, q);
1452 	r = new(OLIST, q, r);
1453 
1454 	n = new(OLIST, r, n);
1455 
1456 no:
1457 	return n;
1458 }
1459