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