// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import (
	"cmd/internal/obj"
	"fmt"
	"sort"
	"strings"
)

func dflag() bool {
	if Debug['d'] == 0 {
		return false
	}
	if Debug['y'] != 0 {
		return true
	}
	if incannedimport != 0 {
		return false
	}
	return true
}

// declaration stack & operations
func dcopy(a *Sym, b *Sym) {
	a.Pkg = b.Pkg
	a.Name = b.Name
	a.Def = b.Def
	a.Block = b.Block
	a.Lastlineno = b.Lastlineno
}

func push() *Sym {
	d := new(Sym)
	d.Lastlineno = lineno
	d.Link = dclstack
	dclstack = d
	return d
}

func pushdcl(s *Sym) *Sym {
	d := push()
	dcopy(d, s)
	if dflag() {
		fmt.Printf("\t%v push %v %p\n", linestr(lineno), s, s.Def)
	}
	return d
}

func popdcl() {
	d := dclstack
	for ; d != nil && d.Name != ""; d = d.Link {
		s := Pkglookup(d.Name, d.Pkg)
		lno := s.Lastlineno
		dcopy(s, d)
		d.Lastlineno = lno
		if dflag() {
			fmt.Printf("\t%v pop %v %p\n", linestr(lineno), s, s.Def)
		}
	}

	if d == nil {
		Fatalf("popdcl: no mark")
	}

	dclstack = d.Link // pop mark
	block = d.Block
}

func markdcl() {
	d := push()
	d.Name = "" // used as a mark in fifo
	d.Block = block

	blockgen++
	block = blockgen
}

func dumpdcl(st string) {
	i := 0
	for d := dclstack; d != nil; d = d.Link {
		i++
		fmt.Printf("    %.2d %p", i, d)
		if d.Name == "" {
			fmt.Printf("\n")
			continue
		}

		fmt.Printf(" '%s'", d.Name)
		fmt.Printf(" %v\n", Pkglookup(d.Name, d.Pkg))
	}
}

func testdclstack() {
	for d := dclstack; d != nil; d = d.Link {
		if d.Name == "" {
			if nerrors != 0 {
				errorexit()
			}
			Yyerror("mark left on the stack")
		}
	}
}

func redeclare(s *Sym, where string) {
	if s.Lastlineno == 0 {
		var tmp string
		if s.Origpkg != nil {
			tmp = s.Origpkg.Path
		} else {
			tmp = s.Pkg.Path
		}
		pkgstr := tmp
		Yyerror("%v redeclared %s\n"+"\tprevious declaration during import %q", s, where, pkgstr)
	} else {
		line1 := lineno
		line2 := s.Lastlineno

		// When an import and a declaration collide in separate files,
		// present the import as the "redeclared", because the declaration
		// is visible where the import is, but not vice versa.
		// See issue 4510.
		if s.Def == nil {
			line2 = line1
			line1 = s.Lastlineno
		}

		yyerrorl(line1, "%v redeclared %s\n"+"\tprevious declaration at %v", s, where, linestr(line2))
	}
}

var vargen int

// declare individual names - var, typ, const

var declare_typegen int

func declare(n *Node, ctxt Class) {
	if ctxt == PDISCARD {
		return
	}

	if isblank(n) {
		return
	}

	if n.Name == nil {
		// named OLITERAL needs Name; most OLITERALs don't.
		n.Name = new(Name)
	}
	n.Lineno = lineno
	s := n.Sym

	// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
	if importpkg == nil && !typecheckok && s.Pkg != localpkg {
		Yyerror("cannot declare name %v", s)
	}

	if ctxt == PEXTERN && s.Name == "init" {
		Yyerror("cannot declare init - must be func")
	}

	gen := 0
	if ctxt == PEXTERN {
		externdcl = append(externdcl, n)
		if dflag() {
			fmt.Printf("\t%v global decl %v %p\n", linestr(lineno), s, n)
		}
	} else {
		if Curfn == nil && ctxt == PAUTO {
			Fatalf("automatic outside function")
		}
		if Curfn != nil {
			Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
		}
		if n.Op == OTYPE {
			declare_typegen++
			gen = declare_typegen
		} else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
			vargen++
			gen = vargen
		}
		pushdcl(s)
		n.Name.Curfn = Curfn
	}

	if ctxt == PAUTO {
		n.Xoffset = 0
	}

	if s.Block == block {
		// functype will print errors about duplicate function arguments.
		// Don't repeat the error here.
		if ctxt != PPARAM && ctxt != PPARAMOUT {
			redeclare(s, "in this block")
		}
	}

	s.Block = block
	s.Lastlineno = lineno
	s.Def = n
	n.Name.Vargen = int32(gen)
	n.Name.Funcdepth = Funcdepth
	n.Class = ctxt

	autoexport(n, ctxt)
}

func addvar(n *Node, t *Type, ctxt Class) {
	if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
		Fatalf("addvar: n=%v t=%v nil", n, t)
	}

	n.Op = ONAME
	declare(n, ctxt)
	n.Type = t
}

// declare variables from grammar
// new_name_list (type | [type] = expr_list)
func variter(vl []*Node, t *Node, el []*Node) []*Node {
	var init []*Node
	doexpr := len(el) > 0

	if len(el) == 1 && len(vl) > 1 {
		e := el[0]
		as2 := Nod(OAS2, nil, nil)
		as2.List.Set(vl)
		as2.Rlist.Set1(e)
		for _, v := range vl {
			v.Op = ONAME
			declare(v, dclcontext)
			v.Name.Param.Ntype = t
			v.Name.Defn = as2
			if Funcdepth > 0 {
				init = append(init, Nod(ODCL, v, nil))
			}
		}

		return append(init, as2)
	}

	for _, v := range vl {
		var e *Node
		if doexpr {
			if len(el) == 0 {
				Yyerror("missing expression in var declaration")
				break
			}

			e = el[0]
			el = el[1:]
		} else {
			e = nil
		}

		v.Op = ONAME
		declare(v, dclcontext)
		v.Name.Param.Ntype = t

		if e != nil || Funcdepth > 0 || isblank(v) {
			if Funcdepth > 0 {
				init = append(init, Nod(ODCL, v, nil))
			}
			e = Nod(OAS, v, e)
			init = append(init, e)
			if e.Right != nil {
				v.Name.Defn = e
			}
		}
	}

	if len(el) != 0 {
		Yyerror("extra expression in var declaration")
	}
	return init
}

// declare constants from grammar
// new_name_list [[type] = expr_list]
func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
	lno := int32(0) // default is to leave line number alone in listtreecopy
	if len(cl) == 0 {
		if t != nil {
			Yyerror("const declaration cannot have type without expression")
		}
		cl = lastconst
		t = lasttype
		lno = vl[0].Lineno
	} else {
		lastconst = cl
		lasttype = t
	}
	clcopy := listtreecopy(cl, lno)

	var c *Node
	var vv []*Node
	for _, v := range vl {
		if len(clcopy) == 0 {
			Yyerror("missing value in const declaration")
			break
		}

		c = clcopy[0]
		clcopy = clcopy[1:]

		v.Op = OLITERAL
		declare(v, dclcontext)

		v.Name.Param.Ntype = t
		v.Name.Defn = c

		vv = append(vv, Nod(ODCLCONST, v, nil))
	}

	if len(clcopy) != 0 {
		Yyerror("extra expression in const declaration")
	}
	iota_ += 1
	return vv
}

// this generates a new name node,
// typically for labels or other one-off names.
func newname(s *Sym) *Node {
	if s == nil {
		Fatalf("newname nil")
	}

	n := Nod(ONAME, nil, nil)
	n.Sym = s
	n.Type = nil
	n.Addable = true
	n.Ullman = 1
	n.Xoffset = 0
	return n
}

// newfuncname generates a new name node for a function or method.
// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
func newfuncname(s *Sym) *Node {
	n := newname(s)
	n.Func = new(Func)
	n.Func.FCurfn = Curfn
	return n
}

// this generates a new name node for a name
// being declared.
func dclname(s *Sym) *Node {
	n := newname(s)
	n.Op = ONONAME // caller will correct it
	return n
}

func typenod(t *Type) *Node {
	// if we copied another type with *t = *u
	// then t->nod might be out of date, so
	// check t->nod->type too
	if t.Nod == nil || t.Nod.Type != t {
		t.Nod = Nod(OTYPE, nil, nil)
		t.Nod.Type = t
		t.Nod.Sym = t.Sym
	}

	return t.Nod
}

// this will return an old name
// that has already been pushed on the
// declaration list. a diagnostic is
// generated if no name has been defined.
func oldname(s *Sym) *Node {
	n := s.Def
	if n == nil {
		// maybe a top-level name will come along
		// to give this a definition later.
		// walkdef will check s->def again once
		// all the input source has been processed.
		n = newname(s)
		n.Op = ONONAME
		n.Name.Iota = iota_ // save current iota value in const declarations
		return n
	}

	if Curfn != nil && n.Op == ONAME && n.Name.Funcdepth > 0 && n.Name.Funcdepth != Funcdepth {
		// inner func is referring to var in outer func.
		//
		// TODO(rsc): If there is an outer variable x and we
		// are parsing x := 5 inside the closure, until we get to
		// the := it looks like a reference to the outer x so we'll
		// make x a closure variable unnecessarily.
		if n.Name.Param.Closure == nil || n.Name.Param.Closure.Name.Funcdepth != Funcdepth {
			// create new closure var.
			c := Nod(ONAME, nil, nil)

			c.Sym = s
			c.Class = PPARAMREF
			c.Isddd = n.Isddd
			c.Name.Defn = n
			c.Addable = false
			c.Ullman = 2
			c.Name.Funcdepth = Funcdepth
			c.Name.Param.Outer = n.Name.Param.Closure
			n.Name.Param.Closure = c
			c.Name.Param.Closure = n
			c.Xoffset = 0
			Curfn.Func.Cvars.Append(c)
		}

		// return ref to closure var, not original
		return n.Name.Param.Closure
	}

	return n
}

// := declarations
func colasname(n *Node) bool {
	switch n.Op {
	case ONAME,
		ONONAME,
		OPACK,
		OTYPE,
		OLITERAL:
		return n.Sym != nil
	}

	return false
}

func colasdefn(left []*Node, defn *Node) {
	for _, n := range left {
		if n.Sym != nil {
			n.Sym.Flags |= SymUniq
		}
	}

	var nnew, nerr int
	for i, n := range left {
		if isblank(n) {
			continue
		}
		if !colasname(n) {
			yyerrorl(defn.Lineno, "non-name %v on left side of :=", n)
			nerr++
			continue
		}

		if n.Sym.Flags&SymUniq == 0 {
			yyerrorl(defn.Lineno, "%v repeated on left side of :=", n.Sym)
			n.Diag++
			nerr++
			continue
		}

		n.Sym.Flags &^= SymUniq
		if n.Sym.Block == block {
			continue
		}

		nnew++
		n = newname(n.Sym)
		declare(n, dclcontext)
		n.Name.Defn = defn
		defn.Ninit.Append(Nod(ODCL, n, nil))
		left[i] = n
	}

	if nnew == 0 && nerr == 0 {
		yyerrorl(defn.Lineno, "no new variables on left side of :=")
	}
}

func colas(left, right []*Node, lno int32) *Node {
	n := Nod(OAS, nil, nil) // assume common case
	n.Colas = true
	n.Lineno = lno     // set before calling colasdefn for correct error line
	colasdefn(left, n) // modifies left, call before using left[0] in common case
	if len(left) == 1 && len(right) == 1 {
		// common case
		n.Left = left[0]
		n.Right = right[0]
	} else {
		n.Op = OAS2
		n.List.Set(left)
		n.Rlist.Set(right)
	}
	return n
}

// declare the arguments in an
// interface field declaration.
func ifacedcl(n *Node) {
	if n.Op != ODCLFIELD || n.Right == nil {
		Fatalf("ifacedcl")
	}

	if isblank(n.Left) {
		Yyerror("methods must have a unique non-blank name")
	}

	n.Func = new(Func)
	n.Func.FCurfn = Curfn
	dclcontext = PPARAM
	markdcl()
	Funcdepth++
	n.Func.Outer = Curfn
	Curfn = n
	funcargs(n.Right)

	// funcbody is normally called after the parser has
	// seen the body of a function but since an interface
	// field declaration does not have a body, we must
	// call it now to pop the current declaration context.
	dclcontext = PAUTO

	funcbody(n)
}

// declare the function proper
// and declare the arguments.
// called in extern-declaration context
// returns in auto-declaration context.
func funchdr(n *Node) {
	// change the declaration context from extern to auto
	if Funcdepth == 0 && dclcontext != PEXTERN {
		Fatalf("funchdr: dclcontext")
	}

	if importpkg == nil && n.Func.Nname != nil {
		makefuncsym(n.Func.Nname.Sym)
	}

	dclcontext = PAUTO
	markdcl()
	Funcdepth++

	n.Func.Outer = Curfn
	Curfn = n

	if n.Func.Nname != nil {
		funcargs(n.Func.Nname.Name.Param.Ntype)
	} else if n.Func.Ntype != nil {
		funcargs(n.Func.Ntype)
	} else {
		funcargs2(n.Type)
	}
}

func funcargs(nt *Node) {
	if nt.Op != OTFUNC {
		Fatalf("funcargs %v", Oconv(nt.Op, 0))
	}

	// re-start the variable generation number
	// we want to use small numbers for the return variables,
	// so let them have the chunk starting at 1.
	vargen = nt.Rlist.Len()

	// declare the receiver and in arguments.
	// no n->defn because type checking of func header
	// will not fill in the types until later
	if nt.Left != nil {
		n := nt.Left
		if n.Op != ODCLFIELD {
			Fatalf("funcargs receiver %v", Oconv(n.Op, 0))
		}
		if n.Left != nil {
			n.Left.Op = ONAME
			n.Left.Name.Param.Ntype = n.Right
			declare(n.Left, PPARAM)
			if dclcontext == PAUTO {
				vargen++
				n.Left.Name.Vargen = int32(vargen)
			}
		}
	}

	var n *Node
	for _, n = range nt.List.Slice() {
		if n.Op != ODCLFIELD {
			Fatalf("funcargs in %v", Oconv(n.Op, 0))
		}
		if n.Left != nil {
			n.Left.Op = ONAME
			n.Left.Name.Param.Ntype = n.Right
			declare(n.Left, PPARAM)
			if dclcontext == PAUTO {
				vargen++
				n.Left.Name.Vargen = int32(vargen)
			}
		}
	}

	// declare the out arguments.
	gen := nt.List.Len()
	var i int = 0
	for _, n = range nt.Rlist.Slice() {
		if n.Op != ODCLFIELD {
			Fatalf("funcargs out %v", Oconv(n.Op, 0))
		}

		if n.Left == nil {
			// Name so that escape analysis can track it. ~r stands for 'result'.
			n.Left = newname(LookupN("~r", gen))
			gen++
		}

		// TODO: n->left->missing = 1;
		n.Left.Op = ONAME

		if isblank(n.Left) {
			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
			// The name must be different from ~r above because if you have
			//	func f() (_ int)
			//	func g() int
			// f is allowed to use a plain 'return' with no arguments, while g is not.
			// So the two cases must be distinguished.
			// We do not record a pointer to the original node (n->orig).
			// Having multiple names causes too much confusion in later passes.
			nn := *n.Left
			nn.Orig = &nn
			nn.Sym = LookupN("~b", gen)
			gen++
			n.Left = &nn
		}

		n.Left.Name.Param.Ntype = n.Right
		declare(n.Left, PPARAMOUT)
		if dclcontext == PAUTO {
			i++
			n.Left.Name.Vargen = int32(i)
		}
	}
}

// Same as funcargs, except run over an already constructed TFUNC.
// This happens during import, where the hidden_fndcl rule has
// used functype directly to parse the function's type.
func funcargs2(t *Type) {
	if t.Etype != TFUNC {
		Fatalf("funcargs2 %v", t)
	}

	for _, ft := range t.Recvs().Fields().Slice() {
		if ft.Nname == nil || ft.Nname.Sym == nil {
			continue
		}
		n := ft.Nname // no need for newname(ft->nname->sym)
		n.Type = ft.Type
		declare(n, PPARAM)
	}

	for _, ft := range t.Params().Fields().Slice() {
		if ft.Nname == nil || ft.Nname.Sym == nil {
			continue
		}
		n := ft.Nname
		n.Type = ft.Type
		declare(n, PPARAM)
	}

	for _, ft := range t.Results().Fields().Slice() {
		if ft.Nname == nil || ft.Nname.Sym == nil {
			continue
		}
		n := ft.Nname
		n.Type = ft.Type
		declare(n, PPARAMOUT)
	}
}

// finish the body.
// called in auto-declaration context.
// returns in extern-declaration context.
func funcbody(n *Node) {
	// change the declaration context from auto to extern
	if dclcontext != PAUTO {
		Fatalf("funcbody: dclcontext")
	}
	popdcl()
	Funcdepth--
	Curfn = n.Func.Outer
	n.Func.Outer = nil
	if Funcdepth == 0 {
		dclcontext = PEXTERN
	}
}

// new type being defined with name s.
func typedcl0(s *Sym) *Node {
	n := newname(s)
	n.Op = OTYPE
	declare(n, dclcontext)
	return n
}

// node n, which was returned by typedcl0
// is being declared to have uncompiled type t.
// return the ODCLTYPE node to use.
func typedcl1(n *Node, t *Node, local bool) *Node {
	n.Name.Param.Ntype = t
	n.Local = local
	return Nod(ODCLTYPE, n, nil)
}

// structs, functions, and methods.
// they don't belong here, but where do they belong?
func checkembeddedtype(t *Type) {
	if t == nil {
		return
	}

	if t.Sym == nil && Isptr[t.Etype] {
		t = t.Type
		if t.Etype == TINTER {
			Yyerror("embedded type cannot be a pointer to interface")
		}
	}

	if Isptr[t.Etype] {
		Yyerror("embedded type cannot be a pointer")
	} else if t.Etype == TFORW && t.Embedlineno == 0 {
		t.Embedlineno = lineno
	}
}

func structfield(n *Node) *Field {
	lno := lineno
	lineno = n.Lineno

	if n.Op != ODCLFIELD {
		Fatalf("structfield: oops %v\n", n)
	}

	f := newField()
	f.Isddd = n.Isddd

	if n.Right != nil {
		n.Right = typecheck(n.Right, Etype)
		n.Type = n.Right.Type
		if n.Left != nil {
			n.Left.Type = n.Type
		}
		if n.Embedded != 0 {
			checkembeddedtype(n.Type)
		}
	}

	n.Right = nil

	f.Type = n.Type
	if f.Type == nil {
		f.Broke = true
	}

	switch n.Val().Ctype() {
	case CTSTR:
		f.Note = new(string)
		*f.Note = n.Val().U.(string)

	default:
		Yyerror("field annotation must be string")
		fallthrough

	case CTxxx:
		f.Note = nil
	}

	if n.Left != nil && n.Left.Op == ONAME {
		f.Nname = n.Left
		f.Embedded = n.Embedded
		f.Sym = f.Nname.Sym
	}

	lineno = lno
	return f
}

// checkdupfields emits errors for duplicately named fields or methods in
// a list of struct or interface types.
func checkdupfields(what string, ts ...*Type) {
	lno := lineno

	seen := make(map[*Sym]bool)
	for _, t := range ts {
		for _, f := range t.Fields().Slice() {
			if f.Sym == nil || f.Nname == nil || isblank(f.Nname) {
				continue
			}
			if seen[f.Sym] {
				lineno = f.Nname.Lineno
				Yyerror("duplicate %s %s", what, f.Sym.Name)
				continue
			}
			seen[f.Sym] = true
		}
	}

	lineno = lno
}

// convert a parsed id/type list into
// a type for struct/interface/arglist
func tostruct(l []*Node) *Type {
	t := typ(TSTRUCT)
	tostruct0(t, l)
	return t
}

func tostruct0(t *Type, l []*Node) {
	if t == nil || t.Etype != TSTRUCT {
		Fatalf("struct expected")
	}

	var fields []*Field
	for _, n := range l {
		fields = append(fields, structfield(n))
	}
	t.SetFields(fields)

	for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() {
		if f.Broke {
			t.Broke = true
		}
	}

	checkdupfields("field", t)

	if !t.Broke {
		checkwidth(t)
	}
}

func tofunargs(l []*Node) *Type {
	t := typ(TSTRUCT)
	t.Funarg = true

	var fields []*Field
	for _, n := range l {
		f := structfield(n)
		f.Funarg = true

		// esc.go needs to find f given a PPARAM to add the tag.
		if n.Left != nil && n.Left.Class == PPARAM {
			n.Left.Name.Param.Field = f
		}

		fields = append(fields, f)
	}
	t.SetFields(fields)

	for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() {
		if f.Broke {
			t.Broke = true
		}
	}

	return t
}

func interfacefield(n *Node) *Field {
	lno := lineno
	lineno = n.Lineno

	if n.Op != ODCLFIELD {
		Fatalf("interfacefield: oops %v\n", n)
	}

	if n.Val().Ctype() != CTxxx {
		Yyerror("interface method cannot have annotation")
	}

	f := newField()
	f.Isddd = n.Isddd

	if n.Right != nil {
		if n.Left != nil {
			// queue resolution of method type for later.
			// right now all we need is the name list.
			// avoids cycles for recursive interface types.
			n.Type = typ(TINTERMETH)

			n.Type.Nname = n.Right
			n.Left.Type = n.Type
			queuemethod(n)

			if n.Left.Op == ONAME {
				f.Nname = n.Left
				f.Embedded = n.Embedded
				f.Sym = f.Nname.Sym
			}
		} else {
			n.Right = typecheck(n.Right, Etype)
			n.Type = n.Right.Type

			if n.Embedded != 0 {
				checkembeddedtype(n.Type)
			}

			if n.Type != nil {
				switch n.Type.Etype {
				case TINTER:
					break

				case TFORW:
					Yyerror("interface type loop involving %v", n.Type)
					f.Broke = true

				default:
					Yyerror("interface contains embedded non-interface %v", n.Type)
					f.Broke = true
				}
			}
		}
	}

	n.Right = nil

	f.Type = n.Type
	if f.Type == nil {
		f.Broke = true
	}

	lineno = lno
	return f
}

func tointerface(l []*Node) *Type {
	t := typ(TINTER)
	tointerface0(t, l)
	return t
}

func tointerface0(t *Type, l []*Node) *Type {
	if t == nil || t.Etype != TINTER {
		Fatalf("interface expected")
	}

	var fields []*Field
	for _, n := range l {
		f := interfacefield(n)

		if n.Left == nil && f.Type.Etype == TINTER {
			// embedded interface, inline methods
			for _, t1 := range f.Type.Fields().Slice() {
				f = newField()
				f.Type = t1.Type
				f.Broke = t1.Broke
				f.Sym = t1.Sym
				if f.Sym != nil {
					f.Nname = newname(f.Sym)
				}
				fields = append(fields, f)
			}
		} else {
			fields = append(fields, f)
		}
	}
	sort.Sort(methcmp(fields))
	t.SetFields(fields)

	for f, it := IterFields(t); f != nil && !t.Broke; f = it.Next() {
		if f.Broke {
			t.Broke = true
		}
	}

	checkdupfields("method", t)
	checkwidth(t)

	return t
}

func embedded(s *Sym, pkg *Pkg) *Node {
	const (
		CenterDot = 0xB7
	)
	// Names sometimes have disambiguation junk
	// appended after a center dot. Discard it when
	// making the name for the embedded struct field.
	name := s.Name

	if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
		name = s.Name[:i]
	}

	var n *Node
	if exportname(name) {
		n = newname(Lookup(name))
	} else if s.Pkg == builtinpkg {
		// The name of embedded builtins belongs to pkg.
		n = newname(Pkglookup(name, pkg))
	} else {
		n = newname(Pkglookup(name, s.Pkg))
	}
	n = Nod(ODCLFIELD, n, oldname(s))
	n.Embedded = 1
	return n
}

func fakethis() *Node {
	n := Nod(ODCLFIELD, nil, typenod(Ptrto(typ(TSTRUCT))))
	return n
}

// Is this field a method on an interface?
// Those methods have an anonymous *struct{} as the receiver.
// (See fakethis above.)
func isifacemethod(f *Type) bool {
	rcvr := f.Recv()
	if rcvr.Sym != nil {
		return false
	}
	t := rcvr.Type
	if !Isptr[t.Etype] {
		return false
	}
	t = t.Type
	if t.Sym != nil || t.Etype != TSTRUCT || t.NumFields() != 0 {
		return false
	}
	return true
}

// turn a parsed function declaration into a type
func functype(this *Node, in, out []*Node) *Type {
	t := typ(TFUNC)
	functype0(t, this, in, out)
	return t
}

func functype0(t *Type, this *Node, in, out []*Node) {
	if t == nil || t.Etype != TFUNC {
		Fatalf("function type expected")
	}

	var rcvr []*Node
	if this != nil {
		rcvr = []*Node{this}
	}
	*t.RecvsP() = tofunargs(rcvr)
	*t.ResultsP() = tofunargs(out)
	*t.ParamsP() = tofunargs(in)

	checkdupfields("argument", t.Recvs(), t.Results(), t.Params())

	if t.Recvs().Broke || t.Results().Broke || t.Params().Broke {
		t.Broke = true
	}

	t.Outnamed = false
	if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
		s := out[0].Left.Orig.Sym
		if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
			t.Outnamed = true
		}
	}
}

var methodsym_toppkg *Pkg

func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
	var s *Sym
	var p string
	var suffix string
	var spkg *Pkg

	t := t0
	if t == nil {
		goto bad
	}
	s = t.Sym
	if s == nil && Isptr[t.Etype] {
		t = t.Type
		if t == nil {
			goto bad
		}
		s = t.Sym
	}

	spkg = nil
	if s != nil {
		spkg = s.Pkg
	}

	// if t0 == *t and t0 has a sym,
	// we want to see *t, not t0, in the method name.
	if t != t0 && t0.Sym != nil {
		t0 = Ptrto(t)
	}

	suffix = ""
	if iface != 0 {
		dowidth(t0)
		if t0.Width < Types[Tptr].Width {
			suffix = "·i"
		}
	}

	if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) {
		if t0.Sym == nil && Isptr[t0.Etype] {
			p = fmt.Sprintf("(%v).%s.%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
		} else {
			p = fmt.Sprintf("%v.%s.%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
		}
	} else {
		if t0.Sym == nil && Isptr[t0.Etype] {
			p = fmt.Sprintf("(%v).%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Name, suffix)
		} else {
			p = fmt.Sprintf("%v.%s%s", Tconv(t0, FmtLeft|FmtShort), nsym.Name, suffix)
		}
	}

	if spkg == nil {
		if methodsym_toppkg == nil {
			methodsym_toppkg = mkpkg("go")
		}
		spkg = methodsym_toppkg
	}

	s = Pkglookup(p, spkg)

	return s

bad:
	Yyerror("illegal receiver type: %v", t0)
	return nil
}

func methodname(n *Node, t *Type) *Node {
	s := methodsym(n.Sym, t, 0)
	if s == nil {
		return n
	}
	return newname(s)
}

func methodname1(n *Node, t *Node) *Node {
	star := ""
	if t.Op == OIND {
		star = "*"
		t = t.Left
	}

	if t.Sym == nil || isblank(n) {
		return newfuncname(n.Sym)
	}

	var p string
	if star != "" {
		p = fmt.Sprintf("(%s%v).%v", star, t.Sym, n.Sym)
	} else {
		p = fmt.Sprintf("%v.%v", t.Sym, n.Sym)
	}

	if exportname(t.Sym.Name) {
		n = newfuncname(Lookup(p))
	} else {
		n = newfuncname(Pkglookup(p, t.Sym.Pkg))
	}

	return n
}

// Add a method, declared as a function.
// - msym is the method symbol
// - t is function type (with receiver)
// - tpkg is the package of the type declaring the method during import, or nil (ignored) --- for verification only
func addmethod(msym *Sym, t *Type, tpkg *Pkg, local, nointerface bool) {
	// get field sym
	if msym == nil {
		Fatalf("no method symbol")
	}

	// get parent type sym
	rf := t.Recv() // ptr to this structure
	if rf == nil {
		Yyerror("missing receiver")
		return
	}

	pa := rf.Type // base type
	mt := methtype(pa, 1)
	if mt == nil {
		t = pa
		if t == nil { // rely on typecheck having complained before
			return
		}
		if t != nil {
			if Isptr[t.Etype] {
				if t.Sym != nil {
					Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
					return
				}

				t = t.Type
			}

			if t.Broke { // rely on typecheck having complained before
				return
			}
			if t.Sym == nil {
				Yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
				return
			}

			if Isptr[t.Etype] {
				Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
				return
			}

			if t.Etype == TINTER {
				Yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
				return
			}
		}

		// Should have picked off all the reasons above,
		// but just in case, fall back to generic error.
		Yyerror("invalid receiver type %v (%v / %v)", pa, Tconv(pa, FmtLong), Tconv(t, FmtLong))

		return
	}

	pa = mt
	if local && !pa.Local {
		Yyerror("cannot define new methods on non-local type %v", pa)
		return
	}

	if isblanksym(msym) {
		return
	}

	if pa.Etype == TSTRUCT {
		for _, f := range pa.Fields().Slice() {
			if f.Sym == msym {
				Yyerror("type %v has both field and method named %v", pa, msym)
				return
			}
		}
	}

	n := Nod(ODCLFIELD, newname(msym), nil)
	n.Type = t

	for _, f := range pa.Methods().Slice() {
		if msym.Name != f.Sym.Name {
			continue
		}
		// Eqtype only checks that incoming and result parameters match,
		// so explicitly check that the receiver parameters match too.
		if !Eqtype(t, f.Type) || !Eqtype(t.Recv().Type, f.Type.Recv().Type) {
			Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", pa, msym, f.Type, t)
		}
		return
	}

	f := structfield(n)
	f.Nointerface = nointerface

	// during import unexported method names should be in the type's package
	if tpkg != nil && f.Sym != nil && !exportname(f.Sym.Name) && f.Sym.Pkg != tpkg {
		Fatalf("imported method name %v in wrong package %s\n", Sconv(f.Sym, FmtSign), tpkg.Name)
	}

	pa.Methods().Append(f)
}

func funccompile(n *Node) {
	Stksize = BADWIDTH
	Maxarg = 0

	if n.Type == nil {
		if nerrors == 0 {
			Fatalf("funccompile missing type")
		}
		return
	}

	// assign parameter offsets
	checkwidth(n.Type)

	if Curfn != nil {
		Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym)
	}

	Stksize = 0
	dclcontext = PAUTO
	Funcdepth = n.Func.Depth + 1
	compile(n)
	Curfn = nil
	Pc = nil
	continpc = nil
	breakpc = nil
	Funcdepth = 0
	dclcontext = PEXTERN
	if nerrors != 0 {
		// If we have compile errors, ignore any assembler/linker errors.
		Ctxt.DiagFunc = func(string, ...interface{}) {}
	}
	flushdata()
	obj.Flushplist(Ctxt) // convert from Prog list to machine code
}

func funcsym(s *Sym) *Sym {
	if s.Fsym != nil {
		return s.Fsym
	}

	s1 := Pkglookup(s.Name+"·f", s.Pkg)
	s.Fsym = s1
	return s1
}

func makefuncsym(s *Sym) {
	if isblanksym(s) {
		return
	}
	if compiling_runtime != 0 && s.Name == "getg" {
		// runtime.getg() is not a real function and so does
		// not get a funcsym.
		return
	}
	s1 := funcsym(s)
	s1.Def = newfuncname(s1)
	s1.Def.Func.Shortname = newname(s)
	funcsyms = append(funcsyms, s1.Def)
}

type nowritebarrierrecChecker struct {
	curfn  *Node
	stable bool

	// best maps from the ODCLFUNC of each visited function that
	// recursively invokes a write barrier to the called function
	// on the shortest path to a write barrier.
	best map[*Node]nowritebarrierrecCall
}

type nowritebarrierrecCall struct {
	target *Node
	depth  int
	lineno int32
}

func checknowritebarrierrec() {
	c := nowritebarrierrecChecker{
		best: make(map[*Node]nowritebarrierrecCall),
	}
	visitBottomUp(xtop, func(list []*Node, recursive bool) {
		// Functions with write barriers have depth 0.
		for _, n := range list {
			if n.Func.WBLineno != 0 {
				c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBLineno}
			}
		}

		// Propagate write barrier depth up from callees. In
		// the recursive case, we have to update this at most
		// len(list) times and can stop when we an iteration
		// that doesn't change anything.
		for _ = range list {
			c.stable = false
			for _, n := range list {
				if n.Func.WBLineno == 0 {
					c.curfn = n
					c.visitcodelist(n.Nbody)
				}
			}
			if c.stable {
				break
			}
		}

		// Check nowritebarrierrec functions.
		for _, n := range list {
			if n.Func.Pragma&Nowritebarrierrec == 0 {
				continue
			}
			call, hasWB := c.best[n]
			if !hasWB {
				continue
			}

			// Build the error message in reverse.
			err := ""
			for call.target != nil {
				err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err)
				n = call.target
				call = c.best[n]
			}
			err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err)
			yyerrorl(n.Func.WBLineno, err)
		}
	})
}

func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) {
	for _, n := range l.Slice() {
		c.visitcode(n)
	}
}

func (c *nowritebarrierrecChecker) visitcode(n *Node) {
	if n == nil {
		return
	}

	if n.Op == OCALLFUNC || n.Op == OCALLMETH {
		c.visitcall(n)
	}

	c.visitcodelist(n.Ninit)
	c.visitcode(n.Left)
	c.visitcode(n.Right)
	c.visitcodelist(n.List)
	c.visitcodelist(n.Nbody)
	c.visitcodelist(n.Rlist)
}

func (c *nowritebarrierrecChecker) visitcall(n *Node) {
	fn := n.Left
	if n.Op == OCALLMETH {
		fn = n.Left.Sym.Def
	}
	if fn == nil || fn.Op != ONAME || fn.Class != PFUNC || fn.Name.Defn == nil {
		return
	}
	if (compiling_runtime != 0 || fn.Sym.Pkg == Runtimepkg) && fn.Sym.Name == "allocm" {
		return
	}
	defn := fn.Name.Defn

	fnbest, ok := c.best[defn]
	if !ok {
		return
	}
	best, ok := c.best[c.curfn]
	if ok && fnbest.depth+1 >= best.depth {
		return
	}
	c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Lineno}
	c.stable = false
}
