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