github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/dcl.go (about) 1 // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/gc/dcl.go 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package gc 8 9 import ( 10 "rsc.io/tmp/bootstrap/internal/obj" 11 "fmt" 12 "strings" 13 ) 14 15 func dflag() bool { 16 if Debug['d'] == 0 { 17 return false 18 } 19 if Debug['y'] != 0 { 20 return true 21 } 22 if incannedimport != 0 { 23 return false 24 } 25 return true 26 } 27 28 /* 29 * declaration stack & operations 30 */ 31 func dcopy(a *Sym, b *Sym) { 32 a.Pkg = b.Pkg 33 a.Name = b.Name 34 a.Def = b.Def 35 a.Block = b.Block 36 a.Lastlineno = b.Lastlineno 37 } 38 39 func push() *Sym { 40 d := new(Sym) 41 d.Lastlineno = lineno 42 d.Link = dclstack 43 dclstack = d 44 return d 45 } 46 47 func pushdcl(s *Sym) *Sym { 48 d := push() 49 dcopy(d, s) 50 if dflag() { 51 fmt.Printf("\t%v push %v %p\n", Ctxt.Line(int(lineno)), s, s.Def) 52 } 53 return d 54 } 55 56 func popdcl() { 57 var d *Sym 58 var s *Sym 59 var lno int 60 61 // if(dflag()) 62 // print("revert\n"); 63 64 for d = dclstack; d != nil; d = d.Link { 65 if d.Name == "" { 66 break 67 } 68 s = Pkglookup(d.Name, d.Pkg) 69 lno = int(s.Lastlineno) 70 dcopy(s, d) 71 d.Lastlineno = int32(lno) 72 if dflag() { 73 fmt.Printf("\t%v pop %v %p\n", Ctxt.Line(int(lineno)), s, s.Def) 74 } 75 } 76 77 if d == nil { 78 Fatal("popdcl: no mark") 79 } 80 dclstack = d.Link 81 block = d.Block 82 } 83 84 func poptodcl() { 85 // pop the old marker and push a new one 86 // (cannot reuse the existing one) 87 // because we use the markers to identify blocks 88 // for the goto restriction checks. 89 popdcl() 90 91 markdcl() 92 } 93 94 func markdcl() { 95 d := push() 96 d.Name = "" // used as a mark in fifo 97 d.Block = block 98 99 blockgen++ 100 block = blockgen 101 } 102 103 // if(dflag()) 104 // print("markdcl\n"); 105 func dumpdcl(st string) { 106 var s *Sym 107 108 i := 0 109 for d := dclstack; d != nil; d = d.Link { 110 i++ 111 fmt.Printf(" %.2d %p", i, d) 112 if d.Name == "" { 113 fmt.Printf("\n") 114 continue 115 } 116 117 fmt.Printf(" '%s'", d.Name) 118 s = Pkglookup(d.Name, d.Pkg) 119 fmt.Printf(" %v\n", s) 120 } 121 } 122 123 func testdclstack() { 124 for d := dclstack; d != nil; d = d.Link { 125 if d.Name == "" { 126 if nerrors != 0 { 127 errorexit() 128 } 129 Yyerror("mark left on the stack") 130 continue 131 } 132 } 133 } 134 135 func redeclare(s *Sym, where string) { 136 if s.Lastlineno == 0 { 137 var tmp string 138 if s.Origpkg != nil { 139 tmp = s.Origpkg.Path 140 } else { 141 tmp = s.Pkg.Path 142 } 143 pkgstr := tmp 144 Yyerror("%v redeclared %s\n"+"\tprevious declaration during import %q", s, where, pkgstr) 145 } else { 146 line1 := parserline() 147 line2 := int(s.Lastlineno) 148 149 // When an import and a declaration collide in separate files, 150 // present the import as the "redeclared", because the declaration 151 // is visible where the import is, but not vice versa. 152 // See issue 4510. 153 if s.Def == nil { 154 line2 = line1 155 line1 = int(s.Lastlineno) 156 } 157 158 yyerrorl(int(line1), "%v redeclared %s\n"+"\tprevious declaration at %v", s, where, Ctxt.Line(line2)) 159 } 160 } 161 162 var vargen int 163 164 /* 165 * declare individual names - var, typ, const 166 */ 167 168 var declare_typegen int 169 170 func declare(n *Node, ctxt uint8) { 171 if ctxt == PDISCARD { 172 return 173 } 174 175 if isblank(n) { 176 return 177 } 178 179 n.Lineno = int32(parserline()) 180 s := n.Sym 181 182 // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later. 183 if importpkg == nil && typecheckok == 0 && s.Pkg != localpkg { 184 Yyerror("cannot declare name %v", s) 185 } 186 187 if ctxt == PEXTERN && s.Name == "init" { 188 Yyerror("cannot declare init - must be func", s) 189 } 190 191 gen := 0 192 if ctxt == PEXTERN { 193 externdcl = list(externdcl, n) 194 if dflag() { 195 fmt.Printf("\t%v global decl %v %p\n", Ctxt.Line(int(lineno)), s, n) 196 } 197 } else { 198 if Curfn == nil && ctxt == PAUTO { 199 Fatal("automatic outside function") 200 } 201 if Curfn != nil { 202 Curfn.Func.Dcl = list(Curfn.Func.Dcl, n) 203 } 204 if n.Op == OTYPE { 205 declare_typegen++ 206 gen = declare_typegen 207 } else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") { 208 vargen++ 209 gen = vargen 210 } 211 pushdcl(s) 212 n.Curfn = Curfn 213 } 214 215 if ctxt == PAUTO { 216 n.Xoffset = 0 217 } 218 219 if s.Block == block { 220 // functype will print errors about duplicate function arguments. 221 // Don't repeat the error here. 222 if ctxt != PPARAM && ctxt != PPARAMOUT { 223 redeclare(s, "in this block") 224 } 225 } 226 227 s.Block = block 228 s.Lastlineno = int32(parserline()) 229 s.Def = n 230 n.Vargen = int32(gen) 231 n.Funcdepth = Funcdepth 232 n.Class = uint8(ctxt) 233 234 autoexport(n, ctxt) 235 } 236 237 func addvar(n *Node, t *Type, ctxt uint8) { 238 if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil { 239 Fatal("addvar: n=%v t=%v nil", n, t) 240 } 241 242 n.Op = ONAME 243 declare(n, ctxt) 244 n.Type = t 245 } 246 247 /* 248 * declare variables from grammar 249 * new_name_list (type | [type] = expr_list) 250 */ 251 func variter(vl *NodeList, t *Node, el *NodeList) *NodeList { 252 var init *NodeList 253 doexpr := el != nil 254 255 if count(el) == 1 && count(vl) > 1 { 256 e := el.N 257 as2 := Nod(OAS2, nil, nil) 258 as2.List = vl 259 as2.Rlist = list1(e) 260 var v *Node 261 for ; vl != nil; vl = vl.Next { 262 v = vl.N 263 v.Op = ONAME 264 declare(v, dclcontext) 265 v.Ntype = t 266 v.Defn = as2 267 if Funcdepth > 0 { 268 init = list(init, Nod(ODCL, v, nil)) 269 } 270 } 271 272 return list(init, as2) 273 } 274 275 var v *Node 276 var e *Node 277 for ; vl != nil; vl = vl.Next { 278 if doexpr { 279 if el == nil { 280 Yyerror("missing expression in var declaration") 281 break 282 } 283 284 e = el.N 285 el = el.Next 286 } else { 287 e = nil 288 } 289 290 v = vl.N 291 v.Op = ONAME 292 declare(v, dclcontext) 293 v.Ntype = t 294 295 if e != nil || Funcdepth > 0 || isblank(v) { 296 if Funcdepth > 0 { 297 init = list(init, Nod(ODCL, v, nil)) 298 } 299 e = Nod(OAS, v, e) 300 init = list(init, e) 301 if e.Right != nil { 302 v.Defn = e 303 } 304 } 305 } 306 307 if el != nil { 308 Yyerror("extra expression in var declaration") 309 } 310 return init 311 } 312 313 /* 314 * declare constants from grammar 315 * new_name_list [[type] = expr_list] 316 */ 317 func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { 318 if cl == nil { 319 if t != nil { 320 Yyerror("const declaration cannot have type without expression") 321 } 322 cl = lastconst 323 t = lasttype 324 } else { 325 lastconst = cl 326 lasttype = t 327 } 328 329 cl = listtreecopy(cl) 330 331 var v *Node 332 var c *Node 333 var vv *NodeList 334 for ; vl != nil; vl = vl.Next { 335 if cl == nil { 336 Yyerror("missing value in const declaration") 337 break 338 } 339 340 c = cl.N 341 cl = cl.Next 342 343 v = vl.N 344 v.Op = OLITERAL 345 declare(v, dclcontext) 346 347 v.Ntype = t 348 v.Defn = c 349 350 vv = list(vv, Nod(ODCLCONST, v, nil)) 351 } 352 353 if cl != nil { 354 Yyerror("extra expression in const declaration") 355 } 356 iota_ += 1 357 return vv 358 } 359 360 /* 361 * this generates a new name node, 362 * typically for labels or other one-off names. 363 */ 364 func newname(s *Sym) *Node { 365 if s == nil { 366 Fatal("newname nil") 367 } 368 369 n := Nod(ONAME, nil, nil) 370 n.Sym = s 371 n.Type = nil 372 n.Addable = true 373 n.Ullman = 1 374 n.Xoffset = 0 375 return n 376 } 377 378 // newfuncname generates a new name node for a function or method. 379 // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360. 380 func newfuncname(s *Sym) *Node { 381 n := newname(s) 382 n.Func = new(Func) 383 return n 384 } 385 386 /* 387 * this generates a new name node for a name 388 * being declared. 389 */ 390 func dclname(s *Sym) *Node { 391 n := newname(s) 392 n.Op = ONONAME // caller will correct it 393 return n 394 } 395 396 func typenod(t *Type) *Node { 397 // if we copied another type with *t = *u 398 // then t->nod might be out of date, so 399 // check t->nod->type too 400 if t.Nod == nil || t.Nod.Type != t { 401 t.Nod = Nod(OTYPE, nil, nil) 402 t.Nod.Type = t 403 t.Nod.Sym = t.Sym 404 } 405 406 return t.Nod 407 } 408 409 /* 410 * this will return an old name 411 * that has already been pushed on the 412 * declaration list. a diagnostic is 413 * generated if no name has been defined. 414 */ 415 func oldname(s *Sym) *Node { 416 n := s.Def 417 if n == nil { 418 // maybe a top-level name will come along 419 // to give this a definition later. 420 // walkdef will check s->def again once 421 // all the input source has been processed. 422 n = newname(s) 423 424 n.Op = ONONAME 425 n.Iota = iota_ // save current iota value in const declarations 426 } 427 428 if Curfn != nil && n.Funcdepth > 0 && n.Funcdepth != Funcdepth && n.Op == ONAME { 429 // inner func is referring to var in outer func. 430 // 431 // TODO(rsc): If there is an outer variable x and we 432 // are parsing x := 5 inside the closure, until we get to 433 // the := it looks like a reference to the outer x so we'll 434 // make x a closure variable unnecessarily. 435 if n.Closure == nil || n.Closure.Funcdepth != Funcdepth { 436 // create new closure var. 437 c := Nod(ONAME, nil, nil) 438 439 c.Sym = s 440 c.Class = PPARAMREF 441 c.Isddd = n.Isddd 442 c.Defn = n 443 c.Addable = false 444 c.Ullman = 2 445 c.Funcdepth = Funcdepth 446 c.Outer = n.Closure 447 n.Closure = c 448 c.Closure = n 449 c.Xoffset = 0 450 Curfn.Func.Cvars = list(Curfn.Func.Cvars, c) 451 } 452 453 // return ref to closure var, not original 454 return n.Closure 455 } 456 457 return n 458 } 459 460 /* 461 * := declarations 462 */ 463 func colasname(n *Node) bool { 464 switch n.Op { 465 case ONAME, 466 ONONAME, 467 OPACK, 468 OTYPE, 469 OLITERAL: 470 return n.Sym != nil 471 } 472 473 return false 474 } 475 476 func colasdefn(left *NodeList, defn *Node) { 477 for l := left; l != nil; l = l.Next { 478 if l.N.Sym != nil { 479 l.N.Sym.Flags |= SymUniq 480 } 481 } 482 483 nnew := 0 484 nerr := 0 485 var n *Node 486 for l := left; l != nil; l = l.Next { 487 n = l.N 488 if isblank(n) { 489 continue 490 } 491 if !colasname(n) { 492 yyerrorl(int(defn.Lineno), "non-name %v on left side of :=", n) 493 nerr++ 494 continue 495 } 496 497 if n.Sym.Flags&SymUniq == 0 { 498 yyerrorl(int(defn.Lineno), "%v repeated on left side of :=", n.Sym) 499 n.Diag++ 500 nerr++ 501 continue 502 } 503 504 n.Sym.Flags &^= SymUniq 505 if n.Sym.Block == block { 506 continue 507 } 508 509 nnew++ 510 n = newname(n.Sym) 511 declare(n, dclcontext) 512 n.Defn = defn 513 defn.Ninit = list(defn.Ninit, Nod(ODCL, n, nil)) 514 l.N = n 515 } 516 517 if nnew == 0 && nerr == 0 { 518 yyerrorl(int(defn.Lineno), "no new variables on left side of :=") 519 } 520 } 521 522 func colas(left *NodeList, right *NodeList, lno int32) *Node { 523 as := Nod(OAS2, nil, nil) 524 as.List = left 525 as.Rlist = right 526 as.Colas = true 527 as.Lineno = lno 528 colasdefn(left, as) 529 530 // make the tree prettier; not necessary 531 if count(left) == 1 && count(right) == 1 { 532 as.Left = as.List.N 533 as.Right = as.Rlist.N 534 as.List = nil 535 as.Rlist = nil 536 as.Op = OAS 537 } 538 539 return as 540 } 541 542 /* 543 * declare the arguments in an 544 * interface field declaration. 545 */ 546 func ifacedcl(n *Node) { 547 if n.Op != ODCLFIELD || n.Right == nil { 548 Fatal("ifacedcl") 549 } 550 551 if isblank(n.Left) { 552 Yyerror("methods must have a unique non-blank name") 553 } 554 555 n.Func = new(Func) 556 dclcontext = PPARAM 557 markdcl() 558 Funcdepth++ 559 n.Outer = Curfn 560 Curfn = n 561 funcargs(n.Right) 562 563 // funcbody is normally called after the parser has 564 // seen the body of a function but since an interface 565 // field declaration does not have a body, we must 566 // call it now to pop the current declaration context. 567 dclcontext = PAUTO 568 569 funcbody(n) 570 } 571 572 /* 573 * declare the function proper 574 * and declare the arguments. 575 * called in extern-declaration context 576 * returns in auto-declaration context. 577 */ 578 func funchdr(n *Node) { 579 // change the declaration context from extern to auto 580 if Funcdepth == 0 && dclcontext != PEXTERN { 581 Fatal("funchdr: dclcontext") 582 } 583 584 dclcontext = PAUTO 585 markdcl() 586 Funcdepth++ 587 588 n.Outer = Curfn 589 Curfn = n 590 591 if n.Nname != nil { 592 funcargs(n.Nname.Ntype) 593 } else if n.Ntype != nil { 594 funcargs(n.Ntype) 595 } else { 596 funcargs2(n.Type) 597 } 598 } 599 600 func funcargs(nt *Node) { 601 if nt.Op != OTFUNC { 602 Fatal("funcargs %v", Oconv(int(nt.Op), 0)) 603 } 604 605 // re-start the variable generation number 606 // we want to use small numbers for the return variables, 607 // so let them have the chunk starting at 1. 608 vargen = count(nt.Rlist) 609 610 // declare the receiver and in arguments. 611 // no n->defn because type checking of func header 612 // will not fill in the types until later 613 if nt.Left != nil { 614 n := nt.Left 615 if n.Op != ODCLFIELD { 616 Fatal("funcargs receiver %v", Oconv(int(n.Op), 0)) 617 } 618 if n.Left != nil { 619 n.Left.Op = ONAME 620 n.Left.Ntype = n.Right 621 declare(n.Left, PPARAM) 622 if dclcontext == PAUTO { 623 vargen++ 624 n.Left.Vargen = int32(vargen) 625 } 626 } 627 } 628 629 var n *Node 630 for l := nt.List; l != nil; l = l.Next { 631 n = l.N 632 if n.Op != ODCLFIELD { 633 Fatal("funcargs in %v", Oconv(int(n.Op), 0)) 634 } 635 if n.Left != nil { 636 n.Left.Op = ONAME 637 n.Left.Ntype = n.Right 638 declare(n.Left, PPARAM) 639 if dclcontext == PAUTO { 640 vargen++ 641 n.Left.Vargen = int32(vargen) 642 } 643 } 644 } 645 646 // declare the out arguments. 647 gen := count(nt.List) 648 var i int = 0 649 var nn *Node 650 for l := nt.Rlist; l != nil; l = l.Next { 651 n = l.N 652 653 if n.Op != ODCLFIELD { 654 Fatal("funcargs out %v", Oconv(int(n.Op), 0)) 655 } 656 657 if n.Left == nil { 658 // Name so that escape analysis can track it. ~r stands for 'result'. 659 n.Left = newname(Lookupf("~r%d", gen)) 660 gen++ 661 } 662 663 // TODO: n->left->missing = 1; 664 n.Left.Op = ONAME 665 666 if isblank(n.Left) { 667 // Give it a name so we can assign to it during return. ~b stands for 'blank'. 668 // The name must be different from ~r above because if you have 669 // func f() (_ int) 670 // func g() int 671 // f is allowed to use a plain 'return' with no arguments, while g is not. 672 // So the two cases must be distinguished. 673 // We do not record a pointer to the original node (n->orig). 674 // Having multiple names causes too much confusion in later passes. 675 nn = Nod(OXXX, nil, nil) 676 677 *nn = *n.Left 678 nn.Orig = nn 679 nn.Sym = Lookupf("~b%d", gen) 680 gen++ 681 n.Left = nn 682 } 683 684 n.Left.Ntype = n.Right 685 declare(n.Left, PPARAMOUT) 686 if dclcontext == PAUTO { 687 i++ 688 n.Left.Vargen = int32(i) 689 } 690 } 691 } 692 693 /* 694 * Same as funcargs, except run over an already constructed TFUNC. 695 * This happens during import, where the hidden_fndcl rule has 696 * used functype directly to parse the function's type. 697 */ 698 func funcargs2(t *Type) { 699 if t.Etype != TFUNC { 700 Fatal("funcargs2 %v", t) 701 } 702 703 if t.Thistuple != 0 { 704 var n *Node 705 for ft := getthisx(t).Type; ft != nil; ft = ft.Down { 706 if ft.Nname == nil || ft.Nname.Sym == nil { 707 continue 708 } 709 n = ft.Nname // no need for newname(ft->nname->sym) 710 n.Type = ft.Type 711 declare(n, PPARAM) 712 } 713 } 714 715 if t.Intuple != 0 { 716 var n *Node 717 for ft := getinargx(t).Type; ft != nil; ft = ft.Down { 718 if ft.Nname == nil || ft.Nname.Sym == nil { 719 continue 720 } 721 n = ft.Nname 722 n.Type = ft.Type 723 declare(n, PPARAM) 724 } 725 } 726 727 if t.Outtuple != 0 { 728 var n *Node 729 for ft := getoutargx(t).Type; ft != nil; ft = ft.Down { 730 if ft.Nname == nil || ft.Nname.Sym == nil { 731 continue 732 } 733 n = ft.Nname 734 n.Type = ft.Type 735 declare(n, PPARAMOUT) 736 } 737 } 738 } 739 740 /* 741 * finish the body. 742 * called in auto-declaration context. 743 * returns in extern-declaration context. 744 */ 745 func funcbody(n *Node) { 746 // change the declaration context from auto to extern 747 if dclcontext != PAUTO { 748 Fatal("funcbody: dclcontext") 749 } 750 popdcl() 751 Funcdepth-- 752 Curfn = n.Outer 753 n.Outer = nil 754 if Funcdepth == 0 { 755 dclcontext = PEXTERN 756 } 757 } 758 759 /* 760 * new type being defined with name s. 761 */ 762 func typedcl0(s *Sym) *Node { 763 n := newname(s) 764 n.Op = OTYPE 765 declare(n, dclcontext) 766 return n 767 } 768 769 /* 770 * node n, which was returned by typedcl0 771 * is being declared to have uncompiled type t. 772 * return the ODCLTYPE node to use. 773 */ 774 func typedcl1(n *Node, t *Node, local bool) *Node { 775 n.Ntype = t 776 n.Local = local 777 return Nod(ODCLTYPE, n, nil) 778 } 779 780 /* 781 * structs, functions, and methods. 782 * they don't belong here, but where do they belong? 783 */ 784 func checkembeddedtype(t *Type) { 785 if t == nil { 786 return 787 } 788 789 if t.Sym == nil && Isptr[t.Etype] { 790 t = t.Type 791 if t.Etype == TINTER { 792 Yyerror("embedded type cannot be a pointer to interface") 793 } 794 } 795 796 if Isptr[t.Etype] { 797 Yyerror("embedded type cannot be a pointer") 798 } else if t.Etype == TFORW && t.Embedlineno == 0 { 799 t.Embedlineno = lineno 800 } 801 } 802 803 func structfield(n *Node) *Type { 804 lno := int(lineno) 805 lineno = n.Lineno 806 807 if n.Op != ODCLFIELD { 808 Fatal("structfield: oops %v\n", n) 809 } 810 811 f := typ(TFIELD) 812 f.Isddd = n.Isddd 813 814 if n.Right != nil { 815 typecheck(&n.Right, Etype) 816 n.Type = n.Right.Type 817 if n.Left != nil { 818 n.Left.Type = n.Type 819 } 820 if n.Embedded != 0 { 821 checkembeddedtype(n.Type) 822 } 823 } 824 825 n.Right = nil 826 827 f.Type = n.Type 828 if f.Type == nil { 829 f.Broke = 1 830 } 831 832 switch n.Val.Ctype { 833 case CTSTR: 834 f.Note = new(string) 835 *f.Note = n.Val.U.Sval 836 837 default: 838 Yyerror("field annotation must be string") 839 fallthrough 840 841 case CTxxx: 842 f.Note = nil 843 } 844 845 if n.Left != nil && n.Left.Op == ONAME { 846 f.Nname = n.Left 847 f.Embedded = n.Embedded 848 f.Sym = f.Nname.Sym 849 } 850 851 lineno = int32(lno) 852 return f 853 } 854 855 var uniqgen uint32 856 857 func checkdupfields(t *Type, what string) { 858 lno := int(lineno) 859 860 for ; t != nil; t = t.Down { 861 if t.Sym != nil && t.Nname != nil && !isblank(t.Nname) { 862 if t.Sym.Uniqgen == uniqgen { 863 lineno = t.Nname.Lineno 864 Yyerror("duplicate %s %s", what, t.Sym.Name) 865 } else { 866 t.Sym.Uniqgen = uniqgen 867 } 868 } 869 } 870 871 lineno = int32(lno) 872 } 873 874 /* 875 * convert a parsed id/type list into 876 * a type for struct/interface/arglist 877 */ 878 func tostruct(l *NodeList) *Type { 879 var f *Type 880 t := typ(TSTRUCT) 881 882 for tp := &t.Type; l != nil; l = l.Next { 883 f = structfield(l.N) 884 885 *tp = f 886 tp = &f.Down 887 } 888 889 for f := t.Type; f != nil && t.Broke == 0; f = f.Down { 890 if f.Broke != 0 { 891 t.Broke = 1 892 } 893 } 894 895 uniqgen++ 896 checkdupfields(t.Type, "field") 897 898 if t.Broke == 0 { 899 checkwidth(t) 900 } 901 902 return t 903 } 904 905 func tofunargs(l *NodeList) *Type { 906 var f *Type 907 908 t := typ(TSTRUCT) 909 t.Funarg = 1 910 911 for tp := &t.Type; l != nil; l = l.Next { 912 f = structfield(l.N) 913 f.Funarg = 1 914 915 // esc.c needs to find f given a PPARAM to add the tag. 916 if l.N.Left != nil && l.N.Left.Class == PPARAM { 917 l.N.Left.Paramfld = f 918 } 919 920 *tp = f 921 tp = &f.Down 922 } 923 924 for f := t.Type; f != nil && t.Broke == 0; f = f.Down { 925 if f.Broke != 0 { 926 t.Broke = 1 927 } 928 } 929 930 return t 931 } 932 933 func interfacefield(n *Node) *Type { 934 lno := int(lineno) 935 lineno = n.Lineno 936 937 if n.Op != ODCLFIELD { 938 Fatal("interfacefield: oops %v\n", n) 939 } 940 941 if n.Val.Ctype != CTxxx { 942 Yyerror("interface method cannot have annotation") 943 } 944 945 f := typ(TFIELD) 946 f.Isddd = n.Isddd 947 948 if n.Right != nil { 949 if n.Left != nil { 950 // queue resolution of method type for later. 951 // right now all we need is the name list. 952 // avoids cycles for recursive interface types. 953 n.Type = typ(TINTERMETH) 954 955 n.Type.Nname = n.Right 956 n.Left.Type = n.Type 957 queuemethod(n) 958 959 if n.Left.Op == ONAME { 960 f.Nname = n.Left 961 f.Embedded = n.Embedded 962 f.Sym = f.Nname.Sym 963 } 964 } else { 965 typecheck(&n.Right, Etype) 966 n.Type = n.Right.Type 967 968 if n.Embedded != 0 { 969 checkembeddedtype(n.Type) 970 } 971 972 if n.Type != nil { 973 switch n.Type.Etype { 974 case TINTER: 975 break 976 977 case TFORW: 978 Yyerror("interface type loop involving %v", n.Type) 979 f.Broke = 1 980 981 default: 982 Yyerror("interface contains embedded non-interface %v", n.Type) 983 f.Broke = 1 984 } 985 } 986 } 987 } 988 989 n.Right = nil 990 991 f.Type = n.Type 992 if f.Type == nil { 993 f.Broke = 1 994 } 995 996 lineno = int32(lno) 997 return f 998 } 999 1000 func tointerface(l *NodeList) *Type { 1001 var f *Type 1002 var t1 *Type 1003 1004 t := typ(TINTER) 1005 1006 tp := &t.Type 1007 for ; l != nil; l = l.Next { 1008 f = interfacefield(l.N) 1009 1010 if l.N.Left == nil && f.Type.Etype == TINTER { 1011 // embedded interface, inline methods 1012 for t1 = f.Type.Type; t1 != nil; t1 = t1.Down { 1013 f = typ(TFIELD) 1014 f.Type = t1.Type 1015 f.Broke = t1.Broke 1016 f.Sym = t1.Sym 1017 if f.Sym != nil { 1018 f.Nname = newname(f.Sym) 1019 } 1020 *tp = f 1021 tp = &f.Down 1022 } 1023 } else { 1024 *tp = f 1025 tp = &f.Down 1026 } 1027 } 1028 1029 for f := t.Type; f != nil && t.Broke == 0; f = f.Down { 1030 if f.Broke != 0 { 1031 t.Broke = 1 1032 } 1033 } 1034 1035 uniqgen++ 1036 checkdupfields(t.Type, "method") 1037 t = sortinter(t) 1038 checkwidth(t) 1039 1040 return t 1041 } 1042 1043 func embedded(s *Sym, pkg *Pkg) *Node { 1044 const ( 1045 CenterDot = 0xB7 1046 ) 1047 // Names sometimes have disambiguation junk 1048 // appended after a center dot. Discard it when 1049 // making the name for the embedded struct field. 1050 name := s.Name 1051 1052 if i := strings.Index(s.Name, string(CenterDot)); i >= 0 { 1053 name = s.Name[:i] 1054 } 1055 1056 var n *Node 1057 if exportname(name) { 1058 n = newname(Lookup(name)) 1059 } else if s.Pkg == builtinpkg { 1060 // The name of embedded builtins belongs to pkg. 1061 n = newname(Pkglookup(name, pkg)) 1062 } else { 1063 n = newname(Pkglookup(name, s.Pkg)) 1064 } 1065 n = Nod(ODCLFIELD, n, oldname(s)) 1066 n.Embedded = 1 1067 return n 1068 } 1069 1070 /* 1071 * check that the list of declarations is either all anonymous or all named 1072 */ 1073 func findtype(l *NodeList) *Node { 1074 for ; l != nil; l = l.Next { 1075 if l.N.Op == OKEY { 1076 return l.N.Right 1077 } 1078 } 1079 return nil 1080 } 1081 1082 func checkarglist(all *NodeList, input int) *NodeList { 1083 named := 0 1084 for l := all; l != nil; l = l.Next { 1085 if l.N.Op == OKEY { 1086 named = 1 1087 break 1088 } 1089 } 1090 1091 if named != 0 { 1092 var n *Node 1093 var l *NodeList 1094 for l = all; l != nil; l = l.Next { 1095 n = l.N 1096 if n.Op != OKEY && n.Sym == nil { 1097 Yyerror("mixed named and unnamed function parameters") 1098 break 1099 } 1100 } 1101 1102 if l == nil && n != nil && n.Op != OKEY { 1103 Yyerror("final function parameter must have type") 1104 } 1105 } 1106 1107 var nextt *Node 1108 var t *Node 1109 var n *Node 1110 for l := all; l != nil; l = l.Next { 1111 // can cache result from findtype to avoid 1112 // quadratic behavior here, but unlikely to matter. 1113 n = l.N 1114 1115 if named != 0 { 1116 if n.Op == OKEY { 1117 t = n.Right 1118 n = n.Left 1119 nextt = nil 1120 } else { 1121 if nextt == nil { 1122 nextt = findtype(l) 1123 } 1124 t = nextt 1125 } 1126 } else { 1127 t = n 1128 n = nil 1129 } 1130 1131 // during import l->n->op is OKEY, but l->n->left->sym == S 1132 // means it was a '?', not that it was 1133 // a lone type This doesn't matter for the exported 1134 // declarations, which are parsed by rules that don't 1135 // use checkargs, but can happen for func literals in 1136 // the inline bodies. 1137 // TODO(rsc) this can go when typefmt case TFIELD in exportmode fmt.c prints _ instead of ? 1138 if importpkg != nil && n.Sym == nil { 1139 n = nil 1140 } 1141 1142 if n != nil && n.Sym == nil { 1143 t = n 1144 n = nil 1145 } 1146 1147 if n != nil { 1148 n = newname(n.Sym) 1149 } 1150 n = Nod(ODCLFIELD, n, t) 1151 if n.Right != nil && n.Right.Op == ODDD { 1152 if input == 0 { 1153 Yyerror("cannot use ... in output argument list") 1154 } else if l.Next != nil { 1155 Yyerror("can only use ... as final argument in list") 1156 } 1157 n.Right.Op = OTARRAY 1158 n.Right.Right = n.Right.Left 1159 n.Right.Left = nil 1160 n.Isddd = true 1161 if n.Left != nil { 1162 n.Left.Isddd = true 1163 } 1164 } 1165 1166 l.N = n 1167 } 1168 1169 return all 1170 } 1171 1172 func fakethis() *Node { 1173 n := Nod(ODCLFIELD, nil, typenod(Ptrto(typ(TSTRUCT)))) 1174 return n 1175 } 1176 1177 /* 1178 * Is this field a method on an interface? 1179 * Those methods have an anonymous 1180 * *struct{} as the receiver. 1181 * (See fakethis above.) 1182 */ 1183 func isifacemethod(f *Type) bool { 1184 rcvr := getthisx(f).Type 1185 if rcvr.Sym != nil { 1186 return false 1187 } 1188 t := rcvr.Type 1189 if !Isptr[t.Etype] { 1190 return false 1191 } 1192 t = t.Type 1193 if t.Sym != nil || t.Etype != TSTRUCT || t.Type != nil { 1194 return false 1195 } 1196 return true 1197 } 1198 1199 /* 1200 * turn a parsed function declaration 1201 * into a type 1202 */ 1203 func functype(this *Node, in *NodeList, out *NodeList) *Type { 1204 t := typ(TFUNC) 1205 1206 var rcvr *NodeList 1207 if this != nil { 1208 rcvr = list1(this) 1209 } 1210 t.Type = tofunargs(rcvr) 1211 t.Type.Down = tofunargs(out) 1212 t.Type.Down.Down = tofunargs(in) 1213 1214 uniqgen++ 1215 checkdupfields(t.Type.Type, "argument") 1216 checkdupfields(t.Type.Down.Type, "argument") 1217 checkdupfields(t.Type.Down.Down.Type, "argument") 1218 1219 if t.Type.Broke != 0 || t.Type.Down.Broke != 0 || t.Type.Down.Down.Broke != 0 { 1220 t.Broke = 1 1221 } 1222 1223 if this != nil { 1224 t.Thistuple = 1 1225 } 1226 t.Outtuple = count(out) 1227 t.Intuple = count(in) 1228 t.Outnamed = 0 1229 if t.Outtuple > 0 && out.N.Left != nil && out.N.Left.Orig != nil { 1230 s := out.N.Left.Orig.Sym 1231 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result 1232 t.Outnamed = 1 1233 } 1234 } 1235 1236 return t 1237 } 1238 1239 var methodsym_toppkg *Pkg 1240 1241 func methodsym(nsym *Sym, t0 *Type, iface int) *Sym { 1242 var s *Sym 1243 var p string 1244 var suffix string 1245 var spkg *Pkg 1246 1247 t := t0 1248 if t == nil { 1249 goto bad 1250 } 1251 s = t.Sym 1252 if s == nil && Isptr[t.Etype] { 1253 t = t.Type 1254 if t == nil { 1255 goto bad 1256 } 1257 s = t.Sym 1258 } 1259 1260 spkg = nil 1261 if s != nil { 1262 spkg = s.Pkg 1263 } 1264 1265 // if t0 == *t and t0 has a sym, 1266 // we want to see *t, not t0, in the method name. 1267 if t != t0 && t0.Sym != nil { 1268 t0 = Ptrto(t) 1269 } 1270 1271 suffix = "" 1272 if iface != 0 { 1273 dowidth(t0) 1274 if t0.Width < Types[Tptr].Width { 1275 suffix = "·i" 1276 } 1277 } 1278 1279 if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) { 1280 if t0.Sym == nil && Isptr[t0.Etype] { 1281 p = fmt.Sprintf("(%v).%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix) 1282 } else { 1283 p = fmt.Sprintf("%v.%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix) 1284 } 1285 } else { 1286 if t0.Sym == nil && Isptr[t0.Etype] { 1287 p = fmt.Sprintf("(%v).%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix) 1288 } else { 1289 p = fmt.Sprintf("%v.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix) 1290 } 1291 } 1292 1293 if spkg == nil { 1294 if methodsym_toppkg == nil { 1295 methodsym_toppkg = mkpkg("go") 1296 } 1297 spkg = methodsym_toppkg 1298 } 1299 1300 s = Pkglookup(p, spkg) 1301 1302 return s 1303 1304 bad: 1305 Yyerror("illegal receiver type: %v", t0) 1306 return nil 1307 } 1308 1309 func methodname(n *Node, t *Type) *Node { 1310 s := methodsym(n.Sym, t, 0) 1311 if s == nil { 1312 return n 1313 } 1314 return newname(s) 1315 } 1316 1317 func methodname1(n *Node, t *Node) *Node { 1318 star := "" 1319 if t.Op == OIND { 1320 star = "*" 1321 t = t.Left 1322 } 1323 1324 if t.Sym == nil || isblank(n) { 1325 return newfuncname(n.Sym) 1326 } 1327 1328 var p string 1329 if star != "" { 1330 p = fmt.Sprintf("(%s%v).%v", star, t.Sym, n.Sym) 1331 } else { 1332 p = fmt.Sprintf("%v.%v", t.Sym, n.Sym) 1333 } 1334 1335 if exportname(t.Sym.Name) { 1336 n = newfuncname(Lookup(p)) 1337 } else { 1338 n = newfuncname(Pkglookup(p, t.Sym.Pkg)) 1339 } 1340 1341 return n 1342 } 1343 1344 /* 1345 * add a method, declared as a function, 1346 * n is fieldname, pa is base type, t is function type 1347 */ 1348 func addmethod(sf *Sym, t *Type, local bool, nointerface bool) { 1349 // get field sym 1350 if sf == nil { 1351 Fatal("no method symbol") 1352 } 1353 1354 // get parent type sym 1355 pa := getthisx(t).Type // ptr to this structure 1356 if pa == nil { 1357 Yyerror("missing receiver") 1358 return 1359 } 1360 1361 pa = pa.Type 1362 f := methtype(pa, 1) 1363 if f == nil { 1364 t = pa 1365 if t == nil { // rely on typecheck having complained before 1366 return 1367 } 1368 if t != nil { 1369 if Isptr[t.Etype] { 1370 if t.Sym != nil { 1371 Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 1372 return 1373 } 1374 1375 t = t.Type 1376 } 1377 1378 if t.Broke != 0 { // rely on typecheck having complained before 1379 return 1380 } 1381 if t.Sym == nil { 1382 Yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t) 1383 return 1384 } 1385 1386 if Isptr[t.Etype] { 1387 Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 1388 return 1389 } 1390 1391 if t.Etype == TINTER { 1392 Yyerror("invalid receiver type %v (%v is an interface type)", pa, t) 1393 return 1394 } 1395 } 1396 1397 // Should have picked off all the reasons above, 1398 // but just in case, fall back to generic error. 1399 Yyerror("invalid receiver type %v (%v / %v)", pa, Tconv(pa, obj.FmtLong), Tconv(t, obj.FmtLong)) 1400 1401 return 1402 } 1403 1404 pa = f 1405 if pa.Etype == TSTRUCT { 1406 for f := pa.Type; f != nil; f = f.Down { 1407 if f.Sym == sf { 1408 Yyerror("type %v has both field and method named %v", pa, sf) 1409 return 1410 } 1411 } 1412 } 1413 1414 if local && !pa.Local { 1415 // defining method on non-local type. 1416 Yyerror("cannot define new methods on non-local type %v", pa) 1417 1418 return 1419 } 1420 1421 n := Nod(ODCLFIELD, newname(sf), nil) 1422 n.Type = t 1423 1424 var d *Type // last found 1425 for f := pa.Method; f != nil; f = f.Down { 1426 d = f 1427 if f.Etype != TFIELD { 1428 Fatal("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong)) 1429 } 1430 if sf.Name != f.Sym.Name { 1431 continue 1432 } 1433 if !Eqtype(t, f.Type) { 1434 Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", pa, sf, f.Type, t) 1435 } 1436 return 1437 } 1438 1439 f = structfield(n) 1440 f.Nointerface = nointerface 1441 1442 // during import unexported method names should be in the type's package 1443 if importpkg != nil && f.Sym != nil && !exportname(f.Sym.Name) && f.Sym.Pkg != structpkg { 1444 Fatal("imported method name %v in wrong package %s\n", Sconv(f.Sym, obj.FmtSign), structpkg.Name) 1445 } 1446 1447 if d == nil { 1448 pa.Method = f 1449 } else { 1450 d.Down = f 1451 } 1452 return 1453 } 1454 1455 func funccompile(n *Node) { 1456 Stksize = BADWIDTH 1457 Maxarg = 0 1458 1459 if n.Type == nil { 1460 if nerrors == 0 { 1461 Fatal("funccompile missing type") 1462 } 1463 return 1464 } 1465 1466 // assign parameter offsets 1467 checkwidth(n.Type) 1468 1469 if Curfn != nil { 1470 Fatal("funccompile %v inside %v", n.Nname.Sym, Curfn.Nname.Sym) 1471 } 1472 1473 Stksize = 0 1474 dclcontext = PAUTO 1475 Funcdepth = n.Funcdepth + 1 1476 compile(n) 1477 Curfn = nil 1478 Funcdepth = 0 1479 dclcontext = PEXTERN 1480 } 1481 1482 func funcsym(s *Sym) *Sym { 1483 if s.Fsym != nil { 1484 return s.Fsym 1485 } 1486 1487 s1 := Pkglookup(s.Name+"·f", s.Pkg) 1488 if s1.Def == nil { 1489 s1.Def = newfuncname(s1) 1490 s1.Def.Func.Shortname = newname(s) 1491 funcsyms = list(funcsyms, s1.Def) 1492 } 1493 s.Fsym = s1 1494 1495 return s1 1496 }