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