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