github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/dcl.go (about)

     1  // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/dcl.go
     2  
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package gc
     8  
     9  import (
    10  	"rsc.io/tmp/bootstrap/internal/obj"
    11  	"fmt"
    12  	"strings"
    13  )
    14  
    15  func dflag() bool {
    16  	if Debug['d'] == 0 {
    17  		return false
    18  	}
    19  	if Debug['y'] != 0 {
    20  		return true
    21  	}
    22  	if incannedimport != 0 {
    23  		return false
    24  	}
    25  	return true
    26  }
    27  
    28  /*
    29   * declaration stack & operations
    30   */
    31  func dcopy(a *Sym, b *Sym) {
    32  	a.Pkg = b.Pkg
    33  	a.Name = b.Name
    34  	a.Def = b.Def
    35  	a.Block = b.Block
    36  	a.Lastlineno = b.Lastlineno
    37  }
    38  
    39  func push() *Sym {
    40  	d := new(Sym)
    41  	d.Lastlineno = lineno
    42  	d.Link = dclstack
    43  	dclstack = d
    44  	return d
    45  }
    46  
    47  func pushdcl(s *Sym) *Sym {
    48  	d := push()
    49  	dcopy(d, s)
    50  	if dflag() {
    51  		fmt.Printf("\t%v push %v %p\n", Ctxt.Line(int(lineno)), s, s.Def)
    52  	}
    53  	return d
    54  }
    55  
    56  func popdcl() {
    57  	var d *Sym
    58  	var s *Sym
    59  	var lno int
    60  
    61  	//	if(dflag())
    62  	//		print("revert\n");
    63  
    64  	for d = dclstack; d != nil; d = d.Link {
    65  		if d.Name == "" {
    66  			break
    67  		}
    68  		s = Pkglookup(d.Name, d.Pkg)
    69  		lno = int(s.Lastlineno)
    70  		dcopy(s, d)
    71  		d.Lastlineno = int32(lno)
    72  		if dflag() {
    73  			fmt.Printf("\t%v pop %v %p\n", Ctxt.Line(int(lineno)), s, s.Def)
    74  		}
    75  	}
    76  
    77  	if d == nil {
    78  		Fatal("popdcl: no mark")
    79  	}
    80  	dclstack = d.Link
    81  	block = d.Block
    82  }
    83  
    84  func poptodcl() {
    85  	// pop the old marker and push a new one
    86  	// (cannot reuse the existing one)
    87  	// because we use the markers to identify blocks
    88  	// for the goto restriction checks.
    89  	popdcl()
    90  
    91  	markdcl()
    92  }
    93  
    94  func markdcl() {
    95  	d := push()
    96  	d.Name = "" // used as a mark in fifo
    97  	d.Block = block
    98  
    99  	blockgen++
   100  	block = blockgen
   101  }
   102  
   103  //	if(dflag())
   104  //		print("markdcl\n");
   105  func dumpdcl(st string) {
   106  	var s *Sym
   107  
   108  	i := 0
   109  	for d := dclstack; d != nil; d = d.Link {
   110  		i++
   111  		fmt.Printf("    %.2d %p", i, d)
   112  		if d.Name == "" {
   113  			fmt.Printf("\n")
   114  			continue
   115  		}
   116  
   117  		fmt.Printf(" '%s'", d.Name)
   118  		s = Pkglookup(d.Name, d.Pkg)
   119  		fmt.Printf(" %v\n", s)
   120  	}
   121  }
   122  
   123  func testdclstack() {
   124  	for d := dclstack; d != nil; d = d.Link {
   125  		if d.Name == "" {
   126  			if nerrors != 0 {
   127  				errorexit()
   128  			}
   129  			Yyerror("mark left on the stack")
   130  			continue
   131  		}
   132  	}
   133  }
   134  
   135  func redeclare(s *Sym, where string) {
   136  	if s.Lastlineno == 0 {
   137  		var tmp string
   138  		if s.Origpkg != nil {
   139  			tmp = s.Origpkg.Path
   140  		} else {
   141  			tmp = s.Pkg.Path
   142  		}
   143  		pkgstr := tmp
   144  		Yyerror("%v redeclared %s\n"+"\tprevious declaration during import %q", s, where, pkgstr)
   145  	} else {
   146  		line1 := parserline()
   147  		line2 := int(s.Lastlineno)
   148  
   149  		// When an import and a declaration collide in separate files,
   150  		// present the import as the "redeclared", because the declaration
   151  		// is visible where the import is, but not vice versa.
   152  		// See issue 4510.
   153  		if s.Def == nil {
   154  			line2 = line1
   155  			line1 = int(s.Lastlineno)
   156  		}
   157  
   158  		yyerrorl(int(line1), "%v redeclared %s\n"+"\tprevious declaration at %v", s, where, Ctxt.Line(line2))
   159  	}
   160  }
   161  
   162  var vargen int
   163  
   164  /*
   165   * declare individual names - var, typ, const
   166   */
   167  
   168  var declare_typegen int
   169  
   170  func declare(n *Node, ctxt uint8) {
   171  	if ctxt == PDISCARD {
   172  		return
   173  	}
   174  
   175  	if isblank(n) {
   176  		return
   177  	}
   178  
   179  	n.Lineno = int32(parserline())
   180  	s := n.Sym
   181  
   182  	// kludgy: typecheckok means we're past parsing.  Eg genwrapper may declare out of package names later.
   183  	if importpkg == nil && typecheckok == 0 && s.Pkg != localpkg {
   184  		Yyerror("cannot declare name %v", s)
   185  	}
   186  
   187  	if ctxt == PEXTERN && s.Name == "init" {
   188  		Yyerror("cannot declare init - must be func", s)
   189  	}
   190  
   191  	gen := 0
   192  	if ctxt == PEXTERN {
   193  		externdcl = list(externdcl, n)
   194  		if dflag() {
   195  			fmt.Printf("\t%v global decl %v %p\n", Ctxt.Line(int(lineno)), s, n)
   196  		}
   197  	} else {
   198  		if Curfn == nil && ctxt == PAUTO {
   199  			Fatal("automatic outside function")
   200  		}
   201  		if Curfn != nil {
   202  			Curfn.Func.Dcl = list(Curfn.Func.Dcl, n)
   203  		}
   204  		if n.Op == OTYPE {
   205  			declare_typegen++
   206  			gen = declare_typegen
   207  		} else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
   208  			vargen++
   209  			gen = vargen
   210  		}
   211  		pushdcl(s)
   212  		n.Curfn = Curfn
   213  	}
   214  
   215  	if ctxt == PAUTO {
   216  		n.Xoffset = 0
   217  	}
   218  
   219  	if s.Block == block {
   220  		// functype will print errors about duplicate function arguments.
   221  		// Don't repeat the error here.
   222  		if ctxt != PPARAM && ctxt != PPARAMOUT {
   223  			redeclare(s, "in this block")
   224  		}
   225  	}
   226  
   227  	s.Block = block
   228  	s.Lastlineno = int32(parserline())
   229  	s.Def = n
   230  	n.Vargen = int32(gen)
   231  	n.Funcdepth = Funcdepth
   232  	n.Class = uint8(ctxt)
   233  
   234  	autoexport(n, ctxt)
   235  }
   236  
   237  func addvar(n *Node, t *Type, ctxt uint8) {
   238  	if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
   239  		Fatal("addvar: n=%v t=%v nil", n, t)
   240  	}
   241  
   242  	n.Op = ONAME
   243  	declare(n, ctxt)
   244  	n.Type = t
   245  }
   246  
   247  /*
   248   * declare variables from grammar
   249   * new_name_list (type | [type] = expr_list)
   250   */
   251  func variter(vl *NodeList, t *Node, el *NodeList) *NodeList {
   252  	var init *NodeList
   253  	doexpr := el != nil
   254  
   255  	if count(el) == 1 && count(vl) > 1 {
   256  		e := el.N
   257  		as2 := Nod(OAS2, nil, nil)
   258  		as2.List = vl
   259  		as2.Rlist = list1(e)
   260  		var v *Node
   261  		for ; vl != nil; vl = vl.Next {
   262  			v = vl.N
   263  			v.Op = ONAME
   264  			declare(v, dclcontext)
   265  			v.Ntype = t
   266  			v.Defn = as2
   267  			if Funcdepth > 0 {
   268  				init = list(init, Nod(ODCL, v, nil))
   269  			}
   270  		}
   271  
   272  		return list(init, as2)
   273  	}
   274  
   275  	var v *Node
   276  	var e *Node
   277  	for ; vl != nil; vl = vl.Next {
   278  		if doexpr {
   279  			if el == nil {
   280  				Yyerror("missing expression in var declaration")
   281  				break
   282  			}
   283  
   284  			e = el.N
   285  			el = el.Next
   286  		} else {
   287  			e = nil
   288  		}
   289  
   290  		v = vl.N
   291  		v.Op = ONAME
   292  		declare(v, dclcontext)
   293  		v.Ntype = t
   294  
   295  		if e != nil || Funcdepth > 0 || isblank(v) {
   296  			if Funcdepth > 0 {
   297  				init = list(init, Nod(ODCL, v, nil))
   298  			}
   299  			e = Nod(OAS, v, e)
   300  			init = list(init, e)
   301  			if e.Right != nil {
   302  				v.Defn = e
   303  			}
   304  		}
   305  	}
   306  
   307  	if el != nil {
   308  		Yyerror("extra expression in var declaration")
   309  	}
   310  	return init
   311  }
   312  
   313  /*
   314   * declare constants from grammar
   315   * new_name_list [[type] = expr_list]
   316   */
   317  func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
   318  	if cl == nil {
   319  		if t != nil {
   320  			Yyerror("const declaration cannot have type without expression")
   321  		}
   322  		cl = lastconst
   323  		t = lasttype
   324  	} else {
   325  		lastconst = cl
   326  		lasttype = t
   327  	}
   328  
   329  	cl = listtreecopy(cl)
   330  
   331  	var v *Node
   332  	var c *Node
   333  	var vv *NodeList
   334  	for ; vl != nil; vl = vl.Next {
   335  		if cl == nil {
   336  			Yyerror("missing value in const declaration")
   337  			break
   338  		}
   339  
   340  		c = cl.N
   341  		cl = cl.Next
   342  
   343  		v = vl.N
   344  		v.Op = OLITERAL
   345  		declare(v, dclcontext)
   346  
   347  		v.Ntype = t
   348  		v.Defn = c
   349  
   350  		vv = list(vv, Nod(ODCLCONST, v, nil))
   351  	}
   352  
   353  	if cl != nil {
   354  		Yyerror("extra expression in const declaration")
   355  	}
   356  	iota_ += 1
   357  	return vv
   358  }
   359  
   360  /*
   361   * this generates a new name node,
   362   * typically for labels or other one-off names.
   363   */
   364  func newname(s *Sym) *Node {
   365  	if s == nil {
   366  		Fatal("newname nil")
   367  	}
   368  
   369  	n := Nod(ONAME, nil, nil)
   370  	n.Sym = s
   371  	n.Type = nil
   372  	n.Addable = true
   373  	n.Ullman = 1
   374  	n.Xoffset = 0
   375  	return n
   376  }
   377  
   378  // newfuncname generates a new name node for a function or method.
   379  // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
   380  func newfuncname(s *Sym) *Node {
   381  	n := newname(s)
   382  	n.Func = new(Func)
   383  	return n
   384  }
   385  
   386  /*
   387   * this generates a new name node for a name
   388   * being declared.
   389   */
   390  func dclname(s *Sym) *Node {
   391  	n := newname(s)
   392  	n.Op = ONONAME // caller will correct it
   393  	return n
   394  }
   395  
   396  func typenod(t *Type) *Node {
   397  	// if we copied another type with *t = *u
   398  	// then t->nod might be out of date, so
   399  	// check t->nod->type too
   400  	if t.Nod == nil || t.Nod.Type != t {
   401  		t.Nod = Nod(OTYPE, nil, nil)
   402  		t.Nod.Type = t
   403  		t.Nod.Sym = t.Sym
   404  	}
   405  
   406  	return t.Nod
   407  }
   408  
   409  /*
   410   * this will return an old name
   411   * that has already been pushed on the
   412   * declaration list. a diagnostic is
   413   * generated if no name has been defined.
   414   */
   415  func oldname(s *Sym) *Node {
   416  	n := s.Def
   417  	if n == nil {
   418  		// maybe a top-level name will come along
   419  		// to give this a definition later.
   420  		// walkdef will check s->def again once
   421  		// all the input source has been processed.
   422  		n = newname(s)
   423  
   424  		n.Op = ONONAME
   425  		n.Iota = iota_ // save current iota value in const declarations
   426  	}
   427  
   428  	if Curfn != nil && n.Funcdepth > 0 && n.Funcdepth != Funcdepth && n.Op == ONAME {
   429  		// inner func is referring to var in outer func.
   430  		//
   431  		// TODO(rsc): If there is an outer variable x and we
   432  		// are parsing x := 5 inside the closure, until we get to
   433  		// the := it looks like a reference to the outer x so we'll
   434  		// make x a closure variable unnecessarily.
   435  		if n.Closure == nil || n.Closure.Funcdepth != Funcdepth {
   436  			// create new closure var.
   437  			c := Nod(ONAME, nil, nil)
   438  
   439  			c.Sym = s
   440  			c.Class = PPARAMREF
   441  			c.Isddd = n.Isddd
   442  			c.Defn = n
   443  			c.Addable = false
   444  			c.Ullman = 2
   445  			c.Funcdepth = Funcdepth
   446  			c.Outer = n.Closure
   447  			n.Closure = c
   448  			c.Closure = n
   449  			c.Xoffset = 0
   450  			Curfn.Func.Cvars = list(Curfn.Func.Cvars, c)
   451  		}
   452  
   453  		// return ref to closure var, not original
   454  		return n.Closure
   455  	}
   456  
   457  	return n
   458  }
   459  
   460  /*
   461   * := declarations
   462   */
   463  func colasname(n *Node) bool {
   464  	switch n.Op {
   465  	case ONAME,
   466  		ONONAME,
   467  		OPACK,
   468  		OTYPE,
   469  		OLITERAL:
   470  		return n.Sym != nil
   471  	}
   472  
   473  	return false
   474  }
   475  
   476  func colasdefn(left *NodeList, defn *Node) {
   477  	for l := left; l != nil; l = l.Next {
   478  		if l.N.Sym != nil {
   479  			l.N.Sym.Flags |= SymUniq
   480  		}
   481  	}
   482  
   483  	nnew := 0
   484  	nerr := 0
   485  	var n *Node
   486  	for l := left; l != nil; l = l.Next {
   487  		n = l.N
   488  		if isblank(n) {
   489  			continue
   490  		}
   491  		if !colasname(n) {
   492  			yyerrorl(int(defn.Lineno), "non-name %v on left side of :=", n)
   493  			nerr++
   494  			continue
   495  		}
   496  
   497  		if n.Sym.Flags&SymUniq == 0 {
   498  			yyerrorl(int(defn.Lineno), "%v repeated on left side of :=", n.Sym)
   499  			n.Diag++
   500  			nerr++
   501  			continue
   502  		}
   503  
   504  		n.Sym.Flags &^= SymUniq
   505  		if n.Sym.Block == block {
   506  			continue
   507  		}
   508  
   509  		nnew++
   510  		n = newname(n.Sym)
   511  		declare(n, dclcontext)
   512  		n.Defn = defn
   513  		defn.Ninit = list(defn.Ninit, Nod(ODCL, n, nil))
   514  		l.N = n
   515  	}
   516  
   517  	if nnew == 0 && nerr == 0 {
   518  		yyerrorl(int(defn.Lineno), "no new variables on left side of :=")
   519  	}
   520  }
   521  
   522  func colas(left *NodeList, right *NodeList, lno int32) *Node {
   523  	as := Nod(OAS2, nil, nil)
   524  	as.List = left
   525  	as.Rlist = right
   526  	as.Colas = true
   527  	as.Lineno = lno
   528  	colasdefn(left, as)
   529  
   530  	// make the tree prettier; not necessary
   531  	if count(left) == 1 && count(right) == 1 {
   532  		as.Left = as.List.N
   533  		as.Right = as.Rlist.N
   534  		as.List = nil
   535  		as.Rlist = nil
   536  		as.Op = OAS
   537  	}
   538  
   539  	return as
   540  }
   541  
   542  /*
   543   * declare the arguments in an
   544   * interface field declaration.
   545   */
   546  func ifacedcl(n *Node) {
   547  	if n.Op != ODCLFIELD || n.Right == nil {
   548  		Fatal("ifacedcl")
   549  	}
   550  
   551  	if isblank(n.Left) {
   552  		Yyerror("methods must have a unique non-blank name")
   553  	}
   554  
   555  	n.Func = new(Func)
   556  	dclcontext = PPARAM
   557  	markdcl()
   558  	Funcdepth++
   559  	n.Outer = Curfn
   560  	Curfn = n
   561  	funcargs(n.Right)
   562  
   563  	// funcbody is normally called after the parser has
   564  	// seen the body of a function but since an interface
   565  	// field declaration does not have a body, we must
   566  	// call it now to pop the current declaration context.
   567  	dclcontext = PAUTO
   568  
   569  	funcbody(n)
   570  }
   571  
   572  /*
   573   * declare the function proper
   574   * and declare the arguments.
   575   * called in extern-declaration context
   576   * returns in auto-declaration context.
   577   */
   578  func funchdr(n *Node) {
   579  	// change the declaration context from extern to auto
   580  	if Funcdepth == 0 && dclcontext != PEXTERN {
   581  		Fatal("funchdr: dclcontext")
   582  	}
   583  
   584  	dclcontext = PAUTO
   585  	markdcl()
   586  	Funcdepth++
   587  
   588  	n.Outer = Curfn
   589  	Curfn = n
   590  
   591  	if n.Nname != nil {
   592  		funcargs(n.Nname.Ntype)
   593  	} else if n.Ntype != nil {
   594  		funcargs(n.Ntype)
   595  	} else {
   596  		funcargs2(n.Type)
   597  	}
   598  }
   599  
   600  func funcargs(nt *Node) {
   601  	if nt.Op != OTFUNC {
   602  		Fatal("funcargs %v", Oconv(int(nt.Op), 0))
   603  	}
   604  
   605  	// re-start the variable generation number
   606  	// we want to use small numbers for the return variables,
   607  	// so let them have the chunk starting at 1.
   608  	vargen = count(nt.Rlist)
   609  
   610  	// declare the receiver and in arguments.
   611  	// no n->defn because type checking of func header
   612  	// will not fill in the types until later
   613  	if nt.Left != nil {
   614  		n := nt.Left
   615  		if n.Op != ODCLFIELD {
   616  			Fatal("funcargs receiver %v", Oconv(int(n.Op), 0))
   617  		}
   618  		if n.Left != nil {
   619  			n.Left.Op = ONAME
   620  			n.Left.Ntype = n.Right
   621  			declare(n.Left, PPARAM)
   622  			if dclcontext == PAUTO {
   623  				vargen++
   624  				n.Left.Vargen = int32(vargen)
   625  			}
   626  		}
   627  	}
   628  
   629  	var n *Node
   630  	for l := nt.List; l != nil; l = l.Next {
   631  		n = l.N
   632  		if n.Op != ODCLFIELD {
   633  			Fatal("funcargs in %v", Oconv(int(n.Op), 0))
   634  		}
   635  		if n.Left != nil {
   636  			n.Left.Op = ONAME
   637  			n.Left.Ntype = n.Right
   638  			declare(n.Left, PPARAM)
   639  			if dclcontext == PAUTO {
   640  				vargen++
   641  				n.Left.Vargen = int32(vargen)
   642  			}
   643  		}
   644  	}
   645  
   646  	// declare the out arguments.
   647  	gen := count(nt.List)
   648  	var i int = 0
   649  	var nn *Node
   650  	for l := nt.Rlist; l != nil; l = l.Next {
   651  		n = l.N
   652  
   653  		if n.Op != ODCLFIELD {
   654  			Fatal("funcargs out %v", Oconv(int(n.Op), 0))
   655  		}
   656  
   657  		if n.Left == nil {
   658  			// Name so that escape analysis can track it. ~r stands for 'result'.
   659  			n.Left = newname(Lookupf("~r%d", gen))
   660  			gen++
   661  		}
   662  
   663  		// TODO: n->left->missing = 1;
   664  		n.Left.Op = ONAME
   665  
   666  		if isblank(n.Left) {
   667  			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
   668  			// The name must be different from ~r above because if you have
   669  			//	func f() (_ int)
   670  			//	func g() int
   671  			// f is allowed to use a plain 'return' with no arguments, while g is not.
   672  			// So the two cases must be distinguished.
   673  			// We do not record a pointer to the original node (n->orig).
   674  			// Having multiple names causes too much confusion in later passes.
   675  			nn = Nod(OXXX, nil, nil)
   676  
   677  			*nn = *n.Left
   678  			nn.Orig = nn
   679  			nn.Sym = Lookupf("~b%d", gen)
   680  			gen++
   681  			n.Left = nn
   682  		}
   683  
   684  		n.Left.Ntype = n.Right
   685  		declare(n.Left, PPARAMOUT)
   686  		if dclcontext == PAUTO {
   687  			i++
   688  			n.Left.Vargen = int32(i)
   689  		}
   690  	}
   691  }
   692  
   693  /*
   694   * Same as funcargs, except run over an already constructed TFUNC.
   695   * This happens during import, where the hidden_fndcl rule has
   696   * used functype directly to parse the function's type.
   697   */
   698  func funcargs2(t *Type) {
   699  	if t.Etype != TFUNC {
   700  		Fatal("funcargs2 %v", t)
   701  	}
   702  
   703  	if t.Thistuple != 0 {
   704  		var n *Node
   705  		for ft := getthisx(t).Type; ft != nil; ft = ft.Down {
   706  			if ft.Nname == nil || ft.Nname.Sym == nil {
   707  				continue
   708  			}
   709  			n = ft.Nname // no need for newname(ft->nname->sym)
   710  			n.Type = ft.Type
   711  			declare(n, PPARAM)
   712  		}
   713  	}
   714  
   715  	if t.Intuple != 0 {
   716  		var n *Node
   717  		for ft := getinargx(t).Type; ft != nil; ft = ft.Down {
   718  			if ft.Nname == nil || ft.Nname.Sym == nil {
   719  				continue
   720  			}
   721  			n = ft.Nname
   722  			n.Type = ft.Type
   723  			declare(n, PPARAM)
   724  		}
   725  	}
   726  
   727  	if t.Outtuple != 0 {
   728  		var n *Node
   729  		for ft := getoutargx(t).Type; ft != nil; ft = ft.Down {
   730  			if ft.Nname == nil || ft.Nname.Sym == nil {
   731  				continue
   732  			}
   733  			n = ft.Nname
   734  			n.Type = ft.Type
   735  			declare(n, PPARAMOUT)
   736  		}
   737  	}
   738  }
   739  
   740  /*
   741   * finish the body.
   742   * called in auto-declaration context.
   743   * returns in extern-declaration context.
   744   */
   745  func funcbody(n *Node) {
   746  	// change the declaration context from auto to extern
   747  	if dclcontext != PAUTO {
   748  		Fatal("funcbody: dclcontext")
   749  	}
   750  	popdcl()
   751  	Funcdepth--
   752  	Curfn = n.Outer
   753  	n.Outer = nil
   754  	if Funcdepth == 0 {
   755  		dclcontext = PEXTERN
   756  	}
   757  }
   758  
   759  /*
   760   * new type being defined with name s.
   761   */
   762  func typedcl0(s *Sym) *Node {
   763  	n := newname(s)
   764  	n.Op = OTYPE
   765  	declare(n, dclcontext)
   766  	return n
   767  }
   768  
   769  /*
   770   * node n, which was returned by typedcl0
   771   * is being declared to have uncompiled type t.
   772   * return the ODCLTYPE node to use.
   773   */
   774  func typedcl1(n *Node, t *Node, local bool) *Node {
   775  	n.Ntype = t
   776  	n.Local = local
   777  	return Nod(ODCLTYPE, n, nil)
   778  }
   779  
   780  /*
   781   * structs, functions, and methods.
   782   * they don't belong here, but where do they belong?
   783   */
   784  func checkembeddedtype(t *Type) {
   785  	if t == nil {
   786  		return
   787  	}
   788  
   789  	if t.Sym == nil && Isptr[t.Etype] {
   790  		t = t.Type
   791  		if t.Etype == TINTER {
   792  			Yyerror("embedded type cannot be a pointer to interface")
   793  		}
   794  	}
   795  
   796  	if Isptr[t.Etype] {
   797  		Yyerror("embedded type cannot be a pointer")
   798  	} else if t.Etype == TFORW && t.Embedlineno == 0 {
   799  		t.Embedlineno = lineno
   800  	}
   801  }
   802  
   803  func structfield(n *Node) *Type {
   804  	lno := int(lineno)
   805  	lineno = n.Lineno
   806  
   807  	if n.Op != ODCLFIELD {
   808  		Fatal("structfield: oops %v\n", n)
   809  	}
   810  
   811  	f := typ(TFIELD)
   812  	f.Isddd = n.Isddd
   813  
   814  	if n.Right != nil {
   815  		typecheck(&n.Right, Etype)
   816  		n.Type = n.Right.Type
   817  		if n.Left != nil {
   818  			n.Left.Type = n.Type
   819  		}
   820  		if n.Embedded != 0 {
   821  			checkembeddedtype(n.Type)
   822  		}
   823  	}
   824  
   825  	n.Right = nil
   826  
   827  	f.Type = n.Type
   828  	if f.Type == nil {
   829  		f.Broke = 1
   830  	}
   831  
   832  	switch n.Val.Ctype {
   833  	case CTSTR:
   834  		f.Note = new(string)
   835  		*f.Note = n.Val.U.Sval
   836  
   837  	default:
   838  		Yyerror("field annotation must be string")
   839  		fallthrough
   840  
   841  	case CTxxx:
   842  		f.Note = nil
   843  	}
   844  
   845  	if n.Left != nil && n.Left.Op == ONAME {
   846  		f.Nname = n.Left
   847  		f.Embedded = n.Embedded
   848  		f.Sym = f.Nname.Sym
   849  	}
   850  
   851  	lineno = int32(lno)
   852  	return f
   853  }
   854  
   855  var uniqgen uint32
   856  
   857  func checkdupfields(t *Type, what string) {
   858  	lno := int(lineno)
   859  
   860  	for ; t != nil; t = t.Down {
   861  		if t.Sym != nil && t.Nname != nil && !isblank(t.Nname) {
   862  			if t.Sym.Uniqgen == uniqgen {
   863  				lineno = t.Nname.Lineno
   864  				Yyerror("duplicate %s %s", what, t.Sym.Name)
   865  			} else {
   866  				t.Sym.Uniqgen = uniqgen
   867  			}
   868  		}
   869  	}
   870  
   871  	lineno = int32(lno)
   872  }
   873  
   874  /*
   875   * convert a parsed id/type list into
   876   * a type for struct/interface/arglist
   877   */
   878  func tostruct(l *NodeList) *Type {
   879  	var f *Type
   880  	t := typ(TSTRUCT)
   881  
   882  	for tp := &t.Type; l != nil; l = l.Next {
   883  		f = structfield(l.N)
   884  
   885  		*tp = f
   886  		tp = &f.Down
   887  	}
   888  
   889  	for f := t.Type; f != nil && t.Broke == 0; f = f.Down {
   890  		if f.Broke != 0 {
   891  			t.Broke = 1
   892  		}
   893  	}
   894  
   895  	uniqgen++
   896  	checkdupfields(t.Type, "field")
   897  
   898  	if t.Broke == 0 {
   899  		checkwidth(t)
   900  	}
   901  
   902  	return t
   903  }
   904  
   905  func tofunargs(l *NodeList) *Type {
   906  	var f *Type
   907  
   908  	t := typ(TSTRUCT)
   909  	t.Funarg = 1
   910  
   911  	for tp := &t.Type; l != nil; l = l.Next {
   912  		f = structfield(l.N)
   913  		f.Funarg = 1
   914  
   915  		// esc.c needs to find f given a PPARAM to add the tag.
   916  		if l.N.Left != nil && l.N.Left.Class == PPARAM {
   917  			l.N.Left.Paramfld = f
   918  		}
   919  
   920  		*tp = f
   921  		tp = &f.Down
   922  	}
   923  
   924  	for f := t.Type; f != nil && t.Broke == 0; f = f.Down {
   925  		if f.Broke != 0 {
   926  			t.Broke = 1
   927  		}
   928  	}
   929  
   930  	return t
   931  }
   932  
   933  func interfacefield(n *Node) *Type {
   934  	lno := int(lineno)
   935  	lineno = n.Lineno
   936  
   937  	if n.Op != ODCLFIELD {
   938  		Fatal("interfacefield: oops %v\n", n)
   939  	}
   940  
   941  	if n.Val.Ctype != CTxxx {
   942  		Yyerror("interface method cannot have annotation")
   943  	}
   944  
   945  	f := typ(TFIELD)
   946  	f.Isddd = n.Isddd
   947  
   948  	if n.Right != nil {
   949  		if n.Left != nil {
   950  			// queue resolution of method type for later.
   951  			// right now all we need is the name list.
   952  			// avoids cycles for recursive interface types.
   953  			n.Type = typ(TINTERMETH)
   954  
   955  			n.Type.Nname = n.Right
   956  			n.Left.Type = n.Type
   957  			queuemethod(n)
   958  
   959  			if n.Left.Op == ONAME {
   960  				f.Nname = n.Left
   961  				f.Embedded = n.Embedded
   962  				f.Sym = f.Nname.Sym
   963  			}
   964  		} else {
   965  			typecheck(&n.Right, Etype)
   966  			n.Type = n.Right.Type
   967  
   968  			if n.Embedded != 0 {
   969  				checkembeddedtype(n.Type)
   970  			}
   971  
   972  			if n.Type != nil {
   973  				switch n.Type.Etype {
   974  				case TINTER:
   975  					break
   976  
   977  				case TFORW:
   978  					Yyerror("interface type loop involving %v", n.Type)
   979  					f.Broke = 1
   980  
   981  				default:
   982  					Yyerror("interface contains embedded non-interface %v", n.Type)
   983  					f.Broke = 1
   984  				}
   985  			}
   986  		}
   987  	}
   988  
   989  	n.Right = nil
   990  
   991  	f.Type = n.Type
   992  	if f.Type == nil {
   993  		f.Broke = 1
   994  	}
   995  
   996  	lineno = int32(lno)
   997  	return f
   998  }
   999  
  1000  func tointerface(l *NodeList) *Type {
  1001  	var f *Type
  1002  	var t1 *Type
  1003  
  1004  	t := typ(TINTER)
  1005  
  1006  	tp := &t.Type
  1007  	for ; l != nil; l = l.Next {
  1008  		f = interfacefield(l.N)
  1009  
  1010  		if l.N.Left == nil && f.Type.Etype == TINTER {
  1011  			// embedded interface, inline methods
  1012  			for t1 = f.Type.Type; t1 != nil; t1 = t1.Down {
  1013  				f = typ(TFIELD)
  1014  				f.Type = t1.Type
  1015  				f.Broke = t1.Broke
  1016  				f.Sym = t1.Sym
  1017  				if f.Sym != nil {
  1018  					f.Nname = newname(f.Sym)
  1019  				}
  1020  				*tp = f
  1021  				tp = &f.Down
  1022  			}
  1023  		} else {
  1024  			*tp = f
  1025  			tp = &f.Down
  1026  		}
  1027  	}
  1028  
  1029  	for f := t.Type; f != nil && t.Broke == 0; f = f.Down {
  1030  		if f.Broke != 0 {
  1031  			t.Broke = 1
  1032  		}
  1033  	}
  1034  
  1035  	uniqgen++
  1036  	checkdupfields(t.Type, "method")
  1037  	t = sortinter(t)
  1038  	checkwidth(t)
  1039  
  1040  	return t
  1041  }
  1042  
  1043  func embedded(s *Sym, pkg *Pkg) *Node {
  1044  	const (
  1045  		CenterDot = 0xB7
  1046  	)
  1047  	// Names sometimes have disambiguation junk
  1048  	// appended after a center dot.  Discard it when
  1049  	// making the name for the embedded struct field.
  1050  	name := s.Name
  1051  
  1052  	if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
  1053  		name = s.Name[:i]
  1054  	}
  1055  
  1056  	var n *Node
  1057  	if exportname(name) {
  1058  		n = newname(Lookup(name))
  1059  	} else if s.Pkg == builtinpkg {
  1060  		// The name of embedded builtins belongs to pkg.
  1061  		n = newname(Pkglookup(name, pkg))
  1062  	} else {
  1063  		n = newname(Pkglookup(name, s.Pkg))
  1064  	}
  1065  	n = Nod(ODCLFIELD, n, oldname(s))
  1066  	n.Embedded = 1
  1067  	return n
  1068  }
  1069  
  1070  /*
  1071   * check that the list of declarations is either all anonymous or all named
  1072   */
  1073  func findtype(l *NodeList) *Node {
  1074  	for ; l != nil; l = l.Next {
  1075  		if l.N.Op == OKEY {
  1076  			return l.N.Right
  1077  		}
  1078  	}
  1079  	return nil
  1080  }
  1081  
  1082  func checkarglist(all *NodeList, input int) *NodeList {
  1083  	named := 0
  1084  	for l := all; l != nil; l = l.Next {
  1085  		if l.N.Op == OKEY {
  1086  			named = 1
  1087  			break
  1088  		}
  1089  	}
  1090  
  1091  	if named != 0 {
  1092  		var n *Node
  1093  		var l *NodeList
  1094  		for l = all; l != nil; l = l.Next {
  1095  			n = l.N
  1096  			if n.Op != OKEY && n.Sym == nil {
  1097  				Yyerror("mixed named and unnamed function parameters")
  1098  				break
  1099  			}
  1100  		}
  1101  
  1102  		if l == nil && n != nil && n.Op != OKEY {
  1103  			Yyerror("final function parameter must have type")
  1104  		}
  1105  	}
  1106  
  1107  	var nextt *Node
  1108  	var t *Node
  1109  	var n *Node
  1110  	for l := all; l != nil; l = l.Next {
  1111  		// can cache result from findtype to avoid
  1112  		// quadratic behavior here, but unlikely to matter.
  1113  		n = l.N
  1114  
  1115  		if named != 0 {
  1116  			if n.Op == OKEY {
  1117  				t = n.Right
  1118  				n = n.Left
  1119  				nextt = nil
  1120  			} else {
  1121  				if nextt == nil {
  1122  					nextt = findtype(l)
  1123  				}
  1124  				t = nextt
  1125  			}
  1126  		} else {
  1127  			t = n
  1128  			n = nil
  1129  		}
  1130  
  1131  		// during import l->n->op is OKEY, but l->n->left->sym == S
  1132  		// means it was a '?', not that it was
  1133  		// a lone type This doesn't matter for the exported
  1134  		// declarations, which are parsed by rules that don't
  1135  		// use checkargs, but can happen for func literals in
  1136  		// the inline bodies.
  1137  		// TODO(rsc) this can go when typefmt case TFIELD in exportmode fmt.c prints _ instead of ?
  1138  		if importpkg != nil && n.Sym == nil {
  1139  			n = nil
  1140  		}
  1141  
  1142  		if n != nil && n.Sym == nil {
  1143  			t = n
  1144  			n = nil
  1145  		}
  1146  
  1147  		if n != nil {
  1148  			n = newname(n.Sym)
  1149  		}
  1150  		n = Nod(ODCLFIELD, n, t)
  1151  		if n.Right != nil && n.Right.Op == ODDD {
  1152  			if input == 0 {
  1153  				Yyerror("cannot use ... in output argument list")
  1154  			} else if l.Next != nil {
  1155  				Yyerror("can only use ... as final argument in list")
  1156  			}
  1157  			n.Right.Op = OTARRAY
  1158  			n.Right.Right = n.Right.Left
  1159  			n.Right.Left = nil
  1160  			n.Isddd = true
  1161  			if n.Left != nil {
  1162  				n.Left.Isddd = true
  1163  			}
  1164  		}
  1165  
  1166  		l.N = n
  1167  	}
  1168  
  1169  	return all
  1170  }
  1171  
  1172  func fakethis() *Node {
  1173  	n := Nod(ODCLFIELD, nil, typenod(Ptrto(typ(TSTRUCT))))
  1174  	return n
  1175  }
  1176  
  1177  /*
  1178   * Is this field a method on an interface?
  1179   * Those methods have an anonymous
  1180   * *struct{} as the receiver.
  1181   * (See fakethis above.)
  1182   */
  1183  func isifacemethod(f *Type) bool {
  1184  	rcvr := getthisx(f).Type
  1185  	if rcvr.Sym != nil {
  1186  		return false
  1187  	}
  1188  	t := rcvr.Type
  1189  	if !Isptr[t.Etype] {
  1190  		return false
  1191  	}
  1192  	t = t.Type
  1193  	if t.Sym != nil || t.Etype != TSTRUCT || t.Type != nil {
  1194  		return false
  1195  	}
  1196  	return true
  1197  }
  1198  
  1199  /*
  1200   * turn a parsed function declaration
  1201   * into a type
  1202   */
  1203  func functype(this *Node, in *NodeList, out *NodeList) *Type {
  1204  	t := typ(TFUNC)
  1205  
  1206  	var rcvr *NodeList
  1207  	if this != nil {
  1208  		rcvr = list1(this)
  1209  	}
  1210  	t.Type = tofunargs(rcvr)
  1211  	t.Type.Down = tofunargs(out)
  1212  	t.Type.Down.Down = tofunargs(in)
  1213  
  1214  	uniqgen++
  1215  	checkdupfields(t.Type.Type, "argument")
  1216  	checkdupfields(t.Type.Down.Type, "argument")
  1217  	checkdupfields(t.Type.Down.Down.Type, "argument")
  1218  
  1219  	if t.Type.Broke != 0 || t.Type.Down.Broke != 0 || t.Type.Down.Down.Broke != 0 {
  1220  		t.Broke = 1
  1221  	}
  1222  
  1223  	if this != nil {
  1224  		t.Thistuple = 1
  1225  	}
  1226  	t.Outtuple = count(out)
  1227  	t.Intuple = count(in)
  1228  	t.Outnamed = 0
  1229  	if t.Outtuple > 0 && out.N.Left != nil && out.N.Left.Orig != nil {
  1230  		s := out.N.Left.Orig.Sym
  1231  		if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
  1232  			t.Outnamed = 1
  1233  		}
  1234  	}
  1235  
  1236  	return t
  1237  }
  1238  
  1239  var methodsym_toppkg *Pkg
  1240  
  1241  func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
  1242  	var s *Sym
  1243  	var p string
  1244  	var suffix string
  1245  	var spkg *Pkg
  1246  
  1247  	t := t0
  1248  	if t == nil {
  1249  		goto bad
  1250  	}
  1251  	s = t.Sym
  1252  	if s == nil && Isptr[t.Etype] {
  1253  		t = t.Type
  1254  		if t == nil {
  1255  			goto bad
  1256  		}
  1257  		s = t.Sym
  1258  	}
  1259  
  1260  	spkg = nil
  1261  	if s != nil {
  1262  		spkg = s.Pkg
  1263  	}
  1264  
  1265  	// if t0 == *t and t0 has a sym,
  1266  	// we want to see *t, not t0, in the method name.
  1267  	if t != t0 && t0.Sym != nil {
  1268  		t0 = Ptrto(t)
  1269  	}
  1270  
  1271  	suffix = ""
  1272  	if iface != 0 {
  1273  		dowidth(t0)
  1274  		if t0.Width < Types[Tptr].Width {
  1275  			suffix = "·i"
  1276  		}
  1277  	}
  1278  
  1279  	if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) {
  1280  		if t0.Sym == nil && Isptr[t0.Etype] {
  1281  			p = fmt.Sprintf("(%v).%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
  1282  		} else {
  1283  			p = fmt.Sprintf("%v.%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
  1284  		}
  1285  	} else {
  1286  		if t0.Sym == nil && Isptr[t0.Etype] {
  1287  			p = fmt.Sprintf("(%v).%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix)
  1288  		} else {
  1289  			p = fmt.Sprintf("%v.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix)
  1290  		}
  1291  	}
  1292  
  1293  	if spkg == nil {
  1294  		if methodsym_toppkg == nil {
  1295  			methodsym_toppkg = mkpkg("go")
  1296  		}
  1297  		spkg = methodsym_toppkg
  1298  	}
  1299  
  1300  	s = Pkglookup(p, spkg)
  1301  
  1302  	return s
  1303  
  1304  bad:
  1305  	Yyerror("illegal receiver type: %v", t0)
  1306  	return nil
  1307  }
  1308  
  1309  func methodname(n *Node, t *Type) *Node {
  1310  	s := methodsym(n.Sym, t, 0)
  1311  	if s == nil {
  1312  		return n
  1313  	}
  1314  	return newname(s)
  1315  }
  1316  
  1317  func methodname1(n *Node, t *Node) *Node {
  1318  	star := ""
  1319  	if t.Op == OIND {
  1320  		star = "*"
  1321  		t = t.Left
  1322  	}
  1323  
  1324  	if t.Sym == nil || isblank(n) {
  1325  		return newfuncname(n.Sym)
  1326  	}
  1327  
  1328  	var p string
  1329  	if star != "" {
  1330  		p = fmt.Sprintf("(%s%v).%v", star, t.Sym, n.Sym)
  1331  	} else {
  1332  		p = fmt.Sprintf("%v.%v", t.Sym, n.Sym)
  1333  	}
  1334  
  1335  	if exportname(t.Sym.Name) {
  1336  		n = newfuncname(Lookup(p))
  1337  	} else {
  1338  		n = newfuncname(Pkglookup(p, t.Sym.Pkg))
  1339  	}
  1340  
  1341  	return n
  1342  }
  1343  
  1344  /*
  1345   * add a method, declared as a function,
  1346   * n is fieldname, pa is base type, t is function type
  1347   */
  1348  func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
  1349  	// get field sym
  1350  	if sf == nil {
  1351  		Fatal("no method symbol")
  1352  	}
  1353  
  1354  	// get parent type sym
  1355  	pa := getthisx(t).Type // ptr to this structure
  1356  	if pa == nil {
  1357  		Yyerror("missing receiver")
  1358  		return
  1359  	}
  1360  
  1361  	pa = pa.Type
  1362  	f := methtype(pa, 1)
  1363  	if f == nil {
  1364  		t = pa
  1365  		if t == nil { // rely on typecheck having complained before
  1366  			return
  1367  		}
  1368  		if t != nil {
  1369  			if Isptr[t.Etype] {
  1370  				if t.Sym != nil {
  1371  					Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
  1372  					return
  1373  				}
  1374  
  1375  				t = t.Type
  1376  			}
  1377  
  1378  			if t.Broke != 0 { // rely on typecheck having complained before
  1379  				return
  1380  			}
  1381  			if t.Sym == nil {
  1382  				Yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
  1383  				return
  1384  			}
  1385  
  1386  			if Isptr[t.Etype] {
  1387  				Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
  1388  				return
  1389  			}
  1390  
  1391  			if t.Etype == TINTER {
  1392  				Yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
  1393  				return
  1394  			}
  1395  		}
  1396  
  1397  		// Should have picked off all the reasons above,
  1398  		// but just in case, fall back to generic error.
  1399  		Yyerror("invalid receiver type %v (%v / %v)", pa, Tconv(pa, obj.FmtLong), Tconv(t, obj.FmtLong))
  1400  
  1401  		return
  1402  	}
  1403  
  1404  	pa = f
  1405  	if pa.Etype == TSTRUCT {
  1406  		for f := pa.Type; f != nil; f = f.Down {
  1407  			if f.Sym == sf {
  1408  				Yyerror("type %v has both field and method named %v", pa, sf)
  1409  				return
  1410  			}
  1411  		}
  1412  	}
  1413  
  1414  	if local && !pa.Local {
  1415  		// defining method on non-local type.
  1416  		Yyerror("cannot define new methods on non-local type %v", pa)
  1417  
  1418  		return
  1419  	}
  1420  
  1421  	n := Nod(ODCLFIELD, newname(sf), nil)
  1422  	n.Type = t
  1423  
  1424  	var d *Type // last found
  1425  	for f := pa.Method; f != nil; f = f.Down {
  1426  		d = f
  1427  		if f.Etype != TFIELD {
  1428  			Fatal("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong))
  1429  		}
  1430  		if sf.Name != f.Sym.Name {
  1431  			continue
  1432  		}
  1433  		if !Eqtype(t, f.Type) {
  1434  			Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", pa, sf, f.Type, t)
  1435  		}
  1436  		return
  1437  	}
  1438  
  1439  	f = structfield(n)
  1440  	f.Nointerface = nointerface
  1441  
  1442  	// during import unexported method names should be in the type's package
  1443  	if importpkg != nil && f.Sym != nil && !exportname(f.Sym.Name) && f.Sym.Pkg != structpkg {
  1444  		Fatal("imported method name %v in wrong package %s\n", Sconv(f.Sym, obj.FmtSign), structpkg.Name)
  1445  	}
  1446  
  1447  	if d == nil {
  1448  		pa.Method = f
  1449  	} else {
  1450  		d.Down = f
  1451  	}
  1452  	return
  1453  }
  1454  
  1455  func funccompile(n *Node) {
  1456  	Stksize = BADWIDTH
  1457  	Maxarg = 0
  1458  
  1459  	if n.Type == nil {
  1460  		if nerrors == 0 {
  1461  			Fatal("funccompile missing type")
  1462  		}
  1463  		return
  1464  	}
  1465  
  1466  	// assign parameter offsets
  1467  	checkwidth(n.Type)
  1468  
  1469  	if Curfn != nil {
  1470  		Fatal("funccompile %v inside %v", n.Nname.Sym, Curfn.Nname.Sym)
  1471  	}
  1472  
  1473  	Stksize = 0
  1474  	dclcontext = PAUTO
  1475  	Funcdepth = n.Funcdepth + 1
  1476  	compile(n)
  1477  	Curfn = nil
  1478  	Funcdepth = 0
  1479  	dclcontext = PEXTERN
  1480  }
  1481  
  1482  func funcsym(s *Sym) *Sym {
  1483  	if s.Fsym != nil {
  1484  		return s.Fsym
  1485  	}
  1486  
  1487  	s1 := Pkglookup(s.Name+"·f", s.Pkg)
  1488  	if s1.Def == nil {
  1489  		s1.Def = newfuncname(s1)
  1490  		s1.Def.Func.Shortname = newname(s)
  1491  		funcsyms = list(funcsyms, s1.Def)
  1492  	}
  1493  	s.Fsym = s1
  1494  
  1495  	return s1
  1496  }