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