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