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