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