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