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