...

Source file src/pkg/cmd/compile/internal/gc/dcl.go

     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		"bytes"
     9		"cmd/compile/internal/types"
    10		"cmd/internal/obj"
    11		"cmd/internal/src"
    12		"fmt"
    13		"strings"
    14	)
    15	
    16	// Declaration stack & operations
    17	
    18	var externdcl []*Node
    19	
    20	func testdclstack() {
    21		if !types.IsDclstackValid() {
    22			if nerrors != 0 {
    23				errorexit()
    24			}
    25			Fatalf("mark left on the dclstack")
    26		}
    27	}
    28	
    29	// redeclare emits a diagnostic about symbol s being redeclared at pos.
    30	func redeclare(pos src.XPos, s *types.Sym, where string) {
    31		if !s.Lastlineno.IsKnown() {
    32			pkg := s.Origpkg
    33			if pkg == nil {
    34				pkg = s.Pkg
    35			}
    36			yyerrorl(pos, "%v redeclared %s\n"+
    37				"\tprevious declaration during import %q", s, where, pkg.Path)
    38		} else {
    39			prevPos := s.Lastlineno
    40	
    41			// When an import and a declaration collide in separate files,
    42			// present the import as the "redeclared", because the declaration
    43			// is visible where the import is, but not vice versa.
    44			// See issue 4510.
    45			if s.Def == nil {
    46				pos, prevPos = prevPos, pos
    47			}
    48	
    49			yyerrorl(pos, "%v redeclared %s\n"+
    50				"\tprevious declaration at %v", s, where, linestr(prevPos))
    51		}
    52	}
    53	
    54	var vargen int
    55	
    56	// declare individual names - var, typ, const
    57	
    58	var declare_typegen int
    59	
    60	// declare records that Node n declares symbol n.Sym in the specified
    61	// declaration context.
    62	func declare(n *Node, ctxt Class) {
    63		if ctxt == PDISCARD {
    64			return
    65		}
    66	
    67		if n.isBlank() {
    68			return
    69		}
    70	
    71		if n.Name == nil {
    72			// named OLITERAL needs Name; most OLITERALs don't.
    73			n.Name = new(Name)
    74		}
    75	
    76		s := n.Sym
    77	
    78		// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
    79		if !inimport && !typecheckok && s.Pkg != localpkg {
    80			yyerrorl(n.Pos, "cannot declare name %v", s)
    81		}
    82	
    83		gen := 0
    84		if ctxt == PEXTERN {
    85			if s.Name == "init" {
    86				yyerrorl(n.Pos, "cannot declare init - must be func")
    87			}
    88			if s.Name == "main" && s.Pkg.Name == "main" {
    89				yyerrorl(n.Pos, "cannot declare main - must be func")
    90			}
    91			externdcl = append(externdcl, n)
    92		} else {
    93			if Curfn == nil && ctxt == PAUTO {
    94				lineno = n.Pos
    95				Fatalf("automatic outside function")
    96			}
    97			if Curfn != nil {
    98				Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
    99			}
   100			if n.Op == OTYPE {
   101				declare_typegen++
   102				gen = declare_typegen
   103			} else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
   104				vargen++
   105				gen = vargen
   106			}
   107			types.Pushdcl(s)
   108			n.Name.Curfn = Curfn
   109		}
   110	
   111		if ctxt == PAUTO {
   112			n.Xoffset = 0
   113		}
   114	
   115		if s.Block == types.Block {
   116			// functype will print errors about duplicate function arguments.
   117			// Don't repeat the error here.
   118			if ctxt != PPARAM && ctxt != PPARAMOUT {
   119				redeclare(n.Pos, s, "in this block")
   120			}
   121		}
   122	
   123		s.Block = types.Block
   124		s.Lastlineno = lineno
   125		s.Def = asTypesNode(n)
   126		n.Name.Vargen = int32(gen)
   127		n.SetClass(ctxt)
   128		if ctxt == PFUNC {
   129			n.Sym.SetFunc(true)
   130		}
   131	
   132		autoexport(n, ctxt)
   133	}
   134	
   135	func addvar(n *Node, t *types.Type, ctxt Class) {
   136		if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
   137			Fatalf("addvar: n=%v t=%v nil", n, t)
   138		}
   139	
   140		n.Op = ONAME
   141		declare(n, ctxt)
   142		n.Type = t
   143	}
   144	
   145	// declare variables from grammar
   146	// new_name_list (type | [type] = expr_list)
   147	func variter(vl []*Node, t *Node, el []*Node) []*Node {
   148		var init []*Node
   149		doexpr := len(el) > 0
   150	
   151		if len(el) == 1 && len(vl) > 1 {
   152			e := el[0]
   153			as2 := nod(OAS2, nil, nil)
   154			as2.List.Set(vl)
   155			as2.Rlist.Set1(e)
   156			for _, v := range vl {
   157				v.Op = ONAME
   158				declare(v, dclcontext)
   159				v.Name.Param.Ntype = t
   160				v.Name.Defn = as2
   161				if Curfn != nil {
   162					init = append(init, nod(ODCL, v, nil))
   163				}
   164			}
   165	
   166			return append(init, as2)
   167		}
   168	
   169		nel := len(el)
   170		for _, v := range vl {
   171			var e *Node
   172			if doexpr {
   173				if len(el) == 0 {
   174					yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
   175					break
   176				}
   177				e = el[0]
   178				el = el[1:]
   179			}
   180	
   181			v.Op = ONAME
   182			declare(v, dclcontext)
   183			v.Name.Param.Ntype = t
   184	
   185			if e != nil || Curfn != nil || v.isBlank() {
   186				if Curfn != nil {
   187					init = append(init, nod(ODCL, v, nil))
   188				}
   189				e = nod(OAS, v, e)
   190				init = append(init, e)
   191				if e.Right != nil {
   192					v.Name.Defn = e
   193				}
   194			}
   195		}
   196	
   197		if len(el) != 0 {
   198			yyerror("assignment mismatch: %d variables but %d values", len(vl), nel)
   199		}
   200		return init
   201	}
   202	
   203	// newnoname returns a new ONONAME Node associated with symbol s.
   204	func newnoname(s *types.Sym) *Node {
   205		if s == nil {
   206			Fatalf("newnoname nil")
   207		}
   208		n := nod(ONONAME, nil, nil)
   209		n.Sym = s
   210		n.SetAddable(true)
   211		n.Xoffset = 0
   212		return n
   213	}
   214	
   215	// newfuncnamel generates a new name node for a function or method.
   216	// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
   217	func newfuncnamel(pos src.XPos, s *types.Sym) *Node {
   218		n := newnamel(pos, s)
   219		n.Func = new(Func)
   220		n.Func.SetIsHiddenClosure(Curfn != nil)
   221		return n
   222	}
   223	
   224	// this generates a new name node for a name
   225	// being declared.
   226	func dclname(s *types.Sym) *Node {
   227		n := newname(s)
   228		n.Op = ONONAME // caller will correct it
   229		return n
   230	}
   231	
   232	func typenod(t *types.Type) *Node {
   233		return typenodl(src.NoXPos, t)
   234	}
   235	
   236	func typenodl(pos src.XPos, t *types.Type) *Node {
   237		// if we copied another type with *t = *u
   238		// then t->nod might be out of date, so
   239		// check t->nod->type too
   240		if asNode(t.Nod) == nil || asNode(t.Nod).Type != t {
   241			t.Nod = asTypesNode(nodl(pos, OTYPE, nil, nil))
   242			asNode(t.Nod).Type = t
   243			asNode(t.Nod).Sym = t.Sym
   244		}
   245	
   246		return asNode(t.Nod)
   247	}
   248	
   249	func anonfield(typ *types.Type) *Node {
   250		return symfield(nil, typ)
   251	}
   252	
   253	func namedfield(s string, typ *types.Type) *Node {
   254		return symfield(lookup(s), typ)
   255	}
   256	
   257	func symfield(s *types.Sym, typ *types.Type) *Node {
   258		n := nodSym(ODCLFIELD, nil, s)
   259		n.Type = typ
   260		return n
   261	}
   262	
   263	// oldname returns the Node that declares symbol s in the current scope.
   264	// If no such Node currently exists, an ONONAME Node is returned instead.
   265	func oldname(s *types.Sym) *Node {
   266		n := asNode(s.Def)
   267		if n == nil {
   268			// Maybe a top-level declaration will come along later to
   269			// define s. resolve will check s.Def again once all input
   270			// source has been processed.
   271			return newnoname(s)
   272		}
   273	
   274		if Curfn != nil && n.Op == ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn {
   275			// Inner func is referring to var in outer func.
   276			//
   277			// TODO(rsc): If there is an outer variable x and we
   278			// are parsing x := 5 inside the closure, until we get to
   279			// the := it looks like a reference to the outer x so we'll
   280			// make x a closure variable unnecessarily.
   281			c := n.Name.Param.Innermost
   282			if c == nil || c.Name.Curfn != Curfn {
   283				// Do not have a closure var for the active closure yet; make one.
   284				c = newname(s)
   285				c.SetClass(PAUTOHEAP)
   286				c.SetIsClosureVar(true)
   287				c.SetIsDDD(n.IsDDD())
   288				c.Name.Defn = n
   289				c.SetAddable(false)
   290	
   291				// Link into list of active closure variables.
   292				// Popped from list in func closurebody.
   293				c.Name.Param.Outer = n.Name.Param.Innermost
   294				n.Name.Param.Innermost = c
   295	
   296				Curfn.Func.Cvars.Append(c)
   297			}
   298	
   299			// return ref to closure var, not original
   300			return c
   301		}
   302	
   303		return n
   304	}
   305	
   306	// := declarations
   307	func colasname(n *Node) bool {
   308		switch n.Op {
   309		case ONAME,
   310			ONONAME,
   311			OPACK,
   312			OTYPE,
   313			OLITERAL:
   314			return n.Sym != nil
   315		}
   316	
   317		return false
   318	}
   319	
   320	func colasdefn(left []*Node, defn *Node) {
   321		for _, n := range left {
   322			if n.Sym != nil {
   323				n.Sym.SetUniq(true)
   324			}
   325		}
   326	
   327		var nnew, nerr int
   328		for i, n := range left {
   329			if n.isBlank() {
   330				continue
   331			}
   332			if !colasname(n) {
   333				yyerrorl(defn.Pos, "non-name %v on left side of :=", n)
   334				nerr++
   335				continue
   336			}
   337	
   338			if !n.Sym.Uniq() {
   339				yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
   340				n.SetDiag(true)
   341				nerr++
   342				continue
   343			}
   344	
   345			n.Sym.SetUniq(false)
   346			if n.Sym.Block == types.Block {
   347				continue
   348			}
   349	
   350			nnew++
   351			n = newname(n.Sym)
   352			declare(n, dclcontext)
   353			n.Name.Defn = defn
   354			defn.Ninit.Append(nod(ODCL, n, nil))
   355			left[i] = n
   356		}
   357	
   358		if nnew == 0 && nerr == 0 {
   359			yyerrorl(defn.Pos, "no new variables on left side of :=")
   360		}
   361	}
   362	
   363	// declare the arguments in an
   364	// interface field declaration.
   365	func ifacedcl(n *Node) {
   366		if n.Op != ODCLFIELD || n.Left == nil {
   367			Fatalf("ifacedcl")
   368		}
   369	
   370		if n.Sym.IsBlank() {
   371			yyerror("methods must have a unique non-blank name")
   372		}
   373	}
   374	
   375	// declare the function proper
   376	// and declare the arguments.
   377	// called in extern-declaration context
   378	// returns in auto-declaration context.
   379	func funchdr(n *Node) {
   380		// change the declaration context from extern to auto
   381		if Curfn == nil && dclcontext != PEXTERN {
   382			Fatalf("funchdr: dclcontext = %d", dclcontext)
   383		}
   384	
   385		dclcontext = PAUTO
   386		types.Markdcl()
   387		funcstack = append(funcstack, Curfn)
   388		Curfn = n
   389	
   390		if n.Func.Nname != nil {
   391			funcargs(n.Func.Nname.Name.Param.Ntype)
   392		} else if n.Func.Ntype != nil {
   393			funcargs(n.Func.Ntype)
   394		} else {
   395			funcargs2(n.Type)
   396		}
   397	}
   398	
   399	func funcargs(nt *Node) {
   400		if nt.Op != OTFUNC {
   401			Fatalf("funcargs %v", nt.Op)
   402		}
   403	
   404		// re-start the variable generation number
   405		// we want to use small numbers for the return variables,
   406		// so let them have the chunk starting at 1.
   407		//
   408		// TODO(mdempsky): This is ugly, and only necessary because
   409		// esc.go uses Vargen to figure out result parameters' index
   410		// within the result tuple.
   411		vargen = nt.Rlist.Len()
   412	
   413		// declare the receiver and in arguments.
   414		if nt.Left != nil {
   415			funcarg(nt.Left, PPARAM)
   416		}
   417		for _, n := range nt.List.Slice() {
   418			funcarg(n, PPARAM)
   419		}
   420	
   421		oldvargen := vargen
   422		vargen = 0
   423	
   424		// declare the out arguments.
   425		gen := nt.List.Len()
   426		for _, n := range nt.Rlist.Slice() {
   427			if n.Sym == nil {
   428				// Name so that escape analysis can track it. ~r stands for 'result'.
   429				n.Sym = lookupN("~r", gen)
   430				gen++
   431			}
   432			if n.Sym.IsBlank() {
   433				// Give it a name so we can assign to it during return. ~b stands for 'blank'.
   434				// The name must be different from ~r above because if you have
   435				//	func f() (_ int)
   436				//	func g() int
   437				// f is allowed to use a plain 'return' with no arguments, while g is not.
   438				// So the two cases must be distinguished.
   439				n.Sym = lookupN("~b", gen)
   440				gen++
   441			}
   442	
   443			funcarg(n, PPARAMOUT)
   444		}
   445	
   446		vargen = oldvargen
   447	}
   448	
   449	func funcarg(n *Node, ctxt Class) {
   450		if n.Op != ODCLFIELD {
   451			Fatalf("funcarg %v", n.Op)
   452		}
   453		if n.Sym == nil {
   454			return
   455		}
   456	
   457		n.Right = newnamel(n.Pos, n.Sym)
   458		n.Right.Name.Param.Ntype = n.Left
   459		n.Right.SetIsDDD(n.IsDDD())
   460		declare(n.Right, ctxt)
   461	
   462		vargen++
   463		n.Right.Name.Vargen = int32(vargen)
   464	}
   465	
   466	// Same as funcargs, except run over an already constructed TFUNC.
   467	// This happens during import, where the hidden_fndcl rule has
   468	// used functype directly to parse the function's type.
   469	func funcargs2(t *types.Type) {
   470		if t.Etype != TFUNC {
   471			Fatalf("funcargs2 %v", t)
   472		}
   473	
   474		for _, f := range t.Recvs().Fields().Slice() {
   475			funcarg2(f, PPARAM)
   476		}
   477		for _, f := range t.Params().Fields().Slice() {
   478			funcarg2(f, PPARAM)
   479		}
   480		for _, f := range t.Results().Fields().Slice() {
   481			funcarg2(f, PPARAMOUT)
   482		}
   483	}
   484	
   485	func funcarg2(f *types.Field, ctxt Class) {
   486		if f.Sym == nil {
   487			return
   488		}
   489		n := newnamel(f.Pos, f.Sym)
   490		f.Nname = asTypesNode(n)
   491		n.Type = f.Type
   492		n.SetIsDDD(f.IsDDD())
   493		declare(n, ctxt)
   494	}
   495	
   496	var funcstack []*Node // stack of previous values of Curfn
   497	
   498	// finish the body.
   499	// called in auto-declaration context.
   500	// returns in extern-declaration context.
   501	func funcbody() {
   502		// change the declaration context from auto to extern
   503		if dclcontext != PAUTO {
   504			Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
   505		}
   506		types.Popdcl()
   507		funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
   508		if Curfn == nil {
   509			dclcontext = PEXTERN
   510		}
   511	}
   512	
   513	// structs, functions, and methods.
   514	// they don't belong here, but where do they belong?
   515	func checkembeddedtype(t *types.Type) {
   516		if t == nil {
   517			return
   518		}
   519	
   520		if t.Sym == nil && t.IsPtr() {
   521			t = t.Elem()
   522			if t.IsInterface() {
   523				yyerror("embedded type cannot be a pointer to interface")
   524			}
   525		}
   526	
   527		if t.IsPtr() || t.IsUnsafePtr() {
   528			yyerror("embedded type cannot be a pointer")
   529		} else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
   530			t.ForwardType().Embedlineno = lineno
   531		}
   532	}
   533	
   534	func structfield(n *Node) *types.Field {
   535		lno := lineno
   536		lineno = n.Pos
   537	
   538		if n.Op != ODCLFIELD {
   539			Fatalf("structfield: oops %v\n", n)
   540		}
   541	
   542		f := types.NewField()
   543		f.Pos = n.Pos
   544		f.Sym = n.Sym
   545	
   546		if n.Left != nil {
   547			n.Left = typecheck(n.Left, Etype)
   548			n.Type = n.Left.Type
   549			n.Left = nil
   550		}
   551	
   552		f.Type = n.Type
   553		if f.Type == nil {
   554			f.SetBroke(true)
   555		}
   556	
   557		if n.Embedded() {
   558			checkembeddedtype(n.Type)
   559			f.Embedded = 1
   560		} else {
   561			f.Embedded = 0
   562		}
   563	
   564		switch u := n.Val().U.(type) {
   565		case string:
   566			f.Note = u
   567		default:
   568			yyerror("field tag must be a string")
   569		case nil:
   570			// no-op
   571		}
   572	
   573		lineno = lno
   574		return f
   575	}
   576	
   577	// checkdupfields emits errors for duplicately named fields or methods in
   578	// a list of struct or interface types.
   579	func checkdupfields(what string, ts ...*types.Type) {
   580		seen := make(map[*types.Sym]bool)
   581		for _, t := range ts {
   582			for _, f := range t.Fields().Slice() {
   583				if f.Sym == nil || f.Sym.IsBlank() {
   584					continue
   585				}
   586				if seen[f.Sym] {
   587					yyerrorl(f.Pos, "duplicate %s %s", what, f.Sym.Name)
   588					continue
   589				}
   590				seen[f.Sym] = true
   591			}
   592		}
   593	}
   594	
   595	// convert a parsed id/type list into
   596	// a type for struct/interface/arglist
   597	func tostruct(l []*Node) *types.Type {
   598		t := types.New(TSTRUCT)
   599		tostruct0(t, l)
   600		return t
   601	}
   602	
   603	func tostruct0(t *types.Type, l []*Node) {
   604		if t == nil || !t.IsStruct() {
   605			Fatalf("struct expected")
   606		}
   607	
   608		fields := make([]*types.Field, len(l))
   609		for i, n := range l {
   610			f := structfield(n)
   611			if f.Broke() {
   612				t.SetBroke(true)
   613			}
   614			fields[i] = f
   615		}
   616		t.SetFields(fields)
   617	
   618		checkdupfields("field", t)
   619	
   620		if !t.Broke() {
   621			checkwidth(t)
   622		}
   623	}
   624	
   625	func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
   626		t := types.New(TSTRUCT)
   627		t.StructType().Funarg = funarg
   628	
   629		fields := make([]*types.Field, len(l))
   630		for i, n := range l {
   631			f := structfield(n)
   632			f.SetIsDDD(n.IsDDD())
   633			if n.Right != nil {
   634				n.Right.Type = f.Type
   635				f.Nname = asTypesNode(n.Right)
   636			}
   637			if f.Broke() {
   638				t.SetBroke(true)
   639			}
   640			fields[i] = f
   641		}
   642		t.SetFields(fields)
   643		return t
   644	}
   645	
   646	func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
   647		t := types.New(TSTRUCT)
   648		t.StructType().Funarg = funarg
   649		t.SetFields(fields)
   650		return t
   651	}
   652	
   653	func interfacefield(n *Node) *types.Field {
   654		lno := lineno
   655		lineno = n.Pos
   656	
   657		if n.Op != ODCLFIELD {
   658			Fatalf("interfacefield: oops %v\n", n)
   659		}
   660	
   661		if n.Val().Ctype() != CTxxx {
   662			yyerror("interface method cannot have annotation")
   663		}
   664	
   665		// MethodSpec = MethodName Signature | InterfaceTypeName .
   666		//
   667		// If Sym != nil, then Sym is MethodName and Left is Signature.
   668		// Otherwise, Left is InterfaceTypeName.
   669	
   670		if n.Left != nil {
   671			n.Left = typecheck(n.Left, Etype)
   672			n.Type = n.Left.Type
   673			n.Left = nil
   674		}
   675	
   676		f := types.NewField()
   677		f.Pos = n.Pos
   678		f.Sym = n.Sym
   679		f.Type = n.Type
   680		if f.Type == nil {
   681			f.SetBroke(true)
   682		}
   683	
   684		lineno = lno
   685		return f
   686	}
   687	
   688	func tointerface(l []*Node) *types.Type {
   689		if len(l) == 0 {
   690			return types.Types[TINTER]
   691		}
   692		t := types.New(TINTER)
   693		tointerface0(t, l)
   694		return t
   695	}
   696	
   697	func tointerface0(t *types.Type, l []*Node) {
   698		if t == nil || !t.IsInterface() {
   699			Fatalf("interface expected")
   700		}
   701	
   702		var fields []*types.Field
   703		for _, n := range l {
   704			f := interfacefield(n)
   705			if f.Broke() {
   706				t.SetBroke(true)
   707			}
   708			fields = append(fields, f)
   709		}
   710		t.SetInterface(fields)
   711	}
   712	
   713	func fakeRecv() *Node {
   714		return anonfield(types.FakeRecvType())
   715	}
   716	
   717	func fakeRecvField() *types.Field {
   718		f := types.NewField()
   719		f.Type = types.FakeRecvType()
   720		return f
   721	}
   722	
   723	// isifacemethod reports whether (field) m is
   724	// an interface method. Such methods have the
   725	// special receiver type types.FakeRecvType().
   726	func isifacemethod(f *types.Type) bool {
   727		return f.Recv().Type == types.FakeRecvType()
   728	}
   729	
   730	// turn a parsed function declaration into a type
   731	func functype(this *Node, in, out []*Node) *types.Type {
   732		t := types.New(TFUNC)
   733		functype0(t, this, in, out)
   734		return t
   735	}
   736	
   737	func functype0(t *types.Type, this *Node, in, out []*Node) {
   738		if t == nil || t.Etype != TFUNC {
   739			Fatalf("function type expected")
   740		}
   741	
   742		var rcvr []*Node
   743		if this != nil {
   744			rcvr = []*Node{this}
   745		}
   746		t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
   747		t.FuncType().Params = tofunargs(in, types.FunargParams)
   748		t.FuncType().Results = tofunargs(out, types.FunargResults)
   749	
   750		checkdupfields("argument", t.Recvs(), t.Params(), t.Results())
   751	
   752		if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() {
   753			t.SetBroke(true)
   754		}
   755	
   756		t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
   757	}
   758	
   759	func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
   760		t := types.New(TFUNC)
   761		functypefield0(t, this, in, out)
   762		return t
   763	}
   764	
   765	func functypefield0(t *types.Type, this *types.Field, in, out []*types.Field) {
   766		var rcvr []*types.Field
   767		if this != nil {
   768			rcvr = []*types.Field{this}
   769		}
   770		t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr)
   771		t.FuncType().Params = tofunargsfield(in, types.FunargParams)
   772		t.FuncType().Results = tofunargsfield(out, types.FunargResults)
   773	
   774		t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
   775	}
   776	
   777	// origSym returns the original symbol written by the user.
   778	func origSym(s *types.Sym) *types.Sym {
   779		if s == nil {
   780			return nil
   781		}
   782	
   783		if len(s.Name) > 1 && s.Name[0] == '~' {
   784			switch s.Name[1] {
   785			case 'r': // originally an unnamed result
   786				return nil
   787			case 'b': // originally the blank identifier _
   788				// TODO(mdempsky): Does s.Pkg matter here?
   789				return nblank.Sym
   790			}
   791			return s
   792		}
   793	
   794		if strings.HasPrefix(s.Name, ".anon") {
   795			// originally an unnamed or _ name (see subr.go: structargs)
   796			return nil
   797		}
   798	
   799		return s
   800	}
   801	
   802	// methodSym returns the method symbol representing a method name
   803	// associated with a specific receiver type.
   804	//
   805	// Method symbols can be used to distinguish the same method appearing
   806	// in different method sets. For example, T.M and (*T).M have distinct
   807	// method symbols.
   808	//
   809	// The returned symbol will be marked as a function.
   810	func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
   811		sym := methodSymSuffix(recv, msym, "")
   812		sym.SetFunc(true)
   813		return sym
   814	}
   815	
   816	// methodSymSuffix is like methodsym, but allows attaching a
   817	// distinguisher suffix. To avoid collisions, the suffix must not
   818	// start with a letter, number, or period.
   819	func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
   820		if msym.IsBlank() {
   821			Fatalf("blank method name")
   822		}
   823	
   824		rsym := recv.Sym
   825		if recv.IsPtr() {
   826			if rsym != nil {
   827				Fatalf("declared pointer receiver type: %v", recv)
   828			}
   829			rsym = recv.Elem().Sym
   830		}
   831	
   832		// Find the package the receiver type appeared in. For
   833		// anonymous receiver types (i.e., anonymous structs with
   834		// embedded fields), use the "go" pseudo-package instead.
   835		rpkg := gopkg
   836		if rsym != nil {
   837			rpkg = rsym.Pkg
   838		}
   839	
   840		var b bytes.Buffer
   841		if recv.IsPtr() {
   842			// The parentheses aren't really necessary, but
   843			// they're pretty traditional at this point.
   844			fmt.Fprintf(&b, "(%-S)", recv)
   845		} else {
   846			fmt.Fprintf(&b, "%-S", recv)
   847		}
   848	
   849		// A particular receiver type may have multiple non-exported
   850		// methods with the same name. To disambiguate them, include a
   851		// package qualifier for names that came from a different
   852		// package than the receiver type.
   853		if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
   854			b.WriteString(".")
   855			b.WriteString(msym.Pkg.Prefix)
   856		}
   857	
   858		b.WriteString(".")
   859		b.WriteString(msym.Name)
   860		b.WriteString(suffix)
   861	
   862		return rpkg.LookupBytes(b.Bytes())
   863	}
   864	
   865	// Add a method, declared as a function.
   866	// - msym is the method symbol
   867	// - t is function type (with receiver)
   868	// Returns a pointer to the existing or added Field; or nil if there's an error.
   869	func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
   870		if msym == nil {
   871			Fatalf("no method symbol")
   872		}
   873	
   874		// get parent type sym
   875		rf := t.Recv() // ptr to this structure
   876		if rf == nil {
   877			yyerror("missing receiver")
   878			return nil
   879		}
   880	
   881		mt := methtype(rf.Type)
   882		if mt == nil || mt.Sym == nil {
   883			pa := rf.Type
   884			t := pa
   885			if t != nil && t.IsPtr() {
   886				if t.Sym != nil {
   887					yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
   888					return nil
   889				}
   890				t = t.Elem()
   891			}
   892	
   893			switch {
   894			case t == nil || t.Broke():
   895				// rely on typecheck having complained before
   896			case t.Sym == nil:
   897				yyerror("invalid receiver type %v (%v is not a defined type)", pa, t)
   898			case t.IsPtr():
   899				yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
   900			case t.IsInterface():
   901				yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
   902			default:
   903				// Should have picked off all the reasons above,
   904				// but just in case, fall back to generic error.
   905				yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
   906			}
   907			return nil
   908		}
   909	
   910		if local && mt.Sym.Pkg != localpkg {
   911			yyerror("cannot define new methods on non-local type %v", mt)
   912			return nil
   913		}
   914	
   915		if msym.IsBlank() {
   916			return nil
   917		}
   918	
   919		if mt.IsStruct() {
   920			for _, f := range mt.Fields().Slice() {
   921				if f.Sym == msym {
   922					yyerror("type %v has both field and method named %v", mt, msym)
   923					f.SetBroke(true)
   924					return nil
   925				}
   926			}
   927		}
   928	
   929		for _, f := range mt.Methods().Slice() {
   930			if msym.Name != f.Sym.Name {
   931				continue
   932			}
   933			// types.Identical only checks that incoming and result parameters match,
   934			// so explicitly check that the receiver parameters match too.
   935			if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
   936				yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
   937			}
   938			return f
   939		}
   940	
   941		f := types.NewField()
   942		f.Pos = lineno
   943		f.Sym = msym
   944		f.Type = t
   945		f.SetNointerface(nointerface)
   946	
   947		mt.Methods().Append(f)
   948		return f
   949	}
   950	
   951	func funcsymname(s *types.Sym) string {
   952		return s.Name + "·f"
   953	}
   954	
   955	// funcsym returns s·f.
   956	func funcsym(s *types.Sym) *types.Sym {
   957		// funcsymsmu here serves to protect not just mutations of funcsyms (below),
   958		// but also the package lookup of the func sym name,
   959		// since this function gets called concurrently from the backend.
   960		// There are no other concurrent package lookups in the backend,
   961		// except for the types package, which is protected separately.
   962		// Reusing funcsymsmu to also cover this package lookup
   963		// avoids a general, broader, expensive package lookup mutex.
   964		// Note makefuncsym also does package look-up of func sym names,
   965		// but that it is only called serially, from the front end.
   966		funcsymsmu.Lock()
   967		sf, existed := s.Pkg.LookupOK(funcsymname(s))
   968		// Don't export s·f when compiling for dynamic linking.
   969		// When dynamically linking, the necessary function
   970		// symbols will be created explicitly with makefuncsym.
   971		// See the makefuncsym comment for details.
   972		if !Ctxt.Flag_dynlink && !existed {
   973			funcsyms = append(funcsyms, s)
   974		}
   975		funcsymsmu.Unlock()
   976		return sf
   977	}
   978	
   979	// makefuncsym ensures that s·f is exported.
   980	// It is only used with -dynlink.
   981	// When not compiling for dynamic linking,
   982	// the funcsyms are created as needed by
   983	// the packages that use them.
   984	// Normally we emit the s·f stubs as DUPOK syms,
   985	// but DUPOK doesn't work across shared library boundaries.
   986	// So instead, when dynamic linking, we only create
   987	// the s·f stubs in s's package.
   988	func makefuncsym(s *types.Sym) {
   989		if !Ctxt.Flag_dynlink {
   990			Fatalf("makefuncsym dynlink")
   991		}
   992		if s.IsBlank() {
   993			return
   994		}
   995		if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") {
   996			// runtime.getg(), getclosureptr(), getcallerpc(), and
   997			// getcallersp() are not real functions and so do not
   998			// get funcsyms.
   999			return
  1000		}
  1001		if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {
  1002			funcsyms = append(funcsyms, s)
  1003		}
  1004	}
  1005	
  1006	// disableExport prevents sym from being included in package export
  1007	// data. To be effectual, it must be called before declare.
  1008	func disableExport(sym *types.Sym) {
  1009		sym.SetOnExportList(true)
  1010	}
  1011	
  1012	func dclfunc(sym *types.Sym, tfn *Node) *Node {
  1013		if tfn.Op != OTFUNC {
  1014			Fatalf("expected OTFUNC node, got %v", tfn)
  1015		}
  1016	
  1017		fn := nod(ODCLFUNC, nil, nil)
  1018		fn.Func.Nname = newfuncnamel(lineno, sym)
  1019		fn.Func.Nname.Name.Defn = fn
  1020		fn.Func.Nname.Name.Param.Ntype = tfn
  1021		declare(fn.Func.Nname, PFUNC)
  1022		funchdr(fn)
  1023		fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype)
  1024		return fn
  1025	}
  1026	
  1027	type nowritebarrierrecChecker struct {
  1028		// extraCalls contains extra function calls that may not be
  1029		// visible during later analysis. It maps from the ODCLFUNC of
  1030		// the caller to a list of callees.
  1031		extraCalls map[*Node][]nowritebarrierrecCall
  1032	
  1033		// curfn is the current function during AST walks.
  1034		curfn *Node
  1035	}
  1036	
  1037	type nowritebarrierrecCall struct {
  1038		target *Node    // ODCLFUNC of caller or callee
  1039		lineno src.XPos // line of call
  1040	}
  1041	
  1042	type nowritebarrierrecCallSym struct {
  1043		target *obj.LSym // LSym of callee
  1044		lineno src.XPos  // line of call
  1045	}
  1046	
  1047	// newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It
  1048	// must be called before transformclosure and walk.
  1049	func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
  1050		c := &nowritebarrierrecChecker{
  1051			extraCalls: make(map[*Node][]nowritebarrierrecCall),
  1052		}
  1053	
  1054		// Find all systemstack calls and record their targets. In
  1055		// general, flow analysis can't see into systemstack, but it's
  1056		// important to handle it for this check, so we model it
  1057		// directly. This has to happen before transformclosure since
  1058		// it's a lot harder to work out the argument after.
  1059		for _, n := range xtop {
  1060			if n.Op != ODCLFUNC {
  1061				continue
  1062			}
  1063			c.curfn = n
  1064			inspect(n, c.findExtraCalls)
  1065		}
  1066		c.curfn = nil
  1067		return c
  1068	}
  1069	
  1070	func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
  1071		if n.Op != OCALLFUNC {
  1072			return true
  1073		}
  1074		fn := n.Left
  1075		if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil {
  1076			return true
  1077		}
  1078		if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" {
  1079			return true
  1080		}
  1081	
  1082		var callee *Node
  1083		arg := n.List.First()
  1084		switch arg.Op {
  1085		case ONAME:
  1086			callee = arg.Name.Defn
  1087		case OCLOSURE:
  1088			callee = arg.Func.Closure
  1089		default:
  1090			Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
  1091		}
  1092		if callee.Op != ODCLFUNC {
  1093			Fatalf("expected ODCLFUNC node, got %+v", callee)
  1094		}
  1095		c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos})
  1096		return true
  1097	}
  1098	
  1099	// recordCall records a call from ODCLFUNC node "from", to function
  1100	// symbol "to" at position pos.
  1101	//
  1102	// This should be done as late as possible during compilation to
  1103	// capture precise call graphs. The target of the call is an LSym
  1104	// because that's all we know after we start SSA.
  1105	//
  1106	// This can be called concurrently for different from Nodes.
  1107	func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) {
  1108		if from.Op != ODCLFUNC {
  1109			Fatalf("expected ODCLFUNC, got %v", from)
  1110		}
  1111		// We record this information on the *Func so this is
  1112		// concurrent-safe.
  1113		fn := from.Func
  1114		if fn.nwbrCalls == nil {
  1115			fn.nwbrCalls = new([]nowritebarrierrecCallSym)
  1116		}
  1117		*fn.nwbrCalls = append(*fn.nwbrCalls, nowritebarrierrecCallSym{to, pos})
  1118	}
  1119	
  1120	func (c *nowritebarrierrecChecker) check() {
  1121		// We walk the call graph as late as possible so we can
  1122		// capture all calls created by lowering, but this means we
  1123		// only get to see the obj.LSyms of calls. symToFunc lets us
  1124		// get back to the ODCLFUNCs.
  1125		symToFunc := make(map[*obj.LSym]*Node)
  1126		// funcs records the back-edges of the BFS call graph walk. It
  1127		// maps from the ODCLFUNC of each function that must not have
  1128		// write barriers to the call that inhibits them. Functions
  1129		// that are directly marked go:nowritebarrierrec are in this
  1130		// map with a zero-valued nowritebarrierrecCall. This also
  1131		// acts as the set of marks for the BFS of the call graph.
  1132		funcs := make(map[*Node]nowritebarrierrecCall)
  1133		// q is the queue of ODCLFUNC Nodes to visit in BFS order.
  1134		var q nodeQueue
  1135	
  1136		for _, n := range xtop {
  1137			if n.Op != ODCLFUNC {
  1138				continue
  1139			}
  1140	
  1141			symToFunc[n.Func.lsym] = n
  1142	
  1143			// Make nowritebarrierrec functions BFS roots.
  1144			if n.Func.Pragma&Nowritebarrierrec != 0 {
  1145				funcs[n] = nowritebarrierrecCall{}
  1146				q.pushRight(n)
  1147			}
  1148			// Check go:nowritebarrier functions.
  1149			if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
  1150				yyerrorl(n.Func.WBPos, "write barrier prohibited")
  1151			}
  1152		}
  1153	
  1154		// Perform a BFS of the call graph from all
  1155		// go:nowritebarrierrec functions.
  1156		enqueue := func(src, target *Node, pos src.XPos) {
  1157			if target.Func.Pragma&Yeswritebarrierrec != 0 {
  1158				// Don't flow into this function.
  1159				return
  1160			}
  1161			if _, ok := funcs[target]; ok {
  1162				// Already found a path to target.
  1163				return
  1164			}
  1165	
  1166			// Record the path.
  1167			funcs[target] = nowritebarrierrecCall{target: src, lineno: pos}
  1168			q.pushRight(target)
  1169		}
  1170		for !q.empty() {
  1171			fn := q.popLeft()
  1172	
  1173			// Check fn.
  1174			if fn.Func.WBPos.IsKnown() {
  1175				var err bytes.Buffer
  1176				call := funcs[fn]
  1177				for call.target != nil {
  1178					fmt.Fprintf(&err, "\n\t%v: called by %v", linestr(call.lineno), call.target.Func.Nname)
  1179					call = funcs[call.target]
  1180				}
  1181				yyerrorl(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String())
  1182				continue
  1183			}
  1184	
  1185			// Enqueue fn's calls.
  1186			for _, callee := range c.extraCalls[fn] {
  1187				enqueue(fn, callee.target, callee.lineno)
  1188			}
  1189			if fn.Func.nwbrCalls == nil {
  1190				continue
  1191			}
  1192			for _, callee := range *fn.Func.nwbrCalls {
  1193				target := symToFunc[callee.target]
  1194				if target != nil {
  1195					enqueue(fn, target, callee.lineno)
  1196				}
  1197			}
  1198		}
  1199	}
  1200	

View as plain text