github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/gc/subr.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  	"bytes"
     9  	"cmd/internal/obj"
    10  	"crypto/md5"
    11  	"encoding/binary"
    12  	"fmt"
    13  	"os"
    14  	"runtime/debug"
    15  	"sort"
    16  	"strconv"
    17  	"strings"
    18  	"unicode"
    19  	"unicode/utf8"
    20  )
    21  
    22  type Error struct {
    23  	lineno int32
    24  	msg    string
    25  }
    26  
    27  var errors []Error
    28  
    29  func errorexit() {
    30  	flusherrors()
    31  	if outfile != "" {
    32  		os.Remove(outfile)
    33  	}
    34  	os.Exit(2)
    35  }
    36  
    37  func adderrorname(n *Node) {
    38  	if n.Op != ODOT {
    39  		return
    40  	}
    41  	old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left)
    42  	if len(errors) > 0 && errors[len(errors)-1].lineno == n.Lineno && errors[len(errors)-1].msg == old {
    43  		errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n)
    44  	}
    45  }
    46  
    47  func adderr(line int32, format string, args ...interface{}) {
    48  	errors = append(errors, Error{
    49  		lineno: line,
    50  		msg:    fmt.Sprintf("%v: %s\n", linestr(line), fmt.Sprintf(format, args...)),
    51  	})
    52  }
    53  
    54  // byLineno sorts errors by lineno.
    55  type byLineno []Error
    56  
    57  func (x byLineno) Len() int           { return len(x) }
    58  func (x byLineno) Less(i, j int) bool { return x[i].lineno < x[j].lineno }
    59  func (x byLineno) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
    60  
    61  // flusherrors sorts errors seen so far by line number, prints them to stdout,
    62  // and empties the errors array.
    63  func flusherrors() {
    64  	Ctxt.Bso.Flush()
    65  	if len(errors) == 0 {
    66  		return
    67  	}
    68  	sort.Stable(byLineno(errors))
    69  	for i := 0; i < len(errors); i++ {
    70  		if i == 0 || errors[i].msg != errors[i-1].msg {
    71  			fmt.Printf("%s", errors[i].msg)
    72  		}
    73  	}
    74  	errors = errors[:0]
    75  }
    76  
    77  func hcrash() {
    78  	if Debug['h'] != 0 {
    79  		flusherrors()
    80  		if outfile != "" {
    81  			os.Remove(outfile)
    82  		}
    83  		var x *int
    84  		*x = 0
    85  	}
    86  }
    87  
    88  func linestr(line int32) string {
    89  	return Ctxt.Line(int(line))
    90  }
    91  
    92  // lasterror keeps track of the most recently issued error.
    93  // It is used to avoid multiple error messages on the same
    94  // line.
    95  var lasterror struct {
    96  	syntax int32  // line of last syntax error
    97  	other  int32  // line of last non-syntax error
    98  	msg    string // error message of last non-syntax error
    99  }
   100  
   101  func yyerrorl(line int32, format string, args ...interface{}) {
   102  	msg := fmt.Sprintf(format, args...)
   103  
   104  	if strings.HasPrefix(msg, "syntax error") {
   105  		nsyntaxerrors++
   106  		// only one syntax error per line, no matter what error
   107  		if lasterror.syntax == line {
   108  			return
   109  		}
   110  		lasterror.syntax = line
   111  	} else {
   112  		// only one of multiple equal non-syntax errors per line
   113  		// (flusherrors shows only one of them, so we filter them
   114  		// here as best as we can (they may not appear in order)
   115  		// so that we don't count them here and exit early, and
   116  		// then have nothing to show for.)
   117  		if lasterror.other == line && lasterror.msg == msg {
   118  			return
   119  		}
   120  		lasterror.other = line
   121  		lasterror.msg = msg
   122  	}
   123  
   124  	adderr(line, "%s", msg)
   125  
   126  	hcrash()
   127  	nerrors++
   128  	if nsavederrors+nerrors >= 10 && Debug['e'] == 0 {
   129  		flusherrors()
   130  		fmt.Printf("%v: too many errors\n", linestr(line))
   131  		errorexit()
   132  	}
   133  }
   134  
   135  func yyerror(format string, args ...interface{}) {
   136  	yyerrorl(lineno, format, args...)
   137  }
   138  
   139  func Warn(fmt_ string, args ...interface{}) {
   140  	adderr(lineno, fmt_, args...)
   141  
   142  	hcrash()
   143  }
   144  
   145  func Warnl(line int32, fmt_ string, args ...interface{}) {
   146  	adderr(line, fmt_, args...)
   147  	if Debug['m'] != 0 {
   148  		flusherrors()
   149  	}
   150  }
   151  
   152  func Fatalf(fmt_ string, args ...interface{}) {
   153  	flusherrors()
   154  
   155  	fmt.Printf("%v: internal compiler error: ", linestr(lineno))
   156  	fmt.Printf(fmt_, args...)
   157  	fmt.Printf("\n")
   158  
   159  	// If this is a released compiler version, ask for a bug report.
   160  	if strings.HasPrefix(obj.Version, "release") {
   161  		fmt.Printf("\n")
   162  		fmt.Printf("Please file a bug report including a short program that triggers the error.\n")
   163  		fmt.Printf("https://golang.org/issue/new\n")
   164  	} else {
   165  		// Not a release; dump a stack trace, too.
   166  		fmt.Println()
   167  		os.Stdout.Write(debug.Stack())
   168  		fmt.Println()
   169  	}
   170  
   171  	hcrash()
   172  	errorexit()
   173  }
   174  
   175  func linehistpragma(file string) {
   176  	if Debug['i'] != 0 {
   177  		fmt.Printf("pragma %s at line %v\n", file, linestr(lexlineno))
   178  	}
   179  	Ctxt.AddImport(file)
   180  }
   181  
   182  func linehistpush(file string) {
   183  	if Debug['i'] != 0 {
   184  		fmt.Printf("import %s at line %v\n", file, linestr(lexlineno))
   185  	}
   186  	Ctxt.LineHist.Push(int(lexlineno), file)
   187  }
   188  
   189  func linehistpop() {
   190  	if Debug['i'] != 0 {
   191  		fmt.Printf("end of import at line %v\n", linestr(lexlineno))
   192  	}
   193  	Ctxt.LineHist.Pop(int(lexlineno))
   194  }
   195  
   196  func linehistupdate(file string, off int) {
   197  	if Debug['i'] != 0 {
   198  		fmt.Printf("line %s at line %v\n", file, linestr(lexlineno))
   199  	}
   200  	Ctxt.LineHist.Update(int(lexlineno), file, off)
   201  }
   202  
   203  func setlineno(n *Node) int32 {
   204  	lno := lineno
   205  	if n != nil {
   206  		switch n.Op {
   207  		case ONAME, OPACK:
   208  			break
   209  
   210  		case OLITERAL, OTYPE:
   211  			if n.Sym != nil {
   212  				break
   213  			}
   214  			fallthrough
   215  
   216  		default:
   217  			lineno = n.Lineno
   218  			if lineno == 0 {
   219  				if Debug['K'] != 0 {
   220  					Warn("setlineno: line 0")
   221  				}
   222  				lineno = lno
   223  			}
   224  		}
   225  	}
   226  
   227  	return lno
   228  }
   229  
   230  func lookup(name string) *Sym {
   231  	return localpkg.Lookup(name)
   232  }
   233  
   234  func lookupf(format string, a ...interface{}) *Sym {
   235  	return lookup(fmt.Sprintf(format, a...))
   236  }
   237  
   238  func lookupBytes(name []byte) *Sym {
   239  	return localpkg.LookupBytes(name)
   240  }
   241  
   242  // lookupN looks up the symbol starting with prefix and ending with
   243  // the decimal n. If prefix is too long, lookupN panics.
   244  func lookupN(prefix string, n int) *Sym {
   245  	var buf [20]byte // plenty long enough for all current users
   246  	copy(buf[:], prefix)
   247  	b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
   248  	return lookupBytes(b)
   249  }
   250  
   251  // autolabel generates a new Name node for use with
   252  // an automatically generated label.
   253  // prefix is a short mnemonic (e.g. ".s" for switch)
   254  // to help with debugging.
   255  // It should begin with "." to avoid conflicts with
   256  // user labels.
   257  func autolabel(prefix string) *Node {
   258  	if prefix[0] != '.' {
   259  		Fatalf("autolabel prefix must start with '.', have %q", prefix)
   260  	}
   261  	fn := Curfn
   262  	if Curfn == nil {
   263  		Fatalf("autolabel outside function")
   264  	}
   265  	n := fn.Func.Label
   266  	fn.Func.Label++
   267  	return newname(lookupN(prefix, int(n)))
   268  }
   269  
   270  var initSyms []*Sym
   271  
   272  var nopkg = &Pkg{
   273  	Syms: make(map[string]*Sym),
   274  }
   275  
   276  func (pkg *Pkg) Lookup(name string) *Sym {
   277  	if pkg == nil {
   278  		pkg = nopkg
   279  	}
   280  	if s := pkg.Syms[name]; s != nil {
   281  		return s
   282  	}
   283  
   284  	s := &Sym{
   285  		Name: name,
   286  		Pkg:  pkg,
   287  	}
   288  	if name == "init" {
   289  		initSyms = append(initSyms, s)
   290  	}
   291  	pkg.Syms[name] = s
   292  	return s
   293  }
   294  
   295  func (pkg *Pkg) LookupBytes(name []byte) *Sym {
   296  	if pkg == nil {
   297  		pkg = nopkg
   298  	}
   299  	if s := pkg.Syms[string(name)]; s != nil {
   300  		return s
   301  	}
   302  	str := internString(name)
   303  	return pkg.Lookup(str)
   304  }
   305  
   306  func Pkglookup(name string, pkg *Pkg) *Sym {
   307  	return pkg.Lookup(name)
   308  }
   309  
   310  func restrictlookup(name string, pkg *Pkg) *Sym {
   311  	if !exportname(name) && pkg != localpkg {
   312  		yyerror("cannot refer to unexported name %s.%s", pkg.Name, name)
   313  	}
   314  	return Pkglookup(name, pkg)
   315  }
   316  
   317  // find all the exported symbols in package opkg
   318  // and make them available in the current package
   319  func importdot(opkg *Pkg, pack *Node) {
   320  	var s1 *Sym
   321  	var pkgerror string
   322  
   323  	n := 0
   324  	for _, s := range opkg.Syms {
   325  		if s.Def == nil {
   326  			continue
   327  		}
   328  		if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
   329  			continue
   330  		}
   331  		s1 = lookup(s.Name)
   332  		if s1.Def != nil {
   333  			pkgerror = fmt.Sprintf("during import %q", opkg.Path)
   334  			redeclare(s1, pkgerror)
   335  			continue
   336  		}
   337  
   338  		s1.Def = s.Def
   339  		s1.Block = s.Block
   340  		if s1.Def.Name == nil {
   341  			Dump("s1def", s1.Def)
   342  			Fatalf("missing Name")
   343  		}
   344  		s1.Def.Name.Pack = pack
   345  		s1.Origpkg = opkg
   346  		n++
   347  	}
   348  
   349  	if n == 0 {
   350  		// can't possibly be used - there were no symbols
   351  		yyerrorl(pack.Lineno, "imported and not used: %q", opkg.Path)
   352  	}
   353  }
   354  
   355  func nod(op Op, nleft *Node, nright *Node) *Node {
   356  	n := new(Node)
   357  	n.Op = op
   358  	n.Left = nleft
   359  	n.Right = nright
   360  	n.Lineno = lineno
   361  	n.Xoffset = BADWIDTH
   362  	n.Orig = n
   363  	switch op {
   364  	case OCLOSURE, ODCLFUNC:
   365  		n.Func = new(Func)
   366  		n.Func.IsHiddenClosure = Curfn != nil
   367  	case ONAME:
   368  		n.Name = new(Name)
   369  		n.Name.Param = new(Param)
   370  	case OLABEL, OPACK:
   371  		n.Name = new(Name)
   372  	}
   373  	if n.Name != nil {
   374  		n.Name.Curfn = Curfn
   375  	}
   376  	return n
   377  }
   378  
   379  // nodSym makes a Node with Op op and with the Left field set to left
   380  // and the Sym field set to sym. This is for ODOT and friends.
   381  func nodSym(op Op, left *Node, sym *Sym) *Node {
   382  	n := nod(op, left, nil)
   383  	n.Sym = sym
   384  	return n
   385  }
   386  
   387  func saveorignode(n *Node) {
   388  	if n.Orig != nil {
   389  		return
   390  	}
   391  	norig := nod(n.Op, nil, nil)
   392  	*norig = *n
   393  	n.Orig = norig
   394  }
   395  
   396  // methcmp sorts by symbol, then by package path for unexported symbols.
   397  type methcmp []*Field
   398  
   399  func (x methcmp) Len() int      { return len(x) }
   400  func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
   401  func (x methcmp) Less(i, j int) bool {
   402  	a := x[i]
   403  	b := x[j]
   404  	if a.Sym == nil && b.Sym == nil {
   405  		return false
   406  	}
   407  	if a.Sym == nil {
   408  		return true
   409  	}
   410  	if b.Sym == nil {
   411  		return false
   412  	}
   413  	if a.Sym.Name != b.Sym.Name {
   414  		return a.Sym.Name < b.Sym.Name
   415  	}
   416  	if !exportname(a.Sym.Name) {
   417  		if a.Sym.Pkg.Path != b.Sym.Pkg.Path {
   418  			return a.Sym.Pkg.Path < b.Sym.Pkg.Path
   419  		}
   420  	}
   421  
   422  	return false
   423  }
   424  
   425  func nodintconst(v int64) *Node {
   426  	c := nod(OLITERAL, nil, nil)
   427  	c.Addable = true
   428  	c.SetVal(Val{new(Mpint)})
   429  	c.Val().U.(*Mpint).SetInt64(v)
   430  	c.Type = Types[TIDEAL]
   431  	ullmancalc(c)
   432  	return c
   433  }
   434  
   435  func nodfltconst(v *Mpflt) *Node {
   436  	c := nod(OLITERAL, nil, nil)
   437  	c.Addable = true
   438  	c.SetVal(Val{newMpflt()})
   439  	c.Val().U.(*Mpflt).Set(v)
   440  	c.Type = Types[TIDEAL]
   441  	ullmancalc(c)
   442  	return c
   443  }
   444  
   445  func Nodconst(n *Node, t *Type, v int64) {
   446  	*n = Node{}
   447  	n.Op = OLITERAL
   448  	n.Addable = true
   449  	ullmancalc(n)
   450  	n.SetVal(Val{new(Mpint)})
   451  	n.Val().U.(*Mpint).SetInt64(v)
   452  	n.Type = t
   453  
   454  	if t.IsFloat() {
   455  		Fatalf("nodconst: bad type %v", t)
   456  	}
   457  }
   458  
   459  func nodnil() *Node {
   460  	c := nodintconst(0)
   461  	c.SetVal(Val{new(NilVal)})
   462  	c.Type = Types[TNIL]
   463  	return c
   464  }
   465  
   466  func nodbool(b bool) *Node {
   467  	c := nodintconst(0)
   468  	c.SetVal(Val{b})
   469  	c.Type = idealbool
   470  	return c
   471  }
   472  
   473  // treecopy recursively copies n, with the exception of
   474  // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves.
   475  // Copies of iota ONONAME nodes are assigned the current
   476  // value of iota_. If lineno != 0, it sets the line number
   477  // of newly allocated nodes to lineno.
   478  func treecopy(n *Node, lineno int32) *Node {
   479  	if n == nil {
   480  		return nil
   481  	}
   482  
   483  	switch n.Op {
   484  	default:
   485  		m := *n
   486  		m.Orig = &m
   487  		m.Left = treecopy(n.Left, lineno)
   488  		m.Right = treecopy(n.Right, lineno)
   489  		m.List.Set(listtreecopy(n.List.Slice(), lineno))
   490  		if lineno != 0 {
   491  			m.Lineno = lineno
   492  		}
   493  		if m.Name != nil && n.Op != ODCLFIELD {
   494  			Dump("treecopy", n)
   495  			Fatalf("treecopy Name")
   496  		}
   497  		return &m
   498  
   499  	case ONONAME:
   500  		if n.Sym == lookup("iota") {
   501  			// Not sure yet whether this is the real iota,
   502  			// but make a copy of the Node* just in case,
   503  			// so that all the copies of this const definition
   504  			// don't have the same iota value.
   505  			m := *n
   506  			if lineno != 0 {
   507  				m.Lineno = lineno
   508  			}
   509  			m.SetIota(iota_)
   510  			return &m
   511  		}
   512  		return n
   513  
   514  	case OPACK:
   515  		// OPACK nodes are never valid in const value declarations,
   516  		// but allow them like any other declared symbol to avoid
   517  		// crashing (golang.org/issue/11361).
   518  		fallthrough
   519  
   520  	case ONAME, OLITERAL, OTYPE:
   521  		return n
   522  
   523  	}
   524  }
   525  
   526  // isnil reports whether n represents the universal untyped zero value "nil".
   527  func isnil(n *Node) bool {
   528  	// Check n.Orig because constant propagation may produce typed nil constants,
   529  	// which don't exist in the Go spec.
   530  	return Isconst(n.Orig, CTNIL)
   531  }
   532  
   533  func isptrto(t *Type, et EType) bool {
   534  	if t == nil {
   535  		return false
   536  	}
   537  	if !t.IsPtr() {
   538  		return false
   539  	}
   540  	t = t.Elem()
   541  	if t == nil {
   542  		return false
   543  	}
   544  	if t.Etype != et {
   545  		return false
   546  	}
   547  	return true
   548  }
   549  
   550  func isblank(n *Node) bool {
   551  	if n == nil {
   552  		return false
   553  	}
   554  	return isblanksym(n.Sym)
   555  }
   556  
   557  func isblanksym(s *Sym) bool {
   558  	return s != nil && s.Name == "_"
   559  }
   560  
   561  // methtype returns the underlying type, if any,
   562  // that owns methods with receiver parameter t.
   563  // The result is either a named type or an anonymous struct.
   564  func methtype(t *Type) *Type {
   565  	if t == nil {
   566  		return nil
   567  	}
   568  
   569  	// Strip away pointer if it's there.
   570  	if t.IsPtr() {
   571  		if t.Sym != nil {
   572  			return nil
   573  		}
   574  		t = t.Elem()
   575  		if t == nil {
   576  			return nil
   577  		}
   578  	}
   579  
   580  	// Must be a named type or anonymous struct.
   581  	if t.Sym == nil && !t.IsStruct() {
   582  		return nil
   583  	}
   584  
   585  	// Check types.
   586  	if issimple[t.Etype] {
   587  		return t
   588  	}
   589  	switch t.Etype {
   590  	case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
   591  		return t
   592  	}
   593  	return nil
   594  }
   595  
   596  func cplxsubtype(et EType) EType {
   597  	switch et {
   598  	case TCOMPLEX64:
   599  		return TFLOAT32
   600  
   601  	case TCOMPLEX128:
   602  		return TFLOAT64
   603  	}
   604  
   605  	Fatalf("cplxsubtype: %v\n", et)
   606  	return 0
   607  }
   608  
   609  // eqtype reports whether t1 and t2 are identical, following the spec rules.
   610  //
   611  // Any cyclic type must go through a named type, and if one is
   612  // named, it is only identical to the other if they are the same
   613  // pointer (t1 == t2), so there's no chance of chasing cycles
   614  // ad infinitum, so no need for a depth counter.
   615  func eqtype(t1, t2 *Type) bool {
   616  	return eqtype1(t1, t2, true, nil)
   617  }
   618  
   619  // eqtypeIgnoreTags is like eqtype but it ignores struct tags for struct identity.
   620  func eqtypeIgnoreTags(t1, t2 *Type) bool {
   621  	return eqtype1(t1, t2, false, nil)
   622  }
   623  
   624  type typePair struct {
   625  	t1 *Type
   626  	t2 *Type
   627  }
   628  
   629  func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool {
   630  	if t1 == t2 {
   631  		return true
   632  	}
   633  	if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke || t2.Broke {
   634  		return false
   635  	}
   636  	if t1.Sym != nil || t2.Sym != nil {
   637  		// Special case: we keep byte/uint8 and rune/int32
   638  		// separate for error messages. Treat them as equal.
   639  		switch t1.Etype {
   640  		case TUINT8:
   641  			return (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype)
   642  		case TINT32:
   643  			return (t1 == Types[TINT32] || t1 == runetype) && (t2 == Types[TINT32] || t2 == runetype)
   644  		default:
   645  			return false
   646  		}
   647  	}
   648  
   649  	if assumedEqual == nil {
   650  		assumedEqual = make(map[typePair]struct{})
   651  	} else if _, ok := assumedEqual[typePair{t1, t2}]; ok {
   652  		return true
   653  	}
   654  	assumedEqual[typePair{t1, t2}] = struct{}{}
   655  
   656  	switch t1.Etype {
   657  	case TINTER, TSTRUCT:
   658  		t1, i1 := iterFields(t1)
   659  		t2, i2 := iterFields(t2)
   660  		for ; t1 != nil && t2 != nil; t1, t2 = i1.Next(), i2.Next() {
   661  			if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, cmpTags, assumedEqual) || cmpTags && t1.Note != t2.Note {
   662  				return false
   663  			}
   664  		}
   665  
   666  		if t1 == nil && t2 == nil {
   667  			return true
   668  		}
   669  		return false
   670  
   671  	case TFUNC:
   672  		// Check parameters and result parameters for type equality.
   673  		// We intentionally ignore receiver parameters for type
   674  		// equality, because they're never relevant.
   675  		for _, f := range paramsResults {
   676  			// Loop over fields in structs, ignoring argument names.
   677  			ta, ia := iterFields(f(t1))
   678  			tb, ib := iterFields(f(t2))
   679  			for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() {
   680  				if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, cmpTags, assumedEqual) {
   681  					return false
   682  				}
   683  			}
   684  			if ta != nil || tb != nil {
   685  				return false
   686  			}
   687  		}
   688  		return true
   689  
   690  	case TARRAY:
   691  		if t1.NumElem() != t2.NumElem() {
   692  			return false
   693  		}
   694  
   695  	case TCHAN:
   696  		if t1.ChanDir() != t2.ChanDir() {
   697  			return false
   698  		}
   699  
   700  	case TMAP:
   701  		if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
   702  			return false
   703  		}
   704  		return eqtype1(t1.Val(), t2.Val(), cmpTags, assumedEqual)
   705  	}
   706  
   707  	return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
   708  }
   709  
   710  // Are t1 and t2 equal struct types when field names are ignored?
   711  // For deciding whether the result struct from g can be copied
   712  // directly when compiling f(g()).
   713  func eqtypenoname(t1 *Type, t2 *Type) bool {
   714  	if t1 == nil || t2 == nil || !t1.IsStruct() || !t2.IsStruct() {
   715  		return false
   716  	}
   717  
   718  	f1, i1 := iterFields(t1)
   719  	f2, i2 := iterFields(t2)
   720  	for {
   721  		if !eqtype(f1.Type, f2.Type) {
   722  			return false
   723  		}
   724  		if f1 == nil {
   725  			return true
   726  		}
   727  		f1 = i1.Next()
   728  		f2 = i2.Next()
   729  	}
   730  }
   731  
   732  // Is type src assignment compatible to type dst?
   733  // If so, return op code to use in conversion.
   734  // If not, return 0.
   735  func assignop(src *Type, dst *Type, why *string) Op {
   736  	if why != nil {
   737  		*why = ""
   738  	}
   739  
   740  	// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
   741  	// https://golang.org/issue/2795
   742  	if safemode && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR {
   743  		yyerror("cannot use unsafe.Pointer")
   744  		errorexit()
   745  	}
   746  
   747  	if src == dst {
   748  		return OCONVNOP
   749  	}
   750  	if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil {
   751  		return 0
   752  	}
   753  
   754  	// 1. src type is identical to dst.
   755  	if eqtype(src, dst) {
   756  		return OCONVNOP
   757  	}
   758  
   759  	// 2. src and dst have identical underlying types
   760  	// and either src or dst is not a named type or
   761  	// both are empty interface types.
   762  	// For assignable but different non-empty interface types,
   763  	// we want to recompute the itab.
   764  	if eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || src.IsEmptyInterface()) {
   765  		return OCONVNOP
   766  	}
   767  
   768  	// 3. dst is an interface type and src implements dst.
   769  	if dst.IsInterface() && src.Etype != TNIL {
   770  		var missing, have *Field
   771  		var ptr int
   772  		if implements(src, dst, &missing, &have, &ptr) {
   773  			return OCONVIFACE
   774  		}
   775  
   776  		// we'll have complained about this method anyway, suppress spurious messages.
   777  		if have != nil && have.Sym == missing.Sym && (have.Type.Broke || missing.Type.Broke) {
   778  			return OCONVIFACE
   779  		}
   780  
   781  		if why != nil {
   782  			if isptrto(src, TINTER) {
   783  				*why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
   784  			} else if have != nil && have.Sym == missing.Sym && have.Nointerface {
   785  				*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
   786  			} else if have != nil && have.Sym == missing.Sym {
   787  				*why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+
   788  					"\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
   789  			} else if ptr != 0 {
   790  				*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
   791  			} else if have != nil {
   792  				*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)\n"+
   793  					"\t\thave %v%0S\n\t\twant %v%0S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
   794  			} else {
   795  				*why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
   796  			}
   797  		}
   798  
   799  		return 0
   800  	}
   801  
   802  	if isptrto(dst, TINTER) {
   803  		if why != nil {
   804  			*why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
   805  		}
   806  		return 0
   807  	}
   808  
   809  	if src.IsInterface() && dst.Etype != TBLANK {
   810  		var missing, have *Field
   811  		var ptr int
   812  		if why != nil && implements(dst, src, &missing, &have, &ptr) {
   813  			*why = ": need type assertion"
   814  		}
   815  		return 0
   816  	}
   817  
   818  	// 4. src is a bidirectional channel value, dst is a channel type,
   819  	// src and dst have identical element types, and
   820  	// either src or dst is not a named type.
   821  	if src.IsChan() && src.ChanDir() == Cboth && dst.IsChan() {
   822  		if eqtype(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
   823  			return OCONVNOP
   824  		}
   825  	}
   826  
   827  	// 5. src is the predeclared identifier nil and dst is a nillable type.
   828  	if src.Etype == TNIL {
   829  		switch dst.Etype {
   830  		case TPTR32,
   831  			TPTR64,
   832  			TFUNC,
   833  			TMAP,
   834  			TCHAN,
   835  			TINTER,
   836  			TSLICE:
   837  			return OCONVNOP
   838  		}
   839  	}
   840  
   841  	// 6. rule about untyped constants - already converted by defaultlit.
   842  
   843  	// 7. Any typed value can be assigned to the blank identifier.
   844  	if dst.Etype == TBLANK {
   845  		return OCONVNOP
   846  	}
   847  
   848  	return 0
   849  }
   850  
   851  // Can we convert a value of type src to a value of type dst?
   852  // If so, return op code to use in conversion (maybe OCONVNOP).
   853  // If not, return 0.
   854  func convertop(src *Type, dst *Type, why *string) Op {
   855  	if why != nil {
   856  		*why = ""
   857  	}
   858  
   859  	if src == dst {
   860  		return OCONVNOP
   861  	}
   862  	if src == nil || dst == nil {
   863  		return 0
   864  	}
   865  
   866  	// Conversions from regular to go:notinheap are not allowed
   867  	// (unless it's unsafe.Pointer). This is a runtime-specific
   868  	// rule.
   869  	if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap && !src.Elem().NotInHeap {
   870  		if why != nil {
   871  			*why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem())
   872  		}
   873  		return 0
   874  	}
   875  
   876  	// 1. src can be assigned to dst.
   877  	op := assignop(src, dst, why)
   878  	if op != 0 {
   879  		return op
   880  	}
   881  
   882  	// The rules for interfaces are no different in conversions
   883  	// than assignments. If interfaces are involved, stop now
   884  	// with the good message from assignop.
   885  	// Otherwise clear the error.
   886  	if src.IsInterface() || dst.IsInterface() {
   887  		return 0
   888  	}
   889  	if why != nil {
   890  		*why = ""
   891  	}
   892  
   893  	// 2. Ignoring struct tags, src and dst have identical underlying types.
   894  	if eqtypeIgnoreTags(src.Orig, dst.Orig) {
   895  		return OCONVNOP
   896  	}
   897  
   898  	// 3. src and dst are unnamed pointer types and, ignoring struct tags,
   899  	// their base types have identical underlying types.
   900  	if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil {
   901  		if eqtypeIgnoreTags(src.Elem().Orig, dst.Elem().Orig) {
   902  			return OCONVNOP
   903  		}
   904  	}
   905  
   906  	// 4. src and dst are both integer or floating point types.
   907  	if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
   908  		if simtype[src.Etype] == simtype[dst.Etype] {
   909  			return OCONVNOP
   910  		}
   911  		return OCONV
   912  	}
   913  
   914  	// 5. src and dst are both complex types.
   915  	if src.IsComplex() && dst.IsComplex() {
   916  		if simtype[src.Etype] == simtype[dst.Etype] {
   917  			return OCONVNOP
   918  		}
   919  		return OCONV
   920  	}
   921  
   922  	// 6. src is an integer or has type []byte or []rune
   923  	// and dst is a string type.
   924  	if src.IsInteger() && dst.IsString() {
   925  		return ORUNESTR
   926  	}
   927  
   928  	if src.IsSlice() && dst.IsString() {
   929  		if src.Elem().Etype == bytetype.Etype {
   930  			return OARRAYBYTESTR
   931  		}
   932  		if src.Elem().Etype == runetype.Etype {
   933  			return OARRAYRUNESTR
   934  		}
   935  	}
   936  
   937  	// 7. src is a string and dst is []byte or []rune.
   938  	// String to slice.
   939  	if src.IsString() && dst.IsSlice() {
   940  		if dst.Elem().Etype == bytetype.Etype {
   941  			return OSTRARRAYBYTE
   942  		}
   943  		if dst.Elem().Etype == runetype.Etype {
   944  			return OSTRARRAYRUNE
   945  		}
   946  	}
   947  
   948  	// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
   949  	if (src.IsPtr() || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR {
   950  		return OCONVNOP
   951  	}
   952  
   953  	// 9. src is unsafe.Pointer and dst is a pointer or uintptr.
   954  	if src.Etype == TUNSAFEPTR && (dst.IsPtr() || dst.Etype == TUINTPTR) {
   955  		return OCONVNOP
   956  	}
   957  
   958  	return 0
   959  }
   960  
   961  func assignconv(n *Node, t *Type, context string) *Node {
   962  	return assignconvfn(n, t, func() string { return context })
   963  }
   964  
   965  // Convert node n for assignment to type t.
   966  func assignconvfn(n *Node, t *Type, context func() string) *Node {
   967  	if n == nil || n.Type == nil || n.Type.Broke {
   968  		return n
   969  	}
   970  
   971  	if t.Etype == TBLANK && n.Type.Etype == TNIL {
   972  		yyerror("use of untyped nil")
   973  	}
   974  
   975  	old := n
   976  	od := old.Diag
   977  	old.Diag = true // silence errors about n; we'll issue one below
   978  	n = defaultlit(n, t)
   979  	old.Diag = od
   980  	if t.Etype == TBLANK {
   981  		return n
   982  	}
   983  
   984  	// Convert ideal bool from comparison to plain bool
   985  	// if the next step is non-bool (like interface{}).
   986  	if n.Type == idealbool && !t.IsBoolean() {
   987  		if n.Op == ONAME || n.Op == OLITERAL {
   988  			r := nod(OCONVNOP, n, nil)
   989  			r.Type = Types[TBOOL]
   990  			r.Typecheck = 1
   991  			r.Implicit = true
   992  			n = r
   993  		}
   994  	}
   995  
   996  	if eqtype(n.Type, t) {
   997  		return n
   998  	}
   999  
  1000  	var why string
  1001  	op := assignop(n.Type, t, &why)
  1002  	if op == 0 {
  1003  		yyerror("cannot use %L as type %v in %s%s", n, t, context(), why)
  1004  		op = OCONV
  1005  	}
  1006  
  1007  	r := nod(op, n, nil)
  1008  	r.Type = t
  1009  	r.Typecheck = 1
  1010  	r.Implicit = true
  1011  	r.Orig = n.Orig
  1012  	return r
  1013  }
  1014  
  1015  // IsMethod reports whether n is a method.
  1016  // n must be a function or a method.
  1017  func (n *Node) IsMethod() bool {
  1018  	return n.Type.Recv() != nil
  1019  }
  1020  
  1021  // SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
  1022  // n must be a slice expression. max is nil if n is a simple slice expression.
  1023  func (n *Node) SliceBounds() (low, high, max *Node) {
  1024  	if n.List.Len() == 0 {
  1025  		return nil, nil, nil
  1026  	}
  1027  
  1028  	switch n.Op {
  1029  	case OSLICE, OSLICEARR, OSLICESTR:
  1030  		s := n.List.Slice()
  1031  		return s[0], s[1], nil
  1032  	case OSLICE3, OSLICE3ARR:
  1033  		s := n.List.Slice()
  1034  		return s[0], s[1], s[2]
  1035  	}
  1036  	Fatalf("SliceBounds op %v: %v", n.Op, n)
  1037  	return nil, nil, nil
  1038  }
  1039  
  1040  // SetSliceBounds sets n's slice bounds, where n is a slice expression.
  1041  // n must be a slice expression. If max is non-nil, n must be a full slice expression.
  1042  func (n *Node) SetSliceBounds(low, high, max *Node) {
  1043  	switch n.Op {
  1044  	case OSLICE, OSLICEARR, OSLICESTR:
  1045  		if max != nil {
  1046  			Fatalf("SetSliceBounds %v given three bounds", n.Op)
  1047  		}
  1048  		s := n.List.Slice()
  1049  		if s == nil {
  1050  			if low == nil && high == nil {
  1051  				return
  1052  			}
  1053  			n.List.Set([]*Node{low, high})
  1054  			return
  1055  		}
  1056  		s[0] = low
  1057  		s[1] = high
  1058  		return
  1059  	case OSLICE3, OSLICE3ARR:
  1060  		s := n.List.Slice()
  1061  		if s == nil {
  1062  			if low == nil && high == nil && max == nil {
  1063  				return
  1064  			}
  1065  			n.List.Set([]*Node{low, high, max})
  1066  			return
  1067  		}
  1068  		s[0] = low
  1069  		s[1] = high
  1070  		s[2] = max
  1071  		return
  1072  	}
  1073  	Fatalf("SetSliceBounds op %v: %v", n.Op, n)
  1074  }
  1075  
  1076  // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
  1077  // o must be a slicing op.
  1078  func (o Op) IsSlice3() bool {
  1079  	switch o {
  1080  	case OSLICE, OSLICEARR, OSLICESTR:
  1081  		return false
  1082  	case OSLICE3, OSLICE3ARR:
  1083  		return true
  1084  	}
  1085  	Fatalf("IsSlice3 op %v", o)
  1086  	return false
  1087  }
  1088  
  1089  func syslook(name string) *Node {
  1090  	s := Pkglookup(name, Runtimepkg)
  1091  	if s == nil || s.Def == nil {
  1092  		Fatalf("syslook: can't find runtime.%s", name)
  1093  	}
  1094  	return s.Def
  1095  }
  1096  
  1097  // typehash computes a hash value for type t to use in type switch
  1098  // statements.
  1099  func typehash(t *Type) uint32 {
  1100  	// t.tconv(FmtLeft | FmtUnsigned) already contains all the necessary logic
  1101  	// to generate a representation that completely describes the type, so using
  1102  	// it here avoids duplicating that code.
  1103  	// See the comments in exprSwitch.checkDupCases.
  1104  	p := t.tconv(FmtLeft | FmtUnsigned)
  1105  
  1106  	// Using MD5 is overkill, but reduces accidental collisions.
  1107  	h := md5.Sum([]byte(p))
  1108  	return binary.LittleEndian.Uint32(h[:4])
  1109  }
  1110  
  1111  // ptrto returns the Type *t.
  1112  // The returned struct must not be modified.
  1113  func ptrto(t *Type) *Type {
  1114  	if Tptr == 0 {
  1115  		Fatalf("ptrto: no tptr")
  1116  	}
  1117  	if t == nil {
  1118  		Fatalf("ptrto: nil ptr")
  1119  	}
  1120  	return typPtr(t)
  1121  }
  1122  
  1123  func frame(context int) {
  1124  	if context != 0 {
  1125  		fmt.Printf("--- external frame ---\n")
  1126  		for _, n := range externdcl {
  1127  			printframenode(n)
  1128  		}
  1129  		return
  1130  	}
  1131  
  1132  	if Curfn != nil {
  1133  		fmt.Printf("--- %v frame ---\n", Curfn.Func.Nname.Sym)
  1134  		for _, ln := range Curfn.Func.Dcl {
  1135  			printframenode(ln)
  1136  		}
  1137  	}
  1138  }
  1139  
  1140  func printframenode(n *Node) {
  1141  	w := int64(-1)
  1142  	if n.Type != nil {
  1143  		w = n.Type.Width
  1144  	}
  1145  	switch n.Op {
  1146  	case ONAME:
  1147  		fmt.Printf("%v %v G%d %v width=%d\n", n.Op, n.Sym, n.Name.Vargen, n.Type, w)
  1148  	case OTYPE:
  1149  		fmt.Printf("%v %v width=%d\n", n.Op, n.Type, w)
  1150  	}
  1151  }
  1152  
  1153  // calculate sethi/ullman number
  1154  // roughly how many registers needed to
  1155  // compile a node. used to compile the
  1156  // hardest side first to minimize registers.
  1157  func ullmancalc(n *Node) {
  1158  	if n == nil {
  1159  		return
  1160  	}
  1161  
  1162  	var ul int
  1163  	var ur int
  1164  	if n.Ninit.Len() != 0 {
  1165  		ul = UINF
  1166  		goto out
  1167  	}
  1168  
  1169  	switch n.Op {
  1170  	case OLITERAL, ONAME:
  1171  		ul = 1
  1172  		if n.Class == PAUTOHEAP {
  1173  			ul++
  1174  		}
  1175  		goto out
  1176  
  1177  	case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OASWB:
  1178  		ul = UINF
  1179  		goto out
  1180  
  1181  		// hard with instrumented code
  1182  	case OANDAND, OOROR:
  1183  		if instrumenting {
  1184  			ul = UINF
  1185  			goto out
  1186  		}
  1187  	case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR,
  1188  		OIND, ODOTPTR, ODOTTYPE, ODIV, OMOD:
  1189  		// These ops might panic, make sure they are done
  1190  		// before we start marshaling args for a call. See issue 16760.
  1191  		ul = UINF
  1192  		goto out
  1193  	}
  1194  
  1195  	ul = 1
  1196  	if n.Left != nil {
  1197  		ul = int(n.Left.Ullman)
  1198  	}
  1199  	ur = 1
  1200  	if n.Right != nil {
  1201  		ur = int(n.Right.Ullman)
  1202  	}
  1203  	if ul == ur {
  1204  		ul += 1
  1205  	}
  1206  	if ur > ul {
  1207  		ul = ur
  1208  	}
  1209  
  1210  out:
  1211  	if ul > 200 {
  1212  		ul = 200 // clamp to uchar with room to grow
  1213  	}
  1214  	n.Ullman = uint8(ul)
  1215  }
  1216  
  1217  func badtype(op Op, tl *Type, tr *Type) {
  1218  	fmt_ := ""
  1219  	if tl != nil {
  1220  		fmt_ += fmt.Sprintf("\n\t%v", tl)
  1221  	}
  1222  	if tr != nil {
  1223  		fmt_ += fmt.Sprintf("\n\t%v", tr)
  1224  	}
  1225  
  1226  	// common mistake: *struct and *interface.
  1227  	if tl != nil && tr != nil && tl.IsPtr() && tr.IsPtr() {
  1228  		if tl.Elem().IsStruct() && tr.Elem().IsInterface() {
  1229  			fmt_ += "\n\t(*struct vs *interface)"
  1230  		} else if tl.Elem().IsInterface() && tr.Elem().IsStruct() {
  1231  			fmt_ += "\n\t(*interface vs *struct)"
  1232  		}
  1233  	}
  1234  
  1235  	s := fmt_
  1236  	yyerror("illegal types for operand: %v%s", op, s)
  1237  }
  1238  
  1239  // brcom returns !(op).
  1240  // For example, brcom(==) is !=.
  1241  func brcom(op Op) Op {
  1242  	switch op {
  1243  	case OEQ:
  1244  		return ONE
  1245  	case ONE:
  1246  		return OEQ
  1247  	case OLT:
  1248  		return OGE
  1249  	case OGT:
  1250  		return OLE
  1251  	case OLE:
  1252  		return OGT
  1253  	case OGE:
  1254  		return OLT
  1255  	}
  1256  	Fatalf("brcom: no com for %v\n", op)
  1257  	return op
  1258  }
  1259  
  1260  // brrev returns reverse(op).
  1261  // For example, Brrev(<) is >.
  1262  func brrev(op Op) Op {
  1263  	switch op {
  1264  	case OEQ:
  1265  		return OEQ
  1266  	case ONE:
  1267  		return ONE
  1268  	case OLT:
  1269  		return OGT
  1270  	case OGT:
  1271  		return OLT
  1272  	case OLE:
  1273  		return OGE
  1274  	case OGE:
  1275  		return OLE
  1276  	}
  1277  	Fatalf("brrev: no rev for %v\n", op)
  1278  	return op
  1279  }
  1280  
  1281  // return side effect-free n, appending side effects to init.
  1282  // result is assignable if n is.
  1283  func safeexpr(n *Node, init *Nodes) *Node {
  1284  	if n == nil {
  1285  		return nil
  1286  	}
  1287  
  1288  	if n.Ninit.Len() != 0 {
  1289  		walkstmtlist(n.Ninit.Slice())
  1290  		init.AppendNodes(&n.Ninit)
  1291  	}
  1292  
  1293  	switch n.Op {
  1294  	case ONAME, OLITERAL:
  1295  		return n
  1296  
  1297  	case ODOT, OLEN, OCAP:
  1298  		l := safeexpr(n.Left, init)
  1299  		if l == n.Left {
  1300  			return n
  1301  		}
  1302  		r := nod(OXXX, nil, nil)
  1303  		*r = *n
  1304  		r.Left = l
  1305  		r = typecheck(r, Erv)
  1306  		r = walkexpr(r, init)
  1307  		return r
  1308  
  1309  	case ODOTPTR, OIND:
  1310  		l := safeexpr(n.Left, init)
  1311  		if l == n.Left {
  1312  			return n
  1313  		}
  1314  		a := nod(OXXX, nil, nil)
  1315  		*a = *n
  1316  		a.Left = l
  1317  		a = walkexpr(a, init)
  1318  		return a
  1319  
  1320  	case OINDEX, OINDEXMAP:
  1321  		l := safeexpr(n.Left, init)
  1322  		r := safeexpr(n.Right, init)
  1323  		if l == n.Left && r == n.Right {
  1324  			return n
  1325  		}
  1326  		a := nod(OXXX, nil, nil)
  1327  		*a = *n
  1328  		a.Left = l
  1329  		a.Right = r
  1330  		a = walkexpr(a, init)
  1331  		return a
  1332  
  1333  	case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
  1334  		if isStaticCompositeLiteral(n) {
  1335  			return n
  1336  		}
  1337  	}
  1338  
  1339  	// make a copy; must not be used as an lvalue
  1340  	if islvalue(n) {
  1341  		Fatalf("missing lvalue case in safeexpr: %v", n)
  1342  	}
  1343  	return cheapexpr(n, init)
  1344  }
  1345  
  1346  func copyexpr(n *Node, t *Type, init *Nodes) *Node {
  1347  	l := temp(t)
  1348  	a := nod(OAS, l, n)
  1349  	a = typecheck(a, Etop)
  1350  	a = walkexpr(a, init)
  1351  	init.Append(a)
  1352  	return l
  1353  }
  1354  
  1355  // return side-effect free and cheap n, appending side effects to init.
  1356  // result may not be assignable.
  1357  func cheapexpr(n *Node, init *Nodes) *Node {
  1358  	switch n.Op {
  1359  	case ONAME, OLITERAL:
  1360  		return n
  1361  	}
  1362  
  1363  	return copyexpr(n, n.Type, init)
  1364  }
  1365  
  1366  // Code to resolve elided DOTs in embedded types.
  1367  
  1368  // A Dlist stores a pointer to a TFIELD Type embedded within
  1369  // a TSTRUCT or TINTER Type.
  1370  type Dlist struct {
  1371  	field *Field
  1372  }
  1373  
  1374  // dotlist is used by adddot1 to record the path of embedded fields
  1375  // used to access a target field or method.
  1376  // Must be non-nil so that dotpath returns a non-nil slice even if d is zero.
  1377  var dotlist = make([]Dlist, 10)
  1378  
  1379  // lookdot0 returns the number of fields or methods named s associated
  1380  // with Type t. If exactly one exists, it will be returned in *save
  1381  // (if save is not nil).
  1382  func lookdot0(s *Sym, t *Type, save **Field, ignorecase bool) int {
  1383  	u := t
  1384  	if u.IsPtr() {
  1385  		u = u.Elem()
  1386  	}
  1387  
  1388  	c := 0
  1389  	if u.IsStruct() || u.IsInterface() {
  1390  		for _, f := range u.Fields().Slice() {
  1391  			if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Recv() != nil && strings.EqualFold(f.Sym.Name, s.Name)) {
  1392  				if save != nil {
  1393  					*save = f
  1394  				}
  1395  				c++
  1396  			}
  1397  		}
  1398  	}
  1399  
  1400  	u = methtype(t)
  1401  	if u != nil {
  1402  		for _, f := range u.Methods().Slice() {
  1403  			if f.Embedded == 0 && (f.Sym == s || (ignorecase && strings.EqualFold(f.Sym.Name, s.Name))) {
  1404  				if save != nil {
  1405  					*save = f
  1406  				}
  1407  				c++
  1408  			}
  1409  		}
  1410  	}
  1411  
  1412  	return c
  1413  }
  1414  
  1415  // adddot1 returns the number of fields or methods named s at depth d in Type t.
  1416  // If exactly one exists, it will be returned in *save (if save is not nil),
  1417  // and dotlist will contain the path of embedded fields traversed to find it,
  1418  // in reverse order. If none exist, more will indicate whether t contains any
  1419  // embedded fields at depth d, so callers can decide whether to retry at
  1420  // a greater depth.
  1421  func adddot1(s *Sym, t *Type, d int, save **Field, ignorecase bool) (c int, more bool) {
  1422  	if t.Trecur != 0 {
  1423  		return
  1424  	}
  1425  	t.Trecur = 1
  1426  
  1427  	var u *Type
  1428  	d--
  1429  	if d < 0 {
  1430  		// We've reached our target depth. If t has any fields/methods
  1431  		// named s, then we're done. Otherwise, we still need to check
  1432  		// below for embedded fields.
  1433  		c = lookdot0(s, t, save, ignorecase)
  1434  		if c != 0 {
  1435  			goto out
  1436  		}
  1437  	}
  1438  
  1439  	u = t
  1440  	if u.IsPtr() {
  1441  		u = u.Elem()
  1442  	}
  1443  	if !u.IsStruct() && !u.IsInterface() {
  1444  		goto out
  1445  	}
  1446  
  1447  	for _, f := range u.Fields().Slice() {
  1448  		if f.Embedded == 0 || f.Sym == nil {
  1449  			continue
  1450  		}
  1451  		if d < 0 {
  1452  			// Found an embedded field at target depth.
  1453  			more = true
  1454  			goto out
  1455  		}
  1456  		a, more1 := adddot1(s, f.Type, d, save, ignorecase)
  1457  		if a != 0 && c == 0 {
  1458  			dotlist[d].field = f
  1459  		}
  1460  		c += a
  1461  		if more1 {
  1462  			more = true
  1463  		}
  1464  	}
  1465  
  1466  out:
  1467  	t.Trecur = 0
  1468  	return c, more
  1469  }
  1470  
  1471  // dotpath computes the unique shortest explicit selector path to fully qualify
  1472  // a selection expression x.f, where x is of type t and f is the symbol s.
  1473  // If no such path exists, dotpath returns nil.
  1474  // If there are multiple shortest paths to the same depth, ambig is true.
  1475  func dotpath(s *Sym, t *Type, save **Field, ignorecase bool) (path []Dlist, ambig bool) {
  1476  	// The embedding of types within structs imposes a tree structure onto
  1477  	// types: structs parent the types they embed, and types parent their
  1478  	// fields or methods. Our goal here is to find the shortest path to
  1479  	// a field or method named s in the subtree rooted at t. To accomplish
  1480  	// that, we iteratively perform depth-first searches of increasing depth
  1481  	// until we either find the named field/method or exhaust the tree.
  1482  	for d := 0; ; d++ {
  1483  		if d > len(dotlist) {
  1484  			dotlist = append(dotlist, Dlist{})
  1485  		}
  1486  		if c, more := adddot1(s, t, d, save, ignorecase); c == 1 {
  1487  			return dotlist[:d], false
  1488  		} else if c > 1 {
  1489  			return nil, true
  1490  		} else if !more {
  1491  			return nil, false
  1492  		}
  1493  	}
  1494  }
  1495  
  1496  // in T.field
  1497  // find missing fields that
  1498  // will give shortest unique addressing.
  1499  // modify the tree with missing type names.
  1500  func adddot(n *Node) *Node {
  1501  	n.Left = typecheck(n.Left, Etype|Erv)
  1502  	if n.Left.Diag {
  1503  		n.Diag = true
  1504  	}
  1505  	t := n.Left.Type
  1506  	if t == nil {
  1507  		return n
  1508  	}
  1509  
  1510  	if n.Left.Op == OTYPE {
  1511  		return n
  1512  	}
  1513  
  1514  	s := n.Sym
  1515  	if s == nil {
  1516  		return n
  1517  	}
  1518  
  1519  	switch path, ambig := dotpath(s, t, nil, false); {
  1520  	case path != nil:
  1521  		// rebuild elided dots
  1522  		for c := len(path) - 1; c >= 0; c-- {
  1523  			n.Left = nodSym(ODOT, n.Left, path[c].field.Sym)
  1524  			n.Left.Implicit = true
  1525  		}
  1526  	case ambig:
  1527  		yyerror("ambiguous selector %v", n)
  1528  		n.Left = nil
  1529  	}
  1530  
  1531  	return n
  1532  }
  1533  
  1534  // code to help generate trampoline
  1535  // functions for methods on embedded
  1536  // subtypes.
  1537  // these are approx the same as
  1538  // the corresponding adddot routines
  1539  // except that they expect to be called
  1540  // with unique tasks and they return
  1541  // the actual methods.
  1542  type Symlink struct {
  1543  	field     *Field
  1544  	followptr bool
  1545  }
  1546  
  1547  var slist []Symlink
  1548  
  1549  func expand0(t *Type, followptr bool) {
  1550  	u := t
  1551  	if u.IsPtr() {
  1552  		followptr = true
  1553  		u = u.Elem()
  1554  	}
  1555  
  1556  	if u.IsInterface() {
  1557  		for _, f := range u.Fields().Slice() {
  1558  			if f.Sym.Flags&SymUniq != 0 {
  1559  				continue
  1560  			}
  1561  			f.Sym.Flags |= SymUniq
  1562  			slist = append(slist, Symlink{field: f, followptr: followptr})
  1563  		}
  1564  
  1565  		return
  1566  	}
  1567  
  1568  	u = methtype(t)
  1569  	if u != nil {
  1570  		for _, f := range u.Methods().Slice() {
  1571  			if f.Sym.Flags&SymUniq != 0 {
  1572  				continue
  1573  			}
  1574  			f.Sym.Flags |= SymUniq
  1575  			slist = append(slist, Symlink{field: f, followptr: followptr})
  1576  		}
  1577  	}
  1578  }
  1579  
  1580  func expand1(t *Type, top, followptr bool) {
  1581  	if t.Trecur != 0 {
  1582  		return
  1583  	}
  1584  	t.Trecur = 1
  1585  
  1586  	if !top {
  1587  		expand0(t, followptr)
  1588  	}
  1589  
  1590  	u := t
  1591  	if u.IsPtr() {
  1592  		followptr = true
  1593  		u = u.Elem()
  1594  	}
  1595  
  1596  	if !u.IsStruct() && !u.IsInterface() {
  1597  		goto out
  1598  	}
  1599  
  1600  	for _, f := range u.Fields().Slice() {
  1601  		if f.Embedded == 0 {
  1602  			continue
  1603  		}
  1604  		if f.Sym == nil {
  1605  			continue
  1606  		}
  1607  		expand1(f.Type, false, followptr)
  1608  	}
  1609  
  1610  out:
  1611  	t.Trecur = 0
  1612  }
  1613  
  1614  func expandmeth(t *Type) {
  1615  	if t == nil || t.AllMethods().Len() != 0 {
  1616  		return
  1617  	}
  1618  
  1619  	// mark top-level method symbols
  1620  	// so that expand1 doesn't consider them.
  1621  	for _, f := range t.Methods().Slice() {
  1622  		f.Sym.Flags |= SymUniq
  1623  	}
  1624  
  1625  	// generate all reachable methods
  1626  	slist = slist[:0]
  1627  	expand1(t, true, false)
  1628  
  1629  	// check each method to be uniquely reachable
  1630  	var ms []*Field
  1631  	for i, sl := range slist {
  1632  		slist[i].field = nil
  1633  		sl.field.Sym.Flags &^= SymUniq
  1634  
  1635  		var f *Field
  1636  		if path, _ := dotpath(sl.field.Sym, t, &f, false); path == nil {
  1637  			continue
  1638  		}
  1639  
  1640  		// dotpath may have dug out arbitrary fields, we only want methods.
  1641  		if f.Type.Etype != TFUNC || f.Type.Recv() == nil {
  1642  			continue
  1643  		}
  1644  
  1645  		// add it to the base type method list
  1646  		f = f.Copy()
  1647  		f.Embedded = 1 // needs a trampoline
  1648  		if sl.followptr {
  1649  			f.Embedded = 2
  1650  		}
  1651  		ms = append(ms, f)
  1652  	}
  1653  
  1654  	for _, f := range t.Methods().Slice() {
  1655  		f.Sym.Flags &^= SymUniq
  1656  	}
  1657  
  1658  	ms = append(ms, t.Methods().Slice()...)
  1659  	t.AllMethods().Set(ms)
  1660  }
  1661  
  1662  // Given funarg struct list, return list of ODCLFIELD Node fn args.
  1663  func structargs(tl *Type, mustname bool) []*Node {
  1664  	var args []*Node
  1665  	gen := 0
  1666  	for _, t := range tl.Fields().Slice() {
  1667  		var n *Node
  1668  		if mustname && (t.Sym == nil || t.Sym.Name == "_") {
  1669  			// invent a name so that we can refer to it in the trampoline
  1670  			buf := fmt.Sprintf(".anon%d", gen)
  1671  			gen++
  1672  			n = newname(lookup(buf))
  1673  		} else if t.Sym != nil {
  1674  			n = newname(t.Sym)
  1675  		}
  1676  		a := nod(ODCLFIELD, n, typenod(t.Type))
  1677  		a.Isddd = t.Isddd
  1678  		if n != nil {
  1679  			n.Isddd = t.Isddd
  1680  		}
  1681  		args = append(args, a)
  1682  	}
  1683  
  1684  	return args
  1685  }
  1686  
  1687  // Generate a wrapper function to convert from
  1688  // a receiver of type T to a receiver of type U.
  1689  // That is,
  1690  //
  1691  //	func (t T) M() {
  1692  //		...
  1693  //	}
  1694  //
  1695  // already exists; this function generates
  1696  //
  1697  //	func (u U) M() {
  1698  //		u.M()
  1699  //	}
  1700  //
  1701  // where the types T and U are such that u.M() is valid
  1702  // and calls the T.M method.
  1703  // The resulting function is for use in method tables.
  1704  //
  1705  //	rcvr - U
  1706  //	method - M func (t T)(), a TFIELD type struct
  1707  //	newnam - the eventual mangled name of this function
  1708  
  1709  var genwrapper_linehistdone int = 0
  1710  
  1711  func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
  1712  	if false && Debug['r'] != 0 {
  1713  		fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
  1714  	}
  1715  
  1716  	lexlineno++
  1717  	lineno = lexlineno
  1718  	if genwrapper_linehistdone == 0 {
  1719  		// All the wrappers can share the same linehist entry.
  1720  		linehistpush("<autogenerated>")
  1721  
  1722  		genwrapper_linehistdone = 1
  1723  	}
  1724  
  1725  	dclcontext = PEXTERN
  1726  	markdcl()
  1727  
  1728  	this := nod(ODCLFIELD, newname(lookup(".this")), typenod(rcvr))
  1729  	this.Left.Name.Param.Ntype = this.Right
  1730  	in := structargs(method.Type.Params(), true)
  1731  	out := structargs(method.Type.Results(), false)
  1732  
  1733  	t := nod(OTFUNC, nil, nil)
  1734  	l := []*Node{this}
  1735  	if iface != 0 && rcvr.Width < Types[Tptr].Width {
  1736  		// Building method for interface table and receiver
  1737  		// is smaller than the single pointer-sized word
  1738  		// that the interface call will pass in.
  1739  		// Add a dummy padding argument after the
  1740  		// receiver to make up the difference.
  1741  		tpad := typArray(Types[TUINT8], Types[Tptr].Width-rcvr.Width)
  1742  		pad := nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad))
  1743  		l = append(l, pad)
  1744  	}
  1745  
  1746  	t.List.Set(append(l, in...))
  1747  	t.Rlist.Set(out)
  1748  
  1749  	fn := nod(ODCLFUNC, nil, nil)
  1750  	fn.Func.Nname = newname(newnam)
  1751  	fn.Func.Nname.Name.Defn = fn
  1752  	fn.Func.Nname.Name.Param.Ntype = t
  1753  	declare(fn.Func.Nname, PFUNC)
  1754  	funchdr(fn)
  1755  
  1756  	// arg list
  1757  	var args []*Node
  1758  
  1759  	isddd := false
  1760  	for _, n := range in {
  1761  		args = append(args, n.Left)
  1762  		isddd = n.Left.Isddd
  1763  	}
  1764  
  1765  	methodrcvr := method.Type.Recv().Type
  1766  
  1767  	// generate nil pointer check for better error
  1768  	if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
  1769  		// generating wrapper from *T to T.
  1770  		n := nod(OIF, nil, nil)
  1771  
  1772  		n.Left = nod(OEQ, this.Left, nodnil())
  1773  
  1774  		// these strings are already in the reflect tables,
  1775  		// so no space cost to use them here.
  1776  		var l []*Node
  1777  
  1778  		var v Val
  1779  		v.U = rcvr.Elem().Sym.Pkg.Name // package name
  1780  		l = append(l, nodlit(v))
  1781  		v.U = rcvr.Elem().Sym.Name // type name
  1782  		l = append(l, nodlit(v))
  1783  		v.U = method.Sym.Name
  1784  		l = append(l, nodlit(v)) // method name
  1785  		call := nod(OCALL, syslook("panicwrap"), nil)
  1786  		call.List.Set(l)
  1787  		n.Nbody.Set1(call)
  1788  		fn.Nbody.Append(n)
  1789  	}
  1790  
  1791  	dot := adddot(nodSym(OXDOT, this.Left, method.Sym))
  1792  
  1793  	// generate call
  1794  	// It's not possible to use a tail call when dynamic linking on ppc64le. The
  1795  	// bad scenario is when a local call is made to the wrapper: the wrapper will
  1796  	// call the implementation, which might be in a different module and so set
  1797  	// the TOC to the appropriate value for that module. But if it returns
  1798  	// directly to the wrapper's caller, nothing will reset it to the correct
  1799  	// value for that function.
  1800  	if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(Thearch.LinkArch.Name == "ppc64le" && Ctxt.Flag_dynlink) {
  1801  		// generate tail call: adjust pointer receiver and jump to embedded method.
  1802  		dot = dot.Left // skip final .M
  1803  		// TODO(mdempsky): Remove dependency on dotlist.
  1804  		if !dotlist[0].field.Type.IsPtr() {
  1805  			dot = nod(OADDR, dot, nil)
  1806  		}
  1807  		as := nod(OAS, this.Left, nod(OCONVNOP, dot, nil))
  1808  		as.Right.Type = rcvr
  1809  		fn.Nbody.Append(as)
  1810  		n := nod(ORETJMP, nil, nil)
  1811  		n.Left = newname(methodsym(method.Sym, methodrcvr, 0))
  1812  		fn.Nbody.Append(n)
  1813  		// When tail-calling, we can't use a frame pointer.
  1814  		fn.Func.NoFramePointer = true
  1815  	} else {
  1816  		fn.Func.Wrapper = true // ignore frame for panic+recover matching
  1817  		call := nod(OCALL, dot, nil)
  1818  		call.List.Set(args)
  1819  		call.Isddd = isddd
  1820  		if method.Type.Results().NumFields() > 0 {
  1821  			n := nod(ORETURN, nil, nil)
  1822  			n.List.Set1(call)
  1823  			call = n
  1824  		}
  1825  
  1826  		fn.Nbody.Append(call)
  1827  	}
  1828  
  1829  	if false && Debug['r'] != 0 {
  1830  		dumplist("genwrapper body", fn.Nbody)
  1831  	}
  1832  
  1833  	funcbody(fn)
  1834  	Curfn = fn
  1835  	popdcl()
  1836  	if debug_dclstack != 0 {
  1837  		testdclstack()
  1838  	}
  1839  
  1840  	// wrappers where T is anonymous (struct or interface) can be duplicated.
  1841  	if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {
  1842  		fn.Func.Dupok = true
  1843  	}
  1844  	fn = typecheck(fn, Etop)
  1845  	typecheckslice(fn.Nbody.Slice(), Etop)
  1846  
  1847  	inlcalls(fn)
  1848  	escAnalyze([]*Node{fn}, false)
  1849  
  1850  	Curfn = nil
  1851  	funccompile(fn)
  1852  }
  1853  
  1854  func hashmem(t *Type) *Node {
  1855  	sym := Pkglookup("memhash", Runtimepkg)
  1856  
  1857  	n := newname(sym)
  1858  	n.Class = PFUNC
  1859  	tfn := nod(OTFUNC, nil, nil)
  1860  	tfn.List.Append(nod(ODCLFIELD, nil, typenod(ptrto(t))))
  1861  	tfn.List.Append(nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
  1862  	tfn.List.Append(nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
  1863  	tfn.Rlist.Append(nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
  1864  	tfn = typecheck(tfn, Etype)
  1865  	n.Type = tfn.Type
  1866  	return n
  1867  }
  1868  
  1869  func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase bool) *Field {
  1870  	*followptr = false
  1871  
  1872  	if t == nil {
  1873  		return nil
  1874  	}
  1875  
  1876  	var m *Field
  1877  	path, ambig := dotpath(s, t, &m, ignorecase)
  1878  	if path == nil {
  1879  		if ambig {
  1880  			yyerror("%v.%v is ambiguous", t, s)
  1881  		}
  1882  		return nil
  1883  	}
  1884  
  1885  	for _, d := range path {
  1886  		if d.field.Type.IsPtr() {
  1887  			*followptr = true
  1888  			break
  1889  		}
  1890  	}
  1891  
  1892  	if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
  1893  		yyerror("%v.%v is a field, not a method", t, s)
  1894  		return nil
  1895  	}
  1896  
  1897  	return m
  1898  }
  1899  
  1900  func implements(t, iface *Type, m, samename **Field, ptr *int) bool {
  1901  	t0 := t
  1902  	if t == nil {
  1903  		return false
  1904  	}
  1905  
  1906  	// if this is too slow,
  1907  	// could sort these first
  1908  	// and then do one loop.
  1909  
  1910  	if t.IsInterface() {
  1911  		for _, im := range iface.Fields().Slice() {
  1912  			for _, tm := range t.Fields().Slice() {
  1913  				if tm.Sym == im.Sym {
  1914  					if eqtype(tm.Type, im.Type) {
  1915  						goto found
  1916  					}
  1917  					*m = im
  1918  					*samename = tm
  1919  					*ptr = 0
  1920  					return false
  1921  				}
  1922  			}
  1923  
  1924  			*m = im
  1925  			*samename = nil
  1926  			*ptr = 0
  1927  			return false
  1928  		found:
  1929  		}
  1930  
  1931  		return true
  1932  	}
  1933  
  1934  	t = methtype(t)
  1935  	if t != nil {
  1936  		expandmeth(t)
  1937  	}
  1938  	for _, im := range iface.Fields().Slice() {
  1939  		if im.Broke {
  1940  			continue
  1941  		}
  1942  		var followptr bool
  1943  		tm := ifacelookdot(im.Sym, t, &followptr, false)
  1944  		if tm == nil || tm.Nointerface || !eqtype(tm.Type, im.Type) {
  1945  			if tm == nil {
  1946  				tm = ifacelookdot(im.Sym, t, &followptr, true)
  1947  			}
  1948  			*m = im
  1949  			*samename = tm
  1950  			*ptr = 0
  1951  			return false
  1952  		}
  1953  
  1954  		// if pointer receiver in method,
  1955  		// the method does not exist for value types.
  1956  		rcvr := tm.Type.Recv().Type
  1957  
  1958  		if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
  1959  			if false && Debug['r'] != 0 {
  1960  				yyerror("interface pointer mismatch")
  1961  			}
  1962  
  1963  			*m = im
  1964  			*samename = nil
  1965  			*ptr = 1
  1966  			return false
  1967  		}
  1968  	}
  1969  
  1970  	return true
  1971  }
  1972  
  1973  // even simpler simtype; get rid of ptr, bool.
  1974  // assuming that the front end has rejected
  1975  // all the invalid conversions (like ptr -> bool)
  1976  func Simsimtype(t *Type) EType {
  1977  	if t == nil {
  1978  		return 0
  1979  	}
  1980  
  1981  	et := simtype[t.Etype]
  1982  	switch et {
  1983  	case TPTR32:
  1984  		et = TUINT32
  1985  
  1986  	case TPTR64:
  1987  		et = TUINT64
  1988  
  1989  	case TBOOL:
  1990  		et = TUINT8
  1991  	}
  1992  
  1993  	return et
  1994  }
  1995  
  1996  func listtreecopy(l []*Node, lineno int32) []*Node {
  1997  	var out []*Node
  1998  	for _, n := range l {
  1999  		out = append(out, treecopy(n, lineno))
  2000  	}
  2001  	return out
  2002  }
  2003  
  2004  func liststmt(l []*Node) *Node {
  2005  	n := nod(OBLOCK, nil, nil)
  2006  	n.List.Set(l)
  2007  	if len(l) != 0 {
  2008  		n.Lineno = l[0].Lineno
  2009  	}
  2010  	return n
  2011  }
  2012  
  2013  // return power of 2 of the constant
  2014  // operand. -1 if it is not a power of 2.
  2015  // 1000+ if it is a -(power of 2)
  2016  func powtwo(n *Node) int {
  2017  	if n == nil || n.Op != OLITERAL || n.Type == nil {
  2018  		return -1
  2019  	}
  2020  	if !n.Type.IsInteger() {
  2021  		return -1
  2022  	}
  2023  
  2024  	v := uint64(n.Int64())
  2025  	b := uint64(1)
  2026  	for i := 0; i < 64; i++ {
  2027  		if b == v {
  2028  			return i
  2029  		}
  2030  		b = b << 1
  2031  	}
  2032  
  2033  	if !n.Type.IsSigned() {
  2034  		return -1
  2035  	}
  2036  
  2037  	v = -v
  2038  	b = 1
  2039  	for i := 0; i < 64; i++ {
  2040  		if b == v {
  2041  			return i + 1000
  2042  		}
  2043  		b = b << 1
  2044  	}
  2045  
  2046  	return -1
  2047  }
  2048  
  2049  func ngotype(n *Node) *Sym {
  2050  	if n.Type != nil {
  2051  		return typenamesym(n.Type)
  2052  	}
  2053  	return nil
  2054  }
  2055  
  2056  // Convert raw string to the prefix that will be used in the symbol
  2057  // table. All control characters, space, '%' and '"', as well as
  2058  // non-7-bit clean bytes turn into %xx. The period needs escaping
  2059  // only in the last segment of the path, and it makes for happier
  2060  // users if we escape that as little as possible.
  2061  //
  2062  // If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
  2063  func pathtoprefix(s string) string {
  2064  	slash := strings.LastIndex(s, "/")
  2065  	for i := 0; i < len(s); i++ {
  2066  		c := s[i]
  2067  		if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
  2068  			var buf bytes.Buffer
  2069  			for i := 0; i < len(s); i++ {
  2070  				c := s[i]
  2071  				if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F {
  2072  					fmt.Fprintf(&buf, "%%%02x", c)
  2073  					continue
  2074  				}
  2075  				buf.WriteByte(c)
  2076  			}
  2077  			return buf.String()
  2078  		}
  2079  	}
  2080  	return s
  2081  }
  2082  
  2083  var pkgMap = make(map[string]*Pkg)
  2084  var pkgs []*Pkg
  2085  
  2086  func mkpkg(path string) *Pkg {
  2087  	if p := pkgMap[path]; p != nil {
  2088  		return p
  2089  	}
  2090  
  2091  	p := new(Pkg)
  2092  	p.Path = path
  2093  	p.Prefix = pathtoprefix(path)
  2094  	p.Syms = make(map[string]*Sym)
  2095  	pkgMap[path] = p
  2096  	pkgs = append(pkgs, p)
  2097  	return p
  2098  }
  2099  
  2100  // The result of addinit MUST be assigned back to n, e.g.
  2101  // 	n.Left = addinit(n.Left, init)
  2102  func addinit(n *Node, init []*Node) *Node {
  2103  	if len(init) == 0 {
  2104  		return n
  2105  	}
  2106  
  2107  	switch n.Op {
  2108  	// There may be multiple refs to this node;
  2109  	// introduce OCONVNOP to hold init list.
  2110  	case ONAME, OLITERAL:
  2111  		n = nod(OCONVNOP, n, nil)
  2112  		n.Type = n.Left.Type
  2113  		n.Typecheck = 1
  2114  	}
  2115  
  2116  	n.Ninit.Prepend(init...)
  2117  	n.Ullman = UINF
  2118  	return n
  2119  }
  2120  
  2121  var reservedimports = []string{
  2122  	"go",
  2123  	"type",
  2124  }
  2125  
  2126  func isbadimport(path string) bool {
  2127  	if strings.Contains(path, "\x00") {
  2128  		yyerror("import path contains NUL")
  2129  		return true
  2130  	}
  2131  
  2132  	for _, ri := range reservedimports {
  2133  		if path == ri {
  2134  			yyerror("import path %q is reserved and cannot be used", path)
  2135  			return true
  2136  		}
  2137  	}
  2138  
  2139  	for _, r := range path {
  2140  		if r == utf8.RuneError {
  2141  			yyerror("import path contains invalid UTF-8 sequence: %q", path)
  2142  			return true
  2143  		}
  2144  
  2145  		if r < 0x20 || r == 0x7f {
  2146  			yyerror("import path contains control character: %q", path)
  2147  			return true
  2148  		}
  2149  
  2150  		if r == '\\' {
  2151  			yyerror("import path contains backslash; use slash: %q", path)
  2152  			return true
  2153  		}
  2154  
  2155  		if unicode.IsSpace(r) {
  2156  			yyerror("import path contains space character: %q", path)
  2157  			return true
  2158  		}
  2159  
  2160  		if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
  2161  			yyerror("import path contains invalid character '%c': %q", r, path)
  2162  			return true
  2163  		}
  2164  	}
  2165  
  2166  	return false
  2167  }
  2168  
  2169  func checknil(x *Node, init *Nodes) {
  2170  	x = walkexpr(x, nil) // caller has not done this yet
  2171  	if x.Type.IsInterface() {
  2172  		x = nod(OITAB, x, nil)
  2173  		x = typecheck(x, Erv)
  2174  	}
  2175  
  2176  	n := nod(OCHECKNIL, x, nil)
  2177  	n.Typecheck = 1
  2178  	init.Append(n)
  2179  }
  2180  
  2181  // Can this type be stored directly in an interface word?
  2182  // Yes, if the representation is a single pointer.
  2183  func isdirectiface(t *Type) bool {
  2184  	switch t.Etype {
  2185  	case TPTR32,
  2186  		TPTR64,
  2187  		TCHAN,
  2188  		TMAP,
  2189  		TFUNC,
  2190  		TUNSAFEPTR:
  2191  		return true
  2192  
  2193  	case TARRAY:
  2194  		// Array of 1 direct iface type can be direct.
  2195  		return t.NumElem() == 1 && isdirectiface(t.Elem())
  2196  
  2197  	case TSTRUCT:
  2198  		// Struct with 1 field of direct iface type can be direct.
  2199  		return t.NumFields() == 1 && isdirectiface(t.Field(0).Type)
  2200  	}
  2201  
  2202  	return false
  2203  }
  2204  
  2205  // itabType loads the _type field from a runtime.itab struct.
  2206  func itabType(itab *Node) *Node {
  2207  	typ := nodSym(ODOTPTR, itab, nil)
  2208  	typ.Type = ptrto(Types[TUINT8])
  2209  	typ.Typecheck = 1
  2210  	typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
  2211  	typ.Bounded = true            // guaranteed not to fault
  2212  	return typ
  2213  }
  2214  
  2215  // ifaceData loads the data field from an interface.
  2216  // The concrete type must be known to have type t.
  2217  // It follows the pointer if !isdirectiface(t).
  2218  func ifaceData(n *Node, t *Type) *Node {
  2219  	ptr := nodSym(OIDATA, n, nil)
  2220  	if isdirectiface(t) {
  2221  		ptr.Type = t
  2222  		ptr.Typecheck = 1
  2223  		return ptr
  2224  	}
  2225  	ptr.Type = ptrto(t)
  2226  	ptr.Bounded = true
  2227  	ptr.Typecheck = 1
  2228  	ind := nod(OIND, ptr, nil)
  2229  	ind.Type = t
  2230  	ind.Typecheck = 1
  2231  	return ind
  2232  }
  2233  
  2234  // iet returns 'T' if t is a concrete type,
  2235  // 'I' if t is an interface type, and 'E' if t is an empty interface type.
  2236  // It is used to build calls to the conv* and assert* runtime routines.
  2237  func (t *Type) iet() byte {
  2238  	if t.IsEmptyInterface() {
  2239  		return 'E'
  2240  	}
  2241  	if t.IsInterface() {
  2242  		return 'I'
  2243  	}
  2244  	return 'T'
  2245  }