1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "go.h"
6 #include "y.tab.h"
7
8 static void funcargs(Node*);
9
10 static int
11 dflag(void)
12 {
13 if(!debug['d'])
14 return 0;
15 if(debug['y'])
16 return 1;
17 if(incannedimport)
18 return 0;
19 return 1;
20 }
21
22 /*
23 * declaration stack & operations
24 */
25
26 static void
27 dcopy(Sym *a, Sym *b)
28 {
29 a->pkg = b->pkg;
30 a->name = b->name;
31 a->def = b->def;
32 a->block = b->block;
33 a->lastlineno = b->lastlineno;
34 }
35
36 static Sym*
37 push(void)
38 {
39 Sym *d;
40
41 d = mal(sizeof(*d));
42 d->lastlineno = lineno;
43 d->link = dclstack;
44 dclstack = d;
45 return d;
46 }
47
48 static Sym*
49 pushdcl(Sym *s)
50 {
51 Sym *d;
52
53 d = push();
54 dcopy(d, s);
55 if(dflag())
56 print("\t%L push %S %p\n", lineno, s, s->def);
57 return d;
58 }
59
60 void
61 popdcl(void)
62 {
63 Sym *d, *s;
64 int lno;
65
66 // if(dflag())
67 // print("revert\n");
68
69 for(d=dclstack; d!=S; d=d->link) {
70 if(d->name == nil)
71 break;
72 s = pkglookup(d->name, d->pkg);
73 lno = s->lastlineno;
74 dcopy(s, d);
75 d->lastlineno = lno;
76 if(dflag())
77 print("\t%L pop %S %p\n", lineno, s, s->def);
78 }
79 if(d == S)
80 fatal("popdcl: no mark");
81 dclstack = d->link;
82 block = d->block;
83 }
84
85 void
86 poptodcl(void)
87 {
88 // pop the old marker and push a new one
89 // (cannot reuse the existing one)
90 // because we use the markers to identify blocks
91 // for the goto restriction checks.
92 popdcl();
93 markdcl();
94 }
95
96 void
97 markdcl(void)
98 {
99 Sym *d;
100
101 d = push();
102 d->name = nil; // used as a mark in fifo
103 d->block = block;
104
105 blockgen++;
106 block = blockgen;
107
108 // if(dflag())
109 // print("markdcl\n");
110 }
111
112 void
113 dumpdcl(char *st)
114 {
115 Sym *s, *d;
116 int i;
117
118 i = 0;
119 for(d=dclstack; d!=S; d=d->link) {
120 i++;
121 print(" %.2d %p", i, d);
122 if(d->name == nil) {
123 print("\n");
124 continue;
125 }
126 print(" '%s'", d->name);
127 s = pkglookup(d->name, d->pkg);
128 print(" %lS\n", s);
129 }
130 }
131
132 void
133 testdclstack(void)
134 {
135 Sym *d;
136
137 for(d=dclstack; d!=S; d=d->link) {
138 if(d->name == nil) {
139 yyerror("mark left on the stack");
140 continue;
141 }
142 }
143 }
144
145 void
146 redeclare(Sym *s, char *where)
147 {
148 if(s->lastlineno == 0)
149 yyerror("%S redeclared %s\n"
150 "\tprevious declaration during import",
151 s, where);
152 else
153 yyerror("%S redeclared %s\n"
154 "\tprevious declaration at %L",
155 s, where, s->lastlineno);
156 }
157
158 /*
159 * declare individual names - var, typ, const
160 */
161 void
162 declare(Node *n, int ctxt)
163 {
164 Sym *s;
165 int gen;
166 static int typegen, vargen;
167
168 if(isblank(n))
169 return;
170
171 n->lineno = parserline();
172 s = n->sym;
173 gen = 0;
174 if(ctxt == PEXTERN) {
175 externdcl = list(externdcl, n);
176 if(dflag())
177 print("\t%L global decl %S %p\n", lineno, s, n);
178 } else {
179 if(curfn == nil && ctxt == PAUTO)
180 fatal("automatic outside function");
181 if(curfn != nil)
182 curfn->dcl = list(curfn->dcl, n);
183 if(n->op == OTYPE)
184 gen = ++typegen;
185 else if(n->op == ONAME)
186 gen = ++vargen;
187 pushdcl(s);
188 n->curfn = curfn;
189 }
190 if(ctxt == PAUTO)
191 n->xoffset = BADWIDTH;
192
193 if(s->block == block)
194 redeclare(s, "in this block");
195
196 s->block = block;
197 s->lastlineno = parserline();
198 s->def = n;
199 n->vargen = gen;
200 n->funcdepth = funcdepth;
201 n->class = ctxt;
202
203 autoexport(n, ctxt);
204 }
205
206 void
207 addvar(Node *n, Type *t, int ctxt)
208 {
209 if(n==N || n->sym == S || (n->op != ONAME && n->op != ONONAME) || t == T)
210 fatal("addvar: n=%N t=%T nil", n, t);
211
212 n->op = ONAME;
213 declare(n, ctxt);
214 n->type = t;
215 }
216
217 /*
218 * declare variables from grammar
219 * new_name_list (type | [type] = expr_list)
220 */
221 NodeList*
222 variter(NodeList *vl, Node *t, NodeList *el)
223 {
224 int doexpr;
225 Node *v, *e, *as2;
226 NodeList *init;
227
228 init = nil;
229 doexpr = el != nil;
230
231 if(count(el) == 1 && count(vl) > 1) {
232 e = el->n;
233 as2 = nod(OAS2, N, N);
234 as2->list = vl;
235 as2->rlist = list1(e);
236 for(; vl; vl=vl->next) {
237 v = vl->n;
238 v->op = ONAME;
239 declare(v, dclcontext);
240 v->ntype = t;
241 v->defn = as2;
242 if(funcdepth > 0)
243 init = list(init, nod(ODCL, v, N));
244 }
245 return list(init, as2);
246 }
247
248 for(; vl; vl=vl->next) {
249 if(doexpr) {
250 if(el == nil) {
251 yyerror("missing expr in var dcl");
252 break;
253 }
254 e = el->n;
255 el = el->next;
256 } else
257 e = N;
258
259 v = vl->n;
260 v->op = ONAME;
261 declare(v, dclcontext);
262 v->ntype = t;
263
264 if(e != N || funcdepth > 0 || isblank(v)) {
265 if(funcdepth > 0)
266 init = list(init, nod(ODCL, v, N));
267 e = nod(OAS, v, e);
268 init = list(init, e);
269 if(e->right != N)
270 v->defn = e;
271 }
272 }
273 if(el != nil)
274 yyerror("extra expr in var dcl");
275 return init;
276 }
277
278 /*
279 * declare constants from grammar
280 * new_name_list [[type] = expr_list]
281 */
282 NodeList*
283 constiter(NodeList *vl, Node *t, NodeList *cl)
284 {
285 Node *v, *c;
286 NodeList *vv;
287
288 vv = nil;
289 if(cl == nil) {
290 if(t != N)
291 yyerror("constdcl cannot have type without expr");
292 cl = lastconst;
293 t = lasttype;
294 } else {
295 lastconst = cl;
296 lasttype = t;
297 }
298 cl = listtreecopy(cl);
299
300 for(; vl; vl=vl->next) {
301 if(cl == nil) {
302 yyerror("missing expr in const dcl");
303 break;
304 }
305 c = cl->n;
306 cl = cl->next;
307
308 v = vl->n;
309 v->op = OLITERAL;
310 declare(v, dclcontext);
311
312 v->ntype = t;
313 v->defn = c;
314
315 vv = list(vv, nod(ODCLCONST, v, N));
316 }
317 if(cl != nil)
318 yyerror("extra expr in const dcl");
319 iota += 1;
320 return vv;
321 }
322
323 /*
324 * this generates a new name node,
325 * typically for labels or other one-off names.
326 */
327 Node*
328 newname(Sym *s)
329 {
330 Node *n;
331
332 if(s == S)
333 fatal("newname nil");
334
335 n = nod(ONAME, N, N);
336 n->sym = s;
337 n->type = T;
338 n->addable = 1;
339 n->ullman = 1;
340 n->xoffset = 0;
341 return n;
342 }
343
344 /*
345 * this generates a new name node for a name
346 * being declared.
347 */
348 Node*
349 dclname(Sym *s)
350 {
351 Node *n;
352
353 n = newname(s);
354 n->op = ONONAME; // caller will correct it
355 return n;
356 }
357
358 Node*
359 typenod(Type *t)
360 {
361 // if we copied another type with *t = *u
362 // then t->nod might be out of date, so
363 // check t->nod->type too
364 if(t->nod == N || t->nod->type != t) {
365 t->nod = nod(OTYPE, N, N);
366 t->nod->type = t;
367 t->nod->sym = t->sym;
368 }
369 return t->nod;
370 }
371
372
373 /*
374 * this will return an old name
375 * that has already been pushed on the
376 * declaration list. a diagnostic is
377 * generated if no name has been defined.
378 */
379 Node*
380 oldname(Sym *s)
381 {
382 Node *n;
383 Node *c;
384
385 n = s->def;
386 if(n == N) {
387 // maybe a top-level name will come along
388 // to give this a definition later.
389 // walkdef will check s->def again once
390 // all the input source has been processed.
391 n = newname(s);
392 n->op = ONONAME;
393 n->iota = iota; // save current iota value in const declarations
394 }
395 if(curfn != nil && n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
396 // inner func is referring to var in outer func.
397 //
398 // TODO(rsc): If there is an outer variable x and we
399 // are parsing x := 5 inside the closure, until we get to
400 // the := it looks like a reference to the outer x so we'll
401 // make x a closure variable unnecessarily.
402 if(n->closure == N || n->closure->funcdepth != funcdepth) {
403 // create new closure var.
404 c = nod(ONAME, N, N);
405 c->sym = s;
406 c->class = PPARAMREF;
407 c->isddd = n->isddd;
408 c->defn = n;
409 c->addable = 0;
410 c->ullman = 2;
411 c->funcdepth = funcdepth;
412 c->outer = n->closure;
413 n->closure = c;
414 c->closure = n;
415 c->xoffset = 0;
416 curfn->cvars = list(curfn->cvars, c);
417 }
418 // return ref to closure var, not original
419 return n->closure;
420 }
421 return n;
422 }
423
424 /*
425 * same for types
426 */
427 Type*
428 newtype(Sym *s)
429 {
430 Type *t;
431
432 t = typ(TFORW);
433 t->sym = s;
434 t->type = T;
435 return t;
436 }
437
438
439 /*
440 * := declarations
441 */
442
443 static int
444 colasname(Node *n)
445 {
446 switch(n->op) {
447 case ONAME:
448 case ONONAME:
449 case OPACK:
450 case OTYPE:
451 case OLITERAL:
452 return n->sym != S;
453 }
454 return 0;
455 }
456
457 void
458 colasdefn(NodeList *left, Node *defn)
459 {
460 int nnew, nerr;
461 NodeList *l;
462 Node *n;
463
464 nnew = 0;
465 nerr = 0;
466 for(l=left; l; l=l->next) {
467 n = l->n;
468 if(isblank(n))
469 continue;
470 if(!colasname(n)) {
471 yyerror("non-name %#N on left side of :=", n);
472 nerr++;
473 continue;
474 }
475 if(n->sym->block == block)
476 continue;
477
478 nnew++;
479 n = newname(n->sym);
480 declare(n, dclcontext);
481 n->defn = defn;
482 defn->ninit = list(defn->ninit, nod(ODCL, n, N));
483 l->n = n;
484 }
485 if(nnew == 0 && nerr == 0)
486 yyerror("no new variables on left side of :=");
487 }
488
489 Node*
490 colas(NodeList *left, NodeList *right)
491 {
492 Node *as;
493
494 as = nod(OAS2, N, N);
495 as->list = left;
496 as->rlist = right;
497 as->colas = 1;
498 colasdefn(left, as);
499
500 // make the tree prettier; not necessary
501 if(count(left) == 1 && count(right) == 1) {
502 as->left = as->list->n;
503 as->right = as->rlist->n;
504 as->list = nil;
505 as->rlist = nil;
506 as->op = OAS;
507 }
508
509 return as;
510 }
511
512 /*
513 * declare the arguments in an
514 * interface field declaration.
515 */
516 void
517 ifacedcl(Node *n)
518 {
519 if(n->op != ODCLFIELD || n->right == N)
520 fatal("ifacedcl");
521
522 dclcontext = PAUTO;
523 markdcl();
524 funcdepth++;
525 n->outer = curfn;
526 curfn = n;
527 funcargs(n->right);
528
529 // funcbody is normally called after the parser has
530 // seen the body of a function but since an interface
531 // field declaration does not have a body, we must
532 // call it now to pop the current declaration context.
533 funcbody(n);
534 }
535
536 /*
537 * declare the function proper
538 * and declare the arguments.
539 * called in extern-declaration context
540 * returns in auto-declaration context.
541 */
542 void
543 funchdr(Node *n)
544 {
545
546 if(n->nname != N) {
547 n->nname->op = ONAME;
548 declare(n->nname, PFUNC);
549 n->nname->defn = n;
550 }
551
552 // change the declaration context from extern to auto
553 if(funcdepth == 0 && dclcontext != PEXTERN)
554 fatal("funchdr: dclcontext");
555
556 dclcontext = PAUTO;
557 markdcl();
558 funcdepth++;
559
560 n->outer = curfn;
561 curfn = n;
562 if(n->nname)
563 funcargs(n->nname->ntype);
564 else
565 funcargs(n->ntype);
566 }
567
568 static void
569 funcargs(Node *nt)
570 {
571 Node *n;
572 NodeList *l;
573 int gen;
574
575 if(nt->op != OTFUNC)
576 fatal("funcargs %O", nt->op);
577
578 // declare the receiver and in arguments.
579 // no n->defn because type checking of func header
580 // will fill in the types before we can demand them.
581 if(nt->left != N) {
582 n = nt->left;
583 if(n->op != ODCLFIELD)
584 fatal("funcargs1 %O", n->op);
585 if(n->left != N) {
586 n->left->op = ONAME;
587 n->left->ntype = n->right;
588 declare(n->left, PPARAM);
589 }
590 }
591 for(l=nt->list; l; l=l->next) {
592 n = l->n;
593 if(n->op != ODCLFIELD)
594 fatal("funcargs2 %O", n->op);
595 if(n->left != N) {
596 n->left->op = ONAME;
597 n->left->ntype = n->right;
598 declare(n->left, PPARAM);
599 }
600 }
601
602 // declare the out arguments.
603 gen = 0;
604 for(l=nt->rlist; l; l=l->next) {
605 n = l->n;
606 if(n->op != ODCLFIELD)
607 fatal("funcargs3 %O", n->op);
608 if(n->left != N) {
609 n->left->op = ONAME;
610 n->left->ntype = n->right;
611 if(isblank(n->left)) {
612 // Give it a name so we can assign to it during return.
613 snprint(namebuf, sizeof(namebuf), ".anon%d", gen++);
614 n->left->sym = lookup(namebuf);
615 }
616 declare(n->left, PPARAMOUT);
617 }
618 }
619 }
620
621 /*
622 * finish the body.
623 * called in auto-declaration context.
624 * returns in extern-declaration context.
625 */
626 void
627 funcbody(Node *n)
628 {
629 // change the declaration context from auto to extern
630 if(dclcontext != PAUTO)
631 fatal("funcbody: dclcontext");
632 popdcl();
633 funcdepth--;
634 curfn = n->outer;
635 n->outer = N;
636 if(funcdepth == 0)
637 dclcontext = PEXTERN;
638 }
639
640 /*
641 * new type being defined with name s.
642 */
643 Node*
644 typedcl0(Sym *s)
645 {
646 Node *n;
647
648 n = dclname(s);
649 n->op = OTYPE;
650 declare(n, dclcontext);
651 return n;
652 }
653
654 /*
655 * node n, which was returned by typedcl0
656 * is being declared to have uncompiled type t.
657 * return the ODCLTYPE node to use.
658 */
659 Node*
660 typedcl1(Node *n, Node *t, int local)
661 {
662 n->ntype = t;
663 n->local = local;
664 return nod(ODCLTYPE, n, N);
665 }
666
667 /*
668 * typedcl1 but during imports
669 */
670 void
671 typedcl2(Type *pt, Type *t)
672 {
673 Node *n;
674
675 // override declaration in unsafe.go for Pointer.
676 // there is no way in Go code to define unsafe.Pointer
677 // so we have to supply it.
678 if(incannedimport &&
679 strcmp(importpkg->name, "unsafe") == 0 &&
680 strcmp(pt->nod->sym->name, "Pointer") == 0) {
681 t = types[TUNSAFEPTR];
682 }
683
684 if(pt->etype == TFORW)
685 goto ok;
686 if(!eqtype(pt->orig, t))
687 yyerror("inconsistent definition for type %S during import\n\t%lT\n\t%lT", pt->sym, pt->orig, t);
688 return;
689
690 ok:
691 n = pt->nod;
692 copytype(pt->nod, t);
693 // unzero nod
694 pt->nod = n;
695
696 pt->sym->lastlineno = parserline();
697 declare(n, PEXTERN);
698
699 checkwidth(pt);
700 }
701
702 /*
703 * structs, functions, and methods.
704 * they don't belong here, but where do they belong?
705 */
706
707
708 /*
709 * turn a parsed struct into a type
710 */
711 static Type**
712 stotype(NodeList *l, int et, Type **t, int funarg)
713 {
714 Type *f, *t1, *t2, **t0;
715 Strlit *note;
716 int lno;
717 Node *n, *left;
718 char *what;
719
720 t0 = t;
721 lno = lineno;
722 what = "field";
723 if(et == TINTER)
724 what = "method";
725
726 for(; l; l=l->next) {
727 n = l->n;
728 lineno = n->lineno;
729 note = nil;
730
731 if(n->op != ODCLFIELD)
732 fatal("stotype: oops %N\n", n);
733 left = n->left;
734 if(funarg && isblank(left))
735 left = N;
736 if(n->right != N) {
737 if(et == TINTER && left != N) {
738 // queue resolution of method type for later.
739 // right now all we need is the name list.
740 // avoids cycles for recursive interface types.
741 n->type = typ(TINTERMETH);
742 n->type->nname = n->right;
743 n->right = N;
744 left->type = n->type;
745 queuemethod(n);
746 } else {
747 typecheck(&n->right, Etype);
748 n->type = n->right->type;
749 if(n->type == T)
750 continue;
751 if(left != N)
752 left->type = n->type;
753 n->right = N;
754 if(n->embedded && n->type != T) {
755 t1 = n->type;
756 if(t1->sym == S && isptr[t1->etype]) {
757 t1 = t1->type;
758 if(t1->etype == TINTER)
759 yyerror("embedded type cannot be a pointer to interface");
760 }
761 if(isptr[t1->etype])
762 yyerror("embedded type cannot be a pointer");
763 else if(t1->etype == TFORW && t1->embedlineno == 0)
764 t1->embedlineno = lineno;
765 }
766 }
767 }
768
769 if(n->type == T) {
770 // assume error already printed
771 continue;
772 }
773
774 switch(n->val.ctype) {
775 case CTSTR:
776 if(et != TSTRUCT)
777 yyerror("interface method cannot have annotation");
778 note = n->val.u.sval;
779 break;
780 default:
781 if(et != TSTRUCT)
782 yyerror("interface method cannot have annotation");
783 else
784 yyerror("field annotation must be string");
785 case CTxxx:
786 note = nil;
787 break;
788 }
789
790 if(et == TINTER && left == N) {
791 // embedded interface - inline the methods
792 if(n->type->etype != TINTER) {
793 if(n->type->etype == TFORW)
794 yyerror("interface type loop involving %T", n->type);
795 else
796 yyerror("interface contains embedded non-interface %T", n->type);
797 continue;
798 }
799 for(t1=n->type->type; t1!=T; t1=t1->down) {
800 f = typ(TFIELD);
801 f->type = t1->type;
802 f->width = BADWIDTH;
803 f->nname = newname(t1->sym);
804 f->sym = t1->sym;
805 for(t2=*t0; t2!=T; t2=t2->down) {
806 if(t2->sym == f->sym) {
807 yyerror("duplicate method %s", t2->sym->name);
808 break;
809 }
810 }
811 *t = f;
812 t = &f->down;
813 }
814 continue;
815 }
816
817 f = typ(TFIELD);
818 f->type = n->type;
819 f->note = note;
820 f->width = BADWIDTH;
821 f->isddd = n->isddd;
822
823 if(left != N && left->op == ONAME) {
824 f->nname = left;
825 f->embedded = n->embedded;
826 f->sym = f->nname->sym;
827 if(importpkg && !exportname(f->sym->name))
828 f->sym = pkglookup(f->sym->name, structpkg);
829 if(f->sym && !isblank(f->nname)) {
830 for(t1=*t0; t1!=T; t1=t1->down) {
831 if(t1->sym == f->sym) {
832 yyerror("duplicate %s %s", what, t1->sym->name);
833 break;
834 }
835 }
836 }
837 }
838
839 *t = f;
840 t = &f->down;
841 }
842
843 *t = T;
844 lineno = lno;
845 return t;
846 }
847
848 Type*
849 dostruct(NodeList *l, int et)
850 {
851 Type *t;
852 int funarg;
853
854 /*
855 * convert a parsed id/type list into
856 * a type for struct/interface/arglist
857 */
858
859 funarg = 0;
860 if(et == TFUNC) {
861 funarg = 1;
862 et = TSTRUCT;
863 }
864 t = typ(et);
865 t->funarg = funarg;
866 stotype(l, et, &t->type, funarg);
867 if(t->type == T && l != nil) {
868 t->broke = 1;
869 return t;
870 }
871 if(et == TINTER)
872 t = sortinter(t);
873 if(!funarg)
874 checkwidth(t);
875 return t;
876 }
877
878
879 Node*
880 embedded(Sym *s)
881 {
882 Node *n;
883 char *name;
884
885 // Names sometimes have disambiguation junk
886 // appended after a center dot. Discard it when
887 // making the name for the embedded struct field.
888 enum { CenterDot = 0xB7 };
889 name = s->name;
890 if(utfrune(s->name, CenterDot)) {
891 name = strdup(s->name);
892 *utfrune(name, CenterDot) = 0;
893 }
894
895 n = newname(lookup(name));
896 n = nod(ODCLFIELD, n, oldname(s));
897 n->embedded = 1;
898 return n;
899 }
900
901 /*
902 * check that the list of declarations is either all anonymous or all named
903 */
904
905 static Node*
906 findtype(NodeList *l)
907 {
908 for(; l; l=l->next)
909 if(l->n->op == OKEY)
910 return l->n->right;
911 return N;
912 }
913
914 NodeList*
915 checkarglist(NodeList *all, int input)
916 {
917 int named;
918 Node *n, *t, *nextt;
919 NodeList *l;
920
921 named = 0;
922 for(l=all; l; l=l->next) {
923 if(l->n->op == OKEY) {
924 named = 1;
925 break;
926 }
927 }
928 if(named) {
929 n = N;
930 for(l=all; l; l=l->next) {
931 n = l->n;
932 if(n->op != OKEY && n->sym == S) {
933 yyerror("mixed named and unnamed function parameters");
934 break;
935 }
936 }
937 if(l == nil && n != N && n->op != OKEY)
938 yyerror("final function parameter must have type");
939 }
940
941 nextt = nil;
942 for(l=all; l; l=l->next) {
943 // can cache result from findtype to avoid
944 // quadratic behavior here, but unlikely to matter.
945 n = l->n;
946 if(named) {
947 if(n->op == OKEY) {
948 t = n->right;
949 n = n->left;
950 nextt = nil;
951 } else {
952 if(nextt == nil)
953 nextt = findtype(l);
954 t = nextt;
955 }
956 } else {
957 t = n;
958 n = N;
959 }
960 if(n != N && n->sym == S) {
961 t = n;
962 n = N;
963 }
964 if(n != N)
965 n = newname(n->sym);
966 n = nod(ODCLFIELD, n, t);
967 if(n->right != N && n->right->op == ODDD) {
968 if(!input)
969 yyerror("cannot use ... in output argument list");
970 else if(l->next != nil)
971 yyerror("can only use ... as final argument in list");
972 n->right->op = OTARRAY;
973 n->right->right = n->right->left;
974 n->right->left = N;
975 n->isddd = 1;
976 if(n->left != N)
977 n->left->isddd = 1;
978 }
979 l->n = n;
980 }
981 return all;
982 }
983
984
985 Node*
986 fakethis(void)
987 {
988 Node *n;
989
990 n = nod(ODCLFIELD, N, typenod(ptrto(typ(TSTRUCT))));
991 return n;
992 }
993
994 /*
995 * Is this field a method on an interface?
996 * Those methods have an anonymous
997 * *struct{} as the receiver.
998 * (See fakethis above.)
999 */
1000 int
1001 isifacemethod(Type *f)
1002 {
1003 Type *rcvr;
1004 Type *t;
1005
1006 rcvr = getthisx(f)->type;
1007 if(rcvr->sym != S)
1008 return 0;
1009 t = rcvr->type;
1010 if(!isptr[t->etype])
1011 return 0;
1012 t = t->type;
1013 if(t->sym != S || t->etype != TSTRUCT || t->type != T)
1014 return 0;
1015 return 1;
1016 }
1017
1018 /*
1019 * turn a parsed function declaration
1020 * into a type
1021 */
1022 Type*
1023 functype(Node *this, NodeList *in, NodeList *out)
1024 {
1025 Type *t;
1026 NodeList *rcvr;
1027
1028 t = typ(TFUNC);
1029
1030 rcvr = nil;
1031 if(this)
1032 rcvr = list1(this);
1033 t->type = dostruct(rcvr, TFUNC);
1034 t->type->down = dostruct(out, TFUNC);
1035 t->type->down->down = dostruct(in, TFUNC);
1036
1037 if(this)
1038 t->thistuple = 1;
1039 t->outtuple = count(out);
1040 t->intuple = count(in);
1041 t->outnamed = t->outtuple > 0 && out->n->left != N;
1042
1043 return t;
1044 }
1045
1046 Sym*
1047 methodsym(Sym *nsym, Type *t0, int iface)
1048 {
1049 Sym *s;
1050 char *p;
1051 Type *t;
1052 char *suffix;
1053
1054 t = t0;
1055 if(t == T)
1056 goto bad;
1057 s = t->sym;
1058 if(s == S) {
1059 if(!isptr[t->etype])
1060 goto bad;
1061 t = t->type;
1062 if(t == T)
1063 goto bad;
1064 s = t->sym;
1065 if(s == S)
1066 goto bad;
1067 }
1068
1069 // if t0 == *t and t0 has a sym,
1070 // we want to see *t, not t0, in the method name.
1071 if(t != t0 && t0->sym)
1072 t0 = ptrto(t);
1073
1074 suffix = "";
1075 if(iface) {
1076 dowidth(t0);
1077 if(t0->width < types[tptr]->width)
1078 suffix = "·i";
1079 }
1080 if(t0->sym == S && isptr[t0->etype])
1081 p = smprint("(%#hT).%s%s", t0, nsym->name, suffix);
1082 else
1083 p = smprint("%#hT.%s%s", t0, nsym->name, suffix);
1084 s = pkglookup(p, s->pkg);
1085 free(p);
1086 return s;
1087
1088 bad:
1089 yyerror("illegal receiver type: %T", t0);
1090 return S;
1091 }
1092
1093 Node*
1094 methodname(Node *n, Type *t)
1095 {
1096 Sym *s;
1097
1098 s = methodsym(n->sym, t, 0);
1099 if(s == S)
1100 return n;
1101 return newname(s);
1102 }
1103
1104 Node*
1105 methodname1(Node *n, Node *t)
1106 {
1107 char *star;
1108 char *p;
1109
1110 star = nil;
1111 if(t->op == OIND) {
1112 star = "*";
1113 t = t->left;
1114 }
1115 if(t->sym == S || isblank(n))
1116 return newname(n->sym);
1117 if(star)
1118 p = smprint("(%s%S).%S", star, t->sym, n->sym);
1119 else
1120 p = smprint("%S.%S", t->sym, n->sym);
1121 n = newname(pkglookup(p, t->sym->pkg));
1122 free(p);
1123 return n;
1124 }
1125
1126 /*
1127 * add a method, declared as a function,
1128 * n is fieldname, pa is base type, t is function type
1129 */
1130 void
1131 addmethod(Sym *sf, Type *t, int local)
1132 {
1133 Type *f, *d, *pa;
1134 Node *n;
1135
1136 pa = nil;
1137
1138 // get field sym
1139 if(sf == S)
1140 fatal("no method symbol");
1141
1142 // get parent type sym
1143 pa = getthisx(t)->type; // ptr to this structure
1144 if(pa == T) {
1145 yyerror("missing receiver");
1146 return;
1147 }
1148
1149 pa = pa->type;
1150 f = methtype(pa);
1151 if(f == T) {
1152 t = pa;
1153 if(t != T) {
1154 if(isptr[t->etype]) {
1155 if(t->sym != S) {
1156 yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
1157 return;
1158 }
1159 t = t->type;
1160 }
1161 }
1162 if(t != T) {
1163 if(t->sym == S) {
1164 yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t);
1165 return;
1166 }
1167 if(isptr[t->etype]) {
1168 yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
1169 return;
1170 }
1171 if(t->etype == TINTER) {
1172 yyerror("invalid receiver type %T (%T is an interface type)", pa, t);
1173 return;
1174 }
1175 }
1176 // Should have picked off all the reasons above,
1177 // but just in case, fall back to generic error.
1178 yyerror("invalid receiver type %T", pa);
1179 return;
1180 }
1181
1182 pa = f;
1183 if(importpkg && !exportname(sf->name))
1184 sf = pkglookup(sf->name, importpkg);
1185
1186 n = nod(ODCLFIELD, newname(sf), N);
1187 n->type = t;
1188
1189 d = T; // last found
1190 for(f=pa->method; f!=T; f=f->down) {
1191 d = f;
1192 if(f->etype != TFIELD)
1193 fatal("addmethod: not TFIELD: %N", f);
1194 if(strcmp(sf->name, f->sym->name) != 0)
1195 continue;
1196 if(!eqtype(t, f->type))
1197 yyerror("method redeclared: %T.%S\n\t%T\n\t%T", pa, sf, f->type, t);
1198 return;
1199 }
1200
1201 if(local && !pa->local) {
1202 // defining method on non-local type.
1203 yyerror("cannot define new methods on non-local type %T", pa);
1204 return;
1205 }
1206
1207 if(d == T)
1208 stotype(list1(n), 0, &pa->method, 0);
1209 else
1210 stotype(list1(n), 0, &d->down, 0);
1211 return;
1212 }
1213
1214 void
1215 funccompile(Node *n, int isclosure)
1216 {
1217 stksize = BADWIDTH;
1218 maxarg = 0;
1219
1220 if(n->type == T) {
1221 if(nerrors == 0)
1222 fatal("funccompile missing type");
1223 return;
1224 }
1225
1226 // assign parameter offsets
1227 checkwidth(n->type);
1228
1229 // record offset to actual frame pointer.
1230 // for closure, have to skip over leading pointers and PC slot.
1231 nodfp->xoffset = 0;
1232 if(isclosure) {
1233 NodeList *l;
1234 for(l=n->nname->ntype->list; l; l=l->next) {
1235 nodfp->xoffset += widthptr;
1236 if(l->n->left == N) // found slot for PC
1237 break;
1238 }
1239 }
1240
1241 if(curfn)
1242 fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);
1243
1244 stksize = 0;
1245 dclcontext = PAUTO;
1246 funcdepth = n->funcdepth + 1;
1247 compile(n);
1248 curfn = nil;
1249 funcdepth = 0;
1250 dclcontext = PEXTERN;
1251 }
1252
1253
1254