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