xref: /inferno-os/limbo/decls.c (revision b24ddd2190855879198319d954c849d72a7f9f26)
1 #include "limbo.h"
2 
3 char *storename[Dend]=
4 {
5 	/* Dtype */	"type",
6 	/* Dfn */	"function",
7 	/* Dglobal */	"global",
8 	/* Darg */	"argument",
9 	/* Dlocal */	"local",
10 	/* Dconst */	"con",
11 	/* Dfield */	"field",
12 	/* Dtag */	"pick tag",
13 	/* Dimport */	"import",
14 	/* Dunbound */	"unbound",
15 	/* Dundef */	"undefined",
16 	/* Dwundef */	"undefined",
17 };
18 
19 char *storeart[Dend] =
20 {
21 	/* Dtype */	"a ",
22 	/* Dfn */	"a ",
23 	/* Dglobal */	"a ",
24 	/* Darg */	"an ",
25 	/* Dlocal */	"a ",
26 	/* Dconst */	"a ",
27 	/* Dfield */	"a ",
28 	/* Dtag */	"a",
29 	/* Dimport */	"an ",
30 	/* Dunbound */	"",
31 	/* Dundef */	"",
32 	/* Dwundef */	"",
33 };
34 
35 int storespace[Dend] =
36 {
37 	/* Dtype */	0,
38 	/* Dfn */	0,
39 	/* Dglobal */	1,
40 	/* Darg */	1,
41 	/* Dlocal */	1,
42 	/* Dconst */	0,
43 	/* Dfield */	1,
44 	/* Dtag */	0,
45 	/* Dimport */	0,
46 	/* Dunbound */	0,
47 	/* Dundef */	0,
48 	/* Dwundef */	0,
49 };
50 
51 static	Decl	*scopes[MaxScope];
52 static	Decl	*tails[MaxScope];
53 static	Node *scopenode[MaxScope];
54 static	uchar scopekind[MaxScope];
55 
56 static	void	freeloc(Decl*);
57 
58 void
popscopes(void)59 popscopes(void)
60 {
61 	Decl *d;
62 	Dlist *id;
63 
64 	/*
65 	 * clear out any decls left in syms
66 	 */
67 	while(scope >= ScopeBuiltin){
68 		for(d = scopes[scope--]; d != nil; d = d->next){
69 			if(d->sym != nil){
70 				d->sym->decl = d->old;
71 				d->old = nil;
72 			}
73 		}
74 	}
75 
76 	for(id = impdecls; id != nil; id = id->next){
77 		for(d = id->d->ty->ids; d != nil; d = d->next){
78 			d->sym->decl = nil;
79 			d->old = nil;
80 		}
81 	}
82 	impdecls = nil;
83 
84 	scope = ScopeBuiltin;
85 	scopes[ScopeBuiltin] = nil;
86 	tails[ScopeBuiltin] = nil;
87 }
88 
89 void
declstart(void)90 declstart(void)
91 {
92 	Decl *d;
93 
94 	iota = mkids(&nosrc, enter("iota", 0), tint, nil);
95 	iota->init = mkconst(&nosrc, 0);
96 
97 	scope = ScopeNils;
98 	scopes[ScopeNils] = nil;
99 	tails[ScopeNils] = nil;
100 
101 	nildecl = mkdecl(&nosrc, Dglobal, tany);
102 	nildecl->sym = enter("nil", 0);
103 	installids(Dglobal, nildecl);
104 	d = mkdecl(&nosrc, Dglobal, tstring);
105 	d->sym = enter("", 0);
106 	installids(Dglobal, d);
107 
108 	scope = ScopeGlobal;
109 	scopes[ScopeGlobal] = nil;
110 	tails[ScopeGlobal] = nil;
111 }
112 
113 void
redecl(Decl * d)114 redecl(Decl *d)
115 {
116 	Decl *old;
117 
118 	old = d->sym->decl;
119 	if(old->store == Dwundef)
120 		return;
121 	error(d->src.start, "redeclaration of %K, previously declared as %k on line %L",
122 		d, old, old->src.start);
123 }
124 
125 void
checkrefs(Decl * d)126 checkrefs(Decl *d)
127 {
128 	Decl *id, *m;
129 	long refs;
130 
131 	for(; d != nil; d = d->next){
132 		if(d->das)
133 			d->refs--;
134 		switch(d->store){
135 		case Dtype:
136 			refs = d->refs;
137 			if(d->ty->kind == Tadt){
138 				for(id = d->ty->ids; id != nil; id = id->next){
139 					d->refs += id->refs;
140 					if(id->store != Dfn)
141 						continue;
142 					if(id->init == nil && id->link == nil && d->importid == nil)
143 						error(d->src.start, "function %s.%s not defined", d->sym->name, id->sym->name);
144 					if(superwarn && !id->refs && d->importid == nil)
145 						warn(d->src.start, "function %s.%s not referenced", d->sym->name, id->sym->name);
146 				}
147 			}
148 			if(d->ty->kind == Tmodule){
149 				for(id = d->ty->ids; id != nil; id = id->next){
150 					refs += id->refs;
151 					if(id->iface != nil)
152 						id->iface->refs += id->refs;
153 					if(id->store == Dtype){
154 						for(m = id->ty->ids; m != nil; m = m->next){
155 							refs += m->refs;
156 							if(m->iface != nil)
157 								m->iface->refs += m->refs;
158 						}
159 					}
160 				}
161 				d->refs = refs;
162 			}
163 			if(superwarn && !refs && d->importid == nil)
164 				warn(d->src.start, "%K not referenced", d);
165 			break;
166 		case Dglobal:
167 			if(!superwarn)
168 				break;
169 		case Dlocal:
170 		case Darg:
171 			if(!d->refs && d->sym != nil
172 			&& d->sym->name != nil && d->sym->name[0] != '.')
173 				warn(d->src.start, "%K not referenced", d);
174 			break;
175 		case Dconst:
176 			if(superwarn && !d->refs && d->sym != nil)
177 				warn(d->src.start, "%K not referenced", d);
178 			if(d->ty == tstring && d->init != nil)
179 				d->init->decl->refs += d->refs;
180 			break;
181 		case Dfn:
182 			if(d->init == nil && d->importid == nil)
183 				error(d->src.start, "%K not defined", d);
184 			if(superwarn && !d->refs)
185 				warn(d->src.start, "%K not referenced", d);
186 			break;
187 		case Dimport:
188 			if(superwarn && !d->refs)
189 				warn(d->src.start, "%K not referenced", d);
190 			break;
191 		}
192 		if(d->das)
193 			d->refs++;
194 	}
195 }
196 
197 Node*
vardecl(Decl * ids,Type * t)198 vardecl(Decl *ids, Type *t)
199 {
200 	Node *n;
201 
202 	n = mkn(Ovardecl, mkn(Oseq, nil, nil), nil);
203 	n->decl = ids;
204 	n->ty = t;
205 	return n;
206 }
207 
208 void
vardecled(Node * n)209 vardecled(Node *n)
210 {
211 	Decl *ids, *last;
212 	Type *t;
213 	int store;
214 
215 	store = Dlocal;
216 	if(scope == ScopeGlobal)
217 		store = Dglobal;
218 	if(n->ty->kind == Texception && n->ty->cons){
219 		store = Dconst;
220 		fatal("Texception in vardecled");
221 	}
222 	ids = n->decl;
223 	installids(store, ids);
224 	t = n->ty;
225 	for(last = ids; ids != nil; ids = ids->next){
226 		ids->ty = t;
227 		last = ids;
228 	}
229 	n->left->decl = last;
230 }
231 
232 Node*
condecl(Decl * ids,Node * init)233 condecl(Decl *ids, Node *init)
234 {
235 	Node *n;
236 
237 	n = mkn(Ocondecl, mkn(Oseq, nil, nil), init);
238 	n->decl = ids;
239 	return n;
240 }
241 
242 void
condecled(Node * n)243 condecled(Node *n)
244 {
245 	Decl *ids, *last;
246 
247 	ids = n->decl;
248 	installids(Dconst, ids);
249 	for(last = ids; ids != nil; ids = ids->next){
250 		ids->ty = tunknown;
251 		last = ids;
252 	}
253 	n->left->decl = last;
254 }
255 
256 Node*
exdecl(Decl * ids,Decl * tids)257 exdecl(Decl *ids, Decl *tids)
258 {
259 	Node *n;
260 	Type *t;
261 
262 	t = mktype(&ids->src.start, &ids->src.stop, Texception, nil, tids);
263 	t->cons = 1;
264 	n = mkn(Oexdecl, mkn(Oseq, nil, nil), nil);
265 	n->decl = ids;
266 	n->ty = t;
267 	return n;
268 }
269 
270 void
exdecled(Node * n)271 exdecled(Node *n)
272 {
273 	Decl *ids, *last;
274 	Type *t;
275 
276 	ids = n->decl;
277 	installids(Dconst, ids);
278 	t = n->ty;
279 	for(last = ids; ids != nil; ids = ids->next){
280 		ids->ty = t;
281 		last = ids;
282 	}
283 	n->left->decl = last;
284 }
285 
286 Node*
importdecl(Node * m,Decl * ids)287 importdecl(Node *m, Decl *ids)
288 {
289 	Node *n;
290 
291 	n = mkn(Oimport, mkn(Oseq, nil, nil), m);
292 	n->decl = ids;
293 	return n;
294 }
295 
296 void
importdecled(Node * n)297 importdecled(Node *n)
298 {
299 	Decl *ids, *last;
300 
301 	ids = n->decl;
302 	installids(Dimport, ids);
303 	for(last = ids; ids != nil; ids = ids->next){
304 		ids->ty = tunknown;
305 		last = ids;
306 	}
307 	n->left->decl = last;
308 }
309 
310 Node*
mkscope(Node * body)311 mkscope(Node *body)
312 {
313 	Node *n;
314 
315 	n = mkn(Oscope, nil, body);
316 	if(body != nil)
317 		n->src = body->src;
318 	return n;
319 }
320 
321 Node*
fndecl(Node * n,Type * t,Node * body)322 fndecl(Node *n, Type *t, Node *body)
323 {
324 	n = mkbin(Ofunc, n, body);
325 	n->ty = t;
326 	return n;
327 }
328 
329 void
fndecled(Node * n)330 fndecled(Node *n)
331 {
332 	Decl *d;
333 	Node *left;
334 
335 	left = n->left;
336 	if(left->op == Oname){
337 		d = left->decl->sym->decl;
338 		if(d == nil || d->store == Dimport){
339 			d = mkids(&left->src, left->decl->sym, n->ty, nil);
340 			installids(Dfn, d);
341 		}
342 		left->decl = d;
343 		d->refs++;
344 	}
345 	if(left->op == Odot)
346 		pushscope(nil, Sother);
347 	if(n->ty->polys != nil){
348 		pushscope(nil, Sother);
349 		installids(Dtype, n->ty->polys);
350 	}
351 	pushscope(nil, Sother);
352 	installids(Darg, n->ty->ids);
353 	n->ty->ids = popscope();
354 	if(n->ty->val != nil)
355 		mergepolydecs(n->ty);
356 	if(n->ty->polys != nil)
357 		n->ty->polys = popscope();
358 	if(left->op == Odot)
359 		popscope();
360 }
361 
362 /*
363  * check the function declaration only
364  * the body will be type checked later by fncheck
365  */
366 Decl *
fnchk(Node * n)367 fnchk(Node *n)
368 {
369 	int bad;
370 	Decl *d, *inadt, *adtp;
371 	Type *t;
372 
373 	bad = 0;
374 	d = n->left->decl;
375 	if(n->left->op == Odot)
376 		d = n->left->right->decl;
377 	if(d == nil)
378 		fatal("decl() fnchk nil");
379 	n->left->decl = d;
380 	if(d->store == Dglobal || d->store == Dfield)
381 		d->store = Dfn;
382 	if(d->store != Dfn || d->init != nil){
383 		nerror(n, "redeclaration of function %D, previously declared as %k on line %L",
384 			d, d, d->src.start);
385 		if(d->store == Dfn && d->init != nil)
386 			bad = 1;
387 	}
388 	d->init = n;
389 
390 	t = n->ty;
391 	inadt = d->dot;
392 	if(inadt != nil && (inadt->store != Dtype || inadt->ty->kind != Tadt))
393 		inadt = nil;
394 	if(n->left->op == Odot){
395 		pushscope(nil, Sother);
396 		adtp = outerpolys(n->left);
397 		if(adtp != nil)
398 			installids(Dtype, adtp);
399 		if(!polyequal(adtp, n->decl))
400 			nerror(n, "adt polymorphic type mismatch");
401 		n->decl = nil;
402 	}
403 	t = validtype(t, inadt);
404 	if(n->left->op == Odot)
405 		popscope();
406 	if(debug['d'])
407 		print("declare function %D ty %T newty %T\n", d, d->ty, t);
408 	t = usetype(t);
409 
410 	if(!polyequal(d->ty->polys, t->polys))
411 		nerror(n, "function polymorphic type mismatch");
412 	if(!tcompat(d->ty, t, 0))
413 		nerror(n, "type mismatch: %D defined as %T declared as %T on line %L",
414 			d, t, d->ty, d->src.start);
415 	else if(!raisescompat(d->ty->u.eraises, t->u.eraises))
416 		nerror(n, "raises mismatch: %D", d);
417 	if(t->varargs != 0)
418 		nerror(n, "cannot define functions with a '*' argument, such as %D", d);
419 
420 	t->u.eraises = d->ty->u.eraises;
421 
422 	d->ty = t;
423 	d->offset = idoffsets(t->ids, MaxTemp, IBY2WD);
424 	d->src = n->src;
425 
426 	d->locals = nil;
427 
428 	n->ty = t;
429 
430 	return bad ? nil: d;
431 }
432 
433 Node*
globalas(Node * dst,Node * v,int valok)434 globalas(Node *dst, Node *v, int valok)
435 {
436 	Node *tv;
437 
438 	if(v == nil)
439 		return nil;
440 	if(v->op == Oas || v->op == Odas){
441 		v = globalas(v->left, v->right, valok);
442 		if(v == nil)
443 			return nil;
444 	}else if(valok && !initable(dst, v, 0))
445 		return nil;
446 	switch(dst->op){
447 	case Oname:
448 		if(dst->decl->init != nil)
449 			nerror(dst, "duplicate assignment to %V, previously assigned on line %L",
450 				dst, dst->decl->init->src.start);
451 		if(valok)
452 			dst->decl->init = v;
453 		return v;
454 	case Otuple:
455 		if(valok && v->op != Otuple)
456 			fatal("can't deal with %n in tuple case of globalas", v);
457 		tv = v->left;
458 		for(dst = dst->left; dst != nil; dst = dst->right){
459 			globalas(dst->left, tv->left, valok);
460 			if(valok)
461 				tv = tv->right;
462 		}
463 		return v;
464 	}
465 	fatal("can't deal with %n in globalas", dst);
466 	return nil;
467 }
468 
469 int
needsstore(Decl * d)470 needsstore(Decl *d)
471 {
472 	if(!d->refs)
473 		return 0;
474 	if(d->importid != nil)
475 		return 0;
476 	if(storespace[d->store])
477 		return 1;
478 	return 0;
479 }
480 
481 /*
482  * return the list of all referenced storage variables
483  */
484 Decl*
vars(Decl * d)485 vars(Decl *d)
486 {
487 	Decl *v, *n;
488 
489 	while(d != nil && !needsstore(d))
490 		d = d->next;
491 	for(v = d; v != nil; v = v->next){
492 		while(v->next != nil){
493 			n = v->next;
494 			if(needsstore(n))
495 				break;
496 			v->next = n->next;
497 		}
498 	}
499 	return d;
500 }
501 
502 /*
503  * declare variables from the left side of a := statement
504  */
505 static int
recdasdecl(Node * n,int store,int * nid)506 recdasdecl(Node *n, int store, int *nid)
507 {
508 	Decl *d, *old;
509 	int ok;
510 
511 	switch(n->op){
512 	case Otuple:
513 		ok = 1;
514 		for(n = n->left; n != nil; n = n->right)
515 			ok &= recdasdecl(n->left, store, nid);
516 		return ok;
517 	case Oname:
518 		if(n->decl == nildecl){
519 			*nid = -1;
520 			return 1;
521 		}
522 		d = mkids(&n->src, n->decl->sym, nil, nil);
523 		installids(store, d);
524 		old = d->old;
525 		if(old != nil
526 		&& old->store != Dfn
527 		&& old->store != Dwundef
528 		&& old->store != Dundef)
529 			warn(d->src.start,  "redeclaration of %K, previously declared as %k on line %L",
530 				d, old, old->src.start);
531 		n->decl = d;
532 		d->refs++;
533 		d->das = 1;
534 		if(*nid >= 0)
535 			(*nid)++;
536 		return 1;
537 	}
538 	return 0;
539 }
540 
541 static int
recmark(Node * n,int nid)542 recmark(Node *n, int nid)
543 {
544 	switch(n->op){
545 	case Otuple:
546 		for(n = n->left; n != nil; n = n->right)
547 			nid = recmark(n->left, nid);
548 		break;
549 	case Oname:
550 		n->decl->nid = nid;
551 		nid = 0;
552 		break;
553 	}
554 	return nid;
555 }
556 
557 int
dasdecl(Node * n)558 dasdecl(Node *n)
559 {
560 	int store, ok, nid;
561 
562 	nid = 0;
563 	if(scope == ScopeGlobal)
564 		store = Dglobal;
565 	else
566 		store = Dlocal;
567 
568 	ok = recdasdecl(n, store, &nid);
569 	if(!ok)
570 		nerror(n, "illegal declaration expression %V", n);
571 	if(ok && store == Dlocal && nid > 1)
572 		recmark(n, nid);
573 	return ok;
574 }
575 
576 /*
577  * declare global variables in nested := expressions
578  */
579 void
gdasdecl(Node * n)580 gdasdecl(Node *n)
581 {
582 	if(n == nil)
583 		return;
584 
585 	if(n->op == Odas){
586 		gdasdecl(n->right);
587 		dasdecl(n->left);
588 	}else{
589 		gdasdecl(n->left);
590 		gdasdecl(n->right);
591 	}
592 }
593 
594 Decl*
undefed(Src * src,Sym * s)595 undefed(Src *src, Sym *s)
596 {
597 	Decl *d;
598 
599 	d = mkids(src, s, tnone, nil);
600 	error(src->start, "%s is not declared", s->name);
601 	installids(Dwundef, d);
602 	return d;
603 }
604 
605 /*
606 int
607 inloop()
608 {
609 	int i;
610 
611 	for (i = scope; i > 0; i--)
612 		if (scopekind[i] == Sloop)
613 			return 1;
614 	return 0;
615 }
616 */
617 
618 int
nested()619 nested()
620 {
621 	int i;
622 
623 	for (i = scope; i > 0; i--)
624 		if (scopekind[i] == Sscope || scopekind[i] == Sloop)
625 			return 1;
626 	return 0;
627 }
628 
629 void
decltozero(Node * n)630 decltozero(Node *n)
631 {
632 	Node *scp;
633 
634 	if ((scp = scopenode[scope]) != nil) {
635 		/* can happen if we do
636 		 *	x[i] := ......
637 		 * which is an error
638 		 */
639 		if (n->right != nil && errors == 0)
640 			fatal("Ovardecl/Oname/Otuple has right field\n");
641 		n->right = scp->left;
642 		scp->left = n;
643 	}
644 }
645 
646 void
pushscope(Node * scp,int kind)647 pushscope(Node *scp, int kind)
648 {
649 	if(scope >= MaxScope)
650 		fatal("scope too deep");
651 	scope++;
652 	scopes[scope] = nil;
653 	tails[scope] = nil;
654 	scopenode[scope] = scp;
655 	scopekind[scope] = kind;
656 }
657 
658 Decl*
curscope(void)659 curscope(void)
660 {
661 	return scopes[scope];
662 }
663 
664 /*
665  * revert to old declarations for each symbol in the currect scope.
666  * remove the effects of any imported adt types
667  * whenever the adt is imported from a module,
668  * we record in the type's decl the module to use
669  * when calling members.  the process is reversed here.
670  */
671 Decl*
popscope(void)672 popscope(void)
673 {
674 	Decl *id;
675 	Type *t;
676 
677 if (debug['X'])
678 	print("popscope\n");
679 	for(id = scopes[scope]; id != nil; id = id->next){
680 		if(id->sym != nil){
681 if (debug['X'])
682 	print("%s : %s %d\n", id->sym->name, kindname[id->ty->kind], id->init != nil ? id->init->op : 0);
683 			id->sym->decl = id->old;
684 			id->old = nil;
685 		}
686 		if(id->importid != nil)
687 			id->importid->refs += id->refs;
688 		t = id->ty;
689 		if(id->store == Dtype
690 		&& t->decl != nil
691 		&& t->decl->timport == id)
692 			t->decl->timport = id->timport;
693 		if(id->store == Dlocal)
694 			freeloc(id);
695 	}
696 	return scopes[scope--];
697 }
698 
699 /*
700  * make a new scope,
701  * preinstalled with some previously installed identifiers
702  * don't add the identifiers to the scope chain,
703  * so they remain separate from any newly installed ids
704  *
705  * these routines assume no ids are imports
706  */
707 void
repushids(Decl * ids)708 repushids(Decl *ids)
709 {
710 	Sym *s;
711 
712 	if(scope >= MaxScope)
713 		fatal("scope too deep");
714 	scope++;
715 	scopes[scope] = nil;
716 	tails[scope] = nil;
717 	scopenode[scope] = nil;
718 	scopekind[scope] = Sother;
719 
720 	for(; ids != nil; ids = ids->next){
721 		if(ids->scope != scope
722 		&& (ids->dot == nil || !isimpmod(ids->dot->sym)
723 			|| ids->scope != ScopeGlobal || scope != ScopeGlobal + 1))
724 			fatal("repushids scope mismatch");
725 		s = ids->sym;
726 		if(s != nil && ids->store != Dtag){
727 			if(s->decl != nil && s->decl->scope >= scope)
728 				ids->old = s->decl->old;
729 			else
730 				ids->old = s->decl;
731 			s->decl = ids;
732 		}
733 	}
734 }
735 
736 /*
737  * pop a scope which was started with repushids
738  * return any newly installed ids
739  */
740 Decl*
popids(Decl * ids)741 popids(Decl *ids)
742 {
743 	for(; ids != nil; ids = ids->next){
744 		if(ids->sym != nil && ids->store != Dtag){
745 			ids->sym->decl = ids->old;
746 			ids->old = nil;
747 		}
748 	}
749 	return popscope();
750 }
751 
752 void
installids(int store,Decl * ids)753 installids(int store, Decl *ids)
754 {
755 	Decl *d, *last;
756 	Sym *s;
757 
758 	last = nil;
759 	for(d = ids; d != nil; d = d->next){
760 		d->scope = scope;
761 		if(d->store == Dundef)
762 			d->store = store;
763 		s = d->sym;
764 		if(s != nil){
765 			if(s->decl != nil && s->decl->scope >= scope){
766 				redecl(d);
767 				d->old = s->decl->old;
768 			}else
769 				d->old = s->decl;
770 			s->decl = d;
771 		}
772 		last = d;
773 	}
774 	if(ids != nil){
775 		d = tails[scope];
776 		if(d == nil)
777 			scopes[scope] = ids;
778 		else
779 			d->next = ids;
780 		tails[scope] = last;
781 	}
782 }
783 
784 Decl*
lookup(Sym * sym)785 lookup(Sym *sym)
786 {
787 	int s;
788 	Decl *d;
789 
790 	for(s = scope; s >= ScopeBuiltin; s--){
791 		for(d = scopes[s]; d != nil; d = d->next){
792 			if(d->sym == sym)
793 				return d;
794 		}
795 	}
796 	return nil;
797 }
798 
799 Decl*
mkids(Src * src,Sym * s,Type * t,Decl * next)800 mkids(Src *src, Sym *s, Type *t, Decl *next)
801 {
802 	Decl *d;
803 
804 	d = mkdecl(src, Dundef, t);
805 	d->next = next;
806 	d->sym = s;
807 	return d;
808 }
809 
810 Decl*
mkdecl(Src * src,int store,Type * t)811 mkdecl(Src *src, int store, Type *t)
812 {
813 	Decl *d;
814 	static Decl z;
815 
816 	d = allocmem(sizeof *d);
817 	*d = z;
818 	d->src = *src;
819 	d->store = store;
820 	d->ty = t;
821 	d->nid = 1;
822 	return d;
823 }
824 
825 Decl*
dupdecl(Decl * old)826 dupdecl(Decl *old)
827 {
828 	Decl *d;
829 
830 	d = allocmem(sizeof *d);
831 	*d = *old;
832 	d->next = nil;
833 	return d;
834 }
835 
836 Decl*
dupdecls(Decl * old)837 dupdecls(Decl *old)
838 {
839 	Decl *d, *nd, *first, *last;
840 
841 	first = last = nil;
842 	for(d = old; d != nil; d = d->next){
843 		nd = dupdecl(d);
844 		if(first == nil)
845 			first = nd;
846 		else
847 			last->next = nd;
848 		last = nd;
849 	}
850 	return first;
851 }
852 
853 Decl*
appdecls(Decl * d,Decl * dd)854 appdecls(Decl *d, Decl *dd)
855 {
856 	Decl *t;
857 
858 	if(d == nil)
859 		return dd;
860 	for(t = d; t->next != nil; t = t->next)
861 		;
862 	t->next = dd;
863 	return d;
864 }
865 
866 Decl*
revids(Decl * id)867 revids(Decl *id)
868 {
869 	Decl *d, *next;
870 
871 	d = nil;
872 	for(; id != nil; id = next){
873 		next = id->next;
874 		id->next = d;
875 		d = id;
876 	}
877 	return d;
878 }
879 
880 long
idoffsets(Decl * id,long offset,int al)881 idoffsets(Decl *id, long offset, int al)
882 {
883 	int a, algn;
884 	Decl *d;
885 
886 	algn = 1;
887 	for(; id != nil; id = id->next){
888 		if(storespace[id->store]){
889 usedty(id->ty);
890 			if(id->store == Dlocal && id->link != nil){
891 				/* id->nid always 1 */
892 				id->offset = id->link->offset;
893 				continue;
894 			}
895 			a = id->ty->align;
896 			if(id->nid > 1){
897 				for(d = id->next; d != nil && d->nid == 0; d = d->next)
898 					if(d->ty->align > a)
899 						a = d->ty->align;
900 				algn = a;
901 			}
902 			offset = align(offset, a);
903 			id->offset = offset;
904 			offset += id->ty->size;
905 			if(id->nid == 0 && (id->next == nil || id->next->nid != 0))
906 				offset = align(offset, algn);
907 		}
908 	}
909 	return align(offset, al);
910 }
911 
912 long
idindices(Decl * id)913 idindices(Decl *id)
914 {
915 	int i;
916 
917 	i = 0;
918 	for(; id != nil; id = id->next){
919 		if(storespace[id->store]){
920 			usedty(id->ty);
921 			id->offset = i++;
922 		}
923 	}
924 	return i;
925 }
926 
927 int
declconv(Fmt * f)928 declconv(Fmt *f)
929 {
930 	Decl *d;
931 	char buf[4096], *s;
932 
933 	d = va_arg(f->args, Decl*);
934 	if(d->sym == nil)
935 		s = "<nil>";
936 	else
937 		s = d->sym->name;
938 	seprint(buf, buf+sizeof(buf), "%s %s", storename[d->store], s);
939 	return fmtstrcpy(f, buf);
940 }
941 
942 int
storeconv(Fmt * f)943 storeconv(Fmt *f)
944 {
945 	Decl *d;
946 	char buf[4096];
947 
948 	d = va_arg(f->args, Decl*);
949 	seprint(buf, buf+sizeof(buf), "%s%s", storeart[d->store], storename[d->store]);
950 	return fmtstrcpy(f, buf);
951 }
952 
953 int
dotconv(Fmt * f)954 dotconv(Fmt *f)
955 {
956 	Decl *d;
957 	char buf[4096], *p, *s;
958 
959 	d = va_arg(f->args, Decl*);
960 	buf[0] = 0;
961 	p = buf;
962 	if(d->dot != nil && !isimpmod(d->dot->sym)){
963 		s = ".";
964 		if(d->dot->ty != nil && d->dot->ty->kind == Tmodule)
965 			s = "->";
966 		p = seprint(buf, buf+sizeof(buf), "%D%s", d->dot, s);
967 	}
968 	seprint(p, buf+sizeof(buf), "%s", d->sym->name);
969 	return fmtstrcpy(f, buf);
970 }
971 
972 /*
973  * merge together two sorted lists, yielding a sorted list
974  */
975 static Decl*
namemerge(Decl * e,Decl * f)976 namemerge(Decl *e, Decl *f)
977 {
978 	Decl rock, *d;
979 
980 	d = &rock;
981 	while(e != nil && f != nil){
982 		if(strcmp(e->sym->name, f->sym->name) <= 0){
983 			d->next = e;
984 			e = e->next;
985 		}else{
986 			d->next = f;
987 			f = f->next;
988 		}
989 		d = d->next;
990 	}
991 	if(e != nil)
992 		d->next = e;
993 	else
994 		d->next = f;
995 	return rock.next;
996 }
997 
998 /*
999  * recursively split lists and remerge them after they are sorted
1000  */
1001 static Decl*
recnamesort(Decl * d,int n)1002 recnamesort(Decl *d, int n)
1003 {
1004 	Decl *r, *dd;
1005 	int i, m;
1006 
1007 	if(n <= 1)
1008 		return d;
1009 	m = n / 2 - 1;
1010 	dd = d;
1011 	for(i = 0; i < m; i++)
1012 		dd = dd->next;
1013 	r = dd->next;
1014 	dd->next = nil;
1015 	return namemerge(recnamesort(d, n / 2),
1016 			recnamesort(r, (n + 1) / 2));
1017 }
1018 
1019 /*
1020  * sort the ids by name
1021  */
1022 Decl*
namesort(Decl * d)1023 namesort(Decl *d)
1024 {
1025 	Decl *dd;
1026 	int n;
1027 
1028 	n = 0;
1029 	for(dd = d; dd != nil; dd = dd->next)
1030 		n++;
1031 	return recnamesort(d, n);
1032 }
1033 
1034 void
printdecls(Decl * d)1035 printdecls(Decl *d)
1036 {
1037 	for(; d != nil; d = d->next)
1038 		print("%ld: %K %T ref %d\n", d->offset, d, d->ty, d->refs);
1039 }
1040 
1041 void
mergepolydecs(Type * t)1042 mergepolydecs(Type *t)
1043 {
1044 	Node *n, *nn;
1045 	Decl *id, *ids, *ids1;
1046 
1047 	for(n = t->val; n != nil; n = n->right){
1048 		nn = n->left;
1049 		for(ids = nn->decl; ids != nil; ids = ids->next){
1050 			id = ids->sym->decl;
1051 			if(id == nil){
1052 				undefed(&ids->src, ids->sym);
1053 				break;
1054 			}
1055 			if(id->store != Dtype){
1056 				error(ids->src.start, "%K is not a type", id);
1057 				break;
1058 			}
1059 			if(id->ty->kind != Tpoly){
1060 				error(ids->src.start, "%K is not a polymorphic type", id);
1061 				break;
1062 			}
1063 			if(id->ty->ids != nil)
1064 				error(ids->src.start, "%K redefined", id);
1065 			pushscope(nil, Sother);
1066 			fielddecled(nn->left);
1067 			id->ty->ids = popscope();
1068 			for(ids1 = id->ty->ids; ids1 != nil; ids1 = ids1->next){
1069 				ids1->dot = id;
1070 				bindtypes(ids1->ty);
1071 				if(ids1->ty->kind != Tfn){
1072 					error(ids1->src.start, "only function types expected");
1073 					id->ty->ids = nil;
1074 				}
1075 			}
1076 		}
1077 	}
1078 	t->val = nil;
1079 }
1080 
1081 static void
adjfnptrs(Decl * d,Decl * polys1,Decl * polys2)1082 adjfnptrs(Decl *d, Decl *polys1, Decl *polys2)
1083 {
1084 	int n;
1085 	Decl *id, *idt, *idf, *arg;
1086 
1087 	if(debug['U'])
1088 		print("adjnptrs %s\n", d->sym->name);
1089 	n = 0;
1090 	for(id = d->ty->ids; id != nil; id = id->next)
1091 		n++;
1092 	for(idt = polys1; idt != nil; idt = idt->next)
1093 		for(idf = idt->ty->ids; idf != nil; idf = idf->next)
1094 			n -= 2;
1095 	for(idt = polys2; idt != nil; idt = idt->next)
1096 		for(idf = idt->ty->ids; idf != nil; idf = idf->next)
1097 			n -= 2;
1098 	for(arg = d->ty->ids; --n >= 0; arg = arg->next)
1099 		;
1100 	for(idt = polys1; idt != nil; idt = idt->next){
1101 		for(idf = idt->ty->ids; idf != nil; idf = idf->next){
1102 			idf->link = arg;
1103 			arg = arg->next->next;
1104 		}
1105 	}
1106 	for(idt = polys2; idt != nil; idt = idt->next){
1107 		for(idf = idt->ty->ids; idf != nil; idf = idf->next){
1108 			idf->link = arg;
1109 			arg = arg->next->next;
1110 		}
1111 	}
1112 }
1113 
1114 static void
addptrs(Decl * polys,Decl ** fps,Decl ** last,int link,Src * src)1115 addptrs(Decl *polys, Decl** fps, Decl **last, int link, Src *src)
1116 {
1117 	Decl *idt, *idf, *fp;
1118 
1119 	if(debug['U'])
1120 		print("addptrs\n");
1121 	for(idt = polys; idt != nil; idt = idt->next){
1122 		for(idf = idt->ty->ids; idf != nil; idf = idf->next){
1123 			fp = mkdecl(src, Darg, tany);
1124 			fp->sym = idf->sym;
1125 			if(link)
1126 				idf->link = fp;
1127 			if(*fps == nil)
1128 				*fps = fp;
1129 			else
1130 				(*last)->next = fp;
1131 			*last = fp;
1132 			fp = mkdecl(src, Darg, tint);
1133 			fp->sym = idf->sym;
1134 			(*last)->next = fp;
1135 			*last = fp;
1136 		}
1137 	}
1138 }
1139 
1140 void
addfnptrs(Decl * d,int link)1141 addfnptrs(Decl *d, int link)
1142 {
1143 	Decl *fps, *last, *polys;
1144 
1145 	if(debug['U'])
1146 		print("addfnptrs %s %d\n", d->sym->name, link);
1147 	polys = encpolys(d);
1148 	if(d->ty->flags&FULLARGS){
1149 		if(link)
1150 			adjfnptrs(d, d->ty->polys, polys);
1151 		if(0 && debug['U']){
1152 			for(d = d->ty->ids; d != nil; d = d->next)
1153 				print("%s=%ld(%d) ", d->sym->name, d->offset, tattr[d->ty->kind].isptr);
1154 			print("\n");
1155 		}
1156 		return;
1157 	}
1158 	d->ty->flags |= FULLARGS;
1159 	fps = last = nil;
1160 	addptrs(d->ty->polys, &fps, &last, link, &d->src);
1161 	addptrs(polys, &fps, &last, link, &d->src);
1162 	for(last = d->ty->ids; last != nil && last->next != nil; last = last->next)
1163 		;
1164 	if(last != nil)
1165 		last->next = fps;
1166 	else
1167 		d->ty->ids = fps;
1168 	d->offset = idoffsets(d->ty->ids, MaxTemp, IBY2WD);
1169 	if(0 && debug['U']){
1170 		for(d = d->ty->ids; d != nil; d = d->next)
1171 			print("%s=%ld(%d) ", d->sym->name, d->offset, tattr[d->ty->kind].isptr);
1172 		print("\n");
1173 	}
1174 }
1175 
1176 void
rmfnptrs(Decl * d)1177 rmfnptrs(Decl *d)
1178 {
1179 	int n;
1180 	Decl *id, *idt, *idf;
1181 
1182 	if(debug['U'])
1183 		print("rmfnptrs %s\n", d->sym->name);
1184 	if(!(d->ty->flags&FULLARGS))
1185 		return;
1186 	d->ty->flags &= ~FULLARGS;
1187 	n = 0;
1188 	for(id = d->ty->ids; id != nil; id = id->next)
1189 		n++;
1190 	for(idt = d->ty->polys; idt != nil; idt = idt->next)
1191 		for(idf = idt->ty->ids; idf != nil; idf = idf->next)
1192 			n -= 2;
1193 	for(idt = encpolys(d); idt != nil; idt = idt->next)
1194 		for(idf = idt->ty->ids; idf != nil; idf = idf->next)
1195 			n -= 2;
1196 	if(n == 0){
1197 		d->ty->ids = nil;
1198 		return;
1199 	}
1200 	for(id = d->ty->ids; --n > 0; id = id->next)
1201 		;
1202 	id->next = nil;
1203 	d->offset = idoffsets(d->ty->ids, MaxTemp, IBY2WD);
1204 }
1205 
1206 int
local(Decl * d)1207 local(Decl *d)
1208 {
1209 	for(d = d->dot; d != nil; d = d->dot)
1210 		if(d->store == Dtype && d->ty->kind == Tmodule)
1211 			return 0;
1212 	return 1;
1213 }
1214 
1215 Decl*
module(Decl * d)1216 module(Decl *d)
1217 {
1218 	for(d = d->dot; d != nil; d = d->dot)
1219 		if(d->store == Dtype && d->ty->kind == Tmodule)
1220 			return d;
1221 	return nil;
1222 }
1223 
1224 Decl*
outerpolys(Node * n)1225 outerpolys(Node *n)
1226 {
1227 	Decl *d;
1228 
1229 	if(n->op == Odot){
1230 		d = n->right->decl;
1231 		if(d == nil)
1232 			fatal("decl() outeradt nil");
1233 		d = d->dot;
1234 		if(d != nil && d->store == Dtype && d->ty->kind == Tadt)
1235 			return d->ty->polys;
1236 	}
1237 	return nil;
1238 }
1239 
1240 Decl*
encpolys(Decl * d)1241 encpolys(Decl *d)
1242 {
1243 	if((d = d->dot) == nil)
1244 		return nil;
1245 	return d->ty->polys;
1246 }
1247 
1248 Decl*
fnlookup(Sym * s,Type * t,Node ** m)1249 fnlookup(Sym *s, Type *t, Node **m)
1250 {
1251 	Decl *id;
1252 	Node *mod;
1253 
1254 	id = nil;
1255 	mod = nil;
1256 	if(t->kind == Tpoly || t->kind == Tmodule)
1257 		id = namedot(t->ids, s);
1258 	else if(t->kind == Tref){
1259 		t = t->tof;
1260 		if(t->kind == Tadt){
1261 			id = namedot(t->ids, s);
1262 			if(t->decl != nil && t->decl->timport != nil)
1263 				mod = t->decl->timport->eimport;
1264 		}
1265 		else if(t->kind == Tadtpick){
1266 			id = namedot(t->ids, s);
1267 			if(t->decl != nil && t->decl->timport != nil)
1268 				mod = t->decl->timport->eimport;
1269 			t = t->decl->dot->ty;
1270 			if(id == nil)
1271 				id = namedot(t->ids, s);
1272 			if(t->decl != nil && t->decl->timport != nil)
1273 				mod = t->decl->timport->eimport;
1274 		}
1275 	}
1276 	if(id == nil){
1277 		id = lookup(s);
1278 		if(id != nil)
1279 			mod = id->eimport;
1280 	}
1281 	if(m != nil)
1282 		*m = mod;
1283 	return id;
1284 }
1285 
1286 int
isimpmod(Sym * s)1287 isimpmod(Sym *s)
1288 {
1289 	Decl *d;
1290 
1291 	for(d = impmods; d != nil; d = d->next)
1292 		if(d->sym == s)
1293 			return 1;
1294 	return 0;
1295 }
1296 
1297 int
dequal(Decl * d1,Decl * d2,int full)1298 dequal(Decl *d1, Decl *d2, int full)
1299 {
1300 	return	d1->sym == d2->sym &&
1301 			d1->store == d2->store &&
1302 			d1->implicit == d2->implicit &&
1303 			d1->cyc == d2->cyc &&
1304 			(!full || tequal(d1->ty, d2->ty)) &&
1305 			(!full || d1->store == Dfn || sametree(d1->init, d2->init));
1306 }
1307 
1308 static int
tzero(Type * t)1309 tzero(Type *t)
1310 {
1311 	return t->kind == Texception || tmustzero(t);
1312 }
1313 
1314 static int
isptr(Type * t)1315 isptr(Type *t)
1316 {
1317 	return t->kind == Texception || tattr[t->kind].isptr;
1318 }
1319 
1320 /* can d share the same stack location as another local ? */
1321 void
shareloc(Decl * d)1322 shareloc(Decl *d)
1323 {
1324 	int z;
1325 	Type *t, *tt;
1326 	Decl *dd, *res;
1327 
1328 	if(d->store != Dlocal || d->nid != 1)
1329 		return;
1330 	t = d->ty;
1331 	res = nil;
1332 	for(dd = fndecls; dd != nil; dd = dd->next){
1333 		if(d == dd)
1334 			fatal("d==dd in shareloc");
1335 		if(dd->store != Dlocal || dd->nid != 1 || dd->link != nil || dd->tref != 0)
1336 			continue;
1337 		tt = dd->ty;
1338 		if(t->size != tt->size || t->align != tt->align)
1339 			continue;
1340 		z = tzero(t)+tzero(tt);
1341 		if(z > 0)
1342 			continue;	/* for now */
1343 		if(t == tt || tequal(t, tt))
1344 			res = dd;
1345 		else{
1346 			if(z == 1)
1347 				continue;
1348 			if(z == 0 || isptr(t) || isptr(tt) || mktdesc(t) == mktdesc(tt))
1349 				res = dd;
1350 		}
1351 		if(res != nil){
1352 			/* print("%L %K share %L %K\n", d->src.start, d, res->src.start, res); */
1353 			d->link = res;
1354 			res->tref = 1;
1355 			return;
1356 		}
1357 	}
1358 	return;
1359 }
1360 
1361 static void
freeloc(Decl * d)1362 freeloc(Decl *d)
1363 {
1364 	if(d->link != nil)
1365 		d->link->tref = 0;
1366 }
1367