github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/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 // isnil reports whether n represents the universal untyped zero value "nil". 764 func isnil(n *Node) bool { 765 // Check n.Orig because constant propagation may produce typed nil constants, 766 // which don't exist in the Go spec. 767 return Isconst(n.Orig, CTNIL) 768 } 769 770 func isptrto(t *Type, et EType) bool { 771 if t == nil { 772 return false 773 } 774 if !Isptr[t.Etype] { 775 return false 776 } 777 t = t.Type 778 if t == nil { 779 return false 780 } 781 if t.Etype != et { 782 return false 783 } 784 return true 785 } 786 787 func Istype(t *Type, et EType) bool { 788 return t != nil && t.Etype == et 789 } 790 791 func Isfixedarray(t *Type) bool { 792 return t != nil && t.Etype == TARRAY && t.Bound >= 0 793 } 794 795 func Isslice(t *Type) bool { 796 return t != nil && t.Etype == TARRAY && t.Bound < 0 797 } 798 799 func isblank(n *Node) bool { 800 if n == nil { 801 return false 802 } 803 return isblanksym(n.Sym) 804 } 805 806 func isblanksym(s *Sym) bool { 807 return s != nil && s.Name == "_" 808 } 809 810 func Isinter(t *Type) bool { 811 return t != nil && t.Etype == TINTER 812 } 813 814 func isnilinter(t *Type) bool { 815 if !Isinter(t) { 816 return false 817 } 818 if t.Type != nil { 819 return false 820 } 821 return true 822 } 823 824 func isideal(t *Type) bool { 825 if t == nil { 826 return false 827 } 828 if t == idealstring || t == idealbool { 829 return true 830 } 831 switch t.Etype { 832 case TNIL, TIDEAL: 833 return true 834 } 835 836 return false 837 } 838 839 // given receiver of type t (t == r or t == *r) 840 // return type to hang methods off (r). 841 func methtype(t *Type, mustname int) *Type { 842 if t == nil { 843 return nil 844 } 845 846 // strip away pointer if it's there 847 if Isptr[t.Etype] { 848 if t.Sym != nil { 849 return nil 850 } 851 t = t.Type 852 if t == nil { 853 return nil 854 } 855 } 856 857 // need a type name 858 if t.Sym == nil && (mustname != 0 || t.Etype != TSTRUCT) { 859 return nil 860 } 861 862 // check types 863 if !issimple[t.Etype] { 864 switch t.Etype { 865 default: 866 return nil 867 868 case TSTRUCT, 869 TARRAY, 870 TMAP, 871 TCHAN, 872 TSTRING, 873 TFUNC: 874 break 875 } 876 } 877 878 return t 879 } 880 881 func cplxsubtype(et EType) EType { 882 switch et { 883 case TCOMPLEX64: 884 return TFLOAT32 885 886 case TCOMPLEX128: 887 return TFLOAT64 888 } 889 890 Fatalf("cplxsubtype: %v\n", Econv(et)) 891 return 0 892 } 893 894 func eqnote(a, b *string) bool { 895 return a == b || a != nil && b != nil && *a == *b 896 } 897 898 type TypePairList struct { 899 t1 *Type 900 t2 *Type 901 next *TypePairList 902 } 903 904 func onlist(l *TypePairList, t1 *Type, t2 *Type) bool { 905 for ; l != nil; l = l.next { 906 if (l.t1 == t1 && l.t2 == t2) || (l.t1 == t2 && l.t2 == t1) { 907 return true 908 } 909 } 910 return false 911 } 912 913 // Return 1 if t1 and t2 are identical, following the spec rules. 914 // 915 // Any cyclic type must go through a named type, and if one is 916 // named, it is only identical to the other if they are the same 917 // pointer (t1 == t2), so there's no chance of chasing cycles 918 // ad infinitum, so no need for a depth counter. 919 func Eqtype(t1 *Type, t2 *Type) bool { 920 return eqtype1(t1, t2, nil) 921 } 922 923 func eqtype1(t1 *Type, t2 *Type, assumed_equal *TypePairList) bool { 924 if t1 == t2 { 925 return true 926 } 927 if t1 == nil || t2 == nil || t1.Etype != t2.Etype { 928 return false 929 } 930 if t1.Sym != nil || t2.Sym != nil { 931 // Special case: we keep byte and uint8 separate 932 // for error messages. Treat them as equal. 933 switch t1.Etype { 934 case TUINT8: 935 if (t1 == Types[TUINT8] || t1 == bytetype) && (t2 == Types[TUINT8] || t2 == bytetype) { 936 return true 937 } 938 939 case TINT, TINT32: 940 if (t1 == Types[runetype.Etype] || t1 == runetype) && (t2 == Types[runetype.Etype] || t2 == runetype) { 941 return true 942 } 943 } 944 945 return false 946 } 947 948 if onlist(assumed_equal, t1, t2) { 949 return true 950 } 951 var l TypePairList 952 l.next = assumed_equal 953 l.t1 = t1 954 l.t2 = t2 955 956 switch t1.Etype { 957 case TINTER, TSTRUCT: 958 t1 = t1.Type 959 t2 = t2.Type 960 for ; t1 != nil && t2 != nil; t1, t2 = t1.Down, t2.Down { 961 if t1.Etype != TFIELD || t2.Etype != TFIELD { 962 Fatalf("struct/interface missing field: %v %v", t1, t2) 963 } 964 if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, &l) || !eqnote(t1.Note, t2.Note) { 965 return false 966 } 967 } 968 969 if t1 == nil && t2 == nil { 970 return true 971 } 972 return false 973 974 // Loop over structs: receiver, in, out. 975 case TFUNC: 976 t1 = t1.Type 977 t2 = t2.Type 978 for ; t1 != nil && t2 != nil; t1, t2 = t1.Down, t2.Down { 979 if t1.Etype != TSTRUCT || t2.Etype != TSTRUCT { 980 Fatalf("func missing struct: %v %v", t1, t2) 981 } 982 983 // Loop over fields in structs, ignoring argument names. 984 ta := t1.Type 985 tb := t2.Type 986 for ; ta != nil && tb != nil; ta, tb = ta.Down, tb.Down { 987 if ta.Etype != TFIELD || tb.Etype != TFIELD { 988 Fatalf("func struct missing field: %v %v", ta, tb) 989 } 990 if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, &l) { 991 return false 992 } 993 } 994 995 if ta != nil || tb != nil { 996 return false 997 } 998 } 999 1000 if t1 == nil && t2 == nil { 1001 return true 1002 } 1003 return false 1004 1005 case TARRAY: 1006 if t1.Bound != t2.Bound { 1007 return false 1008 } 1009 1010 case TCHAN: 1011 if t1.Chan != t2.Chan { 1012 return false 1013 } 1014 } 1015 1016 if eqtype1(t1.Down, t2.Down, &l) && eqtype1(t1.Type, t2.Type, &l) { 1017 return true 1018 } 1019 return false 1020 } 1021 1022 // Are t1 and t2 equal struct types when field names are ignored? 1023 // For deciding whether the result struct from g can be copied 1024 // directly when compiling f(g()). 1025 func eqtypenoname(t1 *Type, t2 *Type) bool { 1026 if t1 == nil || t2 == nil || t1.Etype != TSTRUCT || t2.Etype != TSTRUCT { 1027 return false 1028 } 1029 1030 t1 = t1.Type 1031 t2 = t2.Type 1032 for { 1033 if !Eqtype(t1, t2) { 1034 return false 1035 } 1036 if t1 == nil { 1037 return true 1038 } 1039 t1 = t1.Down 1040 t2 = t2.Down 1041 } 1042 } 1043 1044 // Is type src assignment compatible to type dst? 1045 // If so, return op code to use in conversion. 1046 // If not, return 0. 1047 func assignop(src *Type, dst *Type, why *string) Op { 1048 if why != nil { 1049 *why = "" 1050 } 1051 1052 // TODO(rsc,lvd): This behaves poorly in the presence of inlining. 1053 // https://golang.org/issue/2795 1054 if safemode != 0 && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR { 1055 Yyerror("cannot use unsafe.Pointer") 1056 errorexit() 1057 } 1058 1059 if src == dst { 1060 return OCONVNOP 1061 } 1062 if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil { 1063 return 0 1064 } 1065 1066 // 1. src type is identical to dst. 1067 if Eqtype(src, dst) { 1068 return OCONVNOP 1069 } 1070 1071 // 2. src and dst have identical underlying types 1072 // and either src or dst is not a named type or 1073 // both are empty interface types. 1074 // For assignable but different non-empty interface types, 1075 // we want to recompute the itab. 1076 if Eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || isnilinter(src)) { 1077 return OCONVNOP 1078 } 1079 1080 // 3. dst is an interface type and src implements dst. 1081 if dst.Etype == TINTER && src.Etype != TNIL { 1082 var missing *Type 1083 var ptr int 1084 var have *Type 1085 if implements(src, dst, &missing, &have, &ptr) { 1086 return OCONVIFACE 1087 } 1088 1089 // we'll have complained about this method anyway, suppress spurious messages. 1090 if have != nil && have.Sym == missing.Sym && (have.Type.Broke || missing.Type.Broke) { 1091 return OCONVIFACE 1092 } 1093 1094 if why != nil { 1095 if isptrto(src, TINTER) { 1096 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) 1097 } else if have != nil && have.Sym == missing.Sym && have.Nointerface { 1098 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) 1099 } else if have != nil && have.Sym == missing.Sym { 1100 *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)) 1101 } else if ptr != 0 { 1102 *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym) 1103 } else if have != nil { 1104 *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)) 1105 } else { 1106 *why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym) 1107 } 1108 } 1109 1110 return 0 1111 } 1112 1113 if isptrto(dst, TINTER) { 1114 if why != nil { 1115 *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst) 1116 } 1117 return 0 1118 } 1119 1120 if src.Etype == TINTER && dst.Etype != TBLANK { 1121 var have *Type 1122 var ptr int 1123 var missing *Type 1124 if why != nil && implements(dst, src, &missing, &have, &ptr) { 1125 *why = ": need type assertion" 1126 } 1127 return 0 1128 } 1129 1130 // 4. src is a bidirectional channel value, dst is a channel type, 1131 // src and dst have identical element types, and 1132 // either src or dst is not a named type. 1133 if src.Etype == TCHAN && src.Chan == Cboth && dst.Etype == TCHAN { 1134 if Eqtype(src.Type, dst.Type) && (src.Sym == nil || dst.Sym == nil) { 1135 return OCONVNOP 1136 } 1137 } 1138 1139 // 5. src is the predeclared identifier nil and dst is a nillable type. 1140 if src.Etype == TNIL { 1141 switch dst.Etype { 1142 case TARRAY: 1143 if dst.Bound != -100 { // not slice 1144 break 1145 } 1146 fallthrough 1147 1148 case TPTR32, 1149 TPTR64, 1150 TFUNC, 1151 TMAP, 1152 TCHAN, 1153 TINTER: 1154 return OCONVNOP 1155 } 1156 } 1157 1158 // 6. rule about untyped constants - already converted by defaultlit. 1159 1160 // 7. Any typed value can be assigned to the blank identifier. 1161 if dst.Etype == TBLANK { 1162 return OCONVNOP 1163 } 1164 1165 return 0 1166 } 1167 1168 // Can we convert a value of type src to a value of type dst? 1169 // If so, return op code to use in conversion (maybe OCONVNOP). 1170 // If not, return 0. 1171 func convertop(src *Type, dst *Type, why *string) Op { 1172 if why != nil { 1173 *why = "" 1174 } 1175 1176 if src == dst { 1177 return OCONVNOP 1178 } 1179 if src == nil || dst == nil { 1180 return 0 1181 } 1182 1183 // 1. src can be assigned to dst. 1184 op := assignop(src, dst, why) 1185 if op != 0 { 1186 return op 1187 } 1188 1189 // The rules for interfaces are no different in conversions 1190 // than assignments. If interfaces are involved, stop now 1191 // with the good message from assignop. 1192 // Otherwise clear the error. 1193 if src.Etype == TINTER || dst.Etype == TINTER { 1194 return 0 1195 } 1196 if why != nil { 1197 *why = "" 1198 } 1199 1200 // 2. src and dst have identical underlying types. 1201 if Eqtype(src.Orig, dst.Orig) { 1202 return OCONVNOP 1203 } 1204 1205 // 3. src and dst are unnamed pointer types 1206 // and their base types have identical underlying types. 1207 if Isptr[src.Etype] && Isptr[dst.Etype] && src.Sym == nil && dst.Sym == nil { 1208 if Eqtype(src.Type.Orig, dst.Type.Orig) { 1209 return OCONVNOP 1210 } 1211 } 1212 1213 // 4. src and dst are both integer or floating point types. 1214 if (Isint[src.Etype] || Isfloat[src.Etype]) && (Isint[dst.Etype] || Isfloat[dst.Etype]) { 1215 if Simtype[src.Etype] == Simtype[dst.Etype] { 1216 return OCONVNOP 1217 } 1218 return OCONV 1219 } 1220 1221 // 5. src and dst are both complex types. 1222 if Iscomplex[src.Etype] && Iscomplex[dst.Etype] { 1223 if Simtype[src.Etype] == Simtype[dst.Etype] { 1224 return OCONVNOP 1225 } 1226 return OCONV 1227 } 1228 1229 // 6. src is an integer or has type []byte or []rune 1230 // and dst is a string type. 1231 if Isint[src.Etype] && dst.Etype == TSTRING { 1232 return ORUNESTR 1233 } 1234 1235 if Isslice(src) && dst.Etype == TSTRING { 1236 if src.Type.Etype == bytetype.Etype { 1237 return OARRAYBYTESTR 1238 } 1239 if src.Type.Etype == runetype.Etype { 1240 return OARRAYRUNESTR 1241 } 1242 } 1243 1244 // 7. src is a string and dst is []byte or []rune. 1245 // String to slice. 1246 if src.Etype == TSTRING && Isslice(dst) { 1247 if dst.Type.Etype == bytetype.Etype { 1248 return OSTRARRAYBYTE 1249 } 1250 if dst.Type.Etype == runetype.Etype { 1251 return OSTRARRAYRUNE 1252 } 1253 } 1254 1255 // 8. src is a pointer or uintptr and dst is unsafe.Pointer. 1256 if (Isptr[src.Etype] || src.Etype == TUINTPTR) && dst.Etype == TUNSAFEPTR { 1257 return OCONVNOP 1258 } 1259 1260 // 9. src is unsafe.Pointer and dst is a pointer or uintptr. 1261 if src.Etype == TUNSAFEPTR && (Isptr[dst.Etype] || dst.Etype == TUINTPTR) { 1262 return OCONVNOP 1263 } 1264 1265 return 0 1266 } 1267 1268 func assignconv(n *Node, t *Type, context string) *Node { 1269 return assignconvfn(n, t, func() string { return context }) 1270 } 1271 1272 // Convert node n for assignment to type t. 1273 func assignconvfn(n *Node, t *Type, context func() string) *Node { 1274 if n == nil || n.Type == nil || n.Type.Broke { 1275 return n 1276 } 1277 1278 if t.Etype == TBLANK && n.Type.Etype == TNIL { 1279 Yyerror("use of untyped nil") 1280 } 1281 1282 old := n 1283 old.Diag++ // silence errors about n; we'll issue one below 1284 defaultlit(&n, t) 1285 old.Diag-- 1286 if t.Etype == TBLANK { 1287 return n 1288 } 1289 1290 // Convert ideal bool from comparison to plain bool 1291 // if the next step is non-bool (like interface{}). 1292 if n.Type == idealbool && t.Etype != TBOOL { 1293 if n.Op == ONAME || n.Op == OLITERAL { 1294 r := Nod(OCONVNOP, n, nil) 1295 r.Type = Types[TBOOL] 1296 r.Typecheck = 1 1297 r.Implicit = true 1298 n = r 1299 } 1300 } 1301 1302 if Eqtype(n.Type, t) { 1303 return n 1304 } 1305 1306 var why string 1307 op := assignop(n.Type, t, &why) 1308 if op == 0 { 1309 Yyerror("cannot use %v as type %v in %s%s", Nconv(n, obj.FmtLong), t, context(), why) 1310 op = OCONV 1311 } 1312 1313 r := Nod(op, n, nil) 1314 r.Type = t 1315 r.Typecheck = 1 1316 r.Implicit = true 1317 r.Orig = n.Orig 1318 return r 1319 } 1320 1321 // substArgTypes substitutes the given list of types for 1322 // successive occurrences of the "any" placeholder in the 1323 // type syntax expression n.Type. 1324 func substArgTypes(n *Node, types ...*Type) { 1325 for _, t := range types { 1326 dowidth(t) 1327 } 1328 substAny(&n.Type, &types) 1329 if len(types) > 0 { 1330 Fatalf("substArgTypes: too many argument types") 1331 } 1332 } 1333 1334 // substAny walks *tp, replacing instances of "any" with successive 1335 // elements removed from types. 1336 func substAny(tp **Type, types *[]*Type) { 1337 for { 1338 t := *tp 1339 if t == nil { 1340 return 1341 } 1342 if t.Etype == TANY && t.Copyany { 1343 if len(*types) == 0 { 1344 Fatalf("substArgTypes: not enough argument types") 1345 } 1346 *tp = (*types)[0] 1347 *types = (*types)[1:] 1348 } 1349 1350 switch t.Etype { 1351 case TPTR32, TPTR64, TCHAN, TARRAY: 1352 tp = &t.Type 1353 continue 1354 1355 case TMAP: 1356 substAny(&t.Down, types) 1357 tp = &t.Type 1358 continue 1359 1360 case TFUNC: 1361 substAny(&t.Type, types) 1362 substAny(&t.Type.Down.Down, types) 1363 substAny(&t.Type.Down, types) 1364 1365 case TSTRUCT: 1366 for t = t.Type; t != nil; t = t.Down { 1367 substAny(&t.Type, types) 1368 } 1369 } 1370 return 1371 } 1372 } 1373 1374 // Is this a 64-bit type? 1375 func Is64(t *Type) bool { 1376 if t == nil { 1377 return false 1378 } 1379 switch Simtype[t.Etype] { 1380 case TINT64, TUINT64, TPTR64: 1381 return true 1382 } 1383 1384 return false 1385 } 1386 1387 // Is a conversion between t1 and t2 a no-op? 1388 func Noconv(t1 *Type, t2 *Type) bool { 1389 e1 := Simtype[t1.Etype] 1390 e2 := Simtype[t2.Etype] 1391 1392 switch e1 { 1393 case TINT8, TUINT8: 1394 return e2 == TINT8 || e2 == TUINT8 1395 1396 case TINT16, TUINT16: 1397 return e2 == TINT16 || e2 == TUINT16 1398 1399 case TINT32, TUINT32, TPTR32: 1400 return e2 == TINT32 || e2 == TUINT32 || e2 == TPTR32 1401 1402 case TINT64, TUINT64, TPTR64: 1403 return e2 == TINT64 || e2 == TUINT64 || e2 == TPTR64 1404 1405 case TFLOAT32: 1406 return e2 == TFLOAT32 1407 1408 case TFLOAT64: 1409 return e2 == TFLOAT64 1410 } 1411 1412 return false 1413 } 1414 1415 func shallow(t *Type) *Type { 1416 if t == nil { 1417 return nil 1418 } 1419 nt := typ(0) 1420 *nt = *t 1421 if t.Orig == t { 1422 nt.Orig = nt 1423 } 1424 return nt 1425 } 1426 1427 func deep(t *Type) *Type { 1428 if t == nil { 1429 return nil 1430 } 1431 1432 var nt *Type 1433 switch t.Etype { 1434 default: 1435 nt = t // share from here down 1436 1437 case TANY: 1438 nt = shallow(t) 1439 nt.Copyany = true 1440 1441 case TPTR32, TPTR64, TCHAN, TARRAY: 1442 nt = shallow(t) 1443 nt.Type = deep(t.Type) 1444 1445 case TMAP: 1446 nt = shallow(t) 1447 nt.Down = deep(t.Down) 1448 nt.Type = deep(t.Type) 1449 1450 case TFUNC: 1451 nt = shallow(t) 1452 nt.Type = deep(t.Type) 1453 nt.Type.Down = deep(t.Type.Down) 1454 nt.Type.Down.Down = deep(t.Type.Down.Down) 1455 1456 case TSTRUCT: 1457 nt = shallow(t) 1458 nt.Type = shallow(t.Type) 1459 xt := nt.Type 1460 1461 for t = t.Type; t != nil; t = t.Down { 1462 xt.Type = deep(t.Type) 1463 xt.Down = shallow(t.Down) 1464 xt = xt.Down 1465 } 1466 } 1467 1468 return nt 1469 } 1470 1471 func syslook(name string, copy int) *Node { 1472 s := Pkglookup(name, Runtimepkg) 1473 if s == nil || s.Def == nil { 1474 Fatalf("syslook: can't find runtime.%s", name) 1475 } 1476 1477 if copy == 0 { 1478 return s.Def 1479 } 1480 1481 n := Nod(0, nil, nil) 1482 *n = *s.Def 1483 n.Type = deep(s.Def.Type) 1484 1485 return n 1486 } 1487 1488 // compute a hash value for type t. 1489 // if t is a method type, ignore the receiver 1490 // so that the hash can be used in interface checks. 1491 // %T already contains 1492 // all the necessary logic to generate a representation 1493 // of the type that completely describes it. 1494 // using smprint here avoids duplicating that code. 1495 // using md5 here is overkill, but i got tired of 1496 // accidental collisions making the runtime think 1497 // two types are equal when they really aren't. 1498 func typehash(t *Type) uint32 { 1499 var p string 1500 1501 if t.Thistuple != 0 { 1502 // hide method receiver from Tpretty 1503 t.Thistuple = 0 1504 1505 p = Tconv(t, obj.FmtLeft|obj.FmtUnsigned) 1506 t.Thistuple = 1 1507 } else { 1508 p = Tconv(t, obj.FmtLeft|obj.FmtUnsigned) 1509 } 1510 1511 //print("typehash: %s\n", p); 1512 h := md5.Sum([]byte(p)) 1513 return binary.LittleEndian.Uint32(h[:4]) 1514 } 1515 1516 var initPtrtoDone bool 1517 1518 var ( 1519 ptrToUint8 *Type 1520 ptrToAny *Type 1521 ptrToString *Type 1522 ptrToBool *Type 1523 ptrToInt32 *Type 1524 ) 1525 1526 func initPtrto() { 1527 ptrToUint8 = ptrto1(Types[TUINT8]) 1528 ptrToAny = ptrto1(Types[TANY]) 1529 ptrToString = ptrto1(Types[TSTRING]) 1530 ptrToBool = ptrto1(Types[TBOOL]) 1531 ptrToInt32 = ptrto1(Types[TINT32]) 1532 } 1533 1534 func ptrto1(t *Type) *Type { 1535 t1 := typ(Tptr) 1536 t1.Type = t 1537 t1.Width = int64(Widthptr) 1538 t1.Align = uint8(Widthptr) 1539 return t1 1540 } 1541 1542 // Ptrto returns the Type *t. 1543 // The returned struct must not be modified. 1544 func Ptrto(t *Type) *Type { 1545 if Tptr == 0 { 1546 Fatalf("ptrto: no tptr") 1547 } 1548 // Reduce allocations by pre-creating common cases. 1549 if !initPtrtoDone { 1550 initPtrto() 1551 initPtrtoDone = true 1552 } 1553 switch t { 1554 case Types[TUINT8]: 1555 return ptrToUint8 1556 case Types[TINT32]: 1557 return ptrToInt32 1558 case Types[TANY]: 1559 return ptrToAny 1560 case Types[TSTRING]: 1561 return ptrToString 1562 case Types[TBOOL]: 1563 return ptrToBool 1564 } 1565 return ptrto1(t) 1566 } 1567 1568 func frame(context int) { 1569 if context != 0 { 1570 fmt.Printf("--- external frame ---\n") 1571 for _, n := range externdcl { 1572 printframenode(n) 1573 } 1574 return 1575 } 1576 1577 if Curfn != nil { 1578 fmt.Printf("--- %v frame ---\n", Curfn.Func.Nname.Sym) 1579 for l := Curfn.Func.Dcl; l != nil; l = l.Next { 1580 printframenode(l.N) 1581 } 1582 } 1583 } 1584 1585 func printframenode(n *Node) { 1586 w := int64(-1) 1587 if n.Type != nil { 1588 w = n.Type.Width 1589 } 1590 switch n.Op { 1591 case ONAME: 1592 fmt.Printf("%v %v G%d %v width=%d\n", Oconv(int(n.Op), 0), n.Sym, n.Name.Vargen, n.Type, w) 1593 case OTYPE: 1594 fmt.Printf("%v %v width=%d\n", Oconv(int(n.Op), 0), n.Type, w) 1595 } 1596 } 1597 1598 // calculate sethi/ullman number 1599 // roughly how many registers needed to 1600 // compile a node. used to compile the 1601 // hardest side first to minimize registers. 1602 func ullmancalc(n *Node) { 1603 if n == nil { 1604 return 1605 } 1606 1607 var ul int 1608 var ur int 1609 if n.Ninit != nil { 1610 ul = UINF 1611 goto out 1612 } 1613 1614 switch n.Op { 1615 case OREGISTER, OLITERAL, ONAME: 1616 ul = 1 1617 if n.Class == PPARAMREF || (n.Class&PHEAP != 0) { 1618 ul++ 1619 } 1620 goto out 1621 1622 case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OASWB: 1623 ul = UINF 1624 goto out 1625 1626 // hard with instrumented code 1627 case OANDAND, OOROR: 1628 if instrumenting { 1629 ul = UINF 1630 goto out 1631 } 1632 } 1633 1634 ul = 1 1635 if n.Left != nil { 1636 ul = int(n.Left.Ullman) 1637 } 1638 ur = 1 1639 if n.Right != nil { 1640 ur = int(n.Right.Ullman) 1641 } 1642 if ul == ur { 1643 ul += 1 1644 } 1645 if ur > ul { 1646 ul = ur 1647 } 1648 1649 out: 1650 if ul > 200 { 1651 ul = 200 // clamp to uchar with room to grow 1652 } 1653 n.Ullman = uint8(ul) 1654 } 1655 1656 func badtype(op Op, tl *Type, tr *Type) { 1657 fmt_ := "" 1658 if tl != nil { 1659 fmt_ += fmt.Sprintf("\n\t%v", tl) 1660 } 1661 if tr != nil { 1662 fmt_ += fmt.Sprintf("\n\t%v", tr) 1663 } 1664 1665 // common mistake: *struct and *interface. 1666 if tl != nil && tr != nil && Isptr[tl.Etype] && Isptr[tr.Etype] { 1667 if tl.Type.Etype == TSTRUCT && tr.Type.Etype == TINTER { 1668 fmt_ += "\n\t(*struct vs *interface)" 1669 } else if tl.Type.Etype == TINTER && tr.Type.Etype == TSTRUCT { 1670 fmt_ += "\n\t(*interface vs *struct)" 1671 } 1672 } 1673 1674 s := fmt_ 1675 Yyerror("illegal types for operand: %v%s", Oconv(int(op), 0), s) 1676 } 1677 1678 // iterator to walk a structure declaration 1679 func Structfirst(s *Iter, nn **Type) *Type { 1680 var t *Type 1681 1682 n := *nn 1683 if n == nil { 1684 goto bad 1685 } 1686 1687 switch n.Etype { 1688 default: 1689 goto bad 1690 1691 case TSTRUCT, TINTER, TFUNC: 1692 break 1693 } 1694 1695 t = n.Type 1696 if t == nil { 1697 return nil 1698 } 1699 1700 if t.Etype != TFIELD { 1701 Fatalf("structfirst: not field %v", t) 1702 } 1703 1704 s.T = t 1705 return t 1706 1707 bad: 1708 Fatalf("structfirst: not struct %v", n) 1709 1710 return nil 1711 } 1712 1713 func structnext(s *Iter) *Type { 1714 n := s.T 1715 t := n.Down 1716 if t == nil { 1717 return nil 1718 } 1719 1720 if t.Etype != TFIELD { 1721 Fatalf("structnext: not struct %v", n) 1722 1723 return nil 1724 } 1725 1726 s.T = t 1727 return t 1728 } 1729 1730 // iterator to this and inargs in a function 1731 func funcfirst(s *Iter, t *Type) *Type { 1732 var fp *Type 1733 1734 if t == nil { 1735 goto bad 1736 } 1737 1738 if t.Etype != TFUNC { 1739 goto bad 1740 } 1741 1742 s.Tfunc = t 1743 s.Done = 0 1744 fp = Structfirst(s, getthis(t)) 1745 if fp == nil { 1746 s.Done = 1 1747 fp = Structfirst(s, getinarg(t)) 1748 } 1749 1750 return fp 1751 1752 bad: 1753 Fatalf("funcfirst: not func %v", t) 1754 return nil 1755 } 1756 1757 func funcnext(s *Iter) *Type { 1758 fp := structnext(s) 1759 if fp == nil && s.Done == 0 { 1760 s.Done = 1 1761 fp = Structfirst(s, getinarg(s.Tfunc)) 1762 } 1763 1764 return fp 1765 } 1766 1767 func getthis(t *Type) **Type { 1768 if t.Etype != TFUNC { 1769 Fatalf("getthis: not a func %v", t) 1770 } 1771 return &t.Type 1772 } 1773 1774 func Getoutarg(t *Type) **Type { 1775 if t.Etype != TFUNC { 1776 Fatalf("getoutarg: not a func %v", t) 1777 } 1778 return &t.Type.Down 1779 } 1780 1781 func getinarg(t *Type) **Type { 1782 if t.Etype != TFUNC { 1783 Fatalf("getinarg: not a func %v", t) 1784 } 1785 return &t.Type.Down.Down 1786 } 1787 1788 func getthisx(t *Type) *Type { 1789 return *getthis(t) 1790 } 1791 1792 func getoutargx(t *Type) *Type { 1793 return *Getoutarg(t) 1794 } 1795 1796 func getinargx(t *Type) *Type { 1797 return *getinarg(t) 1798 } 1799 1800 // Brcom returns !(op). 1801 // For example, Brcom(==) is !=. 1802 func Brcom(op Op) Op { 1803 switch op { 1804 case OEQ: 1805 return ONE 1806 case ONE: 1807 return OEQ 1808 case OLT: 1809 return OGE 1810 case OGT: 1811 return OLE 1812 case OLE: 1813 return OGT 1814 case OGE: 1815 return OLT 1816 } 1817 Fatalf("brcom: no com for %v\n", Oconv(int(op), 0)) 1818 return op 1819 } 1820 1821 // Brrev returns reverse(op). 1822 // For example, Brrev(<) is >. 1823 func Brrev(op Op) Op { 1824 switch op { 1825 case OEQ: 1826 return OEQ 1827 case ONE: 1828 return ONE 1829 case OLT: 1830 return OGT 1831 case OGT: 1832 return OLT 1833 case OLE: 1834 return OGE 1835 case OGE: 1836 return OLE 1837 } 1838 Fatalf("brrev: no rev for %v\n", Oconv(int(op), 0)) 1839 return op 1840 } 1841 1842 // return side effect-free n, appending side effects to init. 1843 // result is assignable if n is. 1844 func safeexpr(n *Node, init **NodeList) *Node { 1845 if n == nil { 1846 return nil 1847 } 1848 1849 if n.Ninit != nil { 1850 walkstmtlist(n.Ninit) 1851 *init = concat(*init, n.Ninit) 1852 n.Ninit = nil 1853 } 1854 1855 switch n.Op { 1856 case ONAME, OLITERAL: 1857 return n 1858 1859 case ODOT, OLEN, OCAP: 1860 l := safeexpr(n.Left, init) 1861 if l == n.Left { 1862 return n 1863 } 1864 r := Nod(OXXX, nil, nil) 1865 *r = *n 1866 r.Left = l 1867 typecheck(&r, Erv) 1868 walkexpr(&r, init) 1869 return r 1870 1871 case ODOTPTR, OIND: 1872 l := safeexpr(n.Left, init) 1873 if l == n.Left { 1874 return n 1875 } 1876 a := Nod(OXXX, nil, nil) 1877 *a = *n 1878 a.Left = l 1879 walkexpr(&a, init) 1880 return a 1881 1882 case OINDEX, OINDEXMAP: 1883 l := safeexpr(n.Left, init) 1884 r := safeexpr(n.Right, init) 1885 if l == n.Left && r == n.Right { 1886 return n 1887 } 1888 a := Nod(OXXX, nil, nil) 1889 *a = *n 1890 a.Left = l 1891 a.Right = r 1892 walkexpr(&a, init) 1893 return a 1894 } 1895 1896 // make a copy; must not be used as an lvalue 1897 if islvalue(n) { 1898 Fatalf("missing lvalue case in safeexpr: %v", n) 1899 } 1900 return cheapexpr(n, init) 1901 } 1902 1903 func copyexpr(n *Node, t *Type, init **NodeList) *Node { 1904 l := temp(t) 1905 a := Nod(OAS, l, n) 1906 typecheck(&a, Etop) 1907 walkexpr(&a, init) 1908 *init = list(*init, a) 1909 return l 1910 } 1911 1912 // return side-effect free and cheap n, appending side effects to init. 1913 // result may not be assignable. 1914 func cheapexpr(n *Node, init **NodeList) *Node { 1915 switch n.Op { 1916 case ONAME, OLITERAL: 1917 return n 1918 } 1919 1920 return copyexpr(n, n.Type, init) 1921 } 1922 1923 func Setmaxarg(t *Type, extra int32) { 1924 dowidth(t) 1925 w := t.Argwid 1926 if w >= Thearch.MAXWIDTH { 1927 Fatalf("bad argwid %v", t) 1928 } 1929 w += int64(extra) 1930 if w >= Thearch.MAXWIDTH { 1931 Fatalf("bad argwid %d + %v", extra, t) 1932 } 1933 if w > Maxarg { 1934 Maxarg = w 1935 } 1936 } 1937 1938 // unicode-aware case-insensitive strcmp 1939 1940 // code to resolve elided DOTs 1941 // in embedded types 1942 1943 // search depth 0 -- 1944 // return count of fields+methods 1945 // found with a given name 1946 func lookdot0(s *Sym, t *Type, save **Type, ignorecase int) int { 1947 u := t 1948 if Isptr[u.Etype] { 1949 u = u.Type 1950 } 1951 1952 c := 0 1953 if u.Etype == TSTRUCT || u.Etype == TINTER { 1954 for f := u.Type; f != nil; f = f.Down { 1955 if f.Sym == s || (ignorecase != 0 && f.Type.Etype == TFUNC && f.Type.Thistuple > 0 && strings.EqualFold(f.Sym.Name, s.Name)) { 1956 if save != nil { 1957 *save = f 1958 } 1959 c++ 1960 } 1961 } 1962 } 1963 1964 u = methtype(t, 0) 1965 if u != nil { 1966 for f := u.Method; f != nil; f = f.Down { 1967 if f.Embedded == 0 && (f.Sym == s || (ignorecase != 0 && strings.EqualFold(f.Sym.Name, s.Name))) { 1968 if save != nil { 1969 *save = f 1970 } 1971 c++ 1972 } 1973 } 1974 } 1975 1976 return c 1977 } 1978 1979 // search depth d for field/method s -- 1980 // return count of fields+methods 1981 // found at search depth. 1982 // answer is in dotlist array and 1983 // count of number of ways is returned. 1984 func adddot1(s *Sym, t *Type, d int, save **Type, ignorecase int) int { 1985 if t.Trecur != 0 { 1986 return 0 1987 } 1988 t.Trecur = 1 1989 1990 var c int 1991 var u *Type 1992 var a int 1993 if d == 0 { 1994 c = lookdot0(s, t, save, ignorecase) 1995 goto out 1996 } 1997 1998 c = 0 1999 u = t 2000 if Isptr[u.Etype] { 2001 u = u.Type 2002 } 2003 if u.Etype != TSTRUCT && u.Etype != TINTER { 2004 goto out 2005 } 2006 2007 d-- 2008 for f := u.Type; f != nil; f = f.Down { 2009 if f.Embedded == 0 { 2010 continue 2011 } 2012 if f.Sym == nil { 2013 continue 2014 } 2015 a = adddot1(s, f.Type, d, save, ignorecase) 2016 if a != 0 && c == 0 { 2017 dotlist[d].field = f 2018 } 2019 c += a 2020 } 2021 2022 out: 2023 t.Trecur = 0 2024 return c 2025 } 2026 2027 // in T.field 2028 // find missing fields that 2029 // will give shortest unique addressing. 2030 // modify the tree with missing type names. 2031 func adddot(n *Node) *Node { 2032 typecheck(&n.Left, Etype|Erv) 2033 n.Diag |= n.Left.Diag 2034 t := n.Left.Type 2035 if t == nil { 2036 return n 2037 } 2038 2039 if n.Left.Op == OTYPE { 2040 return n 2041 } 2042 2043 if n.Right.Op != ONAME { 2044 return n 2045 } 2046 s := n.Right.Sym 2047 if s == nil { 2048 return n 2049 } 2050 2051 var c int 2052 for d := 0; d < len(dotlist); d++ { 2053 c = adddot1(s, t, d, nil, 0) 2054 if c > 0 { 2055 if c > 1 { 2056 Yyerror("ambiguous selector %v", n) 2057 n.Left = nil 2058 return n 2059 } 2060 2061 // rebuild elided dots 2062 for c := d - 1; c >= 0; c-- { 2063 n.Left = Nod(ODOT, n.Left, newname(dotlist[c].field.Sym)) 2064 n.Left.Implicit = true 2065 } 2066 2067 return n 2068 } 2069 } 2070 2071 return n 2072 } 2073 2074 // code to help generate trampoline 2075 // functions for methods on embedded 2076 // subtypes. 2077 // these are approx the same as 2078 // the corresponding adddot routines 2079 // except that they expect to be called 2080 // with unique tasks and they return 2081 // the actual methods. 2082 type Symlink struct { 2083 field *Type 2084 link *Symlink 2085 good bool 2086 followptr bool 2087 } 2088 2089 var slist *Symlink 2090 2091 func expand0(t *Type, followptr bool) { 2092 u := t 2093 if Isptr[u.Etype] { 2094 followptr = true 2095 u = u.Type 2096 } 2097 2098 if u.Etype == TINTER { 2099 var sl *Symlink 2100 for f := u.Type; f != nil; f = f.Down { 2101 if f.Sym.Flags&SymUniq != 0 { 2102 continue 2103 } 2104 f.Sym.Flags |= SymUniq 2105 sl = new(Symlink) 2106 sl.field = f 2107 sl.link = slist 2108 sl.followptr = followptr 2109 slist = sl 2110 } 2111 2112 return 2113 } 2114 2115 u = methtype(t, 0) 2116 if u != nil { 2117 var sl *Symlink 2118 for f := u.Method; f != nil; f = f.Down { 2119 if f.Sym.Flags&SymUniq != 0 { 2120 continue 2121 } 2122 f.Sym.Flags |= SymUniq 2123 sl = new(Symlink) 2124 sl.field = f 2125 sl.link = slist 2126 sl.followptr = followptr 2127 slist = sl 2128 } 2129 } 2130 } 2131 2132 func expand1(t *Type, d int, followptr bool) { 2133 if t.Trecur != 0 { 2134 return 2135 } 2136 if d == 0 { 2137 return 2138 } 2139 t.Trecur = 1 2140 2141 if d != len(dotlist)-1 { 2142 expand0(t, followptr) 2143 } 2144 2145 u := t 2146 if Isptr[u.Etype] { 2147 followptr = true 2148 u = u.Type 2149 } 2150 2151 if u.Etype != TSTRUCT && u.Etype != TINTER { 2152 goto out 2153 } 2154 2155 for f := u.Type; f != nil; f = f.Down { 2156 if f.Embedded == 0 { 2157 continue 2158 } 2159 if f.Sym == nil { 2160 continue 2161 } 2162 expand1(f.Type, d-1, followptr) 2163 } 2164 2165 out: 2166 t.Trecur = 0 2167 } 2168 2169 func expandmeth(t *Type) { 2170 if t == nil || t.Xmethod != nil { 2171 return 2172 } 2173 2174 // mark top-level method symbols 2175 // so that expand1 doesn't consider them. 2176 var f *Type 2177 for f = t.Method; f != nil; f = f.Down { 2178 f.Sym.Flags |= SymUniq 2179 } 2180 2181 // generate all reachable methods 2182 slist = nil 2183 2184 expand1(t, len(dotlist)-1, false) 2185 2186 // check each method to be uniquely reachable 2187 var c int 2188 var d int 2189 for sl := slist; sl != nil; sl = sl.link { 2190 sl.field.Sym.Flags &^= SymUniq 2191 for d = 0; d < len(dotlist); d++ { 2192 c = adddot1(sl.field.Sym, t, d, &f, 0) 2193 if c == 0 { 2194 continue 2195 } 2196 if c == 1 { 2197 // addot1 may have dug out arbitrary fields, we only want methods. 2198 if f.Type.Etype == TFUNC && f.Type.Thistuple > 0 { 2199 sl.good = true 2200 sl.field = f 2201 } 2202 } 2203 2204 break 2205 } 2206 } 2207 2208 for f = t.Method; f != nil; f = f.Down { 2209 f.Sym.Flags &^= SymUniq 2210 } 2211 2212 t.Xmethod = t.Method 2213 for sl := slist; sl != nil; sl = sl.link { 2214 if sl.good { 2215 // add it to the base type method list 2216 f = typ(TFIELD) 2217 2218 *f = *sl.field 2219 f.Embedded = 1 // needs a trampoline 2220 if sl.followptr { 2221 f.Embedded = 2 2222 } 2223 f.Down = t.Xmethod 2224 t.Xmethod = f 2225 } 2226 } 2227 } 2228 2229 // Given funarg struct list, return list of ODCLFIELD Node fn args. 2230 func structargs(tl **Type, mustname int) *NodeList { 2231 var savet Iter 2232 var a *Node 2233 var n *Node 2234 var buf string 2235 2236 var args *NodeList 2237 gen := 0 2238 for t := Structfirst(&savet, tl); t != nil; t = structnext(&savet) { 2239 n = nil 2240 if mustname != 0 && (t.Sym == nil || t.Sym.Name == "_") { 2241 // invent a name so that we can refer to it in the trampoline 2242 buf = fmt.Sprintf(".anon%d", gen) 2243 gen++ 2244 2245 n = newname(Lookup(buf)) 2246 } else if t.Sym != nil { 2247 n = newname(t.Sym) 2248 } 2249 a = Nod(ODCLFIELD, n, typenod(t.Type)) 2250 a.Isddd = t.Isddd 2251 if n != nil { 2252 n.Isddd = t.Isddd 2253 } 2254 args = list(args, a) 2255 } 2256 2257 return args 2258 } 2259 2260 // Generate a wrapper function to convert from 2261 // a receiver of type T to a receiver of type U. 2262 // That is, 2263 // 2264 // func (t T) M() { 2265 // ... 2266 // } 2267 // 2268 // already exists; this function generates 2269 // 2270 // func (u U) M() { 2271 // u.M() 2272 // } 2273 // 2274 // where the types T and U are such that u.M() is valid 2275 // and calls the T.M method. 2276 // The resulting function is for use in method tables. 2277 // 2278 // rcvr - U 2279 // method - M func (t T)(), a TFIELD type struct 2280 // newnam - the eventual mangled name of this function 2281 2282 var genwrapper_linehistdone int = 0 2283 2284 func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) { 2285 if false && Debug['r'] != 0 { 2286 fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam) 2287 } 2288 2289 lexlineno++ 2290 lineno = lexlineno 2291 if genwrapper_linehistdone == 0 { 2292 // All the wrappers can share the same linehist entry. 2293 linehistpush("<autogenerated>") 2294 2295 genwrapper_linehistdone = 1 2296 } 2297 2298 dclcontext = PEXTERN 2299 markdcl() 2300 2301 this := Nod(ODCLFIELD, newname(Lookup(".this")), typenod(rcvr)) 2302 this.Left.Name.Param.Ntype = this.Right 2303 in := structargs(getinarg(method.Type), 1) 2304 out := structargs(Getoutarg(method.Type), 0) 2305 2306 t := Nod(OTFUNC, nil, nil) 2307 l := list1(this) 2308 if iface != 0 && rcvr.Width < Types[Tptr].Width { 2309 // Building method for interface table and receiver 2310 // is smaller than the single pointer-sized word 2311 // that the interface call will pass in. 2312 // Add a dummy padding argument after the 2313 // receiver to make up the difference. 2314 tpad := typ(TARRAY) 2315 2316 tpad.Type = Types[TUINT8] 2317 tpad.Bound = Types[Tptr].Width - rcvr.Width 2318 pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad)) 2319 l = list(l, pad) 2320 } 2321 2322 t.List = concat(l, in) 2323 t.Rlist = out 2324 2325 fn := Nod(ODCLFUNC, nil, nil) 2326 fn.Func.Nname = newname(newnam) 2327 fn.Func.Nname.Name.Defn = fn 2328 fn.Func.Nname.Name.Param.Ntype = t 2329 declare(fn.Func.Nname, PFUNC) 2330 funchdr(fn) 2331 2332 // arg list 2333 var args *NodeList 2334 2335 isddd := false 2336 for l := in; l != nil; l = l.Next { 2337 args = list(args, l.N.Left) 2338 isddd = l.N.Left.Isddd 2339 } 2340 2341 methodrcvr := getthisx(method.Type).Type.Type 2342 2343 // generate nil pointer check for better error 2344 if Isptr[rcvr.Etype] && rcvr.Type == methodrcvr { 2345 // generating wrapper from *T to T. 2346 n := Nod(OIF, nil, nil) 2347 2348 n.Left = Nod(OEQ, this.Left, nodnil()) 2349 2350 // these strings are already in the reflect tables, 2351 // so no space cost to use them here. 2352 var l *NodeList 2353 2354 var v Val 2355 v.U = rcvr.Type.Sym.Pkg.Name // package name 2356 l = list(l, nodlit(v)) 2357 v.U = rcvr.Type.Sym.Name // type name 2358 l = list(l, nodlit(v)) 2359 v.U = method.Sym.Name 2360 l = list(l, nodlit(v)) // method name 2361 call := Nod(OCALL, syslook("panicwrap", 0), nil) 2362 call.List = l 2363 n.Nbody = list1(call) 2364 fn.Nbody = list(fn.Nbody, n) 2365 } 2366 2367 dot := adddot(Nod(OXDOT, this.Left, newname(method.Sym))) 2368 2369 // generate call 2370 if !instrumenting && Isptr[rcvr.Etype] && Isptr[methodrcvr.Etype] && method.Embedded != 0 && !isifacemethod(method.Type) { 2371 // generate tail call: adjust pointer receiver and jump to embedded method. 2372 dot = dot.Left // skip final .M 2373 if !Isptr[dotlist[0].field.Type.Etype] { 2374 dot = Nod(OADDR, dot, nil) 2375 } 2376 as := Nod(OAS, this.Left, Nod(OCONVNOP, dot, nil)) 2377 as.Right.Type = rcvr 2378 fn.Nbody = list(fn.Nbody, as) 2379 n := Nod(ORETJMP, nil, nil) 2380 n.Left = newname(methodsym(method.Sym, methodrcvr, 0)) 2381 fn.Nbody = list(fn.Nbody, n) 2382 } else { 2383 fn.Func.Wrapper = true // ignore frame for panic+recover matching 2384 call := Nod(OCALL, dot, nil) 2385 call.List = args 2386 call.Isddd = isddd 2387 if method.Type.Outtuple > 0 { 2388 n := Nod(ORETURN, nil, nil) 2389 n.List = list1(call) 2390 call = n 2391 } 2392 2393 fn.Nbody = list(fn.Nbody, call) 2394 } 2395 2396 if false && Debug['r'] != 0 { 2397 dumplist("genwrapper body", fn.Nbody) 2398 } 2399 2400 funcbody(fn) 2401 Curfn = fn 2402 2403 // wrappers where T is anonymous (struct or interface) can be duplicated. 2404 if rcvr.Etype == TSTRUCT || rcvr.Etype == TINTER || Isptr[rcvr.Etype] && rcvr.Type.Etype == TSTRUCT { 2405 fn.Func.Dupok = true 2406 } 2407 typecheck(&fn, Etop) 2408 typechecklist(fn.Nbody, Etop) 2409 2410 inlcalls(fn) 2411 escAnalyze([]*Node{fn}, false) 2412 2413 Curfn = nil 2414 funccompile(fn) 2415 } 2416 2417 func hashmem(t *Type) *Node { 2418 sym := Pkglookup("memhash", Runtimepkg) 2419 2420 n := newname(sym) 2421 n.Class = PFUNC 2422 tfn := Nod(OTFUNC, nil, nil) 2423 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) 2424 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2425 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2426 tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2427 typecheck(&tfn, Etype) 2428 n.Type = tfn.Type 2429 return n 2430 } 2431 2432 func hashfor(t *Type) *Node { 2433 var sym *Sym 2434 2435 a := algtype1(t, nil) 2436 switch a { 2437 case AMEM: 2438 Fatalf("hashfor with AMEM type") 2439 2440 case AINTER: 2441 sym = Pkglookup("interhash", Runtimepkg) 2442 2443 case ANILINTER: 2444 sym = Pkglookup("nilinterhash", Runtimepkg) 2445 2446 case ASTRING: 2447 sym = Pkglookup("strhash", Runtimepkg) 2448 2449 case AFLOAT32: 2450 sym = Pkglookup("f32hash", Runtimepkg) 2451 2452 case AFLOAT64: 2453 sym = Pkglookup("f64hash", Runtimepkg) 2454 2455 case ACPLX64: 2456 sym = Pkglookup("c64hash", Runtimepkg) 2457 2458 case ACPLX128: 2459 sym = Pkglookup("c128hash", Runtimepkg) 2460 2461 default: 2462 sym = typesymprefix(".hash", t) 2463 } 2464 2465 n := newname(sym) 2466 n.Class = PFUNC 2467 tfn := Nod(OTFUNC, nil, nil) 2468 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Ptrto(t)))) 2469 tfn.List = list(tfn.List, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2470 tfn.Rlist = list(tfn.Rlist, Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR]))) 2471 typecheck(&tfn, Etype) 2472 n.Type = tfn.Type 2473 return n 2474 } 2475 2476 // Generate a helper function to compute the hash of a value of type t. 2477 func genhash(sym *Sym, t *Type) { 2478 if Debug['r'] != 0 { 2479 fmt.Printf("genhash %v %v\n", sym, t) 2480 } 2481 2482 lineno = 1 // less confusing than end of input 2483 dclcontext = PEXTERN 2484 markdcl() 2485 2486 // func sym(p *T, h uintptr) uintptr 2487 fn := Nod(ODCLFUNC, nil, nil) 2488 2489 fn.Func.Nname = newname(sym) 2490 fn.Func.Nname.Class = PFUNC 2491 tfn := Nod(OTFUNC, nil, nil) 2492 fn.Func.Nname.Name.Param.Ntype = tfn 2493 2494 n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t))) 2495 tfn.List = list(tfn.List, n) 2496 np := n.Left 2497 n = Nod(ODCLFIELD, newname(Lookup("h")), typenod(Types[TUINTPTR])) 2498 tfn.List = list(tfn.List, n) 2499 nh := n.Left 2500 n = Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])) // return value 2501 tfn.Rlist = list(tfn.Rlist, n) 2502 2503 funchdr(fn) 2504 typecheck(&fn.Func.Nname.Name.Param.Ntype, Etype) 2505 2506 // genhash is only called for types that have equality but 2507 // cannot be handled by the standard algorithms, 2508 // so t must be either an array or a struct. 2509 switch t.Etype { 2510 default: 2511 Fatalf("genhash %v", t) 2512 2513 case TARRAY: 2514 if Isslice(t) { 2515 Fatalf("genhash %v", t) 2516 } 2517 2518 // An array of pure memory would be handled by the 2519 // standard algorithm, so the element type must not be 2520 // pure memory. 2521 hashel := hashfor(t.Type) 2522 2523 n := Nod(ORANGE, nil, Nod(OIND, np, nil)) 2524 ni := newname(Lookup("i")) 2525 ni.Type = Types[TINT] 2526 n.List = list1(ni) 2527 n.Colas = true 2528 colasdefn(n.List, n) 2529 ni = n.List.N 2530 2531 // h = hashel(&p[i], h) 2532 call := Nod(OCALL, hashel, nil) 2533 2534 nx := Nod(OINDEX, np, ni) 2535 nx.Bounded = true 2536 na := Nod(OADDR, nx, nil) 2537 na.Etype = 1 // no escape to heap 2538 call.List = list(call.List, na) 2539 call.List = list(call.List, nh) 2540 n.Nbody = list(n.Nbody, Nod(OAS, nh, call)) 2541 2542 fn.Nbody = list(fn.Nbody, n) 2543 2544 // Walk the struct using memhash for runs of AMEM 2545 // and calling specific hash functions for the others. 2546 case TSTRUCT: 2547 var first *Type 2548 2549 offend := int64(0) 2550 var size int64 2551 var call *Node 2552 var nx *Node 2553 var na *Node 2554 var hashel *Node 2555 for t1 := t.Type; ; t1 = t1.Down { 2556 if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) { 2557 offend = t1.Width + t1.Type.Width 2558 if first == nil { 2559 first = t1 2560 } 2561 2562 // If it's a memory field but it's padded, stop here. 2563 if ispaddedfield(t1, t.Width) { 2564 t1 = t1.Down 2565 } else { 2566 continue 2567 } 2568 } 2569 2570 // Run memhash for fields up to this one. 2571 if first != nil { 2572 size = offend - first.Width // first->width is offset 2573 hashel = hashmem(first.Type) 2574 2575 // h = hashel(&p.first, size, h) 2576 call = Nod(OCALL, hashel, nil) 2577 2578 nx = Nod(OXDOT, np, newname(first.Sym)) // TODO: fields from other packages? 2579 na = Nod(OADDR, nx, nil) 2580 na.Etype = 1 // no escape to heap 2581 call.List = list(call.List, na) 2582 call.List = list(call.List, nh) 2583 call.List = list(call.List, Nodintconst(size)) 2584 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2585 2586 first = nil 2587 } 2588 2589 if t1 == nil { 2590 break 2591 } 2592 if isblanksym(t1.Sym) { 2593 continue 2594 } 2595 2596 // Run hash for this field. 2597 if algtype1(t1.Type, nil) == AMEM { 2598 hashel = hashmem(t1.Type) 2599 2600 // h = memhash(&p.t1, h, size) 2601 call = Nod(OCALL, hashel, nil) 2602 2603 nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages? 2604 na = Nod(OADDR, nx, nil) 2605 na.Etype = 1 // no escape to heap 2606 call.List = list(call.List, na) 2607 call.List = list(call.List, nh) 2608 call.List = list(call.List, Nodintconst(t1.Type.Width)) 2609 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2610 } else { 2611 hashel = hashfor(t1.Type) 2612 2613 // h = hashel(&p.t1, h) 2614 call = Nod(OCALL, hashel, nil) 2615 2616 nx = Nod(OXDOT, np, newname(t1.Sym)) // TODO: fields from other packages? 2617 na = Nod(OADDR, nx, nil) 2618 na.Etype = 1 // no escape to heap 2619 call.List = list(call.List, na) 2620 call.List = list(call.List, nh) 2621 fn.Nbody = list(fn.Nbody, Nod(OAS, nh, call)) 2622 } 2623 } 2624 } 2625 2626 r := Nod(ORETURN, nil, nil) 2627 r.List = list(r.List, nh) 2628 fn.Nbody = list(fn.Nbody, r) 2629 2630 if Debug['r'] != 0 { 2631 dumplist("genhash body", fn.Nbody) 2632 } 2633 2634 funcbody(fn) 2635 Curfn = fn 2636 fn.Func.Dupok = true 2637 typecheck(&fn, Etop) 2638 typechecklist(fn.Nbody, Etop) 2639 Curfn = nil 2640 2641 // Disable safemode while compiling this code: the code we 2642 // generate internally can refer to unsafe.Pointer. 2643 // In this case it can happen if we need to generate an == 2644 // for a struct containing a reflect.Value, which itself has 2645 // an unexported field of type unsafe.Pointer. 2646 old_safemode := safemode 2647 2648 safemode = 0 2649 funccompile(fn) 2650 safemode = old_safemode 2651 } 2652 2653 // Return node for 2654 // if p.field != q.field { return false } 2655 func eqfield(p *Node, q *Node, field *Node) *Node { 2656 nx := Nod(OXDOT, p, field) 2657 ny := Nod(OXDOT, q, field) 2658 nif := Nod(OIF, nil, nil) 2659 nif.Left = Nod(ONE, nx, ny) 2660 r := Nod(ORETURN, nil, nil) 2661 r.List = list(r.List, Nodbool(false)) 2662 nif.Nbody = list(nif.Nbody, r) 2663 return nif 2664 } 2665 2666 func eqmemfunc(size int64, type_ *Type, needsize *int) *Node { 2667 var fn *Node 2668 2669 switch size { 2670 default: 2671 fn = syslook("memequal", 1) 2672 *needsize = 1 2673 2674 case 1, 2, 4, 8, 16: 2675 buf := fmt.Sprintf("memequal%d", int(size)*8) 2676 fn = syslook(buf, 1) 2677 *needsize = 0 2678 } 2679 2680 substArgTypes(fn, type_, type_) 2681 return fn 2682 } 2683 2684 // Return node for 2685 // if !memequal(&p.field, &q.field [, size]) { return false } 2686 func eqmem(p *Node, q *Node, field *Node, size int64) *Node { 2687 var needsize int 2688 2689 nx := Nod(OADDR, Nod(OXDOT, p, field), nil) 2690 nx.Etype = 1 // does not escape 2691 ny := Nod(OADDR, Nod(OXDOT, q, field), nil) 2692 ny.Etype = 1 // does not escape 2693 typecheck(&nx, Erv) 2694 typecheck(&ny, Erv) 2695 2696 call := Nod(OCALL, eqmemfunc(size, nx.Type.Type, &needsize), nil) 2697 call.List = list(call.List, nx) 2698 call.List = list(call.List, ny) 2699 if needsize != 0 { 2700 call.List = list(call.List, Nodintconst(size)) 2701 } 2702 2703 nif := Nod(OIF, nil, nil) 2704 nif.Left = Nod(ONOT, call, nil) 2705 r := Nod(ORETURN, nil, nil) 2706 r.List = list(r.List, Nodbool(false)) 2707 nif.Nbody = list(nif.Nbody, r) 2708 return nif 2709 } 2710 2711 // Generate a helper function to check equality of two values of type t. 2712 func geneq(sym *Sym, t *Type) { 2713 if Debug['r'] != 0 { 2714 fmt.Printf("geneq %v %v\n", sym, t) 2715 } 2716 2717 lineno = 1 // less confusing than end of input 2718 dclcontext = PEXTERN 2719 markdcl() 2720 2721 // func sym(p, q *T) bool 2722 fn := Nod(ODCLFUNC, nil, nil) 2723 2724 fn.Func.Nname = newname(sym) 2725 fn.Func.Nname.Class = PFUNC 2726 tfn := Nod(OTFUNC, nil, nil) 2727 fn.Func.Nname.Name.Param.Ntype = tfn 2728 2729 n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t))) 2730 tfn.List = list(tfn.List, n) 2731 np := n.Left 2732 n = Nod(ODCLFIELD, newname(Lookup("q")), typenod(Ptrto(t))) 2733 tfn.List = list(tfn.List, n) 2734 nq := n.Left 2735 n = Nod(ODCLFIELD, nil, typenod(Types[TBOOL])) 2736 tfn.Rlist = list(tfn.Rlist, n) 2737 2738 funchdr(fn) 2739 2740 // geneq is only called for types that have equality but 2741 // cannot be handled by the standard algorithms, 2742 // so t must be either an array or a struct. 2743 switch t.Etype { 2744 default: 2745 Fatalf("geneq %v", t) 2746 2747 case TARRAY: 2748 if Isslice(t) { 2749 Fatalf("geneq %v", t) 2750 } 2751 2752 // An array of pure memory would be handled by the 2753 // standard memequal, so the element type must not be 2754 // pure memory. Even if we unrolled the range loop, 2755 // each iteration would be a function call, so don't bother 2756 // unrolling. 2757 nrange := Nod(ORANGE, nil, Nod(OIND, np, nil)) 2758 2759 ni := newname(Lookup("i")) 2760 ni.Type = Types[TINT] 2761 nrange.List = list1(ni) 2762 nrange.Colas = true 2763 colasdefn(nrange.List, nrange) 2764 ni = nrange.List.N 2765 2766 // if p[i] != q[i] { return false } 2767 nx := Nod(OINDEX, np, ni) 2768 2769 nx.Bounded = true 2770 ny := Nod(OINDEX, nq, ni) 2771 ny.Bounded = true 2772 2773 nif := Nod(OIF, nil, nil) 2774 nif.Left = Nod(ONE, nx, ny) 2775 r := Nod(ORETURN, nil, nil) 2776 r.List = list(r.List, Nodbool(false)) 2777 nif.Nbody = list(nif.Nbody, r) 2778 nrange.Nbody = list(nrange.Nbody, nif) 2779 fn.Nbody = list(fn.Nbody, nrange) 2780 2781 // Walk the struct using memequal for runs of AMEM 2782 // and calling specific equality tests for the others. 2783 // Skip blank-named fields. 2784 case TSTRUCT: 2785 var first *Type 2786 2787 offend := int64(0) 2788 var size int64 2789 for t1 := t.Type; ; t1 = t1.Down { 2790 if t1 != nil && algtype1(t1.Type, nil) == AMEM && !isblanksym(t1.Sym) { 2791 offend = t1.Width + t1.Type.Width 2792 if first == nil { 2793 first = t1 2794 } 2795 2796 // If it's a memory field but it's padded, stop here. 2797 if ispaddedfield(t1, t.Width) { 2798 t1 = t1.Down 2799 } else { 2800 continue 2801 } 2802 } 2803 2804 // Run memequal for fields up to this one. 2805 // TODO(rsc): All the calls to newname are wrong for 2806 // cross-package unexported fields. 2807 if first != nil { 2808 if first.Down == t1 { 2809 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2810 } else if first.Down.Down == t1 { 2811 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2812 first = first.Down 2813 if !isblanksym(first.Sym) { 2814 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(first.Sym))) 2815 } 2816 } else { 2817 // More than two fields: use memequal. 2818 size = offend - first.Width // first->width is offset 2819 fn.Nbody = list(fn.Nbody, eqmem(np, nq, newname(first.Sym), size)) 2820 } 2821 2822 first = nil 2823 } 2824 2825 if t1 == nil { 2826 break 2827 } 2828 if isblanksym(t1.Sym) { 2829 continue 2830 } 2831 2832 // Check this field, which is not just memory. 2833 fn.Nbody = list(fn.Nbody, eqfield(np, nq, newname(t1.Sym))) 2834 } 2835 } 2836 2837 // return true 2838 r := Nod(ORETURN, nil, nil) 2839 2840 r.List = list(r.List, Nodbool(true)) 2841 fn.Nbody = list(fn.Nbody, r) 2842 2843 if Debug['r'] != 0 { 2844 dumplist("geneq body", fn.Nbody) 2845 } 2846 2847 funcbody(fn) 2848 Curfn = fn 2849 fn.Func.Dupok = true 2850 typecheck(&fn, Etop) 2851 typechecklist(fn.Nbody, Etop) 2852 Curfn = nil 2853 2854 // Disable safemode while compiling this code: the code we 2855 // generate internally can refer to unsafe.Pointer. 2856 // In this case it can happen if we need to generate an == 2857 // for a struct containing a reflect.Value, which itself has 2858 // an unexported field of type unsafe.Pointer. 2859 old_safemode := safemode 2860 2861 safemode = 0 2862 funccompile(fn) 2863 safemode = old_safemode 2864 } 2865 2866 func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase int) *Type { 2867 *followptr = false 2868 2869 if t == nil { 2870 return nil 2871 } 2872 2873 var m *Type 2874 var i int 2875 var c int 2876 for d := 0; d < len(dotlist); d++ { 2877 c = adddot1(s, t, d, &m, ignorecase) 2878 if c > 1 { 2879 Yyerror("%v.%v is ambiguous", t, s) 2880 return nil 2881 } 2882 2883 if c == 1 { 2884 for i = 0; i < d; i++ { 2885 if Isptr[dotlist[i].field.Type.Etype] { 2886 *followptr = true 2887 break 2888 } 2889 } 2890 2891 if m.Type.Etype != TFUNC || m.Type.Thistuple == 0 { 2892 Yyerror("%v.%v is a field, not a method", t, s) 2893 return nil 2894 } 2895 2896 return m 2897 } 2898 } 2899 2900 return nil 2901 } 2902 2903 func implements(t *Type, iface *Type, m **Type, samename **Type, ptr *int) bool { 2904 t0 := t 2905 if t == nil { 2906 return false 2907 } 2908 2909 // if this is too slow, 2910 // could sort these first 2911 // and then do one loop. 2912 2913 if t.Etype == TINTER { 2914 var tm *Type 2915 for im := iface.Type; im != nil; im = im.Down { 2916 for tm = t.Type; tm != nil; tm = tm.Down { 2917 if tm.Sym == im.Sym { 2918 if Eqtype(tm.Type, im.Type) { 2919 goto found 2920 } 2921 *m = im 2922 *samename = tm 2923 *ptr = 0 2924 return false 2925 } 2926 } 2927 2928 *m = im 2929 *samename = nil 2930 *ptr = 0 2931 return false 2932 found: 2933 } 2934 2935 return true 2936 } 2937 2938 t = methtype(t, 0) 2939 if t != nil { 2940 expandmeth(t) 2941 } 2942 var tm *Type 2943 var imtype *Type 2944 var followptr bool 2945 var rcvr *Type 2946 for im := iface.Type; im != nil; im = im.Down { 2947 if im.Broke { 2948 continue 2949 } 2950 imtype = methodfunc(im.Type, nil) 2951 tm = ifacelookdot(im.Sym, t, &followptr, 0) 2952 if tm == nil || tm.Nointerface || !Eqtype(methodfunc(tm.Type, nil), imtype) { 2953 if tm == nil { 2954 tm = ifacelookdot(im.Sym, t, &followptr, 1) 2955 } 2956 *m = im 2957 *samename = tm 2958 *ptr = 0 2959 return false 2960 } 2961 2962 // if pointer receiver in method, 2963 // the method does not exist for value types. 2964 rcvr = getthisx(tm.Type).Type.Type 2965 2966 if Isptr[rcvr.Etype] && !Isptr[t0.Etype] && !followptr && !isifacemethod(tm.Type) { 2967 if false && Debug['r'] != 0 { 2968 Yyerror("interface pointer mismatch") 2969 } 2970 2971 *m = im 2972 *samename = nil 2973 *ptr = 1 2974 return false 2975 } 2976 } 2977 2978 return true 2979 } 2980 2981 // even simpler simtype; get rid of ptr, bool. 2982 // assuming that the front end has rejected 2983 // all the invalid conversions (like ptr -> bool) 2984 func Simsimtype(t *Type) EType { 2985 if t == nil { 2986 return 0 2987 } 2988 2989 et := Simtype[t.Etype] 2990 switch et { 2991 case TPTR32: 2992 et = TUINT32 2993 2994 case TPTR64: 2995 et = TUINT64 2996 2997 case TBOOL: 2998 et = TUINT8 2999 } 3000 3001 return et 3002 } 3003 3004 func listtreecopy(l *NodeList, lineno int32) *NodeList { 3005 var out *NodeList 3006 for ; l != nil; l = l.Next { 3007 out = list(out, treecopy(l.N, lineno)) 3008 } 3009 return out 3010 } 3011 3012 func liststmt(l *NodeList) *Node { 3013 n := Nod(OBLOCK, nil, nil) 3014 n.List = l 3015 if l != nil { 3016 n.Lineno = l.N.Lineno 3017 } 3018 return n 3019 } 3020 3021 // return nelem of list 3022 func structcount(t *Type) int { 3023 var s Iter 3024 3025 v := 0 3026 for t = Structfirst(&s, &t); t != nil; t = structnext(&s) { 3027 v++ 3028 } 3029 return v 3030 } 3031 3032 // return power of 2 of the constant 3033 // operand. -1 if it is not a power of 2. 3034 // 1000+ if it is a -(power of 2) 3035 func powtwo(n *Node) int { 3036 if n == nil || n.Op != OLITERAL || n.Type == nil { 3037 return -1 3038 } 3039 if !Isint[n.Type.Etype] { 3040 return -1 3041 } 3042 3043 v := uint64(Mpgetfix(n.Val().U.(*Mpint))) 3044 b := uint64(1) 3045 for i := 0; i < 64; i++ { 3046 if b == v { 3047 return i 3048 } 3049 b = b << 1 3050 } 3051 3052 if !Issigned[n.Type.Etype] { 3053 return -1 3054 } 3055 3056 v = -v 3057 b = 1 3058 for i := 0; i < 64; i++ { 3059 if b == v { 3060 return i + 1000 3061 } 3062 b = b << 1 3063 } 3064 3065 return -1 3066 } 3067 3068 // return the unsigned type for 3069 // a signed integer type. 3070 // returns T if input is not a 3071 // signed integer type. 3072 func tounsigned(t *Type) *Type { 3073 // this is types[et+1], but not sure 3074 // that this relation is immutable 3075 switch t.Etype { 3076 default: 3077 fmt.Printf("tounsigned: unknown type %v\n", t) 3078 t = nil 3079 3080 case TINT: 3081 t = Types[TUINT] 3082 3083 case TINT8: 3084 t = Types[TUINT8] 3085 3086 case TINT16: 3087 t = Types[TUINT16] 3088 3089 case TINT32: 3090 t = Types[TUINT32] 3091 3092 case TINT64: 3093 t = Types[TUINT64] 3094 } 3095 3096 return t 3097 } 3098 3099 // magic number for signed division 3100 // see hacker's delight chapter 10 3101 func Smagic(m *Magic) { 3102 var mask uint64 3103 3104 m.Bad = 0 3105 switch m.W { 3106 default: 3107 m.Bad = 1 3108 return 3109 3110 case 8: 3111 mask = 0xff 3112 3113 case 16: 3114 mask = 0xffff 3115 3116 case 32: 3117 mask = 0xffffffff 3118 3119 case 64: 3120 mask = 0xffffffffffffffff 3121 } 3122 3123 two31 := mask ^ (mask >> 1) 3124 3125 p := m.W - 1 3126 ad := uint64(m.Sd) 3127 if m.Sd < 0 { 3128 ad = -uint64(m.Sd) 3129 } 3130 3131 // bad denominators 3132 if ad == 0 || ad == 1 || ad == two31 { 3133 m.Bad = 1 3134 return 3135 } 3136 3137 t := two31 3138 ad &= mask 3139 3140 anc := t - 1 - t%ad 3141 anc &= mask 3142 3143 q1 := two31 / anc 3144 r1 := two31 - q1*anc 3145 q1 &= mask 3146 r1 &= mask 3147 3148 q2 := two31 / ad 3149 r2 := two31 - q2*ad 3150 q2 &= mask 3151 r2 &= mask 3152 3153 var delta uint64 3154 for { 3155 p++ 3156 q1 <<= 1 3157 r1 <<= 1 3158 q1 &= mask 3159 r1 &= mask 3160 if r1 >= anc { 3161 q1++ 3162 r1 -= anc 3163 q1 &= mask 3164 r1 &= mask 3165 } 3166 3167 q2 <<= 1 3168 r2 <<= 1 3169 q2 &= mask 3170 r2 &= mask 3171 if r2 >= ad { 3172 q2++ 3173 r2 -= ad 3174 q2 &= mask 3175 r2 &= mask 3176 } 3177 3178 delta = ad - r2 3179 delta &= mask 3180 if q1 < delta || (q1 == delta && r1 == 0) { 3181 continue 3182 } 3183 3184 break 3185 } 3186 3187 m.Sm = int64(q2 + 1) 3188 if uint64(m.Sm)&two31 != 0 { 3189 m.Sm |= ^int64(mask) 3190 } 3191 m.S = p - m.W 3192 } 3193 3194 // magic number for unsigned division 3195 // see hacker's delight chapter 10 3196 func Umagic(m *Magic) { 3197 var mask uint64 3198 3199 m.Bad = 0 3200 m.Ua = 0 3201 3202 switch m.W { 3203 default: 3204 m.Bad = 1 3205 return 3206 3207 case 8: 3208 mask = 0xff 3209 3210 case 16: 3211 mask = 0xffff 3212 3213 case 32: 3214 mask = 0xffffffff 3215 3216 case 64: 3217 mask = 0xffffffffffffffff 3218 } 3219 3220 two31 := mask ^ (mask >> 1) 3221 3222 m.Ud &= mask 3223 if m.Ud == 0 || m.Ud == two31 { 3224 m.Bad = 1 3225 return 3226 } 3227 3228 nc := mask - (-m.Ud&mask)%m.Ud 3229 p := m.W - 1 3230 3231 q1 := two31 / nc 3232 r1 := two31 - q1*nc 3233 q1 &= mask 3234 r1 &= mask 3235 3236 q2 := (two31 - 1) / m.Ud 3237 r2 := (two31 - 1) - q2*m.Ud 3238 q2 &= mask 3239 r2 &= mask 3240 3241 var delta uint64 3242 for { 3243 p++ 3244 if r1 >= nc-r1 { 3245 q1 <<= 1 3246 q1++ 3247 r1 <<= 1 3248 r1 -= nc 3249 } else { 3250 q1 <<= 1 3251 r1 <<= 1 3252 } 3253 3254 q1 &= mask 3255 r1 &= mask 3256 if r2+1 >= m.Ud-r2 { 3257 if q2 >= two31-1 { 3258 m.Ua = 1 3259 } 3260 3261 q2 <<= 1 3262 q2++ 3263 r2 <<= 1 3264 r2++ 3265 r2 -= m.Ud 3266 } else { 3267 if q2 >= two31 { 3268 m.Ua = 1 3269 } 3270 3271 q2 <<= 1 3272 r2 <<= 1 3273 r2++ 3274 } 3275 3276 q2 &= mask 3277 r2 &= mask 3278 3279 delta = m.Ud - 1 - r2 3280 delta &= mask 3281 3282 if p < m.W+m.W { 3283 if q1 < delta || (q1 == delta && r1 == 0) { 3284 continue 3285 } 3286 } 3287 3288 break 3289 } 3290 3291 m.Um = q2 + 1 3292 m.S = p - m.W 3293 } 3294 3295 func ngotype(n *Node) *Sym { 3296 if n.Type != nil { 3297 return typenamesym(n.Type) 3298 } 3299 return nil 3300 } 3301 3302 // Convert raw string to the prefix that will be used in the symbol 3303 // table. All control characters, space, '%' and '"', as well as 3304 // non-7-bit clean bytes turn into %xx. The period needs escaping 3305 // only in the last segment of the path, and it makes for happier 3306 // users if we escape that as little as possible. 3307 // 3308 // If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 3309 func pathtoprefix(s string) string { 3310 slash := strings.LastIndex(s, "/") 3311 for i := 0; i < len(s); i++ { 3312 c := s[i] 3313 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 3314 var buf bytes.Buffer 3315 for i := 0; i < len(s); i++ { 3316 c := s[i] 3317 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 3318 fmt.Fprintf(&buf, "%%%02x", c) 3319 continue 3320 } 3321 buf.WriteByte(c) 3322 } 3323 return buf.String() 3324 } 3325 } 3326 return s 3327 } 3328 3329 var pkgMap = make(map[string]*Pkg) 3330 var pkgs []*Pkg 3331 3332 func mkpkg(path string) *Pkg { 3333 if p := pkgMap[path]; p != nil { 3334 return p 3335 } 3336 3337 p := new(Pkg) 3338 p.Path = path 3339 p.Prefix = pathtoprefix(path) 3340 p.Syms = make(map[string]*Sym) 3341 pkgMap[path] = p 3342 pkgs = append(pkgs, p) 3343 return p 3344 } 3345 3346 func addinit(np **Node, init *NodeList) { 3347 if init == nil { 3348 return 3349 } 3350 3351 n := *np 3352 switch n.Op { 3353 // There may be multiple refs to this node; 3354 // introduce OCONVNOP to hold init list. 3355 case ONAME, OLITERAL: 3356 n = Nod(OCONVNOP, n, nil) 3357 3358 n.Type = n.Left.Type 3359 n.Typecheck = 1 3360 *np = n 3361 } 3362 3363 n.Ninit = concat(init, n.Ninit) 3364 n.Ullman = UINF 3365 } 3366 3367 var reservedimports = []string{ 3368 "go", 3369 "type", 3370 } 3371 3372 func isbadimport(path string) bool { 3373 if strings.Contains(path, "\x00") { 3374 Yyerror("import path contains NUL") 3375 return true 3376 } 3377 3378 for _, ri := range reservedimports { 3379 if path == ri { 3380 Yyerror("import path %q is reserved and cannot be used", path) 3381 return true 3382 } 3383 } 3384 3385 for _, r := range path { 3386 if r == utf8.RuneError { 3387 Yyerror("import path contains invalid UTF-8 sequence: %q", path) 3388 return true 3389 } 3390 3391 if r < 0x20 || r == 0x7f { 3392 Yyerror("import path contains control character: %q", path) 3393 return true 3394 } 3395 3396 if r == '\\' { 3397 Yyerror("import path contains backslash; use slash: %q", path) 3398 return true 3399 } 3400 3401 if unicode.IsSpace(rune(r)) { 3402 Yyerror("import path contains space character: %q", path) 3403 return true 3404 } 3405 3406 if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) { 3407 Yyerror("import path contains invalid character '%c': %q", r, path) 3408 return true 3409 } 3410 } 3411 3412 return false 3413 } 3414 3415 func checknil(x *Node, init **NodeList) { 3416 if Isinter(x.Type) { 3417 x = Nod(OITAB, x, nil) 3418 typecheck(&x, Erv) 3419 } 3420 3421 n := Nod(OCHECKNIL, x, nil) 3422 n.Typecheck = 1 3423 *init = list(*init, n) 3424 } 3425 3426 // Can this type be stored directly in an interface word? 3427 // Yes, if the representation is a single pointer. 3428 func isdirectiface(t *Type) bool { 3429 switch t.Etype { 3430 case TPTR32, 3431 TPTR64, 3432 TCHAN, 3433 TMAP, 3434 TFUNC, 3435 TUNSAFEPTR: 3436 return true 3437 3438 // Array of 1 direct iface type can be direct. 3439 case TARRAY: 3440 return t.Bound == 1 && isdirectiface(t.Type) 3441 3442 // Struct with 1 field of direct iface type can be direct. 3443 case TSTRUCT: 3444 return t.Type != nil && t.Type.Down == nil && isdirectiface(t.Type.Type) 3445 } 3446 3447 return false 3448 } 3449 3450 // type2IET returns "T" if t is a concrete type, 3451 // "I" if t is an interface type, and "E" if t is an empty interface type. 3452 // It is used to build calls to the conv* and assert* runtime routines. 3453 func type2IET(t *Type) string { 3454 if isnilinter(t) { 3455 return "E" 3456 } 3457 if Isinter(t) { 3458 return "I" 3459 } 3460 return "T" 3461 }