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