Home | History | Annotate | Download | only in gc
      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 }
   2246