github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/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 "sort" 15 "strings" 16 "unicode" 17 "unicode/utf8" 18 ) 19 20 type Error struct { 21 lineno int 22 seq int 23 msg string 24 } 25 26 var errors []Error 27 28 func errorexit() { 29 Flusherrors() 30 if outfile != "" { 31 os.Remove(outfile) 32 } 33 os.Exit(2) 34 } 35 36 func parserline() int { 37 if parsing && theparser.Lookahead() > 0 { 38 // parser has one symbol lookahead 39 return int(prevlineno) 40 } 41 return int(lineno) 42 } 43 44 func adderrorname(n *Node) { 45 if n.Op != ODOT { 46 return 47 } 48 old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left) 49 if len(errors) > 0 && int32(errors[len(errors)-1].lineno) == n.Lineno && errors[len(errors)-1].msg == old { 50 errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n) 51 } 52 } 53 54 func adderr(line int, format string, args ...interface{}) { 55 errors = append(errors, Error{ 56 seq: len(errors), 57 lineno: line, 58 msg: fmt.Sprintf("%v: %s\n", Ctxt.Line(line), fmt.Sprintf(format, args...)), 59 }) 60 } 61 62 // errcmp sorts errors by line, then seq, then message. 63 type errcmp []Error 64 65 func (x errcmp) Len() int { return len(x) } 66 func (x errcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 67 func (x errcmp) Less(i, j int) bool { 68 a := &x[i] 69 b := &x[j] 70 if a.lineno != b.lineno { 71 return a.lineno < b.lineno 72 } 73 if a.seq != b.seq { 74 return a.seq < b.seq 75 } 76 return a.msg < b.msg 77 } 78 79 func Flusherrors() { 80 bstdout.Flush() 81 if len(errors) == 0 { 82 return 83 } 84 sort.Sort(errcmp(errors)) 85 for i := 0; i < len(errors); i++ { 86 if i == 0 || errors[i].msg != errors[i-1].msg { 87 fmt.Printf("%s", errors[i].msg) 88 } 89 } 90 errors = errors[:0] 91 } 92 93 func hcrash() { 94 if Debug['h'] != 0 { 95 Flusherrors() 96 if outfile != "" { 97 os.Remove(outfile) 98 } 99 var x *int 100 *x = 0 101 } 102 } 103 104 func yyerrorl(line int, format string, args ...interface{}) { 105 adderr(line, format, args...) 106 107 hcrash() 108 nerrors++ 109 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 110 Flusherrors() 111 fmt.Printf("%v: too many errors\n", Ctxt.Line(line)) 112 errorexit() 113 } 114 } 115 116 var yyerror_lastsyntax int 117 118 func Yyerror(format string, args ...interface{}) { 119 msg := fmt.Sprintf(format, args...) 120 if strings.HasPrefix(msg, "syntax error") { 121 nsyntaxerrors++ 122 123 // An unexpected EOF caused a syntax error. Use the previous 124 // line number since getc generated a fake newline character. 125 if curio.eofnl { 126 lexlineno = prevlineno 127 } 128 129 // only one syntax error per line 130 if int32(yyerror_lastsyntax) == lexlineno { 131 return 132 } 133 yyerror_lastsyntax = int(lexlineno) 134 135 // plain "syntax error" gets "near foo" added 136 if msg == "syntax error" { 137 yyerrorl(int(lexlineno), "syntax error near %s", lexbuf.String()) 138 return 139 } 140 141 // The grammar has { and LBRACE but both show up as {. 142 // Rewrite syntax error referring to "{ or {" to say just "{". 143 // The grammar has ? and @ but only for reading imports. 144 // Silence them in ordinary errors. 145 msg = strings.Replace(msg, "{ or {", "{", -1) 146 msg = strings.Replace(msg, " or ?", "", -1) 147 msg = strings.Replace(msg, " or @", "", -1) 148 149 msg = strings.Replace(msg, "LLITERAL", litbuf, -1) 150 151 yyerrorl(int(lexlineno), "%s", msg) 152 return 153 } 154 155 adderr(parserline(), "%s", msg) 156 157 hcrash() 158 nerrors++ 159 if nsavederrors+nerrors >= 10 && Debug['e'] == 0 { 160 Flusherrors() 161 fmt.Printf("%v: too many errors\n", Ctxt.Line(parserline())) 162 errorexit() 163 } 164 } 165 166 func Warn(fmt_ string, args ...interface{}) { 167 adderr(parserline(), fmt_, args...) 168 169 hcrash() 170 } 171 172 func Warnl(line int, fmt_ string, args ...interface{}) { 173 adderr(line, fmt_, args...) 174 if Debug['m'] != 0 { 175 Flusherrors() 176 } 177 } 178 179 func Fatalf(fmt_ string, args ...interface{}) { 180 Flusherrors() 181 182 fmt.Printf("%v: internal compiler error: ", Ctxt.Line(int(lineno))) 183 fmt.Printf(fmt_, args...) 184 fmt.Printf("\n") 185 186 // If this is a released compiler version, ask for a bug report. 187 if strings.HasPrefix(obj.Getgoversion(), "release") { 188 fmt.Printf("\n") 189 fmt.Printf("Please file a bug report including a short program that triggers the error.\n") 190 fmt.Printf("https://golang.org/issue/new\n") 191 } 192 193 hcrash() 194 errorexit() 195 } 196 197 func linehistpragma(file string) { 198 if Debug['i'] != 0 { 199 fmt.Printf("pragma %s at line %v\n", file, Ctxt.Line(int(lexlineno))) 200 } 201 Ctxt.AddImport(file) 202 } 203 204 func linehistpush(file string) { 205 if Debug['i'] != 0 { 206 fmt.Printf("import %s at line %v\n", file, Ctxt.Line(int(lexlineno))) 207 } 208 Ctxt.LineHist.Push(int(lexlineno), file) 209 } 210 211 func linehistpop() { 212 if Debug['i'] != 0 { 213 fmt.Printf("end of import at line %v\n", Ctxt.Line(int(lexlineno))) 214 } 215 Ctxt.LineHist.Pop(int(lexlineno)) 216 } 217 218 func linehistupdate(file string, off int) { 219 if Debug['i'] != 0 { 220 fmt.Printf("line %s at line %v\n", file, Ctxt.Line(int(lexlineno))) 221 } 222 Ctxt.LineHist.Update(int(lexlineno), file, off) 223 } 224 225 func setlineno(n *Node) int32 { 226 lno := lineno 227 if n != nil { 228 switch n.Op { 229 case ONAME, OTYPE, OPACK: 230 break 231 232 case OLITERAL: 233 if n.Sym != nil { 234 break 235 } 236 fallthrough 237 238 default: 239 lineno = n.Lineno 240 if lineno == 0 { 241 if Debug['K'] != 0 { 242 Warn("setlineno: line 0") 243 } 244 lineno = lno 245 } 246 } 247 } 248 249 return lno 250 } 251 252 func Lookup(name string) *Sym { 253 return localpkg.Lookup(name) 254 } 255 256 func Lookupf(format string, a ...interface{}) *Sym { 257 return Lookup(fmt.Sprintf(format, a...)) 258 } 259 260 func LookupBytes(name []byte) *Sym { 261 return localpkg.LookupBytes(name) 262 } 263 264 var initSyms []*Sym 265 266 var nopkg = &Pkg{ 267 Syms: make(map[string]*Sym), 268 } 269 270 func (pkg *Pkg) Lookup(name string) *Sym { 271 if pkg == nil { 272 pkg = nopkg 273 } 274 if s := pkg.Syms[name]; s != nil { 275 return s 276 } 277 278 s := &Sym{ 279 Name: name, 280 Pkg: pkg, 281 Lexical: LNAME, 282 } 283 if name == "init" { 284 initSyms = append(initSyms, s) 285 } 286 pkg.Syms[name] = s 287 return s 288 } 289 290 func (pkg *Pkg) LookupBytes(name []byte) *Sym { 291 if pkg == nil { 292 pkg = nopkg 293 } 294 if s := pkg.Syms[string(name)]; s != nil { 295 return s 296 } 297 str := internString(name) 298 return pkg.Lookup(str) 299 } 300 301 func Pkglookup(name string, pkg *Pkg) *Sym { 302 return pkg.Lookup(name) 303 } 304 305 func restrictlookup(name string, pkg *Pkg) *Sym { 306 if !exportname(name) && pkg != localpkg { 307 Yyerror("cannot refer to unexported name %s.%s", pkg.Name, name) 308 } 309 return Pkglookup(name, pkg) 310 } 311 312 // find all the exported symbols in package opkg 313 // and make them available in the current package 314 func importdot(opkg *Pkg, pack *Node) { 315 var s1 *Sym 316 var pkgerror string 317 318 n := 0 319 for _, s := range opkg.Syms { 320 if s.Def == nil { 321 continue 322 } 323 if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot 324 continue 325 } 326 s1 = Lookup(s.Name) 327 if s1.Def != nil { 328 pkgerror = fmt.Sprintf("during import %q", opkg.Path) 329 redeclare(s1, pkgerror) 330 continue 331 } 332 333 s1.Def = s.Def 334 s1.Block = s.Block 335 if s1.Def.Name == nil { 336 Dump("s1def", s1.Def) 337 Fatalf("missing Name") 338 } 339 s1.Def.Name.Pack = pack 340 s1.Origpkg = opkg 341 n++ 342 } 343 344 if n == 0 { 345 // can't possibly be used - there were no symbols 346 yyerrorl(int(pack.Lineno), "imported and not used: %q", opkg.Path) 347 } 348 } 349 350 func Nod(op Op, nleft *Node, nright *Node) *Node { 351 n := new(Node) 352 n.Op = op 353 n.Left = nleft 354 n.Right = nright 355 n.Lineno = int32(parserline()) 356 n.Xoffset = BADWIDTH 357 n.Orig = n 358 switch op { 359 case OCLOSURE, ODCLFUNC: 360 n.Func = new(Func) 361 n.Func.FCurfn = Curfn 362 case ONAME: 363 n.Name = new(Name) 364 n.Name.Param = new(Param) 365 case OLABEL, OPACK: 366 n.Name = new(Name) 367 case ODCLFIELD: 368 if nleft != nil { 369 n.Name = nleft.Name 370 } else { 371 n.Name = new(Name) 372 n.Name.Param = new(Param) 373 } 374 } 375 if n.Name != nil { 376 n.Name.Curfn = Curfn 377 } 378 return n 379 } 380 381 func saveorignode(n *Node) { 382 if n.Orig != nil { 383 return 384 } 385 norig := Nod(n.Op, nil, nil) 386 *norig = *n 387 n.Orig = norig 388 } 389 390 // ispaddedfield reports whether the given field 391 // is followed by padding. For the case where t is 392 // the last field, total gives the size of the enclosing struct. 393 func ispaddedfield(t *Type, total int64) bool { 394 if t.Etype != TFIELD { 395 Fatalf("ispaddedfield called non-field %v", t) 396 } 397 if t.Down == nil { 398 return t.Width+t.Type.Width != total 399 } 400 return t.Width+t.Type.Width != t.Down.Width 401 } 402 403 func algtype1(t *Type, bad **Type) int { 404 if bad != nil { 405 *bad = nil 406 } 407 if t.Broke { 408 return AMEM 409 } 410 if t.Noalg { 411 return ANOEQ 412 } 413 414 switch t.Etype { 415 // will be defined later. 416 case TANY, TFORW: 417 *bad = t 418 419 return -1 420 421 case TINT8, 422 TUINT8, 423 TINT16, 424 TUINT16, 425 TINT32, 426 TUINT32, 427 TINT64, 428 TUINT64, 429 TINT, 430 TUINT, 431 TUINTPTR, 432 TBOOL, 433 TPTR32, 434 TPTR64, 435 TCHAN, 436 TUNSAFEPTR: 437 return AMEM 438 439 case TFUNC, TMAP: 440 if bad != nil { 441 *bad = t 442 } 443 return ANOEQ 444 445 case TFLOAT32: 446 return AFLOAT32 447 448 case TFLOAT64: 449 return AFLOAT64 450 451 case TCOMPLEX64: 452 return ACPLX64 453 454 case TCOMPLEX128: 455 return ACPLX128 456 457 case TSTRING: 458 return ASTRING 459 460 case TINTER: 461 if isnilinter(t) { 462 return ANILINTER 463 } 464 return AINTER 465 466 case TARRAY: 467 if Isslice(t) { 468 if bad != nil { 469 *bad = t 470 } 471 return ANOEQ 472 } 473 474 a := algtype1(t.Type, bad) 475 if a == ANOEQ || a == AMEM { 476 if a == ANOEQ && bad != nil { 477 *bad = t 478 } 479 return a 480 } 481 482 return -1 // needs special compare 483 484 case TSTRUCT: 485 if t.Type != nil && t.Type.Down == nil && !isblanksym(t.Type.Sym) { 486 // One-field struct is same as that one field alone. 487 return algtype1(t.Type.Type, bad) 488 } 489 490 ret := AMEM 491 var a int 492 for t1 := t.Type; t1 != nil; t1 = t1.Down { 493 // All fields must be comparable. 494 a = algtype1(t1.Type, bad) 495 496 if a == ANOEQ { 497 return ANOEQ 498 } 499 500 // Blank fields, padded fields, fields with non-memory 501 // equality need special compare. 502 if a != AMEM || isblanksym(t1.Sym) || ispaddedfield(t1, t.Width) { 503 ret = -1 504 continue 505 } 506 } 507 508 return ret 509 } 510 511 Fatalf("algtype1: unexpected type %v", t) 512 return 0 513 } 514 515 func algtype(t *Type) int { 516 a := algtype1(t, nil) 517 if a == AMEM || a == ANOEQ { 518 if Isslice(t) { 519 return ASLICE 520 } 521 switch t.Width { 522 case 0: 523 return a + AMEM0 - AMEM 524 525 case 1: 526 return a + AMEM8 - AMEM 527 528 case 2: 529 return a + AMEM16 - AMEM 530 531 case 4: 532 return a + AMEM32 - AMEM 533 534 case 8: 535 return a + AMEM64 - AMEM 536 537 case 16: 538 return a + AMEM128 - AMEM 539 } 540 } 541 542 return a 543 } 544 545 func maptype(key *Type, val *Type) *Type { 546 if key != nil { 547 var bad *Type 548 atype := algtype1(key, &bad) 549 var mtype EType 550 if bad == nil { 551 mtype = key.Etype 552 } else { 553 mtype = bad.Etype 554 } 555 switch mtype { 556 default: 557 if atype == ANOEQ { 558 Yyerror("invalid map key type %v", key) 559 } 560 561 // will be resolved later. 562 case TANY: 563 break 564 565 // map[key] used during definition of key. 566 // postpone check until key is fully defined. 567 // if there are multiple uses of map[key] 568 // before key is fully defined, the error 569 // will only be printed for the first one. 570 // good enough. 571 case TFORW: 572 if key.Maplineno == 0 { 573 key.Maplineno = lineno 574 } 575 } 576 } 577 578 t := typ(TMAP) 579 t.Down = key 580 t.Type = val 581 return t 582 } 583 584 func typ(et EType) *Type { 585 t := new(Type) 586 t.Etype = et 587 t.Width = BADWIDTH 588 t.Lineno = int(lineno) 589 t.Orig = t 590 return t 591 } 592 593 // methcmp sorts by symbol, then by package path for unexported symbols. 594 type methcmp []*Type 595 596 func (x methcmp) Len() int { return len(x) } 597 func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 598 func (x methcmp) Less(i, j int) bool { 599 a := x[i] 600 b := x[j] 601 if a.Sym == nil && b.Sym == nil { 602 return false 603 } 604 if a.Sym == nil { 605 return true 606 } 607 if b.Sym == nil { 608 return false 609 } 610 if a.Sym.Name != b.Sym.Name { 611 return a.Sym.Name < b.Sym.Name 612 } 613 if !exportname(a.Sym.Name) { 614 if a.Sym.Pkg.Path != b.Sym.Pkg.Path { 615 return a.Sym.Pkg.Path < b.Sym.Pkg.Path 616 } 617 } 618 619 return false 620 } 621 622 func sortinter(t *Type) *Type { 623 if t.Type == nil || t.Type.Down == nil { 624 return t 625 } 626 627 var a []*Type 628 for f := t.Type; f != nil; f = f.Down { 629 a = append(a, f) 630 } 631 sort.Sort(methcmp(a)) 632 633 n := len(a) // n > 0 due to initial conditions. 634 for i := 0; i < n-1; i++ { 635 a[i].Down = a[i+1] 636 } 637 a[n-1].Down = nil 638 639 t.Type = a[0] 640 return t 641 } 642 643 func Nodintconst(v int64) *Node { 644 c := Nod(OLITERAL, nil, nil) 645 c.Addable = true 646 c.SetVal(Val{new(Mpint)}) 647 Mpmovecfix(c.Val().U.(*Mpint), v) 648 c.Type = Types[TIDEAL] 649 ullmancalc(c) 650 return c 651 } 652 653 func nodfltconst(v *Mpflt) *Node { 654 c := Nod(OLITERAL, nil, nil) 655 c.Addable = true 656 c.SetVal(Val{newMpflt()}) 657 mpmovefltflt(c.Val().U.(*Mpflt), v) 658 c.Type = Types[TIDEAL] 659 ullmancalc(c) 660 return c 661 } 662 663 func Nodconst(n *Node, t *Type, v int64) { 664 *n = Node{} 665 n.Op = OLITERAL 666 n.Addable = true 667 ullmancalc(n) 668 n.SetVal(Val{new(Mpint)}) 669 Mpmovecfix(n.Val().U.(*Mpint), v) 670 n.Type = t 671 672 if Isfloat[t.Etype] { 673 Fatalf("nodconst: bad type %v", t) 674 } 675 } 676 677 func nodnil() *Node { 678 c := Nodintconst(0) 679 c.SetVal(Val{new(NilVal)}) 680 c.Type = Types[TNIL] 681 return c 682 } 683 684 func Nodbool(b bool) *Node { 685 c := Nodintconst(0) 686 c.SetVal(Val{b}) 687 c.Type = idealbool 688 return c 689 } 690 691 func aindex(b *Node, t *Type) *Type { 692 bound := int64(-1) // open bound 693 typecheck(&b, Erv) 694 if b != nil { 695 switch consttype(b) { 696 default: 697 Yyerror("array bound must be an integer expression") 698 699 case CTINT, CTRUNE: 700 bound = Mpgetfix(b.Val().U.(*Mpint)) 701 if bound < 0 { 702 Yyerror("array bound must be non negative") 703 } 704 } 705 } 706 707 // fixed array 708 r := typ(TARRAY) 709 710 r.Type = t 711 r.Bound = bound 712 return r 713 } 714 715 // treecopy recursively copies n, with the exception of 716 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves. 717 // Copies of iota ONONAME nodes are assigned the current 718 // value of iota_. If lineno != 0, it sets the line number 719 // of newly allocated nodes to lineno. 720 func treecopy(n *Node, lineno int32) *Node { 721 if n == nil { 722 return nil 723 } 724 725 var m *Node 726 switch n.Op { 727 default: 728 m = Nod(OXXX, nil, nil) 729 *m = *n 730 m.Orig = m 731 m.Left = treecopy(n.Left, lineno) 732 m.Right = treecopy(n.Right, lineno) 733 m.List = listtreecopy(n.List, lineno) 734 if lineno != 0 { 735 m.Lineno = lineno 736 } 737 if m.Name != nil && n.Op != ODCLFIELD { 738 Dump("treecopy", n) 739 Fatalf("treecopy Name") 740 } 741 742 case ONONAME: 743 if n.Sym == Lookup("iota") { 744 // Not sure yet whether this is the real iota, 745 // but make a copy of the Node* just in case, 746 // so that all the copies of this const definition 747 // don't have the same iota value. 748 m = Nod(OXXX, nil, nil) 749 *m = *n 750 if lineno != 0 { 751 m.Lineno = lineno 752 } 753 m.Name = new(Name) 754 *m.Name = *n.Name 755 m.Name.Iota = iota_ 756 break 757 } 758 fallthrough 759 760 case ONAME, OLITERAL, OTYPE: 761 m = n 762 } 763 764 return m 765 } 766 767 func isnil(n *Node) bool { 768 if n == nil { 769 return false 770 } 771 if n.Op != OLITERAL { 772 return false 773 } 774 if n.Val().Ctype() != CTNIL { 775 return false 776 } 777 return true 778 } 779 780 func isptrto(t *Type, et EType) bool { 781 if t == nil { 782 return false 783 } 784 if !Isptr[t.Etype] { 785 return false 786 } 787 t = t.Type 788 if t == nil { 789 return false 790 } 791 if t.Etype != et { 792 return false 793 } 794 return true 795 } 796 797 func Istype(t *Type, et EType) bool { 798 return t != nil && t.Etype == et 799 } 800 801 func Isfixedarray(t *Type) bool { 802 return t != nil && t.Etype == TARRAY && t.Bound >= 0 803 } 804 805 func Isslice(t *Type) bool { 806 return t != nil && t.Etype == TARRAY && t.Bound < 0 807 } 808 809 func isblank(n *Node) bool { 810 if n == nil { 811 return false 812 } 813 return isblanksym(n.Sym) 814 } 815 816 func isblanksym(s *Sym) bool { 817 return s != nil && s.Name == "_" 818 } 819 820 func Isinter(t *Type) bool { 821 return t != nil && t.Etype == TINTER 822 } 823 824 func isnilinter(t *Type) bool { 825 if !Isinter(t) { 826 return false 827 } 828 if t.Type != nil { 829 return false 830 } 831 return true 832 } 833 834 func isideal(t *Type) bool { 835 if t == nil { 836 return false 837 } 838 if t == idealstring || t == idealbool { 839 return true 840 } 841 switch t.Etype { 842 case TNIL, TIDEAL: 843 return true 844 } 845 846 return false 847 } 848 849 // given receiver of type t (t == r or t == *r) 850 // return type to hang methods off (r). 851 func methtype(t *Type, mustname int) *Type { 852 if t == nil { 853 return nil 854 } 855 856 // strip away pointer if it's there 857 if Isptr[t.Etype] { 858 if t.Sym != nil { 859 return nil 860 } 861 t = t.Type 862 if t == nil { 863 return nil 864 } 865 } 866 867 // need a type name 868 if t.Sym == nil && (mustname != 0 || t.Etype != TSTRUCT) { 869 return nil 870 } 871 872 // check types 873 if !issimple[t.Etype] { 874 switch t.Etype { 875 default: 876 return nil 877 878 case TSTRUCT, 879 TARRAY, 880 TMAP, 881 TCHAN, 882 TSTRING, 883 TFUNC: 884 break 885 } 886 } 887 888 return t 889 } 890 891 func cplxsubtype(et EType) EType { 892 switch et { 893 case TCOMPLEX64: 894 return TFLOAT32 895 896 case TCOMPLEX128: 897 return TFLOAT64 898 } 899 900 Fatalf("cplxsubtype: %v\n", Econv(et)) 901 return 0 902 } 903 904 func eqnote(a, b *string) bool { 905 return a == b || a != nil && b != nil && *a == *b 906 } 907 908 type TypePairList struct { 909 t1 *Type 910 t2 *Type 911 next *TypePairList 912 } 913 914 func onlist(l *TypePairList, t1 *Type, t2 *Type) bool { 915 for ; l != nil; l = l.next { 916 if (l.t1 == t1 && l.t2 == t2) || (l.t1 == t2 && l.t2 == t1) { 917 return true 918 } 919 } 920 return false 921 } 922 923 // Return 1 if t1 and t2 are identical, following the spec rules. 924 // 925 // Any cyclic type must go through a named type, and if one is 926 // named, it is only identical to the other if they are the same 927 // pointer (t1 == t2), so there's no chance of chasing cycles 928 // ad infinitum, so no need for a depth counter. 929 func Eqtype(t1 *Type, t2 *Type) bool { 930 return eqtype1(t1, t2, nil) 931 } 932 933 func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool { 934 if t1 == t2 { 935 return true 936 } 937 if t1 == nil || t2 == nil || t1.Etype != t2.Etype { 938 return false 939 } 940 if t1.Sym != nil || t2.Sym != nil { 941 // Special case: we keep byte and uint8 separate 942 // for error messages. Treat them as equal. 943 switch t1.Etype { 944 case TUINT8: 945 if (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype) { 946 return true 947 } 948 949 case TINT, TINT32: 950 if (t1 == Types[runetype.Etype] || t1 == runetype) && (t2 == Types[runetype.Etype] || t2 == runetype) { 951 return true 952 } 953 } 954 955 return false 956 } 957 958 if onlist(assumed_equal, t1, t2) { 959 return true 960 } 961 var l TypePairList 962 l.next = assumed_equal 963 l.t1 = t1 964 l.t2 = t2 965 966 switch t1.Etype { 967 case TINTER, TSTRUCT: 968 t1 = t1.Type 969 t2 = t2.Type 970 for ; t1 != nil && t2 != nil; t1, t2 = t1.Down, t2.Down { 971 if t1.Etype != TFIELD || t2.Etype != TFIELD { 972 Fatalf("struct/interface missing field: %v %v", t1, t2) 973 } 974 if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) { 975 return false 976 } 977 } 978 979 if t1 == nil && t2 == nil { 980 return true 981 } 982 return false 983 984 // Loop over structs: receiver, in, out. 985 case TFUNC: 986 t1 = t1.Type 987 t2 = t2.Type 988 for ; t1 != nil && t2 != nil; t1, t2 = t1.Down, t2.Down { 989 if t1.Etype != TSTRUCT || t2.Etype != TSTRUCT { 990 Fatalf("func missing struct: %v %v", t1, t2) 991 } 992 993 // Loop over fields in structs, ignoring argument names. 994 ta := t1.Type 995 tb := t2.Type 996 for ; ta != nil && tb != nil; ta, tb = ta.Down, tb.Down { 997 if ta.Etype != TFIELD || tb.Etype != TFIELD { 998 Fatalf("func struct missing field: %v %v", ta, tb) 999 } 1000 if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) { 1001 return false 1002 } 1003 } 1004 1005 if ta != nil || tb != nil { 1006 return false 1007 } 1008 } 1009 1010 if t1 == nil && t2 == nil { 1011 return true 1012 } 1013 return false 1014 1015 case TARRAY: 1016 if t1.Bound != t2.Bound { 1017 return false 1018 } 1019 1020 case TCHAN: 1021 if t1.Chan != t2.Chan { 1022 return false 1023 } 1024 } 1025 1026 if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) { 1027 return true 1028 } 1029 return false 1030 } 1031 1032 // Are t1 and t2 equal struct types when field names are ignored? 1033 // For deciding whether the result struct from g can be copied 1034 // directly when compiling f(g()). 1035 func eqtypenoname(t1 *Type, t2 *Type) bool { 1036 if t1 == nil || t2 == nil || t1.Etype != TSTRUCT || t2.Etype != TSTRUCT { 1037 return false 1038 } 1039 1040 t1 = t1.Type 1041 t2 = t2.Type 1042 for { 1043 if !Eqtype(t1, t2) { 1044 return false 1045 } 1046 if t1 == nil { 1047 return true 1048 } 1049 t1 = t1.Down 1050 t2 = t2.Down 1051 } 1052 } 1053 1054 // Is type src assignment compatible to type dst? 1055 // If so, return op code to use in conversion. 1056 // If not, return 0. 1057 func assignop(src *Type, dst *Type, why *string) Op { 1058 if why != nil { 1059 *why = "" 1060 } 1061 1062 // TODO(rsc,lvd): This behaves poorly in the presence of inlining. 1063 // https://golang.org/issue/2795 1064 if safemode != 0 && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR { 1065 Yyerror("cannot use unsafe.Pointer") 1066 errorexit() 1067 } 1068 1069 if src == dst { 1070 return OCONVNOP 1071 } 1072 if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { 1073 return 0 1074 } 1075 1076 // 1. src type is identical to dst. 1077 if Eqtype(src, dst) { 1078 return OCONVNOP 1079 } 1080 1081 // 2. src and dst have identical underlying types 1082 // and either src or dst is not a named type or 1083 // both are empty interface types. 1084 // For assignable but different non-empty interface types, 1085 // we want to recompute the itab. 1086 if Eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || isnilinter(src)) { 1087 return OCONVNOP 1088 } 1089 1090 // 3. dst is an interface type and src implements dst. 1091 if dst.Etype == TINTER && src.Etype != TNIL { 1092 var missing *Type 1093 var ptr int 1094 var have *Type 1095 if implements(src, dst, &missing, &have, &ptr) { 1096 return OCONVIFACE 1097 } 1098 1099 // we'll have complained about this method anyway, suppress spurious messages. 1100 if have != nil && have.Sym == missing.Sym && (have.Type.Broke || missing.Type.Broke) { 1101 return OCONVIFACE 1102 } 1103 1104 if why != nil { 1105 if isptrto(src, TINTER) { 1106 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) 1107 } else if have != nil && have.Sym == missing.Sym && have.Nointerface { 1108 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) 1109 } else if have != nil && have.Sym == missing.Sym { 1110 *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, obj.FmtShort|obj.FmtByte), missing.Sym, Tconv(missing.Type, obj.FmtShort|obj.FmtByte)) 1111 } else if ptr != 0 { 1112 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) 1113 } else if have != nil { 1114 *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, obj.FmtShort|obj.FmtByte), missing.Sym, Tconv(missing.Type, obj.FmtShort|obj.FmtByte)) 1115 } else { 1116 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) 1117 } 1118 } 1119 1120 return 0 1121 } 1122 1123 if isptrto(dst, TINTER) { 1124 if why != nil { 1125 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) 1126 } 1127 return 0 1128 } 1129 1130 if src.Etype == TINTER && dst.Etype != TBLANK { 1131 var have *Type 1132 var ptr int 1133 var missing *Type 1134 if why != nil && implements(dst, src, &missing, &have, &ptr) { 1135 *why = ": need type assertion" 1136 } 1137 return 0 1138 } 1139 1140 // 4. src is a bidirectional channel value, dst is a channel type, 1141 // src and dst have identical element types, and 1142 // either src or dst is not a named type. 1143 if src.Etype == TCHAN && src.Chan == Cboth && dst.Etype == TCHAN { 1144 if Eqtype(src.Type, dst.Type) && (src.Sym == nil || dst.Sym == nil) { 1145 return OCONVNOP 1146 } 1147 } 1148 1149 // 5. src is the predeclared identifier nil and dst is a nillable type. 1150 if src.Etype == TNIL { 1151 switch dst.Etype { 1152 case TARRAY: 1153 if dst.Bound != -100 { // not slice 1154 break 1155 } 1156 fallthrough 1157 1158 case TPTR32, 1159 TPTR64, 1160 TFUNC, 1161 TMAP, 1162 TCHAN, 1163 TINTER: 1164 return OCONVNOP 1165 } 1166 } 1167 1168 // 6. rule about untyped constants - already converted by defaultlit. 1169 1170 // 7. Any typed value can be assigned to the blank identifier. 1171 if dst.Etype == TBLANK { 1172 return OCONVNOP 1173 } 1174 1175 return 0 1176 } 1177 1178 // Can we convert a value of type src to a value of type dst? 1179 // If so, return op code to use in conversion (maybe OCONVNOP). 1180 // If not, return 0. 1181 func convertop(src *Type, dst *Type, why *string) Op { 1182 if why != nil { 1183 *why = "" 1184 } 1185 1186 if src == dst { 1187 return OCONVNOP 1188 } 1189 if src == nil || dst == nil { 1190 return 0 1191 } 1192 1193 // 1. src can be assigned to dst. 1194 op := assignop(src, dst, why) 1195 if op != 0 { 1196 return op 1197 } 1198 1199 // The rules for interfaces are no different in conversions 1200 // than assignments. If interfaces are involved, stop now 1201 // with the good message from assignop. 1202 // Otherwise clear the error. 1203 if src.Etype == TINTER || dst.Etype == TINTER { 1204 return 0 1205 } 1206 if why != nil { 1207 *why = "" 1208 } 1209 1210 // 2. src and dst have identical underlying types. 1211 if Eqtype(src.Orig, dst.Orig) { 1212 return OCONVNOP 1213 } 1214 1215 // 3. src and dst are unnamed pointer types 1216 // and their base types have identical underlying types. 1217 if Isptr[src.Etype] && Isptr[dst.Etype] && src.Sym == nil && dst.Sym == nil { 1218 if Eqtype(src.Type.Orig, dst.Type.Orig) { 1219 return OCONVNOP 1220 } 1221 } 1222 1223 // 4. src and dst are both integer or floating point types. 1224 if (Isint[src.Etype] || Isfloat[src.Etype]) && (Isint[dst.Etype] || Isfloat[dst.Etype]) { 1225 if Simtype[src.Etype] == Simtype[dst.Etype] { 1226 return OCONVNOP 1227 } 1228 return OCONV 1229 } 1230 1231 // 5. src and dst are both complex types. 1232 if Iscomplex[src.Etype] && Iscomplex[dst.Etype] { 1233 if Simtype[src.Etype] == Simtype[dst.Etype] { 1234 return OCONVNOP 1235 } 1236 return OCONV 1237 } 1238 1239 // 6. src is an integer or has type []byte or []rune 1240 // and dst is a string type. 1241 if Isint[src.Etype] && dst.Etype == TSTRING { 1242 return ORUNESTR 1243 } 1244 1245 if Isslice(src) && dst.Etype == TSTRING { 1246 if src.Type.Etype == bytetype.Etype { 1247 return OARRAYBYTESTR 1248 } 1249 if src.Type.Etype == runetype.Etype { 1250 return OARRAYRUNESTR 1251 } 1252 } 1253 1254 // 7. src is a string and dst is []byte or []rune. 1255 // String to slice. 1256 if src.Etype == TSTRING && Isslice(dst) { 1257 if dst.Type.Etype == bytetype.Etype { 1258 return OSTRARRAYBYTE 1259 } 1260 if dst.Type.Etype == runetype.Etype { 1261 return OSTRARRAYRUNE 1262 } 1263 } 1264 1265 // 8. src is a pointer or uintptr and dst is unsafe.Pointer. 1266 if (Isptr[src.Etype] || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR { 1267 return OCONVNOP 1268 } 1269 1270 // 9. src is unsafe.Pointer and dst is a pointer or uintptr. 1271 if src.Etype == TUNSAFEPTR && (Isptr[dst.Etype] || dst.Etype == TUINTPTR) { 1272 return OCONVNOP 1273 } 1274 1275 return 0 1276 } 1277 1278 func assignconv(n *Node, t *Type, context string) *Node { 1279 return assignconvfn(n, t, func() string { return context }) 1280 } 1281 1282 // Convert node n for assignment to type t. 1283 func assignconvfn(n *Node, t *Type, context func() string) *Node { 1284 if n == nil || n.Type == nil || n.Type.Broke { 1285 return n 1286 } 1287 1288 if t.Etype == TBLANK && n.Type.Etype == TNIL { 1289 Yyerror("use of untyped nil") 1290 } 1291 1292 old := n 1293 old.Diag++ // silence errors about n; we'll issue one below 1294 defaultlit(&n, t) 1295 old.Diag-- 1296 if t.Etype == TBLANK { 1297 return n 1298 } 1299 1300 // Convert ideal bool from comparison to plain bool 1301 // if the next step is non-bool (like interface{}). 1302 if n.Type == idealbool && t.Etype != TBOOL { 1303 if n.Op == ONAME || n.Op == OLITERAL { 1304 r := Nod(OCONVNOP, n, nil) 1305 r.Type = Types[TBOOL] 1306 r.Typecheck = 1 1307 r.Implicit = true 1308 n = r 1309 } 1310 } 1311 1312 if Eqtype(n.Type, t) { 1313 return n 1314 } 1315 1316 var why string 1317 op := assignop(n.Type, t, &why) 1318 if op == 0 { 1319 Yyerror("cannot use %v as type %v in %s%s", Nconv(n, obj.FmtLong), t, context(), why) 1320 op = OCONV 1321 } 1322 1323 r := Nod(op, n, nil) 1324 r.Type = t 1325 r.Typecheck = 1 1326 r.Implicit = true 1327 r.Orig = n.Orig 1328 return r 1329 } 1330 1331 // substArgTypes substitutes the given list of types for 1332 // successive occurrences of the "any" placeholder in the 1333 // type syntax expression n.Type. 1334 func substArgTypes(n *Node, types ...*Type) { 1335 for _, t := range types { 1336 dowidth(t) 1337 } 1338 substAny(&n.Type, &types) 1339 if len(types) > 0 { 1340 Fatalf("substArgTypes: too many argument types") 1341 } 1342 } 1343 1344 // substAny walks *tp, replacing instances of "any" with successive 1345 // elements removed from types. 1346 func substAny(tp **Type, types *[]*Type) { 1347 for { 1348 t := *tp 1349 if t == nil { 1350 return 1351 } 1352 if t.Etype == TANY && t.Copyany { 1353 if len(*types) == 0 { 1354 Fatalf("substArgTypes: not enough argument types") 1355 } 1356 *tp = (*types)[0] 1357 *types = (*types)[1:] 1358 } 1359 1360 switch t.Etype { 1361 case TPTR32, TPTR64, TCHAN, TARRAY: 1362 tp = &t.Type 1363 continue 1364 1365 case TMAP: 1366 substAny(&t.Down, types) 1367 tp = &t.Type 1368 continue 1369 1370 case TFUNC: 1371 substAny(&t.Type, types) 1372 substAny(&t.Type.Down.Down, types) 1373 substAny(&t.Type.Down, types) 1374 1375 case TSTRUCT: 1376 for t = t.Type; t != nil; t = t.Down { 1377 substAny(&t.Type, types) 1378 } 1379 } 1380 return 1381 } 1382 } 1383 1384 // Is this a 64-bit type? 1385 func Is64(t *Type) bool { 1386 if t == nil { 1387 return false 1388 } 1389 switch Simtype[t.Etype] { 1390 case TINT64, TUINT64, TPTR64: 1391 return true 1392 } 1393 1394 return false 1395 } 1396 1397 // Is a conversion between t1 and t2 a no-op? 1398 func Noconv(t1 *Type, t2 *Type) bool { 1399 e1 := Simtype[t1.Etype] 1400 e2 := Simtype[t2.Etype] 1401 1402 switch e1 { 1403 case TINT8, TUINT8: 1404 return e2 == TINT8 || e2 == TUINT8 1405 1406 case TINT16, TUINT16: 1407 return e2 == TINT16 || e2 == TUINT16 1408 1409 case TINT32, TUINT32, TPTR32: 1410 return e2 == TINT32 || e2 == TUINT32 || e2 == TPTR32 1411 1412 case TINT64, TUINT64, TPTR64: 1413 return e2 == TINT64 || e2 == TUINT64 || e2 == TPTR64 1414 1415 case TFLOAT32: 1416 return e2 == TFLOAT32 1417 1418 case TFLOAT64: 1419 return e2 == TFLOAT64 1420 } 1421 1422 return false 1423 } 1424 1425 func shallow(t *Type) *Type { 1426 if t == nil { 1427 return nil 1428 } 1429 nt := typ(0) 1430 *nt = *t 1431 if t.Orig == t { 1432 nt.Orig = nt 1433 } 1434 return nt 1435 } 1436 1437 func deep(t *Type) *Type { 1438 if t == nil { 1439 return nil 1440 } 1441 1442 var nt *Type 1443 switch t.Etype { 1444 default: 1445 nt = t // share from here down 1446 1447 case TANY: 1448 nt = shallow(t) 1449 nt.Copyany = true 1450 1451 case TPTR32, TPTR64, TCHAN, TARRAY: 1452 nt = shallow(t) 1453 nt.Type = deep(t.Type) 1454 1455 case TMAP: 1456 nt = shallow(t) 1457 nt.Down = deep(t.Down) 1458 nt.Type = deep(t.Type) 1459 1460 case TFUNC: 1461 nt = shallow(t) 1462 nt.Type = deep(t.Type) 1463 nt.Type.Down = deep(t.Type.Down) 1464 nt.Type.Down.Down = deep(t.Type.Down.Down) 1465 1466 case TSTRUCT: 1467 nt = shallow(t) 1468 nt.Type = shallow(t.Type) 1469 xt := nt.Type 1470 1471 for t = t.Type; t != nil; t = t.Down { 1472 xt.Type = deep(t.Type) 1473 xt.Down = shallow(t.Down) 1474 xt = xt.Down 1475 } 1476 } 1477 1478 return nt 1479 } 1480 1481 func syslook(name string, copy int) *Node { 1482 s := Pkglookup(name, Runtimepkg) 1483 if s == nil || s.Def == nil { 1484 Fatalf("syslook: can't find runtime.%s", name) 1485 } 1486 1487 if copy == 0 { 1488 return s.Def 1489 } 1490 1491 n := Nod(0, nil, nil) 1492 *n = *s.Def 1493 n.Type = deep(s.Def.Type) 1494 1495 return n 1496 } 1497 1498 // compute a hash value for type t. 1499 // if t is a method type, ignore the receiver 1500 // so that the hash can be used in interface checks. 1501 // %T already contains 1502 // all the necessary logic to generate a representation 1503 // of the type that completely describes it. 1504 // using smprint here avoids duplicating that code. 1505 // using md5 here is overkill, but i got tired of 1506 // accidental collisions making the runtime think 1507 // two types are equal when they really aren't. 1508 func typehash(t *Type) uint32 { 1509 var p string 1510 1511 if t.Thistuple != 0 { 1512 // hide method receiver from Tpretty 1513 t.Thistuple = 0 1514 1515 p = Tconv(t, obj.FmtLeft|obj.FmtUnsigned) 1516 t.Thistuple = 1 1517 } else { 1518 p = Tconv(t, obj.FmtLeft|obj.FmtUnsigned) 1519 } 1520 1521 //print("typehash: %s\n", p); 1522 h := md5.Sum([]byte(p)) 1523 return binary.LittleEndian.Uint32(h[:4]) 1524 } 1525 1526 var initPtrtoDone bool 1527 1528 var ( 1529 ptrToUint8 *Type 1530 ptrToAny *Type 1531 ptrToString *Type 1532 ptrToBool *Type 1533 ptrToInt32 *Type 1534 ) 1535 1536 func initPtrto() { 1537 ptrToUint8 = ptrto1(Types[TUINT8]) 1538 ptrToAny = ptrto1(Types[TANY]) 1539 ptrToString = ptrto1(Types[TSTRING]) 1540 ptrToBool = ptrto1(Types[TBOOL]) 1541 ptrToInt32 = ptrto1(Types[TINT32]) 1542 } 1543 1544 func ptrto1(t *Type) *Type { 1545 t1 := typ(Tptr) 1546 t1.Type = t 1547 t1.Width = int64(Widthptr) 1548 t1.Align = uint8(Widthptr) 1549 return t1 1550 } 1551 1552 // Ptrto returns the Type *t. 1553 // The returned struct must not be modified. 1554 func Ptrto(t *Type) *Type { 1555 if Tptr == 0 { 1556 Fatalf("ptrto: no tptr") 1557 } 1558 // Reduce allocations by pre-creating common cases. 1559 if !initPtrtoDone { 1560 initPtrto() 1561 initPtrtoDone = true 1562 } 1563 switch t { 1564 case Types[TUINT8]: 1565 return ptrToUint8 1566 case Types[TINT32]: 1567 return ptrToInt32 1568 case Types[TANY]: 1569 return ptrToAny 1570 case Types[TSTRING]: 1571 return ptrToString 1572 case Types[TBOOL]: 1573 return ptrToBool 1574 } 1575 return ptrto1(t) 1576 } 1577 1578 func frame(context int) { 1579 if context != 0 { 1580 fmt.Printf("--- external frame ---\n") 1581 for _, n := range externdcl { 1582 printframenode(n) 1583 } 1584 return 1585 } 1586 1587 if Curfn != nil { 1588 fmt.Printf("--- %v frame ---\n", Curfn.Func.Nname.Sym) 1589 for l := Curfn.Func.Dcl; l != nil; l = l.Next { 1590 printframenode(l.N) 1591 } 1592 } 1593 } 1594 1595 func printframenode(n *Node) { 1596 w := int64(-1) 1597 if n.Type != nil { 1598 w = n.Type.Width 1599 } 1600 switch n.Op { 1601 case ONAME: 1602 fmt.Printf("%v %v G%d %v width=%d\n", Oconv(int(n.Op), 0), n.Sym, n.Name.Vargen, n.Type, w) 1603 case OTYPE: 1604 fmt.Printf("%v %v width=%d\n", Oconv(int(n.Op), 0), n.Type, w) 1605 } 1606 } 1607 1608 // calculate sethi/ullman number 1609 // roughly how many registers needed to 1610 // compile a node. used to compile the 1611 // hardest side first to minimize registers. 1612 func ullmancalc(n *Node) { 1613 if n == nil { 1614 return 1615 } 1616 1617 var ul int 1618 var ur int 1619 if n.Ninit != nil { 1620 ul = UINF 1621 goto out 1622 } 1623 1624 switch n.Op { 1625 case OREGISTER, OLITERAL, ONAME: 1626 ul = 1 1627 if n.Class == PPARAMREF || (n.Class&PHEAP != 0) { 1628 ul++ 1629 } 1630 goto out 1631 1632 case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OASWB: 1633 ul = UINF 1634 goto out 1635 1636 // hard with instrumented code 1637 case OANDAND, OOROR: 1638 if instrumenting { 1639 ul = UINF 1640 goto out 1641 } 1642 } 1643 1644 ul = 1 1645 if n.Left != nil { 1646 ul = int(n.Left.Ullman) 1647 } 1648 ur = 1 1649 if n.Right != nil { 1650 ur = int(n.Right.Ullman) 1651 } 1652 if ul == ur { 1653 ul += 1 1654 } 1655 if ur > ul { 1656 ul = ur 1657 } 1658 1659 out: 1660 if ul > 200 { 1661 ul = 200 // clamp to uchar with room to grow 1662 } 1663 n.Ullman = uint8(ul) 1664 } 1665 1666 func badtype(op Op, tl *Type, tr *Type) { 1667 fmt_ := "" 1668 if tl != nil { 1669 fmt_ += fmt.Sprintf("\n\t%v", tl) 1670 } 1671 if tr != nil { 1672 fmt_ += fmt.Sprintf("\n\t%v", tr) 1673 } 1674 1675 // common mistake: *struct and *interface. 1676 if tl != nil && tr != nil && Isptr[tl.Etype] && Isptr[tr.Etype] { 1677 if tl.Type.Etype == TSTRUCT && tr.Type.Etype == TINTER { 1678 fmt_ += "\n\t(*struct vs *interface)" 1679 } else if tl.Type.Etype == TINTER && tr.Type.Etype == TSTRUCT { 1680 fmt_ += "\n\t(*interface vs *struct)" 1681 } 1682 } 1683 1684 s := fmt_ 1685 Yyerror("illegal types for operand: %v%s", Oconv(int(op), 0), s) 1686 } 1687 1688 // iterator to walk a structure declaration 1689 func Structfirst(s *Iter, nn **Type) *Type { 1690 var t *Type 1691 1692 n := *nn 1693 if n == nil { 1694 goto bad 1695 } 1696 1697 switch n.Etype { 1698 default: 1699 goto bad 1700 1701 case TSTRUCT, TINTER, TFUNC: 1702 break 1703 } 1704 1705 t = n.Type 1706 if t == nil { 1707 return nil 1708 } 1709 1710 if t.Etype != TFIELD { 1711 Fatalf("structfirst: not field %v", t) 1712 } 1713 1714 s.T = t 1715 return t 1716 1717 bad: 1718 Fatalf("structfirst: not struct %v", n) 1719 1720 return nil 1721 } 1722 1723 func structnext(s *Iter) *Type { 1724 n := s.T 1725 t := n.Down 1726 if t == nil { 1727 return nil 1728 } 1729 1730 if t.Etype != TFIELD { 1731 Fatalf("structnext: not struct %v", n) 1732 1733 return nil 1734 } 1735 1736 s.T = t 1737 return t 1738 } 1739 1740 // iterator to this and inargs in a function 1741 func funcfirst(s *Iter, t *Type) *Type { 1742 var fp *Type 1743 1744 if t == nil { 1745 goto bad 1746 } 1747 1748 if t.Etype != TFUNC { 1749 goto bad 1750 } 1751 1752 s.Tfunc = t 1753 s.Done = 0 1754 fp = Structfirst(s, getthis(t)) 1755 if fp == nil { 1756 s.Done = 1 1757 fp = Structfirst(s, getinarg(t)) 1758 } 1759 1760 return fp 1761 1762 bad: 1763 Fatalf("funcfirst: not func %v", t) 1764 return nil 1765 } 1766 1767 func funcnext(s *Iter) *Type { 1768 fp := structnext(s) 1769 if fp == nil && s.Done == 0 { 1770 s.Done = 1 1771 fp = Structfirst(s, getinarg(s.Tfunc)) 1772 } 1773 1774 return fp 1775 } 1776 1777 func getthis(t *Type) **Type { 1778 if t.Etype != TFUNC { 1779 Fatalf("getthis: not a func %v", t) 1780 } 1781 return &t.Type 1782 } 1783 1784 func Getoutarg(t *Type) **Type { 1785 if t.Etype != TFUNC { 1786 Fatalf("getoutarg: not a func %v", t) 1787 } 1788 return &t.Type.Down 1789 } 1790 1791 func getinarg(t *Type) **Type { 1792 if t.Etype != TFUNC { 1793 Fatalf("getinarg: not a func %v", t) 1794 } 1795 return &t.Type.Down.Down 1796 } 1797 1798 func getthisx(t *Type) *Type { 1799 return *getthis(t) 1800 } 1801 1802 func getoutargx(t *Type) *Type { 1803 return *Getoutarg(t) 1804 } 1805 1806 func getinargx(t *Type) *Type { 1807 return *getinarg(t) 1808 } 1809 1810 // Brcom returns !(op). 1811 // For example, Brcom(==) is !=. 1812 func Brcom(op Op) Op { 1813 switch op { 1814 case OEQ: 1815 return ONE 1816 case ONE: 1817 return OEQ 1818 case OLT: 1819 return OGE 1820 case OGT: 1821 return OLE 1822 case OLE: 1823 return OGT 1824 case OGE: 1825 return OLT 1826 } 1827 Fatalf("brcom: no com for %v\n", Oconv(int(op), 0)) 1828 return op 1829 } 1830 1831 // Brrev returns reverse(op). 1832 // For example, Brrev(<) is >. 1833 func Brrev(op Op) Op { 1834 switch op { 1835 case OEQ: 1836 return OEQ 1837 case ONE: 1838 return ONE 1839 case OLT: 1840 return OGT 1841 case OGT: 1842 return OLT 1843 case OLE: 1844 return OGE 1845 case OGE: 1846 return OLE 1847 } 1848 Fatalf("brrev: no rev for %v\n", Oconv(int(op), 0)) 1849 return op 1850 } 1851 1852 // return side effect-free n, appending side effects to init. 1853 // result is assignable if n is. 1854 func safeexpr(n *Node, init **NodeList) *Node { 1855 if n == nil { 1856 return nil 1857 } 1858 1859 if n.Ninit != nil { 1860 walkstmtlist(n.Ninit) 1861 *init = concat(*init, n.Ninit) 1862 n.Ninit = nil 1863 } 1864 1865 switch n.Op { 1866 case ONAME, OLITERAL: 1867 return n 1868 1869 case ODOT, OLEN, OCAP: 1870 l := safeexpr(n.Left, init) 1871 if l == n.Left { 1872 return n 1873 } 1874 r := Nod(OXXX, nil, nil) 1875 *r = *n 1876 r.Left = l 1877 typecheck(&r, Erv) 1878 walkexpr(&r, init) 1879 return r 1880 1881 case ODOTPTR, OIND: 1882 l := safeexpr(n.Left, init) 1883 if l == n.Left { 1884 return n 1885 } 1886 a := Nod(OXXX, nil, nil) 1887 *a = *n 1888 a.Left = l 1889 walkexpr(&a, init) 1890 return a 1891 1892 case OINDEX, OINDEXMAP: 1893 l := safeexpr(n.Left, init) 1894 r := safeexpr(n.Right, init) 1895 if l == n.Left && r == n.Right { 1896 return n 1897 } 1898 a := Nod(OXXX, nil, nil) 1899 *a = *n 1900 a.Left = l 1901 a.Right = r 1902 walkexpr(&a, init) 1903 return a 1904 } 1905 1906 // make a copy; must not be used as an lvalue 1907 if islvalue(n) { 1908 Fatalf("missing lvalue case in safeexpr: %v", n) 1909 } 1910 return cheapexpr(n, init) 1911 } 1912 1913 func copyexpr(n *Node, t *Type, init **NodeList) *Node { 1914 l := temp(t) 1915 a := Nod(OAS, l, n) 1916 typecheck(&a, Etop) 1917 walkexpr(&a, init) 1918 *init = list(*init, a) 1919 return l 1920 } 1921 1922 // return side-effect free and cheap n, appending side effects to init. 1923 // result may not be assignable. 1924 func cheapexpr(n *Node, init **NodeList) *Node { 1925 switch n.Op { 1926 case ONAME, OLITERAL: 1927 return n 1928 } 1929 1930 return copyexpr(n, n.Type, init) 1931 } 1932 1933 func Setmaxarg(t *Type, extra int32) { 1934 dowidth(t) 1935 w := t.Argwid 1936 if w >= Thearch.MAXWIDTH { 1937 Fatalf("bad argwid %v", t) 1938 } 1939 w += int64(extra) 1940 if w >= Thearch.MAXWIDTH { 1941 Fatalf("bad argwid %d + %v", extra, t) 1942 } 1943 if w > Maxarg { 1944 Maxarg = w 1945 } 1946 } 1947 1948 // unicode-aware case-insensitive strcmp 1949 1950 // code to resolve elided DOTs 1951 // in embedded types 1952 1953 // search depth 0 -- 1954 // return count of fields+methods 1955 // found with a given name 1956 func lookdot0(s *Sym, t *Type, save **Type, ignorecase int) int { 1957 u := t 1958 if Isptr[u.Etype] { 1959 u = u.Type 1960 } 1961 1962 c := 0 1963 if u.Etype == TSTRUCT || u.Etype == TINTER { 1964 for f := u.Type; f != nil; f = f.Down { 1965 if f.Sym == s || (ignorecase != 0 && f.Type.Etype == TFUNC && f.Type.Thistuple > 0 && strings.EqualFold(f.Sym.Name, s.Name)) { 1966 if save != nil { 1967 *save = f 1968 } 1969 c++ 1970 } 1971 } 1972 } 1973 1974 u = methtype(t, 0) 1975 if u != nil { 1976 for f := u.Method; f != nil; f = f.Down { 1977 if f.Embedded == 0 && (f.Sym == s || (ignorecase != 0 && strings.EqualFold(f.Sym.Name, s.Name))) { 1978 if save != nil { 1979 *save = f 1980 } 1981 c++ 1982 } 1983 } 1984 } 1985 1986 return c 1987 } 1988 1989 // search depth d for field/method s -- 1990 // return count of fields+methods 1991 // found at search depth. 1992 // answer is in dotlist array and 1993 // count of number of ways is returned. 1994 func adddot1(s *Sym, t *Type, d int, save **Type, ignorecase int) int { 1995 if t.Trecur != 0 { 1996 return 0 1997 } 1998 t.Trecur = 1 1999 2000 var c int 2001 var u *Type 2002 var a int 2003 if d == 0 { 2004 c = lookdot0(s, t, save, ignorecase) 2005 goto out 2006 } 2007 2008 c = 0 2009 u = t 2010 if Isptr[u.Etype] { 2011 u = u.Type 2012 } 2013 if u.Etype != TSTRUCT && u.Etype != TINTER { 2014 goto out 2015 } 2016 2017 d-- 2018 for f := u.Type; f != nil; f = f.Down { 2019 if f.Embedded == 0 { 2020 continue 2021 } 2022 if f.Sym == nil { 2023 continue 2024 } 2025 a = adddot1(s, f.Type, d, save, ignorecase) 2026 if a != 0 && c == 0 { 2027 dotlist[d].field = f 2028 } 2029 c += a 2030 } 2031 2032 out: 2033 t.Trecur = 0 2034 return c 2035 } 2036 2037 // in T.field 2038 // find missing fields that 2039 // will give shortest unique addressing. 2040 // modify the tree with missing type names. 2041 func adddot(n *Node) *Node { 2042 typecheck(&n.Left, Etype|Erv) 2043 n.Diag |= n.Left.Diag 2044 t := n.Left.Type 2045 if t == nil { 2046 return n 2047 } 2048 2049 if n.Left.Op == OTYPE { 2050 return n 2051 } 2052 2053 if n.Right.Op != ONAME { 2054 return n 2055 } 2056 s := n.Right.Sym 2057 if s == nil { 2058 return n 2059 } 2060 2061 var c int 2062 for d := 0; d < len(dotlist); d++ { 2063 c = adddot1(s, t, d, nil, 0) 2064 if c > 0 { 2065 if c > 1 { 2066 Yyerror("ambiguous selector %v", n) 2067 n.Left = nil 2068 return n 2069 } 2070 2071 // rebuild elided dots 2072 for c := d - 1; c >= 0; c-- { 2073 n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym)) 2074 n.Left.Implicit = true 2075 } 2076 2077 return n 2078 } 2079 } 2080 2081 return n 2082 } 2083 2084 // code to help generate trampoline 2085 // functions for methods on embedded 2086 // subtypes. 2087 // these are approx the same as 2088 // the corresponding adddot routines 2089 // except that they expect to be called 2090 // with unique tasks and they return 2091 // the actual methods. 2092 type Symlink struct { 2093 field *Type 2094 link *Symlink 2095 good bool 2096 followptr bool 2097 } 2098 2099 var slist *Symlink 2100 2101 func expand0(t *Type, followptr bool) { 2102 u := t 2103 if Isptr[u.Etype] { 2104 followptr = true 2105 u = u.Type 2106 } 2107 2108 if u.Etype == TINTER { 2109 var sl *Symlink 2110 for f := u.Type; f != nil; f = f.Down { 2111 if f.Sym.Flags&SymUniq != 0 { 2112 continue 2113 } 2114 f.Sym.Flags |= SymUniq 2115 sl = new(Symlink) 2116 sl.field = f 2117 sl.link = slist 2118 sl.followptr = followptr 2119 slist = sl 2120 } 2121 2122 return 2123 } 2124 2125 u = methtype(t, 0) 2126 if u != nil { 2127 var sl *Symlink 2128 for f := u.Method; f != nil; f = f.Down { 2129 if f.Sym.Flags&SymUniq != 0 { 2130 continue 2131 } 2132 f.Sym.Flags |= SymUniq 2133 sl = new(Symlink) 2134 sl.field = f 2135 sl.link = slist 2136 sl.followptr = followptr 2137 slist = sl 2138 } 2139 } 2140 } 2141 2142 func expand1(t *Type, d int, followptr bool) { 2143 if t.Trecur != 0 { 2144 return 2145 } 2146 if d == 0 { 2147 return 2148 } 2149 t.Trecur = 1 2150 2151 if d != len(dotlist)-1 { 2152 expand0(t, followptr) 2153 } 2154 2155 u := t 2156 if Isptr[u.Etype] { 2157 followptr = true 2158 u = u.Type 2159 } 2160 2161 if u.Etype != TSTRUCT && u.Etype != TINTER { 2162 goto out 2163 } 2164 2165 for f := u.Type; f != nil; f = f.Down { 2166 if f.Embedded == 0 { 2167 continue 2168 } 2169 if f.Sym == nil { 2170 continue 2171 } 2172 expand1(f.Type, d-1, followptr) 2173 } 2174 2175 out: 2176 t.Trecur = 0 2177 } 2178 2179 func expandmeth(t *Type) { 2180 if t == nil || t.Xmethod != nil { 2181 return 2182 } 2183 2184 // mark top-level method symbols 2185 // so that expand1 doesn't consider them. 2186 var f *Type 2187 for f = t.Method; f != nil; f = f.Down { 2188 f.Sym.Flags |= SymUniq 2189 } 2190 2191 // generate all reachable methods 2192 slist = nil 2193 2194 expand1(t, len(dotlist)-1, false) 2195 2196 // check each method to be uniquely reachable 2197 var c int 2198 var d int 2199 for sl := slist; sl != nil; sl = sl.link { 2200 sl.field.Sym.Flags &^= SymUniq 2201 for d = 0; d < len(dotlist); d++ { 2202 c = adddot1(sl.field.Sym, t, d, &f, 0) 2203 if c == 0 { 2204 continue 2205 } 2206 if c == 1 { 2207 // addot1 may have dug out arbitrary fields, we only want methods. 2208 if f.Type.Etype == TFUNC && f.Type.Thistuple > 0 { 2209 sl.good = true 2210 sl.field = f 2211 } 2212 } 2213 2214 break 2215 } 2216 } 2217 2218 for f = t.Method; f != nil; f = f.Down { 2219 f.Sym.Flags &^= SymUniq 2220 } 2221 2222 t.Xmethod = t.Method 2223 for sl := slist; sl != nil; sl = sl.link { 2224 if sl.good { 2225 // add it to the base type method list 2226 f = typ(TFIELD) 2227 2228 *f = *sl.field 2229 f.Embedded = 1 // needs a trampoline 2230 if sl.followptr { 2231 f.Embedded = 2 2232 } 2233 f.Down = t.Xmethod 2234 t.Xmethod = f 2235 } 2236 } 2237 } 2238 2239 // Given funarg struct list, return list of ODCLFIELD Node fn args. 2240 func structargs(tl **Type, mustname int) *NodeList { 2241 var savet Iter 2242 var a *Node 2243 var n *Node 2244 var buf string 2245 2246 var args *NodeList 2247 gen := 0 2248 for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) { 2249 n = nil 2250 if mustname != 0 && (t.Sym == nil || t.Sym.Name == "_") { 2251 // invent a name so that we can refer to it in the trampoline 2252 buf = fmt.Sprintf(".anon%d", gen) 2253 gen++ 2254 2255 n = newname(Lookup(buf)) 2256 } else if t.Sym != nil { 2257 n = newname(t.Sym) 2258 } 2259 a = Nod(ODCLFIELD, n, typenod(t.Type)) 2260 a.Isddd = t.Isddd 2261 if n != nil { 2262 n.Isddd = t.Isddd 2263 } 2264 args = list(args, a) 2265 } 2266 2267 return args 2268 } 2269 2270 // Generate a wrapper function to convert from 2271 // a receiver of type T to a receiver of type U. 2272 // That is, 2273 // 2274 // func (t T) M() { 2275 // ... 2276 // } 2277 // 2278 // already exists; this function generates 2279 // 2280 // func (u U) M() { 2281 // u.M() 2282 // } 2283 // 2284 // where the types T and U are such that u.M() is valid 2285 // and calls the T.M method. 2286 // The resulting function is for use in method tables. 2287 // 2288 // rcvr - U 2289 // method - M func (t T)(), a TFIELD type struct 2290 // newnam - the eventual mangled name of this function 2291 2292 var genwrapper_linehistdone int = 0 2293 2294 func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { 2295 if false && Debug['r'] != 0 { 2296 fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) 2297 } 2298 2299 lexlineno++ 2300 lineno = lexlineno 2301 if genwrapper_linehistdone == 0 { 2302 // All the wrappers can share the same linehist entry. 2303 linehistpush("<autogenerated>") 2304 2305 genwrapper_linehistdone = 1 2306 } 2307 2308 dclcontext = PEXTERN 2309 markdcl() 2310 2311 this := Nod(ODCLFIELD, newname(Lookup(".this")), typenod(rcvr)) 2312 this.Left.Name.Param.Ntype = this.Right 2313 in := structargs(getinarg(method.Type), 1) 2314 out := structargs(Getoutarg(method.Type), 0) 2315 2316 t := Nod(OTFUNC, nil, nil) 2317 l := list1(this) 2318 if iface != 0 && rcvr.Width < Types[Tptr].Width { 2319 // Building method for interface table and receiver 2320 // is smaller than the single pointer-sized word 2321 // that the interface call will pass in. 2322 // Add a dummy padding argument after the 2323 // receiver to make up the difference. 2324 tpad := typ(TARRAY) 2325 2326 tpad.Type = Types[TUINT8] 2327 tpad.Bound = Types[Tptr].Width - rcvr.Width 2328 pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad)) 2329 l = list(l, pad) 2330 } 2331 2332 t.List = concat(l, in) 2333 t.Rlist = out 2334 2335 fn := Nod(ODCLFUNC, nil, nil) 2336 fn.Func.Nname = newname(newnam) 2337 fn.Func.Nname.Name.Defn = fn 2338 fn.Func.Nname.Name.Param.Ntype = t 2339 declare(fn.Func.Nname, PFUNC) 2340 funchdr(fn) 2341 2342 // arg list 2343 var args *NodeList 2344 2345 isddd := false 2346 for l := in; l != nil; l = l.Next { 2347 args = list(args, l.N.Left) 2348 isddd = l.N.Left.Isddd 2349 } 2350 2351 methodrcvr := getthisx(method.Type).Type.Type 2352 2353 // generate nil pointer check for better error 2354 if Isptr[rcvr.Etype] && rcvr.Type == methodrcvr { 2355 // generating wrapper from *T to T. 2356 n := Nod(OIF, nil, nil) 2357 2358 n.Left = Nod(OEQ, this.Left, nodnil()) 2359 2360 // these strings are already in the reflect tables, 2361 // so no space cost to use them here. 2362 var l *NodeList 2363 2364 var v Val 2365 v.U = rcvr.Type.Sym.Pkg.Name // package name 2366 l = list(l, nodlit(v)) 2367 v.U = rcvr.Type.Sym.Name // type name 2368 l = list(l, nodlit(v)) 2369 v.U = method.Sym.Name 2370 l = list(l, nodlit(v)) // method name 2371 call := Nod(OCALL, syslook("panicwrap", 0), nil) 2372 call.List = l 2373 n.Nbody = list1(call) 2374 fn.Nbody = list(fn.Nbody, n) 2375 } 2376 2377 dot := adddot(Nod(OXDOT, this.Left, newname(method.Sym))) 2378 2379 // generate call 2380 if !instrumenting && Isptr[rcvr.Etype] && Isptr[methodrcvr.Etype] && method.Embedded != 0 && !isifacemethod(method.Type) { 2381 // generate tail call: adjust pointer receiver and jump to embedded method. 2382 dot = dot.Left // skip final .M 2383 if !Isptr[dotlist[0].field.Type.Etype] { 2384 dot = Nod(OADDR, dot, nil) 2385 } 2386 as := Nod(OAS, this.Left, Nod(OCONVNOP, dot, nil)) 2387 as.Right.Type = rcvr 2388 fn.Nbody = list(fn.Nbody, as) 2389 n := Nod(ORETJMP, nil, nil) 2390 n.Left = newname(methodsym(method.Sym, methodrcvr, 0)) 2391 fn.Nbody = list(fn.Nbody, n) 2392 } else { 2393 fn.Func.Wrapper = true // ignore frame for panic+recover matching 2394 call := Nod(OCALL, dot, nil) 2395 call.List = args 2396 call.Isddd = isddd 2397 if method.Type.Outtuple > 0 { 2398 n := Nod(ORETURN, nil, nil) 2399 n.List = list1(call) 2400 call = n 2401 } 2402 2403 fn.Nbody = list(fn.Nbody, call) 2404 } 2405 2406 if false && Debug['r'] != 0 { 2407 dumplist("genwrapper body", fn.Nbody) 2408 } 2409 2410 funcbody(fn) 2411 Curfn = fn 2412 2413 // wrappers where T is anonymous (struct or interface) can be duplicated. 2414 if rcvr.Etype == TSTRUCT || rcvr.Etype == TINTER || Isptr[rcvr.Etype] && rcvr.Type.Etype == TSTRUCT { 2415 fn.Func.Dupok = true 2416 } 2417 typecheck(&fn, Etop) 2418 typechecklist(fn.Nbody, Etop) 2419 2420 inlcalls(fn) 2421 escAnalyze([]*Node{fn}, false) 2422 2423 Curfn = nil 2424 funccompile(fn) 2425 } 2426 2427 func hashmem(t *Type) *Node { 2428 sym := Pkglookup("memhash", Runtimepkg) 2429 2430 n := newname(sym) 2431 n.Class = PFUNC 2432 tfn := Nod(OTFUNC, nil, nil) 2433 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) 2434 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2435 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2436 tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2437 typecheck(&tfn, Etype) 2438 n.Type = tfn.Type 2439 return n 2440 } 2441 2442 func hashfor(t *Type) *Node { 2443 var sym *Sym 2444 2445 a := algtype1(t, nil) 2446 switch a { 2447 case AMEM: 2448 Fatalf("hashfor with AMEM type") 2449 2450 case AINTER: 2451 sym = Pkglookup("interhash", Runtimepkg) 2452 2453 case ANILINTER: 2454 sym = Pkglookup("nilinterhash", Runtimepkg) 2455 2456 case ASTRING: 2457 sym = Pkglookup("strhash", Runtimepkg) 2458 2459 case AFLOAT32: 2460 sym = Pkglookup("f32hash", Runtimepkg) 2461 2462 case AFLOAT64: 2463 sym = Pkglookup("f64hash", Runtimepkg) 2464 2465 case ACPLX64: 2466 sym = Pkglookup("c64hash", Runtimepkg) 2467 2468 case ACPLX128: 2469 sym = Pkglookup("c128hash", Runtimepkg) 2470 2471 default: 2472 sym = typesymprefix(".hash", t) 2473 } 2474 2475 n := newname(sym) 2476 n.Class = PFUNC 2477 tfn := Nod(OTFUNC, nil, nil) 2478 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) 2479 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2480 tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2481 typecheck(&tfn, Etype) 2482 n.Type = tfn.Type 2483 return n 2484 } 2485 2486 // Generate a helper function to compute the hash of a value of type t. 2487 func genhash(sym *Sym, t *Type) { 2488 if Debug['r'] != 0 { 2489 fmt.Printf("genhash %v %v\n", sym, t) 2490 } 2491 2492 lineno = 1 // less confusing than end of input 2493 dclcontext = PEXTERN 2494 markdcl() 2495 2496 // func sym(p *T, h uintptr) uintptr 2497 fn := Nod(ODCLFUNC, nil, nil) 2498 2499 fn.Func.Nname = newname(sym) 2500 fn.Func.Nname.Class = PFUNC 2501 tfn := Nod(OTFUNC, nil, nil) 2502 fn.Func.Nname.Name.Param.Ntype = tfn 2503 2504 n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t))) 2505 tfn.List = list(tfn.List, n) 2506 np := n.Left 2507 n = Nod(ODCLFIELD, newname(Lookup("h")), typenod(Types[TUINTPTR])) 2508 tfn.List = list(tfn.List, n) 2509 nh := n.Left 2510 n = Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])) // return value 2511 tfn.Rlist = list(tfn.Rlist, n) 2512 2513 funchdr(fn) 2514 typecheck(&fn.Func.Nname.Name.Param.Ntype, Etype) 2515 2516 // genhash is only called for types that have equality but 2517 // cannot be handled by the standard algorithms, 2518 // so t must be either an array or a struct. 2519 switch t.Etype { 2520 default: 2521 Fatalf("genhash %v", t) 2522 2523 case TARRAY: 2524 if Isslice(t) { 2525 Fatalf("genhash %v", t) 2526 } 2527 2528 // An array of pure memory would be handled by the 2529 // standard algorithm, so the element type must not be 2530 // pure memory. 2531 hashel := hashfor(t.Type) 2532 2533 n := Nod(ORANGE, nil, Nod(OIND, np, nil)) 2534 ni := newname(Lookup("i")) 2535 ni.Type = Types[TINT] 2536 n.List = list1(ni) 2537 n.Colas = true 2538 colasdefn(n.List, n) 2539 ni = n.List.N 2540 2541 // h = hashel(&p[i], h) 2542 call := Nod(OCALL, hashel, nil) 2543 2544 nx := Nod(OINDEX, np, ni) 2545 nx.Bounded = true 2546 na := Nod(OADDR, nx, nil) 2547 na.Etype = 1 // no escape to heap 2548 call.List = list(call.List, na) 2549 call.List = list(call.List, nh) 2550 n.Nbody = list(n.Nbody, Nod(OAS, nh, call)) 2551 2552 fn.Nbody = list(fn.Nbody, n) 2553 2554 // Walk the struct using memhash for runs of AMEM 2555 // and calling specific hash functions for the others. 2556 case TSTRUCT: 2557 var first *Type 2558 2559 offend := int64(0) 2560 var size int64 2561 var call *Node 2562 var nx *Node 2563 var na *Node 2564 var hashel *Node 2565 for t1 := t.Type; ; t1 = t1.Down { 2566 if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) { 2567 offend = t1.Width + t1.Type.Width 2568 if first == nil { 2569 first = t1 2570 } 2571 2572 // If it's a memory field but it's padded, stop here. 2573 if ispaddedfield(t1, t.Width) { 2574 t1 = t1.Down 2575 } else { 2576 continue 2577 } 2578 } 2579 2580 // Run memhash for fields up to this one. 2581 if first != nil { 2582 size = offend - first.Width // first->width is offset 2583 hashel = hashmem(first.Type) 2584 2585 // h = hashel(&p.first, size, h) 2586 call = Nod(OCALL, hashel, nil) 2587 2588 nx = Nod(OXDOT, np, newname(first.Sym)) // TODO: fields from other packages? 2589 na = Nod(OADDR, nx, nil) 2590 na.Etype = 1 // no escape to heap 2591 call.List = list(call.List, na) 2592 call.List = list(call.List, nh) 2593 call.List = list(call.List, Nodintconst(size)) 2594 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2595 2596 first = nil 2597 } 2598 2599 if t1 == nil { 2600 break 2601 } 2602 if isblanksym(t1.Sym) { 2603 continue 2604 } 2605 2606 // Run hash for this field. 2607 if algtype1(t1.Type, nil) == AMEM { 2608 hashel = hashmem(t1.Type) 2609 2610 // h = memhash(&p.t1, h, size) 2611 call = Nod(OCALL, hashel, nil) 2612 2613 nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages? 2614 na = Nod(OADDR, nx, nil) 2615 na.Etype = 1 // no escape to heap 2616 call.List = list(call.List, na) 2617 call.List = list(call.List, nh) 2618 call.List = list(call.List, Nodintconst(t1.Type.Width)) 2619 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2620 } else { 2621 hashel = hashfor(t1.Type) 2622 2623 // h = hashel(&p.t1, h) 2624 call = Nod(OCALL, hashel, nil) 2625 2626 nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages? 2627 na = Nod(OADDR, nx, nil) 2628 na.Etype = 1 // no escape to heap 2629 call.List = list(call.List, na) 2630 call.List = list(call.List, nh) 2631 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2632 } 2633 } 2634 } 2635 2636 r := Nod(ORETURN, nil, nil) 2637 r.List = list(r.List, nh) 2638 fn.Nbody = list(fn.Nbody, r) 2639 2640 if Debug['r'] != 0 { 2641 dumplist("genhash body", fn.Nbody) 2642 } 2643 2644 funcbody(fn) 2645 Curfn = fn 2646 fn.Func.Dupok = true 2647 typecheck(&fn, Etop) 2648 typechecklist(fn.Nbody, Etop) 2649 Curfn = nil 2650 2651 // Disable safemode while compiling this code: the code we 2652 // generate internally can refer to unsafe.Pointer. 2653 // In this case it can happen if we need to generate an == 2654 // for a struct containing a reflect.Value, which itself has 2655 // an unexported field of type unsafe.Pointer. 2656 old_safemode := safemode 2657 2658 safemode = 0 2659 funccompile(fn) 2660 safemode = old_safemode 2661 } 2662 2663 // Return node for 2664 // if p.field != q.field { return false } 2665 func eqfield(p *Node, q *Node, field *Node) *Node { 2666 nx := Nod(OXDOT, p, field) 2667 ny := Nod(OXDOT, q, field) 2668 nif := Nod(OIF, nil, nil) 2669 nif.Left = Nod(ONE, nx, ny) 2670 r := Nod(ORETURN, nil, nil) 2671 r.List = list(r.List, Nodbool(false)) 2672 nif.Nbody = list(nif.Nbody, r) 2673 return nif 2674 } 2675 2676 func eqmemfunc(size int64, type_ *Type, needsize *int) *Node { 2677 var fn *Node 2678 2679 switch size { 2680 default: 2681 fn = syslook("memequal", 1) 2682 *needsize = 1 2683 2684 case 1, 2, 4, 8, 16: 2685 buf := fmt.Sprintf("memequal%d", int(size)*8) 2686 fn = syslook(buf, 1) 2687 *needsize = 0 2688 } 2689 2690 substArgTypes(fn, type_, type_) 2691 return fn 2692 } 2693 2694 // Return node for 2695 // if !memequal(&p.field, &q.field [, size]) { return false } 2696 func eqmem(p *Node, q *Node, field *Node, size int64) *Node { 2697 var needsize int 2698 2699 nx := Nod(OADDR, Nod(OXDOT, p, field), nil) 2700 nx.Etype = 1 // does not escape 2701 ny := Nod(OADDR, Nod(OXDOT, q, field), nil) 2702 ny.Etype = 1 // does not escape 2703 typecheck(&nx, Erv) 2704 typecheck(&ny, Erv) 2705 2706 call := Nod(OCALL, eqmemfunc(size, nx.Type.Type, &needsize), nil) 2707 call.List = list(call.List, nx) 2708 call.List = list(call.List, ny) 2709 if needsize != 0 { 2710 call.List = list(call.List, Nodintconst(size)) 2711 } 2712 2713 nif := Nod(OIF, nil, nil) 2714 nif.Left = Nod(ONOT, call, nil) 2715 r := Nod(ORETURN, nil, nil) 2716 r.List = list(r.List, Nodbool(false)) 2717 nif.Nbody = list(nif.Nbody, r) 2718 return nif 2719 } 2720 2721 // Generate a helper function to check equality of two values of type t. 2722 func geneq(sym *Sym, t *Type) { 2723 if Debug['r'] != 0 { 2724 fmt.Printf("geneq %v %v\n", sym, t) 2725 } 2726 2727 lineno = 1 // less confusing than end of input 2728 dclcontext = PEXTERN 2729 markdcl() 2730 2731 // func sym(p, q *T) bool 2732 fn := Nod(ODCLFUNC, nil, nil) 2733 2734 fn.Func.Nname = newname(sym) 2735 fn.Func.Nname.Class = PFUNC 2736 tfn := Nod(OTFUNC, nil, nil) 2737 fn.Func.Nname.Name.Param.Ntype = tfn 2738 2739 n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t))) 2740 tfn.List = list(tfn.List, n) 2741 np := n.Left 2742 n = Nod(ODCLFIELD, newname(Lookup("q")), typenod(Ptrto(t))) 2743 tfn.List = list(tfn.List, n) 2744 nq := n.Left 2745 n = Nod(ODCLFIELD, nil, typenod(Types[TBOOL])) 2746 tfn.Rlist = list(tfn.Rlist, n) 2747 2748 funchdr(fn) 2749 2750 // geneq is only called for types that have equality but 2751 // cannot be handled by the standard algorithms, 2752 // so t must be either an array or a struct. 2753 switch t.Etype { 2754 default: 2755 Fatalf("geneq %v", t) 2756 2757 case TARRAY: 2758 if Isslice(t) { 2759 Fatalf("geneq %v", t) 2760 } 2761 2762 // An array of pure memory would be handled by the 2763 // standard memequal, so the element type must not be 2764 // pure memory. Even if we unrolled the range loop, 2765 // each iteration would be a function call, so don't bother 2766 // unrolling. 2767 nrange := Nod(ORANGE, nil, Nod(OIND, np, nil)) 2768 2769 ni := newname(Lookup("i")) 2770 ni.Type = Types[TINT] 2771 nrange.List = list1(ni) 2772 nrange.Colas = true 2773 colasdefn(nrange.List, nrange) 2774 ni = nrange.List.N 2775 2776 // if p[i] != q[i] { return false } 2777 nx := Nod(OINDEX, np, ni) 2778 2779 nx.Bounded = true 2780 ny := Nod(OINDEX, nq, ni) 2781 ny.Bounded = true 2782 2783 nif := Nod(OIF, nil, nil) 2784 nif.Left = Nod(ONE, nx, ny) 2785 r := Nod(ORETURN, nil, nil) 2786 r.List = list(r.List, Nodbool(false)) 2787 nif.Nbody = list(nif.Nbody, r) 2788 nrange.Nbody = list(nrange.Nbody, nif) 2789 fn.Nbody = list(fn.Nbody, nrange) 2790 2791 // Walk the struct using memequal for runs of AMEM 2792 // and calling specific equality tests for the others. 2793 // Skip blank-named fields. 2794 case TSTRUCT: 2795 var first *Type 2796 2797 offend := int64(0) 2798 var size int64 2799 for t1 := t.Type; ; t1 = t1.Down { 2800 if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) { 2801 offend = t1.Width + t1.Type.Width 2802 if first == nil { 2803 first = t1 2804 } 2805 2806 // If it's a memory field but it's padded, stop here. 2807 if ispaddedfield(t1, t.Width) { 2808 t1 = t1.Down 2809 } else { 2810 continue 2811 } 2812 } 2813 2814 // Run memequal for fields up to this one. 2815 // TODO(rsc): All the calls to newname are wrong for 2816 // cross-package unexported fields. 2817 if first != nil { 2818 if first.Down == t1 { 2819 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2820 } else if first.Down.Down == t1 { 2821 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2822 first = first.Down 2823 if !isblanksym(first.Sym) { 2824 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2825 } 2826 } else { 2827 // More than two fields: use memequal. 2828 size = offend - first.Width // first->width is offset 2829 fn.Nbody = list(fn.Nbody, eqmem(np, nq, newname(first.Sym), size)) 2830 } 2831 2832 first = nil 2833 } 2834 2835 if t1 == nil { 2836 break 2837 } 2838 if isblanksym(t1.Sym) { 2839 continue 2840 } 2841 2842 // Check this field, which is not just memory. 2843 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(t1.Sym))) 2844 } 2845 } 2846 2847 // return true 2848 r := Nod(ORETURN, nil, nil) 2849 2850 r.List = list(r.List, Nodbool(true)) 2851 fn.Nbody = list(fn.Nbody, r) 2852 2853 if Debug['r'] != 0 { 2854 dumplist("geneq body", fn.Nbody) 2855 } 2856 2857 funcbody(fn) 2858 Curfn = fn 2859 fn.Func.Dupok = true 2860 typecheck(&fn, Etop) 2861 typechecklist(fn.Nbody, Etop) 2862 Curfn = nil 2863 2864 // Disable safemode while compiling this code: the code we 2865 // generate internally can refer to unsafe.Pointer. 2866 // In this case it can happen if we need to generate an == 2867 // for a struct containing a reflect.Value, which itself has 2868 // an unexported field of type unsafe.Pointer. 2869 old_safemode := safemode 2870 2871 safemode = 0 2872 funccompile(fn) 2873 safemode = old_safemode 2874 } 2875 2876 func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase int) *Type { 2877 *followptr = false 2878 2879 if t == nil { 2880 return nil 2881 } 2882 2883 var m *Type 2884 var i int 2885 var c int 2886 for d := 0; d < len(dotlist); d++ { 2887 c = adddot1(s, t, d, &m, ignorecase) 2888 if c > 1 { 2889 Yyerror("%v.%v is ambiguous", t, s) 2890 return nil 2891 } 2892 2893 if c == 1 { 2894 for i = 0; i < d; i++ { 2895 if Isptr[dotlist[i].field.Type.Etype] { 2896 *followptr = true 2897 break 2898 } 2899 } 2900 2901 if m.Type.Etype != TFUNC || m.Type.Thistuple == 0 { 2902 Yyerror("%v.%v is a field, not a method", t, s) 2903 return nil 2904 } 2905 2906 return m 2907 } 2908 } 2909 2910 return nil 2911 } 2912 2913 func implements(t *Type, iface *Type, m **Type, samename **Type, ptr *int) bool { 2914 t0 := t 2915 if t == nil { 2916 return false 2917 } 2918 2919 // if this is too slow, 2920 // could sort these first 2921 // and then do one loop. 2922 2923 if t.Etype == TINTER { 2924 var tm *Type 2925 for im := iface.Type; im != nil; im = im.Down { 2926 for tm = t.Type; tm != nil; tm = tm.Down { 2927 if tm.Sym == im.Sym { 2928 if Eqtype(tm.Type, im.Type) { 2929 goto found 2930 } 2931 *m = im 2932 *samename = tm 2933 *ptr = 0 2934 return false 2935 } 2936 } 2937 2938 *m = im 2939 *samename = nil 2940 *ptr = 0 2941 return false 2942 found: 2943 } 2944 2945 return true 2946 } 2947 2948 t = methtype(t, 0) 2949 if t != nil { 2950 expandmeth(t) 2951 } 2952 var tm *Type 2953 var imtype *Type 2954 var followptr bool 2955 var rcvr *Type 2956 for im := iface.Type; im != nil; im = im.Down { 2957 if im.Broke { 2958 continue 2959 } 2960 imtype = methodfunc(im.Type, nil) 2961 tm = ifacelookdot(im.Sym, t, &followptr, 0) 2962 if tm == nil || tm.Nointerface || !Eqtype(methodfunc(tm.Type, nil), imtype) { 2963 if tm == nil { 2964 tm = ifacelookdot(im.Sym, t, &followptr, 1) 2965 } 2966 *m = im 2967 *samename = tm 2968 *ptr = 0 2969 return false 2970 } 2971 2972 // if pointer receiver in method, 2973 // the method does not exist for value types. 2974 rcvr = getthisx(tm.Type).Type.Type 2975 2976 if Isptr[rcvr.Etype] && !Isptr[t0.Etype] && !followptr && !isifacemethod(tm.Type) { 2977 if false && Debug['r'] != 0 { 2978 Yyerror("interface pointer mismatch") 2979 } 2980 2981 *m = im 2982 *samename = nil 2983 *ptr = 1 2984 return false 2985 } 2986 } 2987 2988 return true 2989 } 2990 2991 // even simpler simtype; get rid of ptr, bool. 2992 // assuming that the front end has rejected 2993 // all the invalid conversions (like ptr -> bool) 2994 func Simsimtype(t *Type) EType { 2995 if t == nil { 2996 return 0 2997 } 2998 2999 et := Simtype[t.Etype] 3000 switch et { 3001 case TPTR32: 3002 et = TUINT32 3003 3004 case TPTR64: 3005 et = TUINT64 3006 3007 case TBOOL: 3008 et = TUINT8 3009 } 3010 3011 return et 3012 } 3013 3014 func listtreecopy(l *NodeList, lineno int32) *NodeList { 3015 var out *NodeList 3016 for ; l != nil; l = l.Next { 3017 out = list(out, treecopy(l.N, lineno)) 3018 } 3019 return out 3020 } 3021 3022 func liststmt(l *NodeList) *Node { 3023 n := Nod(OBLOCK, nil, nil) 3024 n.List = l 3025 if l != nil { 3026 n.Lineno = l.N.Lineno 3027 } 3028 return n 3029 } 3030 3031 // return nelem of list 3032 func structcount(t *Type) int { 3033 var s Iter 3034 3035 v := 0 3036 for t = Structfirst(&s, &t); t != nil; t = structnext(&s) { 3037 v++ 3038 } 3039 return v 3040 } 3041 3042 // return power of 2 of the constant 3043 // operand. -1 if it is not a power of 2. 3044 // 1000+ if it is a -(power of 2) 3045 func powtwo(n *Node) int { 3046 if n == nil || n.Op != OLITERAL || n.Type == nil { 3047 return -1 3048 } 3049 if !Isint[n.Type.Etype] { 3050 return -1 3051 } 3052 3053 v := uint64(Mpgetfix(n.Val().U.(*Mpint))) 3054 b := uint64(1) 3055 for i := 0; i < 64; i++ { 3056 if b == v { 3057 return i 3058 } 3059 b = b << 1 3060 } 3061 3062 if !Issigned[n.Type.Etype] { 3063 return -1 3064 } 3065 3066 v = -v 3067 b = 1 3068 for i := 0; i < 64; i++ { 3069 if b == v { 3070 return i + 1000 3071 } 3072 b = b << 1 3073 } 3074 3075 return -1 3076 } 3077 3078 // return the unsigned type for 3079 // a signed integer type. 3080 // returns T if input is not a 3081 // signed integer type. 3082 func tounsigned(t *Type) *Type { 3083 // this is types[et+1], but not sure 3084 // that this relation is immutable 3085 switch t.Etype { 3086 default: 3087 fmt.Printf("tounsigned: unknown type %v\n", t) 3088 t = nil 3089 3090 case TINT: 3091 t = Types[TUINT] 3092 3093 case TINT8: 3094 t = Types[TUINT8] 3095 3096 case TINT16: 3097 t = Types[TUINT16] 3098 3099 case TINT32: 3100 t = Types[TUINT32] 3101 3102 case TINT64: 3103 t = Types[TUINT64] 3104 } 3105 3106 return t 3107 } 3108 3109 // magic number for signed division 3110 // see hacker's delight chapter 10 3111 func Smagic(m *Magic) { 3112 var mask uint64 3113 3114 m.Bad = 0 3115 switch m.W { 3116 default: 3117 m.Bad = 1 3118 return 3119 3120 case 8: 3121 mask = 0xff 3122 3123 case 16: 3124 mask = 0xffff 3125 3126 case 32: 3127 mask = 0xffffffff 3128 3129 case 64: 3130 mask = 0xffffffffffffffff 3131 } 3132 3133 two31 := mask ^ (mask >> 1) 3134 3135 p := m.W - 1 3136 ad := uint64(m.Sd) 3137 if m.Sd < 0 { 3138 ad = -uint64(m.Sd) 3139 } 3140 3141 // bad denominators 3142 if ad == 0 || ad == 1 || ad == two31 { 3143 m.Bad = 1 3144 return 3145 } 3146 3147 t := two31 3148 ad &= mask 3149 3150 anc := t - 1 - t%ad 3151 anc &= mask 3152 3153 q1 := two31 / anc 3154 r1 := two31 - q1*anc 3155 q1 &= mask 3156 r1 &= mask 3157 3158 q2 := two31 / ad 3159 r2 := two31 - q2*ad 3160 q2 &= mask 3161 r2 &= mask 3162 3163 var delta uint64 3164 for { 3165 p++ 3166 q1 <<= 1 3167 r1 <<= 1 3168 q1 &= mask 3169 r1 &= mask 3170 if r1 >= anc { 3171 q1++ 3172 r1 -= anc 3173 q1 &= mask 3174 r1 &= mask 3175 } 3176 3177 q2 <<= 1 3178 r2 <<= 1 3179 q2 &= mask 3180 r2 &= mask 3181 if r2 >= ad { 3182 q2++ 3183 r2 -= ad 3184 q2 &= mask 3185 r2 &= mask 3186 } 3187 3188 delta = ad - r2 3189 delta &= mask 3190 if q1 < delta || (q1 == delta && r1 == 0) { 3191 continue 3192 } 3193 3194 break 3195 } 3196 3197 m.Sm = int64(q2 + 1) 3198 if uint64(m.Sm)&two31 != 0 { 3199 m.Sm |= ^int64(mask) 3200 } 3201 m.S = p - m.W 3202 } 3203 3204 // magic number for unsigned division 3205 // see hacker's delight chapter 10 3206 func Umagic(m *Magic) { 3207 var mask uint64 3208 3209 m.Bad = 0 3210 m.Ua = 0 3211 3212 switch m.W { 3213 default: 3214 m.Bad = 1 3215 return 3216 3217 case 8: 3218 mask = 0xff 3219 3220 case 16: 3221 mask = 0xffff 3222 3223 case 32: 3224 mask = 0xffffffff 3225 3226 case 64: 3227 mask = 0xffffffffffffffff 3228 } 3229 3230 two31 := mask ^ (mask >> 1) 3231 3232 m.Ud &= mask 3233 if m.Ud == 0 || m.Ud == two31 { 3234 m.Bad = 1 3235 return 3236 } 3237 3238 nc := mask - (-m.Ud&mask)%m.Ud 3239 p := m.W - 1 3240 3241 q1 := two31 / nc 3242 r1 := two31 - q1*nc 3243 q1 &= mask 3244 r1 &= mask 3245 3246 q2 := (two31 - 1) / m.Ud 3247 r2 := (two31 - 1) - q2*m.Ud 3248 q2 &= mask 3249 r2 &= mask 3250 3251 var delta uint64 3252 for { 3253 p++ 3254 if r1 >= nc-r1 { 3255 q1 <<= 1 3256 q1++ 3257 r1 <<= 1 3258 r1 -= nc 3259 } else { 3260 q1 <<= 1 3261 r1 <<= 1 3262 } 3263 3264 q1 &= mask 3265 r1 &= mask 3266 if r2+1 >= m.Ud-r2 { 3267 if q2 >= two31-1 { 3268 m.Ua = 1 3269 } 3270 3271 q2 <<= 1 3272 q2++ 3273 r2 <<= 1 3274 r2++ 3275 r2 -= m.Ud 3276 } else { 3277 if q2 >= two31 { 3278 m.Ua = 1 3279 } 3280 3281 q2 <<= 1 3282 r2 <<= 1 3283 r2++ 3284 } 3285 3286 q2 &= mask 3287 r2 &= mask 3288 3289 delta = m.Ud - 1 - r2 3290 delta &= mask 3291 3292 if p < m.W+m.W { 3293 if q1 < delta || (q1 == delta && r1 == 0) { 3294 continue 3295 } 3296 } 3297 3298 break 3299 } 3300 3301 m.Um = q2 + 1 3302 m.S = p - m.W 3303 } 3304 3305 func ngotype(n *Node) *Sym { 3306 if n.Type != nil { 3307 return typenamesym(n.Type) 3308 } 3309 return nil 3310 } 3311 3312 // Convert raw string to the prefix that will be used in the symbol 3313 // table. All control characters, space, '%' and '"', as well as 3314 // non-7-bit clean bytes turn into %xx. The period needs escaping 3315 // only in the last segment of the path, and it makes for happier 3316 // users if we escape that as little as possible. 3317 // 3318 // If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 3319 func pathtoprefix(s string) string { 3320 slash := strings.LastIndex(s, "/") 3321 for i := 0; i < len(s); i++ { 3322 c := s[i] 3323 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 3324 var buf bytes.Buffer 3325 for i := 0; i < len(s); i++ { 3326 c := s[i] 3327 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 3328 fmt.Fprintf(&buf, "%%%02x", c) 3329 continue 3330 } 3331 buf.WriteByte(c) 3332 } 3333 return buf.String() 3334 } 3335 } 3336 return s 3337 } 3338 3339 var pkgMap = make(map[string]*Pkg) 3340 var pkgs []*Pkg 3341 3342 func mkpkg(path string) *Pkg { 3343 if p := pkgMap[path]; p != nil { 3344 return p 3345 } 3346 3347 p := new(Pkg) 3348 p.Path = path 3349 p.Prefix = pathtoprefix(path) 3350 p.Syms = make(map[string]*Sym) 3351 pkgMap[path] = p 3352 pkgs = append(pkgs, p) 3353 return p 3354 } 3355 3356 func addinit(np **Node, init *NodeList) { 3357 if init == nil { 3358 return 3359 } 3360 3361 n := *np 3362 switch n.Op { 3363 // There may be multiple refs to this node; 3364 // introduce OCONVNOP to hold init list. 3365 case ONAME, OLITERAL: 3366 n = Nod(OCONVNOP, n, nil) 3367 3368 n.Type = n.Left.Type 3369 n.Typecheck = 1 3370 *np = n 3371 } 3372 3373 n.Ninit = concat(init, n.Ninit) 3374 n.Ullman = UINF 3375 } 3376 3377 var reservedimports = []string{ 3378 "go", 3379 "type", 3380 } 3381 3382 func isbadimport(path string) bool { 3383 if strings.Contains(path, "\x00") { 3384 Yyerror("import path contains NUL") 3385 return true 3386 } 3387 3388 for _, ri := range reservedimports { 3389 if path == ri { 3390 Yyerror("import path %q is reserved and cannot be used", path) 3391 return true 3392 } 3393 } 3394 3395 for _, r := range path { 3396 if r == utf8.RuneError { 3397 Yyerror("import path contains invalid UTF-8 sequence: %q", path) 3398 return true 3399 } 3400 3401 if r < 0x20 || r == 0x7f { 3402 Yyerror("import path contains control character: %q", path) 3403 return true 3404 } 3405 3406 if r == '\\' { 3407 Yyerror("import path contains backslash; use slash: %q", path) 3408 return true 3409 } 3410 3411 if unicode.IsSpace(rune(r)) { 3412 Yyerror("import path contains space character: %q", path) 3413 return true 3414 } 3415 3416 if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) { 3417 Yyerror("import path contains invalid character '%c': %q", r, path) 3418 return true 3419 } 3420 } 3421 3422 return false 3423 } 3424 3425 func checknil(x *Node, init **NodeList) { 3426 if Isinter(x.Type) { 3427 x = Nod(OITAB, x, nil) 3428 typecheck(&x, Erv) 3429 } 3430 3431 n := Nod(OCHECKNIL, x, nil) 3432 n.Typecheck = 1 3433 *init = list(*init, n) 3434 } 3435 3436 // Can this type be stored directly in an interface word? 3437 // Yes, if the representation is a single pointer. 3438 func isdirectiface(t *Type) bool { 3439 switch t.Etype { 3440 case TPTR32, 3441 TPTR64, 3442 TCHAN, 3443 TMAP, 3444 TFUNC, 3445 TUNSAFEPTR: 3446 return true 3447 3448 // Array of 1 direct iface type can be direct. 3449 case TARRAY: 3450 return t.Bound == 1 && isdirectiface(t.Type) 3451 3452 // Struct with 1 field of direct iface type can be direct. 3453 case TSTRUCT: 3454 return t.Type != nil && t.Type.Down == nil && isdirectiface(t.Type.Type) 3455 } 3456 3457 return false 3458 } 3459 3460 // type2IET returns "T" if t is a concrete type, 3461 // "I" if t is an interface type, and "E" if t is an empty interface type. 3462 // It is used to build calls to the conv* and assert* runtime routines. 3463 func type2IET(t *Type) string { 3464 if isnilinter(t) { 3465 return "E" 3466 } 3467 if Isinter(t) { 3468 return "I" 3469 } 3470 return "T" 3471 }