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