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