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