github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/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, lineno) 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.Class = 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.Class = 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(lineno) 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 != 0 { 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 f.Embedded = n.Embedded 597 f.Sym = asNode(f.Nname).Sym 598 } 599 600 lineno = lno 601 return f 602 } 603 604 // checkdupfields emits errors for duplicately named fields or methods in 605 // a list of struct or interface types. 606 func checkdupfields(what string, ts ...*types.Type) { 607 seen := make(map[*types.Sym]bool) 608 for _, t := range ts { 609 for _, f := range t.Fields().Slice() { 610 if f.Sym == nil || isblanksym(f.Sym) || asNode(f.Nname) == nil { 611 continue 612 } 613 if seen[f.Sym] { 614 yyerrorl(asNode(f.Nname).Pos, "duplicate %s %s", what, f.Sym.Name) 615 continue 616 } 617 seen[f.Sym] = true 618 } 619 } 620 } 621 622 // convert a parsed id/type list into 623 // a type for struct/interface/arglist 624 func tostruct(l []*Node) *types.Type { 625 t := types.New(TSTRUCT) 626 tostruct0(t, l) 627 return t 628 } 629 630 func tostruct0(t *types.Type, l []*Node) { 631 if t == nil || !t.IsStruct() { 632 Fatalf("struct expected") 633 } 634 635 fields := make([]*types.Field, len(l)) 636 for i, n := range l { 637 f := structfield(n) 638 if f.Broke() { 639 t.SetBroke(true) 640 } 641 fields[i] = f 642 } 643 t.SetFields(fields) 644 645 checkdupfields("field", t) 646 647 if !t.Broke() { 648 checkwidth(t) 649 } 650 } 651 652 func tofunargs(l []*Node, funarg types.Funarg) *types.Type { 653 t := types.New(TSTRUCT) 654 t.StructType().Funarg = funarg 655 656 fields := make([]*types.Field, len(l)) 657 for i, n := range l { 658 f := structfield(n) 659 f.Funarg = funarg 660 661 // esc.go needs to find f given a PPARAM to add the tag. 662 if n.Left != nil && n.Left.Class == PPARAM { 663 n.Left.Name.Param.Field = f 664 } 665 if f.Broke() { 666 t.SetBroke(true) 667 } 668 fields[i] = f 669 } 670 t.SetFields(fields) 671 return t 672 } 673 674 func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type { 675 t := types.New(TSTRUCT) 676 t.StructType().Funarg = funarg 677 678 for _, f := range fields { 679 f.Funarg = funarg 680 681 // esc.go needs to find f given a PPARAM to add the tag. 682 if asNode(f.Nname) != nil && asNode(f.Nname).Class == PPARAM { 683 asNode(f.Nname).Name.Param.Field = f 684 } 685 } 686 t.SetFields(fields) 687 return t 688 } 689 690 func interfacefield(n *Node) *types.Field { 691 lno := lineno 692 lineno = n.Pos 693 694 if n.Op != ODCLFIELD { 695 Fatalf("interfacefield: oops %v\n", n) 696 } 697 698 if n.Val().Ctype() != CTxxx { 699 yyerror("interface method cannot have annotation") 700 } 701 702 // MethodSpec = MethodName Signature | InterfaceTypeName . 703 // 704 // If Left != nil, then Left is MethodName and Right is Signature. 705 // Otherwise, Right is InterfaceTypeName. 706 707 if n.Right != nil { 708 n.Right = typecheck(n.Right, Etype) 709 n.Type = n.Right.Type 710 n.Right = nil 711 } 712 713 f := types.NewField() 714 if n.Left != nil { 715 f.Nname = asTypesNode(n.Left) 716 f.Sym = asNode(f.Nname).Sym 717 } else { 718 // Placeholder ONAME just to hold Pos. 719 // TODO(mdempsky): Add Pos directly to Field instead. 720 f.Nname = asTypesNode(newname(nblank.Sym)) 721 } 722 723 f.Type = n.Type 724 if f.Type == nil { 725 f.SetBroke(true) 726 } 727 728 lineno = lno 729 return f 730 } 731 732 func tointerface(l []*Node) *types.Type { 733 if len(l) == 0 { 734 return types.Types[TINTER] 735 } 736 t := types.New(TINTER) 737 tointerface0(t, l) 738 return t 739 } 740 741 func tointerface0(t *types.Type, l []*Node) *types.Type { 742 if t == nil || !t.IsInterface() { 743 Fatalf("interface expected") 744 } 745 746 var fields []*types.Field 747 for _, n := range l { 748 f := interfacefield(n) 749 if f.Broke() { 750 t.SetBroke(true) 751 } 752 fields = append(fields, f) 753 } 754 t.SetInterface(fields) 755 756 return t 757 } 758 759 func embedded(s *types.Sym, pkg *types.Pkg) *Node { 760 const ( 761 CenterDot = 0xB7 762 ) 763 // Names sometimes have disambiguation junk 764 // appended after a center dot. Discard it when 765 // making the name for the embedded struct field. 766 name := s.Name 767 768 if i := strings.Index(s.Name, string(CenterDot)); i >= 0 { 769 name = s.Name[:i] 770 } 771 772 var n *Node 773 if exportname(name) { 774 n = newname(lookup(name)) 775 } else if s.Pkg == builtinpkg { 776 // The name of embedded builtins belongs to pkg. 777 n = newname(pkg.Lookup(name)) 778 } else { 779 n = newname(s.Pkg.Lookup(name)) 780 } 781 n = nod(ODCLFIELD, n, oldname(s)) 782 n.Embedded = 1 783 return n 784 } 785 786 // thisT is the singleton type used for interface method receivers. 787 var thisT *types.Type 788 789 func fakethis() *Node { 790 if thisT == nil { 791 thisT = types.NewPtr(types.New(TSTRUCT)) 792 } 793 return anonfield(thisT) 794 } 795 796 func fakethisfield() *types.Field { 797 if thisT == nil { 798 thisT = types.NewPtr(types.New(TSTRUCT)) 799 } 800 f := types.NewField() 801 f.Type = thisT 802 return f 803 } 804 805 // Is this field a method on an interface? 806 // Those methods have thisT as the receiver. 807 // (See fakethis above.) 808 func isifacemethod(f *types.Type) bool { 809 return f.Recv().Type == thisT 810 } 811 812 // turn a parsed function declaration into a type 813 func functype(this *Node, in, out []*Node) *types.Type { 814 t := types.New(TFUNC) 815 functype0(t, this, in, out) 816 return t 817 } 818 819 func functype0(t *types.Type, this *Node, in, out []*Node) { 820 if t == nil || t.Etype != TFUNC { 821 Fatalf("function type expected") 822 } 823 824 var rcvr []*Node 825 if this != nil { 826 rcvr = []*Node{this} 827 } 828 t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr) 829 t.FuncType().Results = tofunargs(out, types.FunargResults) 830 t.FuncType().Params = tofunargs(in, types.FunargParams) 831 832 checkdupfields("argument", t.Recvs(), t.Results(), t.Params()) 833 834 if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() { 835 t.SetBroke(true) 836 } 837 838 t.FuncType().Outnamed = false 839 if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil { 840 s := out[0].Left.Orig.Sym 841 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result 842 t.FuncType().Outnamed = true 843 } 844 } 845 } 846 847 func functypefield(this *types.Field, in, out []*types.Field) *types.Type { 848 t := types.New(TFUNC) 849 functypefield0(t, this, in, out) 850 return t 851 } 852 853 func functypefield0(t *types.Type, this *types.Field, in, out []*types.Field) { 854 var rcvr []*types.Field 855 if this != nil { 856 rcvr = []*types.Field{this} 857 } 858 t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr) 859 t.FuncType().Results = tofunargsfield(out, types.FunargRcvr) 860 t.FuncType().Params = tofunargsfield(in, types.FunargRcvr) 861 862 t.FuncType().Outnamed = false 863 if len(out) > 0 && asNode(out[0].Nname) != nil && asNode(out[0].Nname).Orig != nil { 864 s := asNode(out[0].Nname).Orig.Sym 865 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result 866 t.FuncType().Outnamed = true 867 } 868 } 869 } 870 871 var methodsym_toppkg *types.Pkg 872 873 func methodsym(nsym *types.Sym, t0 *types.Type, iface bool) *types.Sym { 874 if t0 == nil { 875 Fatalf("methodsym: nil receiver type") 876 } 877 878 t := t0 879 s := t.Sym 880 if s == nil && t.IsPtr() { 881 t = t.Elem() 882 if t == nil { 883 Fatalf("methodsym: ptrto nil") 884 } 885 s = t.Sym 886 } 887 888 // if t0 == *t and t0 has a sym, 889 // we want to see *t, not t0, in the method name. 890 if t != t0 && t0.Sym != nil { 891 t0 = types.NewPtr(t) 892 } 893 894 suffix := "" 895 if iface { 896 dowidth(t0) 897 if t0.Width < int64(Widthptr) { 898 suffix = "·i" 899 } 900 } 901 902 var spkg *types.Pkg 903 if s != nil { 904 spkg = s.Pkg 905 } 906 pkgprefix := "" 907 if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) { 908 pkgprefix = "." + nsym.Pkg.Prefix 909 } 910 var p string 911 if t0.Sym == nil && t0.IsPtr() { 912 p = fmt.Sprintf("(%-S)%s.%s%s", t0, pkgprefix, nsym.Name, suffix) 913 } else { 914 p = fmt.Sprintf("%-S%s.%s%s", t0, pkgprefix, nsym.Name, suffix) 915 } 916 917 if spkg == nil { 918 if methodsym_toppkg == nil { 919 methodsym_toppkg = mkpkg("go") 920 } 921 spkg = methodsym_toppkg 922 } 923 924 return spkg.Lookup(p) 925 } 926 927 // methodname is a misnomer because this now returns a Sym, rather 928 // than an ONAME. 929 // TODO(mdempsky): Reconcile with methodsym. 930 func methodname(s *types.Sym, recv *types.Type) *types.Sym { 931 star := false 932 if recv.IsPtr() { 933 star = true 934 recv = recv.Elem() 935 } 936 937 tsym := recv.Sym 938 if tsym == nil || isblanksym(s) { 939 return s 940 } 941 942 var p string 943 if star { 944 p = fmt.Sprintf("(*%v).%v", tsym.Name, s) 945 } else { 946 p = fmt.Sprintf("%v.%v", tsym, s) 947 } 948 949 s = tsym.Pkg.Lookup(p) 950 951 return s 952 } 953 954 // Add a method, declared as a function. 955 // - msym is the method symbol 956 // - t is function type (with receiver) 957 func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) { 958 if msym == nil { 959 Fatalf("no method symbol") 960 } 961 962 // get parent type sym 963 rf := t.Recv() // ptr to this structure 964 if rf == nil { 965 yyerror("missing receiver") 966 return 967 } 968 969 mt := methtype(rf.Type) 970 if mt == nil || mt.Sym == nil { 971 pa := rf.Type 972 t := pa 973 if t != nil && t.IsPtr() { 974 if t.Sym != nil { 975 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 976 return 977 } 978 t = t.Elem() 979 } 980 981 switch { 982 case t == nil || t.Broke(): 983 // rely on typecheck having complained before 984 case t.Sym == nil: 985 yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t) 986 case t.IsPtr(): 987 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 988 case t.IsInterface(): 989 yyerror("invalid receiver type %v (%v is an interface type)", pa, t) 990 default: 991 // Should have picked off all the reasons above, 992 // but just in case, fall back to generic error. 993 yyerror("invalid receiver type %v (%L / %L)", pa, pa, t) 994 } 995 return 996 } 997 998 if local && !mt.Local() { 999 yyerror("cannot define new methods on non-local type %v", mt) 1000 return 1001 } 1002 1003 if isblanksym(msym) { 1004 return 1005 } 1006 1007 if mt.IsStruct() { 1008 for _, f := range mt.Fields().Slice() { 1009 if f.Sym == msym { 1010 yyerror("type %v has both field and method named %v", mt, msym) 1011 return 1012 } 1013 } 1014 } 1015 1016 for _, f := range mt.Methods().Slice() { 1017 if msym.Name != f.Sym.Name { 1018 continue 1019 } 1020 // eqtype only checks that incoming and result parameters match, 1021 // so explicitly check that the receiver parameters match too. 1022 if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) { 1023 yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t) 1024 } 1025 return 1026 } 1027 1028 f := types.NewField() 1029 f.Sym = msym 1030 f.Nname = asTypesNode(newname(msym)) 1031 f.Type = t 1032 f.SetNointerface(nointerface) 1033 1034 mt.Methods().Append(f) 1035 } 1036 1037 func funccompile(n *Node) { 1038 if n.Type == nil { 1039 if nerrors == 0 { 1040 Fatalf("funccompile missing type") 1041 } 1042 return 1043 } 1044 1045 // assign parameter offsets 1046 checkwidth(n.Type) 1047 1048 if Curfn != nil { 1049 Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym) 1050 } 1051 1052 dclcontext = PAUTO 1053 funcdepth = n.Func.Depth + 1 1054 compile(n) 1055 Curfn = nil 1056 funcdepth = 0 1057 dclcontext = PEXTERN 1058 } 1059 1060 func funcsymname(s *types.Sym) string { 1061 return s.Name + "·f" 1062 } 1063 1064 // funcsym returns s·f. 1065 func funcsym(s *types.Sym) *types.Sym { 1066 sf, existed := s.Pkg.LookupOK(funcsymname(s)) 1067 // Don't export s·f when compiling for dynamic linking. 1068 // When dynamically linking, the necessary function 1069 // symbols will be created explicitly with makefuncsym. 1070 // See the makefuncsym comment for details. 1071 if !Ctxt.Flag_dynlink && !existed { 1072 funcsyms = append(funcsyms, s) 1073 } 1074 return sf 1075 } 1076 1077 // makefuncsym ensures that s·f is exported. 1078 // It is only used with -dynlink. 1079 // When not compiling for dynamic linking, 1080 // the funcsyms are created as needed by 1081 // the packages that use them. 1082 // Normally we emit the s·f stubs as DUPOK syms, 1083 // but DUPOK doesn't work across shared library boundaries. 1084 // So instead, when dynamic linking, we only create 1085 // the s·f stubs in s's package. 1086 func makefuncsym(s *types.Sym) { 1087 if !Ctxt.Flag_dynlink { 1088 Fatalf("makefuncsym dynlink") 1089 } 1090 if isblanksym(s) { 1091 return 1092 } 1093 if compiling_runtime && s.Name == "getg" { 1094 // runtime.getg() is not a real function and so does 1095 // not get a funcsym. 1096 return 1097 } 1098 if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed { 1099 funcsyms = append(funcsyms, s) 1100 } 1101 } 1102 1103 func dclfunc(sym *types.Sym, tfn *Node) *Node { 1104 if tfn.Op != OTFUNC { 1105 Fatalf("expected OTFUNC node, got %v", tfn) 1106 } 1107 1108 fn := nod(ODCLFUNC, nil, nil) 1109 fn.Func.Nname = newname(sym) 1110 fn.Func.Nname.Name.Defn = fn 1111 fn.Func.Nname.Name.Param.Ntype = tfn 1112 declare(fn.Func.Nname, PFUNC) 1113 funchdr(fn) 1114 fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype) 1115 return fn 1116 } 1117 1118 type nowritebarrierrecChecker struct { 1119 curfn *Node 1120 stable bool 1121 1122 // best maps from the ODCLFUNC of each visited function that 1123 // recursively invokes a write barrier to the called function 1124 // on the shortest path to a write barrier. 1125 best map[*Node]nowritebarrierrecCall 1126 } 1127 1128 type nowritebarrierrecCall struct { 1129 target *Node 1130 depth int 1131 lineno src.XPos 1132 } 1133 1134 func checknowritebarrierrec() { 1135 c := nowritebarrierrecChecker{ 1136 best: make(map[*Node]nowritebarrierrecCall), 1137 } 1138 visitBottomUp(xtop, func(list []*Node, recursive bool) { 1139 // Functions with write barriers have depth 0. 1140 for _, n := range list { 1141 if n.Func.WBPos.IsKnown() && n.Func.Pragma&Nowritebarrier != 0 { 1142 yyerrorl(n.Func.WBPos, "write barrier prohibited") 1143 } 1144 if n.Func.WBPos.IsKnown() && n.Func.Pragma&Yeswritebarrierrec == 0 { 1145 c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBPos} 1146 } 1147 } 1148 1149 // Propagate write barrier depth up from callees. In 1150 // the recursive case, we have to update this at most 1151 // len(list) times and can stop when we an iteration 1152 // that doesn't change anything. 1153 for _ = range list { 1154 c.stable = false 1155 for _, n := range list { 1156 if n.Func.Pragma&Yeswritebarrierrec != 0 { 1157 // Don't propagate write 1158 // barrier up to a 1159 // yeswritebarrierrec function. 1160 continue 1161 } 1162 if !n.Func.WBPos.IsKnown() { 1163 c.curfn = n 1164 c.visitcodelist(n.Nbody) 1165 } 1166 } 1167 if c.stable { 1168 break 1169 } 1170 } 1171 1172 // Check nowritebarrierrec functions. 1173 for _, n := range list { 1174 if n.Func.Pragma&Nowritebarrierrec == 0 { 1175 continue 1176 } 1177 call, hasWB := c.best[n] 1178 if !hasWB { 1179 continue 1180 } 1181 1182 // Build the error message in reverse. 1183 err := "" 1184 for call.target != nil { 1185 err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err) 1186 n = call.target 1187 call = c.best[n] 1188 } 1189 err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err) 1190 yyerrorl(n.Func.WBPos, err) 1191 } 1192 }) 1193 } 1194 1195 func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) { 1196 for _, n := range l.Slice() { 1197 c.visitcode(n) 1198 } 1199 } 1200 1201 func (c *nowritebarrierrecChecker) visitcode(n *Node) { 1202 if n == nil { 1203 return 1204 } 1205 1206 if n.Op == OCALLFUNC || n.Op == OCALLMETH { 1207 c.visitcall(n) 1208 } 1209 1210 c.visitcodelist(n.Ninit) 1211 c.visitcode(n.Left) 1212 c.visitcode(n.Right) 1213 c.visitcodelist(n.List) 1214 c.visitcodelist(n.Nbody) 1215 c.visitcodelist(n.Rlist) 1216 } 1217 1218 func (c *nowritebarrierrecChecker) visitcall(n *Node) { 1219 fn := n.Left 1220 if n.Op == OCALLMETH { 1221 fn = asNode(n.Left.Sym.Def) 1222 } 1223 if fn == nil || fn.Op != ONAME || fn.Class != PFUNC || fn.Name.Defn == nil { 1224 return 1225 } 1226 defn := fn.Name.Defn 1227 1228 fnbest, ok := c.best[defn] 1229 if !ok { 1230 return 1231 } 1232 best, ok := c.best[c.curfn] 1233 if ok && fnbest.depth+1 >= best.depth { 1234 return 1235 } 1236 c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Pos} 1237 c.stable = false 1238 }