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