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