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