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