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