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