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