github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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 "bytes" 9 "cmd/compile/internal/types" 10 "cmd/internal/obj" 11 "cmd/internal/src" 12 "fmt" 13 "strings" 14 ) 15 16 // Declaration stack & operations 17 18 var externdcl []*Node 19 20 func testdclstack() { 21 if !types.IsDclstackValid() { 22 if nerrors != 0 { 23 errorexit() 24 } 25 Fatalf("mark left on the dclstack") 26 } 27 } 28 29 // redeclare emits a diagnostic about symbol s being redeclared at pos. 30 func redeclare(pos src.XPos, s *types.Sym, where string) { 31 if !s.Lastlineno.IsKnown() { 32 pkg := s.Origpkg 33 if pkg == nil { 34 pkg = s.Pkg 35 } 36 yyerrorl(pos, "%v redeclared %s\n"+ 37 "\tprevious declaration during import %q", s, where, pkg.Path) 38 } else { 39 prevPos := s.Lastlineno 40 41 // When an import and a declaration collide in separate files, 42 // present the import as the "redeclared", because the declaration 43 // is visible where the import is, but not vice versa. 44 // See issue 4510. 45 if s.Def == nil { 46 pos, prevPos = prevPos, pos 47 } 48 49 yyerrorl(pos, "%v redeclared %s\n"+ 50 "\tprevious declaration at %v", s, where, linestr(prevPos)) 51 } 52 } 53 54 var vargen int 55 56 // declare individual names - var, typ, const 57 58 var declare_typegen int 59 60 // declare records that Node n declares symbol n.Sym in the specified 61 // declaration context. 62 func declare(n *Node, ctxt Class) { 63 if ctxt == PDISCARD { 64 return 65 } 66 67 if n.isBlank() { 68 return 69 } 70 71 if n.Name == nil { 72 // named OLITERAL needs Name; most OLITERALs don't. 73 n.Name = new(Name) 74 } 75 76 s := n.Sym 77 78 // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later. 79 if !inimport && !typecheckok && s.Pkg != localpkg { 80 yyerrorl(n.Pos, "cannot declare name %v", s) 81 } 82 83 gen := 0 84 if ctxt == PEXTERN { 85 if s.Name == "init" { 86 yyerrorl(n.Pos, "cannot declare init - must be func") 87 } 88 if s.Name == "main" && s.Pkg.Name == "main" { 89 yyerrorl(n.Pos, "cannot declare main - must be func") 90 } 91 externdcl = append(externdcl, n) 92 } else { 93 if Curfn == nil && ctxt == PAUTO { 94 lineno = n.Pos 95 Fatalf("automatic outside function") 96 } 97 if Curfn != nil { 98 Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) 99 } 100 if n.Op == OTYPE { 101 declare_typegen++ 102 gen = declare_typegen 103 } else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") { 104 vargen++ 105 gen = vargen 106 } 107 types.Pushdcl(s) 108 n.Name.Curfn = Curfn 109 } 110 111 if ctxt == PAUTO { 112 n.Xoffset = 0 113 } 114 115 if s.Block == types.Block { 116 // functype will print errors about duplicate function arguments. 117 // Don't repeat the error here. 118 if ctxt != PPARAM && ctxt != PPARAMOUT { 119 redeclare(n.Pos, s, "in this block") 120 } 121 } 122 123 s.Block = types.Block 124 s.Lastlineno = lineno 125 s.Def = asTypesNode(n) 126 n.Name.Vargen = int32(gen) 127 n.SetClass(ctxt) 128 129 autoexport(n, ctxt) 130 } 131 132 func addvar(n *Node, t *types.Type, ctxt Class) { 133 if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil { 134 Fatalf("addvar: n=%v t=%v nil", n, t) 135 } 136 137 n.Op = ONAME 138 declare(n, ctxt) 139 n.Type = t 140 } 141 142 // declare variables from grammar 143 // new_name_list (type | [type] = expr_list) 144 func variter(vl []*Node, t *Node, el []*Node) []*Node { 145 var init []*Node 146 doexpr := len(el) > 0 147 148 if len(el) == 1 && len(vl) > 1 { 149 e := el[0] 150 as2 := nod(OAS2, nil, nil) 151 as2.List.Set(vl) 152 as2.Rlist.Set1(e) 153 for _, v := range vl { 154 v.Op = ONAME 155 declare(v, dclcontext) 156 v.Name.Param.Ntype = t 157 v.Name.Defn = as2 158 if Curfn != nil { 159 init = append(init, nod(ODCL, v, nil)) 160 } 161 } 162 163 return append(init, as2) 164 } 165 166 for _, v := range vl { 167 var e *Node 168 if doexpr { 169 if len(el) == 0 { 170 yyerror("missing expression in var declaration") 171 break 172 } 173 e = el[0] 174 el = el[1:] 175 } 176 177 v.Op = ONAME 178 declare(v, dclcontext) 179 v.Name.Param.Ntype = t 180 181 if e != nil || Curfn != nil || v.isBlank() { 182 if Curfn != nil { 183 init = append(init, nod(ODCL, v, nil)) 184 } 185 e = nod(OAS, v, e) 186 init = append(init, e) 187 if e.Right != nil { 188 v.Name.Defn = e 189 } 190 } 191 } 192 193 if len(el) != 0 { 194 yyerror("extra expression in var declaration") 195 } 196 return init 197 } 198 199 // newnoname returns a new ONONAME Node associated with symbol s. 200 func newnoname(s *types.Sym) *Node { 201 if s == nil { 202 Fatalf("newnoname nil") 203 } 204 n := nod(ONONAME, nil, nil) 205 n.Sym = s 206 n.SetAddable(true) 207 n.Xoffset = 0 208 return n 209 } 210 211 // newfuncname generates a new name node for a function or method. 212 // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360. 213 func newfuncname(s *types.Sym) *Node { 214 return newfuncnamel(lineno, s) 215 } 216 217 // newfuncnamel generates a new name node for a function or method. 218 // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360. 219 func newfuncnamel(pos src.XPos, s *types.Sym) *Node { 220 n := newnamel(pos, s) 221 n.Func = new(Func) 222 n.Func.SetIsHiddenClosure(Curfn != nil) 223 return n 224 } 225 226 // this generates a new name node for a name 227 // being declared. 228 func dclname(s *types.Sym) *Node { 229 n := newname(s) 230 n.Op = ONONAME // caller will correct it 231 return n 232 } 233 234 func typenod(t *types.Type) *Node { 235 return typenodl(src.NoXPos, t) 236 } 237 238 func typenodl(pos src.XPos, t *types.Type) *Node { 239 // if we copied another type with *t = *u 240 // then t->nod might be out of date, so 241 // check t->nod->type too 242 if asNode(t.Nod) == nil || asNode(t.Nod).Type != t { 243 t.Nod = asTypesNode(nodl(pos, OTYPE, nil, nil)) 244 asNode(t.Nod).Type = t 245 asNode(t.Nod).Sym = t.Sym 246 } 247 248 return asNode(t.Nod) 249 } 250 251 func anonfield(typ *types.Type) *Node { 252 return symfield(nil, typ) 253 } 254 255 func namedfield(s string, typ *types.Type) *Node { 256 return symfield(lookup(s), typ) 257 } 258 259 func symfield(s *types.Sym, typ *types.Type) *Node { 260 n := nodSym(ODCLFIELD, nil, s) 261 n.Type = typ 262 return n 263 } 264 265 // oldname returns the Node that declares symbol s in the current scope. 266 // If no such Node currently exists, an ONONAME Node is returned instead. 267 func oldname(s *types.Sym) *Node { 268 n := asNode(s.Def) 269 if n == nil { 270 // Maybe a top-level declaration will come along later to 271 // define s. resolve will check s.Def again once all input 272 // source has been processed. 273 return newnoname(s) 274 } 275 276 if Curfn != nil && n.Op == ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn { 277 // Inner func is referring to var in outer func. 278 // 279 // TODO(rsc): If there is an outer variable x and we 280 // are parsing x := 5 inside the closure, until we get to 281 // the := it looks like a reference to the outer x so we'll 282 // make x a closure variable unnecessarily. 283 c := n.Name.Param.Innermost 284 if c == nil || c.Name.Curfn != Curfn { 285 // Do not have a closure var for the active closure yet; make one. 286 c = newname(s) 287 c.SetClass(PAUTOHEAP) 288 c.SetIsClosureVar(true) 289 c.SetIsddd(n.Isddd()) 290 c.Name.Defn = n 291 c.SetAddable(false) 292 293 // Link into list of active closure variables. 294 // Popped from list in func closurebody. 295 c.Name.Param.Outer = n.Name.Param.Innermost 296 n.Name.Param.Innermost = c 297 298 Curfn.Func.Cvars.Append(c) 299 } 300 301 // return ref to closure var, not original 302 return c 303 } 304 305 return n 306 } 307 308 // := declarations 309 func colasname(n *Node) bool { 310 switch n.Op { 311 case ONAME, 312 ONONAME, 313 OPACK, 314 OTYPE, 315 OLITERAL: 316 return n.Sym != nil 317 } 318 319 return false 320 } 321 322 func colasdefn(left []*Node, defn *Node) { 323 for _, n := range left { 324 if n.Sym != nil { 325 n.Sym.SetUniq(true) 326 } 327 } 328 329 var nnew, nerr int 330 for i, n := range left { 331 if n.isBlank() { 332 continue 333 } 334 if !colasname(n) { 335 yyerrorl(defn.Pos, "non-name %v on left side of :=", n) 336 nerr++ 337 continue 338 } 339 340 if !n.Sym.Uniq() { 341 yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym) 342 n.SetDiag(true) 343 nerr++ 344 continue 345 } 346 347 n.Sym.SetUniq(false) 348 if n.Sym.Block == types.Block { 349 continue 350 } 351 352 nnew++ 353 n = newname(n.Sym) 354 declare(n, dclcontext) 355 n.Name.Defn = defn 356 defn.Ninit.Append(nod(ODCL, n, nil)) 357 left[i] = n 358 } 359 360 if nnew == 0 && nerr == 0 { 361 yyerrorl(defn.Pos, "no new variables on left side of :=") 362 } 363 } 364 365 // declare the arguments in an 366 // interface field declaration. 367 func ifacedcl(n *Node) { 368 if n.Op != ODCLFIELD || n.Left == nil { 369 Fatalf("ifacedcl") 370 } 371 372 if n.Sym.IsBlank() { 373 yyerror("methods must have a unique non-blank name") 374 } 375 } 376 377 // declare the function proper 378 // and declare the arguments. 379 // called in extern-declaration context 380 // returns in auto-declaration context. 381 func funchdr(n *Node) { 382 // change the declaration context from extern to auto 383 if Curfn == nil && dclcontext != PEXTERN { 384 Fatalf("funchdr: dclcontext = %d", dclcontext) 385 } 386 387 dclcontext = PAUTO 388 types.Markdcl() 389 funcstack = append(funcstack, Curfn) 390 Curfn = n 391 392 if n.Func.Nname != nil { 393 funcargs(n.Func.Nname.Name.Param.Ntype) 394 } else if n.Func.Ntype != nil { 395 funcargs(n.Func.Ntype) 396 } else { 397 funcargs2(n.Type) 398 } 399 } 400 401 func funcargs(nt *Node) { 402 if nt.Op != OTFUNC { 403 Fatalf("funcargs %v", nt.Op) 404 } 405 406 // re-start the variable generation number 407 // we want to use small numbers for the return variables, 408 // so let them have the chunk starting at 1. 409 // 410 // TODO(mdempsky): This is ugly, and only necessary because 411 // esc.go uses Vargen to figure out result parameters' index 412 // within the result tuple. 413 vargen = nt.Rlist.Len() 414 415 // declare the receiver and in arguments. 416 if nt.Left != nil { 417 funcarg(nt.Left, PPARAM) 418 } 419 for _, n := range nt.List.Slice() { 420 funcarg(n, PPARAM) 421 } 422 423 oldvargen := vargen 424 vargen = 0 425 426 // declare the out arguments. 427 gen := nt.List.Len() 428 for _, n := range nt.Rlist.Slice() { 429 if n.Sym == nil { 430 // Name so that escape analysis can track it. ~r stands for 'result'. 431 n.Sym = lookupN("~r", gen) 432 gen++ 433 } 434 if n.Sym.IsBlank() { 435 // Give it a name so we can assign to it during return. ~b stands for 'blank'. 436 // The name must be different from ~r above because if you have 437 // func f() (_ int) 438 // func g() int 439 // f is allowed to use a plain 'return' with no arguments, while g is not. 440 // So the two cases must be distinguished. 441 n.Sym = lookupN("~b", gen) 442 gen++ 443 } 444 445 funcarg(n, PPARAMOUT) 446 } 447 448 vargen = oldvargen 449 } 450 451 func funcarg(n *Node, ctxt Class) { 452 if n.Op != ODCLFIELD { 453 Fatalf("funcarg %v", n.Op) 454 } 455 if n.Sym == nil { 456 return 457 } 458 459 n.Right = newnamel(n.Pos, n.Sym) 460 n.Right.Name.Param.Ntype = n.Left 461 n.Right.SetIsddd(n.Isddd()) 462 declare(n.Right, ctxt) 463 464 vargen++ 465 n.Right.Name.Vargen = int32(vargen) 466 } 467 468 // Same as funcargs, except run over an already constructed TFUNC. 469 // This happens during import, where the hidden_fndcl rule has 470 // used functype directly to parse the function's type. 471 func funcargs2(t *types.Type) { 472 if t.Etype != TFUNC { 473 Fatalf("funcargs2 %v", t) 474 } 475 476 for _, f := range t.Recvs().Fields().Slice() { 477 funcarg2(f, PPARAM) 478 } 479 for _, f := range t.Params().Fields().Slice() { 480 funcarg2(f, PPARAM) 481 } 482 for _, f := range t.Results().Fields().Slice() { 483 funcarg2(f, PPARAMOUT) 484 } 485 } 486 487 func funcarg2(f *types.Field, ctxt Class) { 488 if f.Sym == nil { 489 return 490 } 491 n := newnamel(f.Pos, f.Sym) 492 f.Nname = asTypesNode(n) 493 n.Type = f.Type 494 n.SetIsddd(f.Isddd()) 495 declare(n, ctxt) 496 } 497 498 var funcstack []*Node // stack of previous values of Curfn 499 500 // finish the body. 501 // called in auto-declaration context. 502 // returns in extern-declaration context. 503 func funcbody() { 504 // change the declaration context from auto to extern 505 if dclcontext != PAUTO { 506 Fatalf("funcbody: unexpected dclcontext %d", dclcontext) 507 } 508 types.Popdcl() 509 funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1] 510 if Curfn == nil { 511 dclcontext = PEXTERN 512 } 513 } 514 515 // structs, functions, and methods. 516 // they don't belong here, but where do they belong? 517 func checkembeddedtype(t *types.Type) { 518 if t == nil { 519 return 520 } 521 522 if t.Sym == nil && t.IsPtr() { 523 t = t.Elem() 524 if t.IsInterface() { 525 yyerror("embedded type cannot be a pointer to interface") 526 } 527 } 528 529 if t.IsPtr() || t.IsUnsafePtr() { 530 yyerror("embedded type cannot be a pointer") 531 } else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() { 532 t.ForwardType().Embedlineno = lineno 533 } 534 } 535 536 func structfield(n *Node) *types.Field { 537 lno := lineno 538 lineno = n.Pos 539 540 if n.Op != ODCLFIELD { 541 Fatalf("structfield: oops %v\n", n) 542 } 543 544 f := types.NewField() 545 f.Pos = n.Pos 546 f.Sym = n.Sym 547 548 if n.Left != nil { 549 n.Left = typecheck(n.Left, Etype) 550 n.Type = n.Left.Type 551 n.Left = nil 552 } 553 554 f.Type = n.Type 555 if f.Type == nil { 556 f.SetBroke(true) 557 } 558 559 if n.Embedded() { 560 checkembeddedtype(n.Type) 561 f.Embedded = 1 562 } else { 563 f.Embedded = 0 564 } 565 566 switch u := n.Val().U.(type) { 567 case string: 568 f.Note = u 569 default: 570 yyerror("field tag must be a string") 571 case nil: 572 // no-op 573 } 574 575 lineno = lno 576 return f 577 } 578 579 // checkdupfields emits errors for duplicately named fields or methods in 580 // a list of struct or interface types. 581 func checkdupfields(what string, ts ...*types.Type) { 582 seen := make(map[*types.Sym]bool) 583 for _, t := range ts { 584 for _, f := range t.Fields().Slice() { 585 if f.Sym == nil || f.Sym.IsBlank() { 586 continue 587 } 588 if seen[f.Sym] { 589 yyerrorl(f.Pos, "duplicate %s %s", what, f.Sym.Name) 590 continue 591 } 592 seen[f.Sym] = true 593 } 594 } 595 } 596 597 // convert a parsed id/type list into 598 // a type for struct/interface/arglist 599 func tostruct(l []*Node) *types.Type { 600 t := types.New(TSTRUCT) 601 tostruct0(t, l) 602 return t 603 } 604 605 func tostruct0(t *types.Type, l []*Node) { 606 if t == nil || !t.IsStruct() { 607 Fatalf("struct expected") 608 } 609 610 fields := make([]*types.Field, len(l)) 611 for i, n := range l { 612 f := structfield(n) 613 if f.Broke() { 614 t.SetBroke(true) 615 } 616 fields[i] = f 617 } 618 t.SetFields(fields) 619 620 checkdupfields("field", t) 621 622 if !t.Broke() { 623 checkwidth(t) 624 } 625 } 626 627 func tofunargs(l []*Node, funarg types.Funarg) *types.Type { 628 t := types.New(TSTRUCT) 629 t.StructType().Funarg = funarg 630 631 fields := make([]*types.Field, len(l)) 632 for i, n := range l { 633 f := structfield(n) 634 f.SetIsddd(n.Isddd()) 635 if n.Right != nil { 636 n.Right.Type = f.Type 637 f.Nname = asTypesNode(n.Right) 638 } 639 if f.Broke() { 640 t.SetBroke(true) 641 } 642 fields[i] = f 643 } 644 t.SetFields(fields) 645 return t 646 } 647 648 func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type { 649 t := types.New(TSTRUCT) 650 t.StructType().Funarg = funarg 651 t.SetFields(fields) 652 return t 653 } 654 655 func interfacefield(n *Node) *types.Field { 656 lno := lineno 657 lineno = n.Pos 658 659 if n.Op != ODCLFIELD { 660 Fatalf("interfacefield: oops %v\n", n) 661 } 662 663 if n.Val().Ctype() != CTxxx { 664 yyerror("interface method cannot have annotation") 665 } 666 667 // MethodSpec = MethodName Signature | InterfaceTypeName . 668 // 669 // If Sym != nil, then Sym is MethodName and Left is Signature. 670 // Otherwise, Left is InterfaceTypeName. 671 672 if n.Left != nil { 673 n.Left = typecheck(n.Left, Etype) 674 n.Type = n.Left.Type 675 n.Left = nil 676 } 677 678 f := types.NewField() 679 f.Pos = n.Pos 680 f.Sym = n.Sym 681 f.Type = n.Type 682 if f.Type == nil { 683 f.SetBroke(true) 684 } 685 686 lineno = lno 687 return f 688 } 689 690 func tointerface(l []*Node) *types.Type { 691 if len(l) == 0 { 692 return types.Types[TINTER] 693 } 694 t := types.New(TINTER) 695 tointerface0(t, l) 696 return t 697 } 698 699 func tointerface0(t *types.Type, l []*Node) { 700 if t == nil || !t.IsInterface() { 701 Fatalf("interface expected") 702 } 703 704 var fields []*types.Field 705 for _, n := range l { 706 f := interfacefield(n) 707 if f.Broke() { 708 t.SetBroke(true) 709 } 710 fields = append(fields, f) 711 } 712 t.SetInterface(fields) 713 } 714 715 func fakeRecv() *Node { 716 return anonfield(types.FakeRecvType()) 717 } 718 719 func fakeRecvField() *types.Field { 720 f := types.NewField() 721 f.Type = types.FakeRecvType() 722 return f 723 } 724 725 // isifacemethod reports whether (field) m is 726 // an interface method. Such methods have the 727 // special receiver type types.FakeRecvType(). 728 func isifacemethod(f *types.Type) bool { 729 return f.Recv().Type == types.FakeRecvType() 730 } 731 732 // turn a parsed function declaration into a type 733 func functype(this *Node, in, out []*Node) *types.Type { 734 t := types.New(TFUNC) 735 functype0(t, this, in, out) 736 return t 737 } 738 739 func functype0(t *types.Type, this *Node, in, out []*Node) { 740 if t == nil || t.Etype != TFUNC { 741 Fatalf("function type expected") 742 } 743 744 var rcvr []*Node 745 if this != nil { 746 rcvr = []*Node{this} 747 } 748 t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr) 749 t.FuncType().Params = tofunargs(in, types.FunargParams) 750 t.FuncType().Results = tofunargs(out, types.FunargResults) 751 752 checkdupfields("argument", t.Recvs(), t.Params(), t.Results()) 753 754 if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() { 755 t.SetBroke(true) 756 } 757 758 t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil 759 } 760 761 func functypefield(this *types.Field, in, out []*types.Field) *types.Type { 762 t := types.New(TFUNC) 763 functypefield0(t, this, in, out) 764 return t 765 } 766 767 func functypefield0(t *types.Type, this *types.Field, in, out []*types.Field) { 768 var rcvr []*types.Field 769 if this != nil { 770 rcvr = []*types.Field{this} 771 } 772 t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr) 773 t.FuncType().Params = tofunargsfield(in, types.FunargParams) 774 t.FuncType().Results = tofunargsfield(out, types.FunargResults) 775 776 t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil 777 } 778 779 // origSym returns the original symbol written by the user. 780 func origSym(s *types.Sym) *types.Sym { 781 if s == nil { 782 return nil 783 } 784 785 if len(s.Name) > 1 && s.Name[0] == '~' { 786 switch s.Name[1] { 787 case 'r': // originally an unnamed result 788 return nil 789 case 'b': // originally the blank identifier _ 790 // TODO(mdempsky): Does s.Pkg matter here? 791 return nblank.Sym 792 } 793 return s 794 } 795 796 if strings.HasPrefix(s.Name, ".anon") { 797 // originally an unnamed or _ name (see subr.go: structargs) 798 return nil 799 } 800 801 return s 802 } 803 804 // methodSym returns the method symbol representing a method name 805 // associated with a specific receiver type. 806 // 807 // Method symbols can be used to distinguish the same method appearing 808 // in different method sets. For example, T.M and (*T).M have distinct 809 // method symbols. 810 func methodSym(recv *types.Type, msym *types.Sym) *types.Sym { 811 return methodSymSuffix(recv, msym, "") 812 } 813 814 // methodSymSuffix is like methodsym, but allows attaching a 815 // distinguisher suffix. To avoid collisions, the suffix must not 816 // start with a letter, number, or period. 817 func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym { 818 if msym.IsBlank() { 819 Fatalf("blank method name") 820 } 821 822 rsym := recv.Sym 823 if recv.IsPtr() { 824 if rsym != nil { 825 Fatalf("declared pointer receiver type: %v", recv) 826 } 827 rsym = recv.Elem().Sym 828 } 829 830 // Find the package the receiver type appeared in. For 831 // anonymous receiver types (i.e., anonymous structs with 832 // embedded fields), use the "go" pseudo-package instead. 833 rpkg := gopkg 834 if rsym != nil { 835 rpkg = rsym.Pkg 836 } 837 838 var b bytes.Buffer 839 if recv.IsPtr() { 840 // The parentheses aren't really necessary, but 841 // they're pretty traditional at this point. 842 fmt.Fprintf(&b, "(%-S)", recv) 843 } else { 844 fmt.Fprintf(&b, "%-S", recv) 845 } 846 847 // A particular receiver type may have multiple non-exported 848 // methods with the same name. To disambiguate them, include a 849 // package qualifier for names that came from a different 850 // package than the receiver type. 851 if !types.IsExported(msym.Name) && msym.Pkg != rpkg { 852 b.WriteString(".") 853 b.WriteString(msym.Pkg.Prefix) 854 } 855 856 b.WriteString(".") 857 b.WriteString(msym.Name) 858 b.WriteString(suffix) 859 860 return rpkg.LookupBytes(b.Bytes()) 861 } 862 863 // Add a method, declared as a function. 864 // - msym is the method symbol 865 // - t is function type (with receiver) 866 // Returns a pointer to the existing or added Field; or nil if there's an error. 867 func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field { 868 if msym == nil { 869 Fatalf("no method symbol") 870 } 871 872 // get parent type sym 873 rf := t.Recv() // ptr to this structure 874 if rf == nil { 875 yyerror("missing receiver") 876 return nil 877 } 878 879 mt := methtype(rf.Type) 880 if mt == nil || mt.Sym == nil { 881 pa := rf.Type 882 t := pa 883 if t != nil && t.IsPtr() { 884 if t.Sym != nil { 885 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 886 return nil 887 } 888 t = t.Elem() 889 } 890 891 switch { 892 case t == nil || t.Broke(): 893 // rely on typecheck having complained before 894 case t.Sym == nil: 895 yyerror("invalid receiver type %v (%v is not a defined type)", pa, t) 896 case t.IsPtr(): 897 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 898 case t.IsInterface(): 899 yyerror("invalid receiver type %v (%v is an interface type)", pa, t) 900 default: 901 // Should have picked off all the reasons above, 902 // but just in case, fall back to generic error. 903 yyerror("invalid receiver type %v (%L / %L)", pa, pa, t) 904 } 905 return nil 906 } 907 908 if local && mt.Sym.Pkg != localpkg { 909 yyerror("cannot define new methods on non-local type %v", mt) 910 return nil 911 } 912 913 if msym.IsBlank() { 914 return nil 915 } 916 917 if mt.IsStruct() { 918 for _, f := range mt.Fields().Slice() { 919 if f.Sym == msym { 920 yyerror("type %v has both field and method named %v", mt, msym) 921 f.SetBroke(true) 922 return nil 923 } 924 } 925 } 926 927 for _, f := range mt.Methods().Slice() { 928 if msym.Name != f.Sym.Name { 929 continue 930 } 931 // types.Identical only checks that incoming and result parameters match, 932 // so explicitly check that the receiver parameters match too. 933 if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) { 934 yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t) 935 } 936 return f 937 } 938 939 f := types.NewField() 940 f.Pos = lineno 941 f.Sym = msym 942 f.Type = t 943 f.SetNointerface(nointerface) 944 945 mt.Methods().Append(f) 946 return f 947 } 948 949 func funcsymname(s *types.Sym) string { 950 return s.Name + "·f" 951 } 952 953 // funcsym returns s·f. 954 func funcsym(s *types.Sym) *types.Sym { 955 // funcsymsmu here serves to protect not just mutations of funcsyms (below), 956 // but also the package lookup of the func sym name, 957 // since this function gets called concurrently from the backend. 958 // There are no other concurrent package lookups in the backend, 959 // except for the types package, which is protected separately. 960 // Reusing funcsymsmu to also cover this package lookup 961 // avoids a general, broader, expensive package lookup mutex. 962 // Note makefuncsym also does package look-up of func sym names, 963 // but that it is only called serially, from the front end. 964 funcsymsmu.Lock() 965 sf, existed := s.Pkg.LookupOK(funcsymname(s)) 966 // Don't export s·f when compiling for dynamic linking. 967 // When dynamically linking, the necessary function 968 // symbols will be created explicitly with makefuncsym. 969 // See the makefuncsym comment for details. 970 if !Ctxt.Flag_dynlink && !existed { 971 funcsyms = append(funcsyms, s) 972 } 973 funcsymsmu.Unlock() 974 return sf 975 } 976 977 // makefuncsym ensures that s·f is exported. 978 // It is only used with -dynlink. 979 // When not compiling for dynamic linking, 980 // the funcsyms are created as needed by 981 // the packages that use them. 982 // Normally we emit the s·f stubs as DUPOK syms, 983 // but DUPOK doesn't work across shared library boundaries. 984 // So instead, when dynamic linking, we only create 985 // the s·f stubs in s's package. 986 func makefuncsym(s *types.Sym) { 987 if !Ctxt.Flag_dynlink { 988 Fatalf("makefuncsym dynlink") 989 } 990 if s.IsBlank() { 991 return 992 } 993 if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr" || s.Name == "getcallerpc" || s.Name == "getcallersp") { 994 // runtime.getg(), getclosureptr(), getcallerpc(), and 995 // getcallersp() are not real functions and so do not 996 // get funcsyms. 997 return 998 } 999 if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed { 1000 funcsyms = append(funcsyms, s) 1001 } 1002 } 1003 1004 // disableExport prevents sym from being included in package export 1005 // data. To be effectual, it must be called before declare. 1006 func disableExport(sym *types.Sym) { 1007 sym.SetOnExportList(true) 1008 } 1009 1010 func dclfunc(sym *types.Sym, tfn *Node) *Node { 1011 if tfn.Op != OTFUNC { 1012 Fatalf("expected OTFUNC node, got %v", tfn) 1013 } 1014 1015 fn := nod(ODCLFUNC, nil, nil) 1016 fn.Func.Nname = newfuncname(sym) 1017 fn.Func.Nname.Name.Defn = fn 1018 fn.Func.Nname.Name.Param.Ntype = tfn 1019 declare(fn.Func.Nname, PFUNC) 1020 funchdr(fn) 1021 fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype) 1022 return fn 1023 } 1024 1025 type nowritebarrierrecChecker struct { 1026 // extraCalls contains extra function calls that may not be 1027 // visible during later analysis. It maps from the ODCLFUNC of 1028 // the caller to a list of callees. 1029 extraCalls map[*Node][]nowritebarrierrecCall 1030 1031 // curfn is the current function during AST walks. 1032 curfn *Node 1033 } 1034 1035 type nowritebarrierrecCall struct { 1036 target *Node // ODCLFUNC of caller or callee 1037 lineno src.XPos // line of call 1038 } 1039 1040 type nowritebarrierrecCallSym struct { 1041 target *obj.LSym // LSym of callee 1042 lineno src.XPos // line of call 1043 } 1044 1045 // newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It 1046 // must be called before transformclosure and walk. 1047 func newNowritebarrierrecChecker() *nowritebarrierrecChecker { 1048 c := &nowritebarrierrecChecker{ 1049 extraCalls: make(map[*Node][]nowritebarrierrecCall), 1050 } 1051 1052 // Find all systemstack calls and record their targets. In 1053 // general, flow analysis can't see into systemstack, but it's 1054 // important to handle it for this check, so we model it 1055 // directly. This has to happen before transformclosure since 1056 // it's a lot harder to work out the argument after. 1057 for _, n := range xtop { 1058 if n.Op != ODCLFUNC { 1059 continue 1060 } 1061 c.curfn = n 1062 inspect(n, c.findExtraCalls) 1063 } 1064 c.curfn = nil 1065 return c 1066 } 1067 1068 func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool { 1069 if n.Op != OCALLFUNC { 1070 return true 1071 } 1072 fn := n.Left 1073 if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil { 1074 return true 1075 } 1076 if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" { 1077 return true 1078 } 1079 1080 var callee *Node 1081 arg := n.List.First() 1082 switch arg.Op { 1083 case ONAME: 1084 callee = arg.Name.Defn 1085 case OCLOSURE: 1086 callee = arg.Func.Closure 1087 default: 1088 Fatalf("expected ONAME or OCLOSURE node, got %+v", arg) 1089 } 1090 if callee.Op != ODCLFUNC { 1091 Fatalf("expected ODCLFUNC node, got %+v", callee) 1092 } 1093 c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos}) 1094 return true 1095 } 1096 1097 // recordCall records a call from ODCLFUNC node "from", to function 1098 // symbol "to" at position pos. 1099 // 1100 // This should be done as late as possible during compilation to 1101 // capture precise call graphs. The target of the call is an LSym 1102 // because that's all we know after we start SSA. 1103 // 1104 // This can be called concurrently for different from Nodes. 1105 func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) { 1106 if from.Op != ODCLFUNC { 1107 Fatalf("expected ODCLFUNC, got %v", from) 1108 } 1109 // We record this information on the *Func so this is 1110 // concurrent-safe. 1111 fn := from.Func 1112 if fn.nwbrCalls == nil { 1113 fn.nwbrCalls = new([]nowritebarrierrecCallSym) 1114 } 1115 *fn.nwbrCalls = append(*fn.nwbrCalls, nowritebarrierrecCallSym{to, pos}) 1116 } 1117 1118 func (c *nowritebarrierrecChecker) check() { 1119 // We walk the call graph as late as possible so we can 1120 // capture all calls created by lowering, but this means we 1121 // only get to see the obj.LSyms of calls. symToFunc lets us 1122 // get back to the ODCLFUNCs. 1123 symToFunc := make(map[*obj.LSym]*Node) 1124 // funcs records the back-edges of the BFS call graph walk. It 1125 // maps from the ODCLFUNC of each function that must not have 1126 // write barriers to the call that inhibits them. Functions 1127 // that are directly marked go:nowritebarrierrec are in this 1128 // map with a zero-valued nowritebarrierrecCall. This also 1129 // acts as the set of marks for the BFS of the call graph. 1130 funcs := make(map[*Node]nowritebarrierrecCall) 1131 // q is the queue of ODCLFUNC Nodes to visit in BFS order. 1132 var q nodeQueue 1133 1134 for _, n := range xtop { 1135 if n.Op != ODCLFUNC { 1136 continue 1137 } 1138 1139 symToFunc[n.Func.lsym] = n 1140 1141 // Make nowritebarrierrec functions BFS roots. 1142 if n.Func.Pragma&Nowritebarrierrec != 0 { 1143 funcs[n] = nowritebarrierrecCall{} 1144 q.pushRight(n) 1145 } 1146 // Check go:nowritebarrier functions. 1147 if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() { 1148 yyerrorl(n.Func.WBPos, "write barrier prohibited") 1149 } 1150 } 1151 1152 // Perform a BFS of the call graph from all 1153 // go:nowritebarrierrec functions. 1154 enqueue := func(src, target *Node, pos src.XPos) { 1155 if target.Func.Pragma&Yeswritebarrierrec != 0 { 1156 // Don't flow into this function. 1157 return 1158 } 1159 if _, ok := funcs[target]; ok { 1160 // Already found a path to target. 1161 return 1162 } 1163 1164 // Record the path. 1165 funcs[target] = nowritebarrierrecCall{target: src, lineno: pos} 1166 q.pushRight(target) 1167 } 1168 for !q.empty() { 1169 fn := q.popLeft() 1170 1171 // Check fn. 1172 if fn.Func.WBPos.IsKnown() { 1173 var err bytes.Buffer 1174 call := funcs[fn] 1175 for call.target != nil { 1176 fmt.Fprintf(&err, "\n\t%v: called by %v", linestr(call.lineno), call.target.Func.Nname) 1177 call = funcs[call.target] 1178 } 1179 yyerrorl(fn.Func.WBPos, "write barrier prohibited by caller; %v%s", fn.Func.Nname, err.String()) 1180 continue 1181 } 1182 1183 // Enqueue fn's calls. 1184 for _, callee := range c.extraCalls[fn] { 1185 enqueue(fn, callee.target, callee.lineno) 1186 } 1187 if fn.Func.nwbrCalls == nil { 1188 continue 1189 } 1190 for _, callee := range *fn.Func.nwbrCalls { 1191 target := symToFunc[callee.target] 1192 if target != nil { 1193 enqueue(fn, target, callee.lineno) 1194 } 1195 } 1196 } 1197 }