Home | History | Annotate | Download | only in gc
      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 }
   1514