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