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
5package gc
6
7import (
8	"cmd/compile/internal/types"
9	"cmd/internal/src"
10	"fmt"
11	"strings"
12)
13
14// Declaration stack & operations
15
16var externdcl []*Node
17
18func testdclstack() {
19	if !types.IsDclstackValid() {
20		if nerrors != 0 {
21			errorexit()
22		}
23		Fatalf("mark left on the dclstack")
24	}
25}
26
27// redeclare emits a diagnostic about symbol s being redeclared somewhere.
28func redeclare(s *types.Sym, where string) {
29	if !s.Lastlineno.IsKnown() {
30		var tmp string
31		if s.Origpkg != nil {
32			tmp = s.Origpkg.Path
33		} else {
34			tmp = s.Pkg.Path
35		}
36		pkgstr := tmp
37		yyerror("%v redeclared %s\n"+
38			"\tprevious declaration during import %q", s, where, pkgstr)
39	} else {
40		line1 := lineno
41		line2 := s.Lastlineno
42
43		// When an import and a declaration collide in separate files,
44		// present the import as the "redeclared", because the declaration
45		// is visible where the import is, but not vice versa.
46		// See issue 4510.
47		if s.Def == nil {
48			line2 = line1
49			line1 = s.Lastlineno
50		}
51
52		yyerrorl(line1, "%v redeclared %s\n"+
53			"\tprevious declaration at %v", s, where, linestr(line2))
54	}
55}
56
57var vargen int
58
59// declare individual names - var, typ, const
60
61var declare_typegen int
62
63// declare records that Node n declares symbol n.Sym in the specified
64// declaration context.
65func declare(n *Node, ctxt Class) {
66	if ctxt == PDISCARD {
67		return
68	}
69
70	if isblank(n) {
71		return
72	}
73
74	if n.Name == nil {
75		// named OLITERAL needs Name; most OLITERALs don't.
76		n.Name = new(Name)
77	}
78	n.Pos = lineno
79	s := n.Sym
80
81	// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
82	if !inimport && !typecheckok && s.Pkg != localpkg {
83		yyerror("cannot declare name %v", s)
84	}
85
86	if ctxt == PEXTERN && s.Name == "init" {
87		yyerror("cannot declare init - must be func")
88	}
89
90	gen := 0
91	if ctxt == PEXTERN {
92		externdcl = append(externdcl, n)
93	} else {
94		if Curfn == nil && ctxt == PAUTO {
95			Fatalf("automatic outside function")
96		}
97		if Curfn != nil {
98			Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
99		}
100		if n.Op == OTYPE {
101			declare_typegen++
102			gen = declare_typegen
103		} else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
104			vargen++
105			gen = vargen
106		}
107		types.Pushdcl(s)
108		n.Name.Curfn = Curfn
109	}
110
111	if ctxt == PAUTO {
112		n.Xoffset = 0
113	}
114
115	if s.Block == types.Block {
116		// functype will print errors about duplicate function arguments.
117		// Don't repeat the error here.
118		if ctxt != PPARAM && ctxt != PPARAMOUT {
119			redeclare(s, "in this block")
120		}
121	}
122
123	s.Block = types.Block
124	s.Lastlineno = lineno
125	s.Def = asTypesNode(n)
126	n.Name.Vargen = int32(gen)
127	n.Name.Funcdepth = funcdepth
128	n.SetClass(ctxt)
129
130	autoexport(n, ctxt)
131}
132
133func addvar(n *Node, t *types.Type, ctxt Class) {
134	if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
135		Fatalf("addvar: n=%v t=%v nil", n, t)
136	}
137
138	n.Op = ONAME
139	declare(n, ctxt)
140	n.Type = t
141}
142
143// declare variables from grammar
144// new_name_list (type | [type] = expr_list)
145func variter(vl []*Node, t *Node, el []*Node) []*Node {
146	var init []*Node
147	doexpr := len(el) > 0
148
149	if len(el) == 1 && len(vl) > 1 {
150		e := el[0]
151		as2 := nod(OAS2, nil, nil)
152		as2.List.Set(vl)
153		as2.Rlist.Set1(e)
154		for _, v := range vl {
155			v.Op = ONAME
156			declare(v, dclcontext)
157			v.Name.Param.Ntype = t
158			v.Name.Defn = as2
159			if funcdepth > 0 {
160				init = append(init, nod(ODCL, v, nil))
161			}
162		}
163
164		return append(init, as2)
165	}
166
167	for _, v := range vl {
168		var e *Node
169		if doexpr {
170			if len(el) == 0 {
171				yyerror("missing expression in var declaration")
172				break
173			}
174			e = el[0]
175			el = el[1:]
176		}
177
178		v.Op = ONAME
179		declare(v, dclcontext)
180		v.Name.Param.Ntype = t
181
182		if e != nil || funcdepth > 0 || isblank(v) {
183			if funcdepth > 0 {
184				init = append(init, nod(ODCL, v, nil))
185			}
186			e = nod(OAS, v, e)
187			init = append(init, e)
188			if e.Right != nil {
189				v.Name.Defn = e
190			}
191		}
192	}
193
194	if len(el) != 0 {
195		yyerror("extra expression in var declaration")
196	}
197	return init
198}
199
200// newnoname returns a new ONONAME Node associated with symbol s.
201func newnoname(s *types.Sym) *Node {
202	if s == nil {
203		Fatalf("newnoname nil")
204	}
205	n := nod(ONONAME, nil, nil)
206	n.Sym = s
207	n.SetAddable(true)
208	n.Xoffset = 0
209	return n
210}
211
212// newfuncname generates a new name node for a function or method.
213// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
214func newfuncname(s *types.Sym) *Node {
215	n := newname(s)
216	n.Func = new(Func)
217	n.Func.SetIsHiddenClosure(Curfn != nil)
218	return n
219}
220
221// this generates a new name node for a name
222// being declared.
223func dclname(s *types.Sym) *Node {
224	n := newname(s)
225	n.Op = ONONAME // caller will correct it
226	return n
227}
228
229func typenod(t *types.Type) *Node {
230	// if we copied another type with *t = *u
231	// then t->nod might be out of date, so
232	// check t->nod->type too
233	if asNode(t.Nod) == nil || asNode(t.Nod).Type != t {
234		t.Nod = asTypesNode(nod(OTYPE, nil, nil))
235		asNode(t.Nod).Type = t
236		asNode(t.Nod).Sym = t.Sym
237	}
238
239	return asNode(t.Nod)
240}
241
242func anonfield(typ *types.Type) *Node {
243	return nod(ODCLFIELD, nil, typenod(typ))
244}
245
246func namedfield(s string, typ *types.Type) *Node {
247	return nod(ODCLFIELD, newname(lookup(s)), typenod(typ))
248}
249
250// oldname returns the Node that declares symbol s in the current scope.
251// If no such Node currently exists, an ONONAME Node is returned instead.
252func oldname(s *types.Sym) *Node {
253	n := asNode(s.Def)
254	if n == nil {
255		// Maybe a top-level declaration will come along later to
256		// define s. resolve will check s.Def again once all input
257		// source has been processed.
258		return newnoname(s)
259	}
260
261	if Curfn != nil && n.Op == ONAME && n.Name.Funcdepth > 0 && n.Name.Funcdepth != funcdepth {
262		// Inner func is referring to var in outer func.
263		//
264		// TODO(rsc): If there is an outer variable x and we
265		// are parsing x := 5 inside the closure, until we get to
266		// the := it looks like a reference to the outer x so we'll
267		// make x a closure variable unnecessarily.
268		c := n.Name.Param.Innermost
269		if c == nil || c.Name.Funcdepth != funcdepth {
270			// Do not have a closure var for the active closure yet; make one.
271			c = newname(s)
272			c.SetClass(PAUTOHEAP)
273			c.SetIsClosureVar(true)
274			c.SetIsddd(n.Isddd())
275			c.Name.Defn = n
276			c.SetAddable(false)
277			c.Name.Funcdepth = funcdepth
278
279			// Link into list of active closure variables.
280			// Popped from list in func closurebody.
281			c.Name.Param.Outer = n.Name.Param.Innermost
282			n.Name.Param.Innermost = c
283
284			Curfn.Func.Cvars.Append(c)
285		}
286
287		// return ref to closure var, not original
288		return c
289	}
290
291	return n
292}
293
294// := declarations
295func colasname(n *Node) bool {
296	switch n.Op {
297	case ONAME,
298		ONONAME,
299		OPACK,
300		OTYPE,
301		OLITERAL:
302		return n.Sym != nil
303	}
304
305	return false
306}
307
308func colasdefn(left []*Node, defn *Node) {
309	for _, n := range left {
310		if n.Sym != nil {
311			n.Sym.SetUniq(true)
312		}
313	}
314
315	var nnew, nerr int
316	for i, n := range left {
317		if isblank(n) {
318			continue
319		}
320		if !colasname(n) {
321			yyerrorl(defn.Pos, "non-name %v on left side of :=", n)
322			nerr++
323			continue
324		}
325
326		if !n.Sym.Uniq() {
327			yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
328			n.SetDiag(true)
329			nerr++
330			continue
331		}
332
333		n.Sym.SetUniq(false)
334		if n.Sym.Block == types.Block {
335			continue
336		}
337
338		nnew++
339		n = newname(n.Sym)
340		declare(n, dclcontext)
341		n.Name.Defn = defn
342		defn.Ninit.Append(nod(ODCL, n, nil))
343		left[i] = n
344	}
345
346	if nnew == 0 && nerr == 0 {
347		yyerrorl(defn.Pos, "no new variables on left side of :=")
348	}
349}
350
351// declare the arguments in an
352// interface field declaration.
353func ifacedcl(n *Node) {
354	if n.Op != ODCLFIELD || n.Right == nil {
355		Fatalf("ifacedcl")
356	}
357
358	if isblank(n.Left) {
359		yyerror("methods must have a unique non-blank name")
360	}
361}
362
363// declare the function proper
364// and declare the arguments.
365// called in extern-declaration context
366// returns in auto-declaration context.
367func funchdr(n *Node) {
368	// change the declaration context from extern to auto
369	if funcdepth == 0 && dclcontext != PEXTERN {
370		Fatalf("funchdr: dclcontext = %d", dclcontext)
371	}
372
373	dclcontext = PAUTO
374	funcstart(n)
375
376	if n.Func.Nname != nil {
377		funcargs(n.Func.Nname.Name.Param.Ntype)
378	} else if n.Func.Ntype != nil {
379		funcargs(n.Func.Ntype)
380	} else {
381		funcargs2(n.Type)
382	}
383}
384
385func funcargs(nt *Node) {
386	if nt.Op != OTFUNC {
387		Fatalf("funcargs %v", nt.Op)
388	}
389
390	// re-start the variable generation number
391	// we want to use small numbers for the return variables,
392	// so let them have the chunk starting at 1.
393	vargen = nt.Rlist.Len()
394
395	// declare the receiver and in arguments.
396	// no n->defn because type checking of func header
397	// will not fill in the types until later
398	if nt.Left != nil {
399		n := nt.Left
400		if n.Op != ODCLFIELD {
401			Fatalf("funcargs receiver %v", n.Op)
402		}
403		if n.Left != nil {
404			n.Left.Op = ONAME
405			n.Left.Name.Param.Ntype = n.Right
406			declare(n.Left, PPARAM)
407			if dclcontext == PAUTO {
408				vargen++
409				n.Left.Name.Vargen = int32(vargen)
410			}
411		}
412	}
413
414	for _, n := range nt.List.Slice() {
415		if n.Op != ODCLFIELD {
416			Fatalf("funcargs in %v", n.Op)
417		}
418		if n.Left != nil {
419			n.Left.Op = ONAME
420			n.Left.Name.Param.Ntype = n.Right
421			declare(n.Left, PPARAM)
422			if dclcontext == PAUTO {
423				vargen++
424				n.Left.Name.Vargen = int32(vargen)
425			}
426		}
427	}
428
429	// declare the out arguments.
430	gen := nt.List.Len()
431	var i int = 0
432	for _, n := range nt.Rlist.Slice() {
433		if n.Op != ODCLFIELD {
434			Fatalf("funcargs out %v", n.Op)
435		}
436
437		if n.Left == nil {
438			// Name so that escape analysis can track it. ~r stands for 'result'.
439			n.Left = newname(lookupN("~r", gen))
440			gen++
441		}
442
443		// TODO: n->left->missing = 1;
444		n.Left.Op = ONAME
445
446		if isblank(n.Left) {
447			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
448			// The name must be different from ~r above because if you have
449			//	func f() (_ int)
450			//	func g() int
451			// f is allowed to use a plain 'return' with no arguments, while g is not.
452			// So the two cases must be distinguished.
453			// We do not record a pointer to the original node (n->orig).
454			// Having multiple names causes too much confusion in later passes.
455			nn := *n.Left
456			nn.Orig = &nn
457			nn.Sym = lookupN("~b", gen)
458			gen++
459			n.Left = &nn
460		}
461
462		n.Left.Name.Param.Ntype = n.Right
463		declare(n.Left, PPARAMOUT)
464		if dclcontext == PAUTO {
465			i++
466			n.Left.Name.Vargen = int32(i)
467		}
468	}
469}
470
471// Same as funcargs, except run over an already constructed TFUNC.
472// This happens during import, where the hidden_fndcl rule has
473// used functype directly to parse the function's type.
474func funcargs2(t *types.Type) {
475	if t.Etype != TFUNC {
476		Fatalf("funcargs2 %v", t)
477	}
478
479	for _, ft := range t.Recvs().Fields().Slice() {
480		if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil {
481			continue
482		}
483		n := asNode(ft.Nname) // no need for newname(ft->nname->sym)
484		n.Type = ft.Type
485		declare(n, PPARAM)
486	}
487
488	for _, ft := range t.Params().Fields().Slice() {
489		if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil {
490			continue
491		}
492		n := asNode(ft.Nname)
493		n.Type = ft.Type
494		declare(n, PPARAM)
495	}
496
497	for _, ft := range t.Results().Fields().Slice() {
498		if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil {
499			continue
500		}
501		n := asNode(ft.Nname)
502		n.Type = ft.Type
503		declare(n, PPARAMOUT)
504	}
505}
506
507var funcstack []*Node // stack of previous values of Curfn
508var funcdepth int32   // len(funcstack) during parsing, but then forced to be the same later during compilation
509
510// start the function.
511// called before funcargs; undone at end of funcbody.
512func funcstart(n *Node) {
513	types.Markdcl()
514	funcstack = append(funcstack, Curfn)
515	funcdepth++
516	Curfn = n
517}
518
519// finish the body.
520// called in auto-declaration context.
521// returns in extern-declaration context.
522func funcbody(n *Node) {
523	// change the declaration context from auto to extern
524	if dclcontext != PAUTO {
525		Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
526	}
527	types.Popdcl()
528	funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
529	funcdepth--
530	if funcdepth == 0 {
531		dclcontext = PEXTERN
532	}
533}
534
535// structs, functions, and methods.
536// they don't belong here, but where do they belong?
537func checkembeddedtype(t *types.Type) {
538	if t == nil {
539		return
540	}
541
542	if t.Sym == nil && t.IsPtr() {
543		t = t.Elem()
544		if t.IsInterface() {
545			yyerror("embedded type cannot be a pointer to interface")
546		}
547	}
548
549	if t.IsPtr() || t.IsUnsafePtr() {
550		yyerror("embedded type cannot be a pointer")
551	} else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
552		t.ForwardType().Embedlineno = lineno
553	}
554}
555
556func structfield(n *Node) *types.Field {
557	lno := lineno
558	lineno = n.Pos
559
560	if n.Op != ODCLFIELD {
561		Fatalf("structfield: oops %v\n", n)
562	}
563
564	f := types.NewField()
565	f.SetIsddd(n.Isddd())
566
567	if n.Right != nil {
568		n.Right = typecheck(n.Right, Etype)
569		n.Type = n.Right.Type
570		if n.Left != nil {
571			n.Left.Type = n.Type
572		}
573		if n.Embedded() {
574			checkembeddedtype(n.Type)
575		}
576	}
577
578	n.Right = nil
579
580	f.Type = n.Type
581	if f.Type == nil {
582		f.SetBroke(true)
583	}
584
585	switch u := n.Val().U.(type) {
586	case string:
587		f.Note = u
588	default:
589		yyerror("field tag must be a string")
590	case nil:
591		// no-op
592	}
593
594	if n.Left != nil && n.Left.Op == ONAME {
595		f.Nname = asTypesNode(n.Left)
596		if n.Embedded() {
597			f.Embedded = 1
598		} else {
599			f.Embedded = 0
600		}
601		f.Sym = asNode(f.Nname).Sym
602	}
603
604	lineno = lno
605	return f
606}
607
608// checkdupfields emits errors for duplicately named fields or methods in
609// a list of struct or interface types.
610func checkdupfields(what string, ts ...*types.Type) {
611	seen := make(map[*types.Sym]bool)
612	for _, t := range ts {
613		for _, f := range t.Fields().Slice() {
614			if f.Sym == nil || f.Sym.IsBlank() || asNode(f.Nname) == nil {
615				continue
616			}
617			if seen[f.Sym] {
618				yyerrorl(asNode(f.Nname).Pos, "duplicate %s %s", what, f.Sym.Name)
619				continue
620			}
621			seen[f.Sym] = true
622		}
623	}
624}
625
626// convert a parsed id/type list into
627// a type for struct/interface/arglist
628func tostruct(l []*Node) *types.Type {
629	t := types.New(TSTRUCT)
630	tostruct0(t, l)
631	return t
632}
633
634func tostruct0(t *types.Type, l []*Node) {
635	if t == nil || !t.IsStruct() {
636		Fatalf("struct expected")
637	}
638
639	fields := make([]*types.Field, len(l))
640	for i, n := range l {
641		f := structfield(n)
642		if f.Broke() {
643			t.SetBroke(true)
644		}
645		fields[i] = f
646	}
647	t.SetFields(fields)
648
649	checkdupfields("field", t)
650
651	if !t.Broke() {
652		checkwidth(t)
653	}
654}
655
656func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
657	t := types.New(TSTRUCT)
658	t.StructType().Funarg = funarg
659
660	fields := make([]*types.Field, len(l))
661	for i, n := range l {
662		f := structfield(n)
663		f.Funarg = funarg
664
665		// esc.go needs to find f given a PPARAM to add the tag.
666		if n.Left != nil && n.Left.Class() == PPARAM {
667			n.Left.Name.Param.Field = f
668		}
669		if f.Broke() {
670			t.SetBroke(true)
671		}
672		fields[i] = f
673	}
674	t.SetFields(fields)
675	return t
676}
677
678func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
679	t := types.New(TSTRUCT)
680	t.StructType().Funarg = funarg
681
682	for _, f := range fields {
683		f.Funarg = funarg
684
685		// esc.go needs to find f given a PPARAM to add the tag.
686		if asNode(f.Nname) != nil && asNode(f.Nname).Class() == PPARAM {
687			asNode(f.Nname).Name.Param.Field = f
688		}
689	}
690	t.SetFields(fields)
691	return t
692}
693
694func interfacefield(n *Node) *types.Field {
695	lno := lineno
696	lineno = n.Pos
697
698	if n.Op != ODCLFIELD {
699		Fatalf("interfacefield: oops %v\n", n)
700	}
701
702	if n.Val().Ctype() != CTxxx {
703		yyerror("interface method cannot have annotation")
704	}
705
706	// MethodSpec = MethodName Signature | InterfaceTypeName .
707	//
708	// If Left != nil, then Left is MethodName and Right is Signature.
709	// Otherwise, Right is InterfaceTypeName.
710
711	if n.Right != nil {
712		n.Right = typecheck(n.Right, Etype)
713		n.Type = n.Right.Type
714		n.Right = nil
715	}
716
717	f := types.NewField()
718	if n.Left != nil {
719		f.Nname = asTypesNode(n.Left)
720		f.Sym = asNode(f.Nname).Sym
721	} else {
722		// Placeholder ONAME just to hold Pos.
723		// TODO(mdempsky): Add Pos directly to Field instead.
724		f.Nname = asTypesNode(newname(nblank.Sym))
725	}
726
727	f.Type = n.Type
728	if f.Type == nil {
729		f.SetBroke(true)
730	}
731
732	lineno = lno
733	return f
734}
735
736func tointerface(l []*Node) *types.Type {
737	if len(l) == 0 {
738		return types.Types[TINTER]
739	}
740	t := types.New(TINTER)
741	tointerface0(t, l)
742	return t
743}
744
745func tointerface0(t *types.Type, l []*Node) *types.Type {
746	if t == nil || !t.IsInterface() {
747		Fatalf("interface expected")
748	}
749
750	var fields []*types.Field
751	for _, n := range l {
752		f := interfacefield(n)
753		if f.Broke() {
754			t.SetBroke(true)
755		}
756		fields = append(fields, f)
757	}
758	t.SetInterface(fields)
759
760	return t
761}
762
763func embedded(s *types.Sym, pkg *types.Pkg) *Node {
764	const (
765		CenterDot = 0xB7
766	)
767	// Names sometimes have disambiguation junk
768	// appended after a center dot. Discard it when
769	// making the name for the embedded struct field.
770	name := s.Name
771
772	if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
773		name = s.Name[:i]
774	}
775
776	var n *Node
777	if exportname(name) {
778		n = newname(lookup(name))
779	} else if s.Pkg == builtinpkg {
780		// The name of embedded builtins belongs to pkg.
781		n = newname(pkg.Lookup(name))
782	} else {
783		n = newname(s.Pkg.Lookup(name))
784	}
785	n = nod(ODCLFIELD, n, oldname(s))
786	n.SetEmbedded(true)
787	return n
788}
789
790func fakeRecv() *Node {
791	return anonfield(types.FakeRecvType())
792}
793
794func fakeRecvField() *types.Field {
795	f := types.NewField()
796	f.Type = types.FakeRecvType()
797	return f
798}
799
800// isifacemethod reports whether (field) m is
801// an interface method. Such methods have the
802// special receiver type types.FakeRecvType().
803func isifacemethod(f *types.Type) bool {
804	return f.Recv().Type == types.FakeRecvType()
805}
806
807// turn a parsed function declaration into a type
808func functype(this *Node, in, out []*Node) *types.Type {
809	t := types.New(TFUNC)
810	functype0(t, this, in, out)
811	return t
812}
813
814func functype0(t *types.Type, this *Node, in, out []*Node) {
815	if t == nil || t.Etype != TFUNC {
816		Fatalf("function type expected")
817	}
818
819	var rcvr []*Node
820	if this != nil {
821		rcvr = []*Node{this}
822	}
823	t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
824	t.FuncType().Results = tofunargs(out, types.FunargResults)
825	t.FuncType().Params = tofunargs(in, types.FunargParams)
826
827	checkdupfields("argument", t.Recvs(), t.Results(), t.Params())
828
829	if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() {
830		t.SetBroke(true)
831	}
832
833	t.FuncType().Outnamed = false
834	if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
835		s := out[0].Left.Orig.Sym
836		if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
837			t.FuncType().Outnamed = true
838		}
839	}
840}
841
842func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
843	t := types.New(TFUNC)
844	functypefield0(t, this, in, out)
845	return t
846}
847
848func functypefield0(t *types.Type, this *types.Field, in, out []*types.Field) {
849	var rcvr []*types.Field
850	if this != nil {
851		rcvr = []*types.Field{this}
852	}
853	t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr)
854	t.FuncType().Results = tofunargsfield(out, types.FunargRcvr)
855	t.FuncType().Params = tofunargsfield(in, types.FunargRcvr)
856
857	t.FuncType().Outnamed = false
858	if len(out) > 0 && asNode(out[0].Nname) != nil && asNode(out[0].Nname).Orig != nil {
859		s := asNode(out[0].Nname).Orig.Sym
860		if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
861			t.FuncType().Outnamed = true
862		}
863	}
864}
865
866var methodsym_toppkg *types.Pkg
867
868func methodsym(nsym *types.Sym, t0 *types.Type, iface bool) *types.Sym {
869	if t0 == nil {
870		Fatalf("methodsym: nil receiver type")
871	}
872
873	t := t0
874	s := t.Sym
875	if s == nil && t.IsPtr() {
876		t = t.Elem()
877		if t == nil {
878			Fatalf("methodsym: ptrto nil")
879		}
880		s = t.Sym
881	}
882
883	// if t0 == *t and t0 has a sym,
884	// we want to see *t, not t0, in the method name.
885	if t != t0 && t0.Sym != nil {
886		t0 = types.NewPtr(t)
887	}
888
889	suffix := ""
890	if iface {
891		dowidth(t0)
892		if t0.Width < int64(Widthptr) {
893			suffix = "·i"
894		}
895	}
896
897	var spkg *types.Pkg
898	if s != nil {
899		spkg = s.Pkg
900	}
901	pkgprefix := ""
902	if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) && nsym.Pkg.Prefix != `""` {
903		pkgprefix = "." + nsym.Pkg.Prefix
904	}
905	var p string
906	if t0.Sym == nil && t0.IsPtr() {
907		p = fmt.Sprintf("(%-S)%s.%s%s", t0, pkgprefix, nsym.Name, suffix)
908	} else {
909		p = fmt.Sprintf("%-S%s.%s%s", t0, pkgprefix, nsym.Name, suffix)
910	}
911
912	if spkg == nil {
913		if methodsym_toppkg == nil {
914			methodsym_toppkg = types.NewPkg("go", "")
915		}
916		spkg = methodsym_toppkg
917	}
918
919	return spkg.Lookup(p)
920}
921
922// methodname is a misnomer because this now returns a Sym, rather
923// than an ONAME.
924// TODO(mdempsky): Reconcile with methodsym.
925func methodname(s *types.Sym, recv *types.Type) *types.Sym {
926	star := false
927	if recv.IsPtr() {
928		star = true
929		recv = recv.Elem()
930	}
931
932	tsym := recv.Sym
933	if tsym == nil || s.IsBlank() {
934		return s
935	}
936
937	var p string
938	if star {
939		p = fmt.Sprintf("(*%v).%v", tsym.Name, s)
940	} else {
941		p = fmt.Sprintf("%v.%v", tsym, s)
942	}
943
944	s = tsym.Pkg.Lookup(p)
945
946	return s
947}
948
949// Add a method, declared as a function.
950// - msym is the method symbol
951// - t is function type (with receiver)
952func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) {
953	if msym == nil {
954		Fatalf("no method symbol")
955	}
956
957	// get parent type sym
958	rf := t.Recv() // ptr to this structure
959	if rf == nil {
960		yyerror("missing receiver")
961		return
962	}
963
964	mt := methtype(rf.Type)
965	if mt == nil || mt.Sym == nil {
966		pa := rf.Type
967		t := pa
968		if t != nil && t.IsPtr() {
969			if t.Sym != nil {
970				yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
971				return
972			}
973			t = t.Elem()
974		}
975
976		switch {
977		case t == nil || t.Broke():
978			// rely on typecheck having complained before
979		case t.Sym == nil:
980			yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
981		case t.IsPtr():
982			yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
983		case t.IsInterface():
984			yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
985		default:
986			// Should have picked off all the reasons above,
987			// but just in case, fall back to generic error.
988			yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
989		}
990		return
991	}
992
993	if local && !mt.Local() {
994		yyerror("cannot define new methods on non-local type %v", mt)
995		return
996	}
997
998	if msym.IsBlank() {
999		return
1000	}
1001
1002	if mt.IsStruct() {
1003		for _, f := range mt.Fields().Slice() {
1004			if f.Sym == msym {
1005				yyerror("type %v has both field and method named %v", mt, msym)
1006				return
1007			}
1008		}
1009	}
1010
1011	for _, f := range mt.Methods().Slice() {
1012		if msym.Name != f.Sym.Name {
1013			continue
1014		}
1015		// eqtype only checks that incoming and result parameters match,
1016		// so explicitly check that the receiver parameters match too.
1017		if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
1018			yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
1019		}
1020		return
1021	}
1022
1023	f := types.NewField()
1024	f.Sym = msym
1025	f.Nname = asTypesNode(newname(msym))
1026	f.Type = t
1027	f.SetNointerface(nointerface)
1028
1029	mt.Methods().Append(f)
1030}
1031
1032func funccompile(n *Node) {
1033	if n.Type == nil {
1034		if nerrors == 0 {
1035			Fatalf("funccompile missing type")
1036		}
1037		return
1038	}
1039
1040	// assign parameter offsets
1041	checkwidth(n.Type)
1042
1043	if Curfn != nil {
1044		Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym)
1045	}
1046
1047	dclcontext = PAUTO
1048	funcdepth = n.Func.Depth + 1
1049	compile(n)
1050	Curfn = nil
1051	funcdepth = 0
1052	dclcontext = PEXTERN
1053}
1054
1055func funcsymname(s *types.Sym) string {
1056	return s.Name + "·f"
1057}
1058
1059// funcsym returns s·f.
1060func funcsym(s *types.Sym) *types.Sym {
1061	// funcsymsmu here serves to protect not just mutations of funcsyms (below),
1062	// but also the package lookup of the func sym name,
1063	// since this function gets called concurrently from the backend.
1064	// There are no other concurrent package lookups in the backend,
1065	// except for the types package, which is protected separately.
1066	// Reusing funcsymsmu to also cover this package lookup
1067	// avoids a general, broader, expensive package lookup mutex.
1068	// Note makefuncsym also does package look-up of func sym names,
1069	// but that it is only called serially, from the front end.
1070	funcsymsmu.Lock()
1071	sf, existed := s.Pkg.LookupOK(funcsymname(s))
1072	// Don't export s·f when compiling for dynamic linking.
1073	// When dynamically linking, the necessary function
1074	// symbols will be created explicitly with makefuncsym.
1075	// See the makefuncsym comment for details.
1076	if !Ctxt.Flag_dynlink && !existed {
1077		funcsyms = append(funcsyms, s)
1078	}
1079	funcsymsmu.Unlock()
1080	return sf
1081}
1082
1083// makefuncsym ensures that s·f is exported.
1084// It is only used with -dynlink.
1085// When not compiling for dynamic linking,
1086// the funcsyms are created as needed by
1087// the packages that use them.
1088// Normally we emit the s·f stubs as DUPOK syms,
1089// but DUPOK doesn't work across shared library boundaries.
1090// So instead, when dynamic linking, we only create
1091// the s·f stubs in s's package.
1092func makefuncsym(s *types.Sym) {
1093	if !Ctxt.Flag_dynlink {
1094		Fatalf("makefuncsym dynlink")
1095	}
1096	if s.IsBlank() {
1097		return
1098	}
1099	if compiling_runtime && s.Name == "getg" {
1100		// runtime.getg() is not a real function and so does
1101		// not get a funcsym.
1102		return
1103	}
1104	if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {
1105		funcsyms = append(funcsyms, s)
1106	}
1107}
1108
1109func dclfunc(sym *types.Sym, tfn *Node) *Node {
1110	if tfn.Op != OTFUNC {
1111		Fatalf("expected OTFUNC node, got %v", tfn)
1112	}
1113
1114	fn := nod(ODCLFUNC, nil, nil)
1115	fn.Func.Nname = newname(sym)
1116	fn.Func.Nname.Name.Defn = fn
1117	fn.Func.Nname.Name.Param.Ntype = tfn
1118	declare(fn.Func.Nname, PFUNC)
1119	funchdr(fn)
1120	fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype)
1121	return fn
1122}
1123
1124type nowritebarrierrecChecker struct {
1125	curfn  *Node
1126	stable bool
1127
1128	// best maps from the ODCLFUNC of each visited function that
1129	// recursively invokes a write barrier to the called function
1130	// on the shortest path to a write barrier.
1131	best map[*Node]nowritebarrierrecCall
1132}
1133
1134type nowritebarrierrecCall struct {
1135	target *Node
1136	depth  int
1137	lineno src.XPos
1138}
1139
1140func checknowritebarrierrec() {
1141	c := nowritebarrierrecChecker{
1142		best: make(map[*Node]nowritebarrierrecCall),
1143	}
1144	visitBottomUp(xtop, func(list []*Node, recursive bool) {
1145		// Functions with write barriers have depth 0.
1146		for _, n := range list {
1147			if n.Func.WBPos.IsKnown() && n.Func.Pragma&Nowritebarrier != 0 {
1148				yyerrorl(n.Func.WBPos, "write barrier prohibited")
1149			}
1150			if n.Func.WBPos.IsKnown() && n.Func.Pragma&Yeswritebarrierrec == 0 {
1151				c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBPos}
1152			}
1153		}
1154
1155		// Propagate write barrier depth up from callees. In
1156		// the recursive case, we have to update this at most
1157		// len(list) times and can stop when we an iteration
1158		// that doesn't change anything.
1159		for _ = range list {
1160			c.stable = false
1161			for _, n := range list {
1162				if n.Func.Pragma&Yeswritebarrierrec != 0 {
1163					// Don't propagate write
1164					// barrier up to a
1165					// yeswritebarrierrec function.
1166					continue
1167				}
1168				if !n.Func.WBPos.IsKnown() {
1169					c.curfn = n
1170					c.visitcodelist(n.Nbody)
1171				}
1172			}
1173			if c.stable {
1174				break
1175			}
1176		}
1177
1178		// Check nowritebarrierrec functions.
1179		for _, n := range list {
1180			if n.Func.Pragma&Nowritebarrierrec == 0 {
1181				continue
1182			}
1183			call, hasWB := c.best[n]
1184			if !hasWB {
1185				continue
1186			}
1187
1188			// Build the error message in reverse.
1189			err := ""
1190			for call.target != nil {
1191				err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err)
1192				n = call.target
1193				call = c.best[n]
1194			}
1195			err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err)
1196			yyerrorl(n.Func.WBPos, err)
1197		}
1198	})
1199}
1200
1201func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) {
1202	for _, n := range l.Slice() {
1203		c.visitcode(n)
1204	}
1205}
1206
1207func (c *nowritebarrierrecChecker) visitcode(n *Node) {
1208	if n == nil {
1209		return
1210	}
1211
1212	if n.Op == OCALLFUNC || n.Op == OCALLMETH {
1213		c.visitcall(n)
1214	}
1215
1216	c.visitcodelist(n.Ninit)
1217	c.visitcode(n.Left)
1218	c.visitcode(n.Right)
1219	c.visitcodelist(n.List)
1220	c.visitcodelist(n.Nbody)
1221	c.visitcodelist(n.Rlist)
1222}
1223
1224func (c *nowritebarrierrecChecker) visitcall(n *Node) {
1225	fn := n.Left
1226	if n.Op == OCALLMETH {
1227		fn = asNode(n.Left.Sym.Def)
1228	}
1229	if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil {
1230		return
1231	}
1232	defn := fn.Name.Defn
1233
1234	fnbest, ok := c.best[defn]
1235	if !ok {
1236		return
1237	}
1238	best, ok := c.best[c.curfn]
1239	if ok && fnbest.depth+1 >= best.depth {
1240		return
1241	}
1242	c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Pos}
1243	c.stable = false
1244}
1245