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