github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/src/cmd/compile/internal/gc/dcl.go (about)

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