// 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"
	"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", Ctxt.Line(int(lineno)), Sconv(s, 0), s.Def)
	}
	return d
}

func popdcl() {
	var d *Sym
	var s *Sym
	var lno int

	//	if(dflag())
	//		print("revert\n");

	for d = dclstack; d != nil; d = d.Link {
		if d.Name == "" {
			break
		}
		s = Pkglookup(d.Name, d.Pkg)
		lno = int(s.Lastlineno)
		dcopy(s, d)
		d.Lastlineno = int32(lno)
		if dflag() {
			fmt.Printf("\t%v pop %v %p\n", Ctxt.Line(int(lineno)), Sconv(s, 0), s.Def)
		}
	}

	if d == nil {
		Fatal("popdcl: no mark")
	}
	dclstack = d.Link
	block = d.Block
}

func poptodcl() {
	// pop the old marker and push a new one
	// (cannot reuse the existing one)
	// because we use the markers to identify blocks
	// for the goto restriction checks.
	popdcl()

	markdcl()
}

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

	blockgen++
	block = blockgen
}

//	if(dflag())
//		print("markdcl\n");
func dumpdcl(st string) {
	var s *Sym

	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)
		s = Pkglookup(d.Name, d.Pkg)
		fmt.Printf(" %v\n", Sconv(s, 0))
	}
}

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

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", Sconv(s, 0), where, pkgstr)
	} else {
		line1 := parserline()
		line2 := int(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 = int(s.Lastlineno)
		}

		yyerrorl(int(line1), "%v redeclared %s\n"+"\tprevious declaration at %v", Sconv(s, 0), where, Ctxt.Line(line2))
	}
}

var vargen int

/*
 * declare individual names - var, typ, const
 */

var declare_typegen int

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

	if isblank(n) {
		return
	}

	n.Lineno = int32(parserline())
	s := n.Sym

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

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

	gen := 0
	if ctxt == PEXTERN {
		externdcl = list(externdcl, n)
		if dflag() {
			fmt.Printf("\t%v global decl %v %p\n", Ctxt.Line(int(lineno)), Sconv(s, 0), n)
		}
	} else {
		if Curfn == nil && ctxt == PAUTO {
			Fatal("automatic outside function")
		}
		if Curfn != nil {
			Curfn.Dcl = list(Curfn.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.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 = int32(parserline())
	s.Def = n
	n.Vargen = int32(gen)
	n.Funcdepth = Funcdepth
	n.Class = uint8(ctxt)

	autoexport(n, ctxt)
}

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

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

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

	if count(el) == 1 && count(vl) > 1 {
		e := el.N
		as2 := Nod(OAS2, nil, nil)
		as2.List = vl
		as2.Rlist = list1(e)
		var v *Node
		for ; vl != nil; vl = vl.Next {
			v = vl.N
			v.Op = ONAME
			declare(v, dclcontext)
			v.Ntype = t
			v.Defn = as2
			if Funcdepth > 0 {
				init = list(init, Nod(ODCL, v, nil))
			}
		}

		return list(init, as2)
	}

	var v *Node
	var e *Node
	for ; vl != nil; vl = vl.Next {
		if doexpr {
			if el == nil {
				Yyerror("missing expression in var declaration")
				break
			}

			e = el.N
			el = el.Next
		} else {
			e = nil
		}

		v = vl.N
		v.Op = ONAME
		declare(v, dclcontext)
		v.Ntype = t

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

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

/*
 * declare constants from grammar
 * new_name_list [[type] = expr_list]
 */
func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
	var vv *NodeList
	if cl == nil {
		if t != nil {
			Yyerror("const declaration cannot have type without expression")
		}
		cl = lastconst
		t = lasttype
	} else {
		lastconst = cl
		lasttype = t
	}

	cl = listtreecopy(cl)

	var v *Node
	var c *Node
	for ; vl != nil; vl = vl.Next {
		if cl == nil {
			Yyerror("missing value in const declaration")
			break
		}

		c = cl.N
		cl = cl.Next

		v = vl.N
		v.Op = OLITERAL
		declare(v, dclcontext)

		v.Ntype = t
		v.Defn = c

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

	if cl != nil {
		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 {
		Fatal("newname nil")
	}

	n := Nod(ONAME, nil, nil)
	n.Sym = s
	n.Type = nil
	n.Addable = 1
	n.Ullman = 1
	n.Xoffset = 0
	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.Iota = iota_ // save current iota value in const declarations
	}

	if Curfn != nil && n.Funcdepth > 0 && n.Funcdepth != Funcdepth && n.Op == ONAME {
		// 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.Closure == nil || n.Closure.Funcdepth != Funcdepth {
			// create new closure var.
			c := Nod(ONAME, nil, nil)

			c.Sym = s
			c.Class = PPARAMREF
			c.Isddd = n.Isddd
			c.Defn = n
			c.Addable = 0
			c.Ullman = 2
			c.Funcdepth = Funcdepth
			c.Outer = n.Closure
			n.Closure = c
			c.Closure = n
			c.Xoffset = 0
			Curfn.Cvars = list(Curfn.Cvars, c)
		}

		// return ref to closure var, not original
		return n.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 *NodeList, defn *Node) {
	for l := left; l != nil; l = l.Next {
		if l.N.Sym != nil {
			l.N.Sym.Flags |= SymUniq
		}
	}

	nnew := 0
	nerr := 0
	var n *Node
	for l := left; l != nil; l = l.Next {
		n = l.N
		if isblank(n) {
			continue
		}
		if !colasname(n) {
			yyerrorl(int(defn.Lineno), "non-name %v on left side of :=", Nconv(n, 0))
			nerr++
			continue
		}

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

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

		nnew++
		n = newname(n.Sym)
		declare(n, dclcontext)
		n.Defn = defn
		defn.Ninit = list(defn.Ninit, Nod(ODCL, n, nil))
		l.N = n
	}

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

func colas(left *NodeList, right *NodeList, lno int32) *Node {
	as := Nod(OAS2, nil, nil)
	as.List = left
	as.Rlist = right
	as.Colas = 1
	as.Lineno = lno
	colasdefn(left, as)

	// make the tree prettier; not necessary
	if count(left) == 1 && count(right) == 1 {
		as.Left = as.List.N
		as.Right = as.Rlist.N
		as.List = nil
		as.Rlist = nil
		as.Op = OAS
	}

	return as
}

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

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

	dclcontext = PPARAM
	markdcl()
	Funcdepth++
	n.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 {
		Fatal("funchdr: dclcontext")
	}

	dclcontext = PAUTO
	markdcl()
	Funcdepth++

	n.Outer = Curfn
	Curfn = n

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

func funcargs(nt *Node) {
	if nt.Op != OTFUNC {
		Fatal("funcargs %v", Oconv(int(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 = count(nt.Rlist)

	// 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 {
			Fatal("funcargs receiver %v", Oconv(int(n.Op), 0))
		}
		if n.Left != nil {
			n.Left.Op = ONAME
			n.Left.Ntype = n.Right
			declare(n.Left, PPARAM)
			if dclcontext == PAUTO {
				vargen++
				n.Left.Vargen = int32(vargen)
			}
		}
	}

	var n *Node
	for l := nt.List; l != nil; l = l.Next {
		n = l.N
		if n.Op != ODCLFIELD {
			Fatal("funcargs in %v", Oconv(int(n.Op), 0))
		}
		if n.Left != nil {
			n.Left.Op = ONAME
			n.Left.Ntype = n.Right
			declare(n.Left, PPARAM)
			if dclcontext == PAUTO {
				vargen++
				n.Left.Vargen = int32(vargen)
			}
		}
	}

	// declare the out arguments.
	gen := count(nt.List)
	var i int = 0
	var nn *Node
	for l := nt.Rlist; l != nil; l = l.Next {
		n = l.N

		if n.Op != ODCLFIELD {
			Fatal("funcargs out %v", Oconv(int(n.Op), 0))
		}

		if n.Left == nil {
			// Name so that escape analysis can track it. ~r stands for 'result'.
			namebuf = fmt.Sprintf("~r%d", gen)
			gen++

			n.Left = newname(Lookup(namebuf))
		}

		// 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 = Nod(OXXX, nil, nil)

			*nn = *n.Left
			nn.Orig = nn
			namebuf = fmt.Sprintf("~b%d", gen)
			gen++
			nn.Sym = Lookup(namebuf)
			n.Left = nn
		}

		n.Left.Ntype = n.Right
		declare(n.Left, PPARAMOUT)
		if dclcontext == PAUTO {
			i++
			n.Left.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 {
		Fatal("funcargs2 %v", Tconv(t, 0))
	}

	if t.Thistuple != 0 {
		var n *Node
		for ft := getthisx(t).Type; ft != nil; ft = ft.Down {
			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)
		}
	}

	if t.Intuple != 0 {
		var n *Node
		for ft := getinargx(t).Type; ft != nil; ft = ft.Down {
			if ft.Nname == nil || ft.Nname.Sym == nil {
				continue
			}
			n = ft.Nname
			n.Type = ft.Type
			declare(n, PPARAM)
		}
	}

	if t.Outtuple != 0 {
		var n *Node
		for ft := getoutargx(t).Type; ft != nil; ft = ft.Down {
			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 {
		Fatal("funcbody: dclcontext")
	}
	popdcl()
	Funcdepth--
	Curfn = n.Outer
	n.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 int) *Node {
	n.Ntype = t
	n.Local = uint8(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) *Type {
	lno := int(lineno)
	lineno = n.Lineno

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

	f := typ(TFIELD)
	f.Isddd = n.Isddd

	if n.Right != nil {
		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 = 1
	}

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

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

		// 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 = int32(lno)
	return f
}

var uniqgen uint32

func checkdupfields(t *Type, what string) {
	lno := int(lineno)

	for ; t != nil; t = t.Down {
		if t.Sym != nil && t.Nname != nil && !isblank(t.Nname) {
			if t.Sym.Uniqgen == uniqgen {
				lineno = t.Nname.Lineno
				Yyerror("duplicate %s %s", what, t.Sym.Name)
			} else {
				t.Sym.Uniqgen = uniqgen
			}
		}
	}

	lineno = int32(lno)
}

/*
 * convert a parsed id/type list into
 * a type for struct/interface/arglist
 */
func tostruct(l *NodeList) *Type {
	var f *Type
	t := typ(TSTRUCT)

	for tp := &t.Type; l != nil; l = l.Next {
		f = structfield(l.N)

		*tp = f
		tp = &f.Down
	}

	for f := t.Type; f != nil && t.Broke == 0; f = f.Down {
		if f.Broke != 0 {
			t.Broke = 1
		}
	}

	uniqgen++
	checkdupfields(t.Type, "field")

	if t.Broke == 0 {
		checkwidth(t)
	}

	return t
}

func tofunargs(l *NodeList) *Type {
	var f *Type

	t := typ(TSTRUCT)
	t.Funarg = 1

	for tp := &t.Type; l != nil; l = l.Next {
		f = structfield(l.N)
		f.Funarg = 1

		// esc.c needs to find f given a PPARAM to add the tag.
		if l.N.Left != nil && l.N.Left.Class == PPARAM {
			l.N.Left.Paramfld = f
		}

		*tp = f
		tp = &f.Down
	}

	for f := t.Type; f != nil && t.Broke == 0; f = f.Down {
		if f.Broke != 0 {
			t.Broke = 1
		}
	}

	return t
}

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

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

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

	f := typ(TFIELD)
	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 {
			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", Tconv(n.Type, 0))
					f.Broke = 1

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

	n.Right = nil

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

	lineno = int32(lno)
	return f
}

func tointerface(l *NodeList) *Type {
	var f *Type
	var t1 *Type

	t := typ(TINTER)

	tp := &t.Type
	for ; l != nil; l = l.Next {
		f = interfacefield(l.N)

		if l.N.Left == nil && f.Type.Etype == TINTER {
			// embedded interface, inline methods
			for t1 = f.Type.Type; t1 != nil; t1 = t1.Down {
				f = typ(TFIELD)
				f.Type = t1.Type
				f.Broke = t1.Broke
				f.Sym = t1.Sym
				if f.Sym != nil {
					f.Nname = newname(f.Sym)
				}
				*tp = f
				tp = &f.Down
			}
		} else {
			*tp = f
			tp = &f.Down
		}
	}

	for f := t.Type; f != nil && t.Broke == 0; f = f.Down {
		if f.Broke != 0 {
			t.Broke = 1
		}
	}

	uniqgen++
	checkdupfields(t.Type, "method")
	t = sortinter(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
}

/*
 * check that the list of declarations is either all anonymous or all named
 */
func findtype(l *NodeList) *Node {
	for ; l != nil; l = l.Next {
		if l.N.Op == OKEY {
			return l.N.Right
		}
	}
	return nil
}

func checkarglist(all *NodeList, input int) *NodeList {
	named := 0
	for l := all; l != nil; l = l.Next {
		if l.N.Op == OKEY {
			named = 1
			break
		}
	}

	if named != 0 {
		var n *Node
		var l *NodeList
		for l = all; l != nil; l = l.Next {
			n = l.N
			if n.Op != OKEY && n.Sym == nil {
				Yyerror("mixed named and unnamed function parameters")
				break
			}
		}

		if l == nil && n != nil && n.Op != OKEY {
			Yyerror("final function parameter must have type")
		}
	}

	var nextt *Node
	var t *Node
	var n *Node
	for l := all; l != nil; l = l.Next {
		// can cache result from findtype to avoid
		// quadratic behavior here, but unlikely to matter.
		n = l.N

		if named != 0 {
			if n.Op == OKEY {
				t = n.Right
				n = n.Left
				nextt = nil
			} else {
				if nextt == nil {
					nextt = findtype(l)
				}
				t = nextt
			}
		} else {
			t = n
			n = nil
		}

		// during import l->n->op is OKEY, but l->n->left->sym == S
		// means it was a '?', not that it was
		// a lone type This doesn't matter for the exported
		// declarations, which are parsed by rules that don't
		// use checkargs, but can happen for func literals in
		// the inline bodies.
		// TODO(rsc) this can go when typefmt case TFIELD in exportmode fmt.c prints _ instead of ?
		if importpkg != nil && n.Sym == nil {
			n = nil
		}

		if n != nil && n.Sym == nil {
			t = n
			n = nil
		}

		if n != nil {
			n = newname(n.Sym)
		}
		n = Nod(ODCLFIELD, n, t)
		if n.Right != nil && n.Right.Op == ODDD {
			if input == 0 {
				Yyerror("cannot use ... in output argument list")
			} else if l.Next != nil {
				Yyerror("can only use ... as final argument in list")
			}
			n.Right.Op = OTARRAY
			n.Right.Right = n.Right.Left
			n.Right.Left = nil
			n.Isddd = 1
			if n.Left != nil {
				n.Left.Isddd = 1
			}
		}

		l.N = n
	}

	return all
}

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 := getthisx(f).Type
	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.Type != nil {
		return false
	}
	return true
}

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

	var rcvr *NodeList
	if this != nil {
		rcvr = list1(this)
	}
	t.Type = tofunargs(rcvr)
	t.Type.Down = tofunargs(out)
	t.Type.Down.Down = tofunargs(in)

	uniqgen++
	checkdupfields(t.Type.Type, "argument")
	checkdupfields(t.Type.Down.Type, "argument")
	checkdupfields(t.Type.Down.Down.Type, "argument")

	if t.Type.Broke != 0 || t.Type.Down.Broke != 0 || t.Type.Down.Down.Broke != 0 {
		t.Broke = 1
	}

	if this != nil {
		t.Thistuple = 1
	}
	t.Outtuple = count(out)
	t.Intuple = count(in)
	t.Outnamed = 0
	if t.Outtuple > 0 && out.N.Left != nil && out.N.Left.Orig != nil {
		s := out.N.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 = 1
		}
	}

	return t
}

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, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
		} else {
			p = fmt.Sprintf("%v.%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
		}
	} else {
		if t0.Sym == nil && Isptr[t0.Etype] {
			p = fmt.Sprintf("(%v).%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix)
		} else {
			p = fmt.Sprintf("%v.%s%s", Tconv(t0, obj.FmtLeft|obj.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", Tconv(t0, 0))
	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 newname(n.Sym)
	}

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

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

	return n
}

/*
 * add a method, declared as a function,
 * n is fieldname, pa is base type, t is function type
 */
func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
	// get field sym
	if sf == nil {
		Fatal("no method symbol")
	}

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

	pa = pa.Type
	f := methtype(pa, 1)
	if f == 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)", Tconv(pa, 0), Tconv(t, 0))
					return
				}

				t = t.Type
			}

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

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

			if t.Etype == TINTER {
				Yyerror("invalid receiver type %v (%v is an interface type)", Tconv(pa, 0), Tconv(t, 0))
				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)", Tconv(pa, 0), Tconv(pa, obj.FmtLong), Tconv(t, obj.FmtLong))

		return
	}

	pa = f
	if pa.Etype == TSTRUCT {
		for f := pa.Type; f != nil; f = f.Down {
			if f.Sym == sf {
				Yyerror("type %v has both field and method named %v", Tconv(pa, 0), Sconv(sf, 0))
				return
			}
		}
	}

	if local && pa.Local == 0 {
		// defining method on non-local type.
		Yyerror("cannot define new methods on non-local type %v", Tconv(pa, 0))

		return
	}

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

	var d *Type // last found
	for f := pa.Method; f != nil; f = f.Down {
		d = f
		if f.Etype != TFIELD {
			Fatal("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong))
		}
		if sf.Name != f.Sym.Name {
			continue
		}
		if !Eqtype(t, f.Type) {
			Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", Tconv(pa, 0), Sconv(sf, 0), Tconv(f.Type, 0), Tconv(t, 0))
		}
		return
	}

	f = structfield(n)
	f.Nointerface = nointerface

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

	if d == nil {
		pa.Method = f
	} else {
		d.Down = f
	}
	return
}

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

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

	// assign parameter offsets
	checkwidth(n.Type)

	if Curfn != nil {
		Fatal("funccompile %v inside %v", Sconv(n.Nname.Sym, 0), Sconv(Curfn.Nname.Sym, 0))
	}

	Stksize = 0
	dclcontext = PAUTO
	Funcdepth = n.Funcdepth + 1
	compile(n)
	Curfn = nil
	Funcdepth = 0
	dclcontext = PEXTERN
}

func funcsym(s *Sym) *Sym {
	p := fmt.Sprintf("%s·f", s.Name)
	s1 := Pkglookup(p, s.Pkg)

	if s1.Def == nil {
		s1.Def = newname(s1)
		s1.Def.Shortname = newname(s)
		funcsyms = list(funcsyms, s1.Def)
	}

	return s1
}
