github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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/internal/obj" 9 "fmt" 10 "sort" 11 "strings" 12 ) 13 14 // Declaration stack & operations 15 16 var externdcl []*Node 17 18 var blockgen int32 // max block number 19 20 var block int32 // current block number 21 22 // dclstack maintains a stack of shadowed symbol declarations so that 23 // popdcl can restore their declarations when a block scope ends. 24 // The stack is maintained as a linked list, using Sym's Link field. 25 // 26 // In practice, the "stack" actually ends up forming a tree: goto and label 27 // statements record the current state of dclstack so that checkgoto can 28 // validate that a goto statement does not jump over any declarations or 29 // into a new block scope. 30 // 31 // Finally, the Syms in this list are not "real" Syms as they don't actually 32 // represent object names. Sym is just a convenient type for saving shadowed 33 // Sym definitions, and only a subset of its fields are actually used. 34 var dclstack *Sym 35 36 func dcopy(a, b *Sym) { 37 a.Pkg = b.Pkg 38 a.Name = b.Name 39 a.Def = b.Def 40 a.Block = b.Block 41 a.Lastlineno = b.Lastlineno 42 } 43 44 func push() *Sym { 45 d := new(Sym) 46 d.Lastlineno = lineno 47 d.Link = dclstack 48 dclstack = d 49 return d 50 } 51 52 // pushdcl pushes the current declaration for symbol s (if any) so that 53 // it can be shadowed by a new declaration within a nested block scope. 54 func pushdcl(s *Sym) *Sym { 55 d := push() 56 dcopy(d, s) 57 return d 58 } 59 60 // popdcl pops the innermost block scope and restores all symbol declarations 61 // to their previous state. 62 func popdcl() { 63 d := dclstack 64 for ; d != nil && d.Name != ""; d = d.Link { 65 s := Pkglookup(d.Name, d.Pkg) 66 lno := s.Lastlineno 67 dcopy(s, d) 68 d.Lastlineno = lno 69 } 70 71 if d == nil { 72 Fatalf("popdcl: no mark") 73 } 74 75 dclstack = d.Link // pop mark 76 block = d.Block 77 } 78 79 // markdcl records the start of a new block scope for declarations. 80 func markdcl() { 81 d := push() 82 d.Name = "" // used as a mark in fifo 83 d.Block = block 84 85 blockgen++ 86 block = blockgen 87 } 88 89 // keep around for debugging 90 func dumpdclstack() { 91 i := 0 92 for d := dclstack; d != nil; d = d.Link { 93 fmt.Printf("%6d %p", i, d) 94 if d.Name != "" { 95 fmt.Printf(" '%s' %v\n", d.Name, Pkglookup(d.Name, d.Pkg)) 96 } else { 97 fmt.Printf(" ---\n") 98 } 99 i++ 100 } 101 } 102 103 func testdclstack() { 104 for d := dclstack; d != nil; d = d.Link { 105 if d.Name == "" { 106 if nerrors != 0 { 107 errorexit() 108 } 109 yyerror("mark left on the stack") 110 } 111 } 112 } 113 114 // redeclare emits a diagnostic about symbol s being redeclared somewhere. 115 func redeclare(s *Sym, where string) { 116 if s.Lastlineno == 0 { 117 var tmp string 118 if s.Origpkg != nil { 119 tmp = s.Origpkg.Path 120 } else { 121 tmp = s.Pkg.Path 122 } 123 pkgstr := tmp 124 yyerror("%v redeclared %s\n"+ 125 "\tprevious declaration during import %q", s, where, pkgstr) 126 } else { 127 line1 := lineno 128 line2 := s.Lastlineno 129 130 // When an import and a declaration collide in separate files, 131 // present the import as the "redeclared", because the declaration 132 // is visible where the import is, but not vice versa. 133 // See issue 4510. 134 if s.Def == nil { 135 line2 = line1 136 line1 = s.Lastlineno 137 } 138 139 yyerrorl(line1, "%v redeclared %s\n"+ 140 "\tprevious declaration at %v", s, where, linestr(line2)) 141 } 142 } 143 144 var vargen int 145 146 // declare individual names - var, typ, const 147 148 var declare_typegen int 149 150 // declare records that Node n declares symbol n.Sym in the specified 151 // declaration context. 152 func declare(n *Node, ctxt Class) { 153 if ctxt == PDISCARD { 154 return 155 } 156 157 if isblank(n) { 158 return 159 } 160 161 if n.Name == nil { 162 // named OLITERAL needs Name; most OLITERALs don't. 163 n.Name = new(Name) 164 } 165 n.Lineno = lineno 166 s := n.Sym 167 168 // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later. 169 if importpkg == nil && !typecheckok && s.Pkg != localpkg { 170 yyerror("cannot declare name %v", s) 171 } 172 173 if ctxt == PEXTERN && s.Name == "init" { 174 yyerror("cannot declare init - must be func") 175 } 176 177 gen := 0 178 if ctxt == PEXTERN { 179 externdcl = append(externdcl, n) 180 } else { 181 if Curfn == nil && ctxt == PAUTO { 182 Fatalf("automatic outside function") 183 } 184 if Curfn != nil { 185 Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) 186 } 187 if n.Op == OTYPE { 188 declare_typegen++ 189 gen = declare_typegen 190 } else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") { 191 vargen++ 192 gen = vargen 193 } 194 pushdcl(s) 195 n.Name.Curfn = Curfn 196 } 197 198 if ctxt == PAUTO { 199 n.Xoffset = 0 200 } 201 202 if s.Block == block { 203 // functype will print errors about duplicate function arguments. 204 // Don't repeat the error here. 205 if ctxt != PPARAM && ctxt != PPARAMOUT { 206 redeclare(s, "in this block") 207 } 208 } 209 210 s.Block = block 211 s.Lastlineno = lineno 212 s.Def = n 213 n.Name.Vargen = int32(gen) 214 n.Name.Funcdepth = funcdepth 215 n.Class = ctxt 216 217 autoexport(n, ctxt) 218 } 219 220 func addvar(n *Node, t *Type, ctxt Class) { 221 if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil { 222 Fatalf("addvar: n=%v t=%v nil", n, t) 223 } 224 225 n.Op = ONAME 226 declare(n, ctxt) 227 n.Type = t 228 } 229 230 // declare variables from grammar 231 // new_name_list (type | [type] = expr_list) 232 func variter(vl []*Node, t *Node, el []*Node) []*Node { 233 var init []*Node 234 doexpr := len(el) > 0 235 236 if len(el) == 1 && len(vl) > 1 { 237 e := el[0] 238 as2 := nod(OAS2, nil, nil) 239 as2.List.Set(vl) 240 as2.Rlist.Set1(e) 241 for _, v := range vl { 242 v.Op = ONAME 243 declare(v, dclcontext) 244 v.Name.Param.Ntype = t 245 v.Name.Defn = as2 246 if funcdepth > 0 { 247 init = append(init, nod(ODCL, v, nil)) 248 } 249 } 250 251 return append(init, as2) 252 } 253 254 for _, v := range vl { 255 var e *Node 256 if doexpr { 257 if len(el) == 0 { 258 yyerror("missing expression in var declaration") 259 break 260 } 261 e = el[0] 262 el = el[1:] 263 } 264 265 v.Op = ONAME 266 declare(v, dclcontext) 267 v.Name.Param.Ntype = t 268 269 if e != nil || funcdepth > 0 || isblank(v) { 270 if funcdepth > 0 { 271 init = append(init, nod(ODCL, v, nil)) 272 } 273 e = nod(OAS, v, e) 274 init = append(init, e) 275 if e.Right != nil { 276 v.Name.Defn = e 277 } 278 } 279 } 280 281 if len(el) != 0 { 282 yyerror("extra expression in var declaration") 283 } 284 return init 285 } 286 287 // declare constants from grammar 288 // new_name_list [[type] = expr_list] 289 func constiter(vl []*Node, t *Node, cl []*Node) []*Node { 290 lno := int32(0) // default is to leave line number alone in listtreecopy 291 if len(cl) == 0 { 292 if t != nil { 293 yyerror("const declaration cannot have type without expression") 294 } 295 cl = lastconst 296 t = lasttype 297 lno = vl[0].Lineno 298 } else { 299 lastconst = cl 300 lasttype = t 301 } 302 clcopy := listtreecopy(cl, lno) 303 304 var vv []*Node 305 for _, v := range vl { 306 if len(clcopy) == 0 { 307 yyerror("missing value in const declaration") 308 break 309 } 310 311 c := clcopy[0] 312 clcopy = clcopy[1:] 313 314 v.Op = OLITERAL 315 declare(v, dclcontext) 316 317 v.Name.Param.Ntype = t 318 v.Name.Defn = c 319 320 vv = append(vv, nod(ODCLCONST, v, nil)) 321 } 322 323 if len(clcopy) != 0 { 324 yyerror("extra expression in const declaration") 325 } 326 iota_ += 1 327 return vv 328 } 329 330 // newname returns a new ONAME Node associated with symbol s. 331 func newname(s *Sym) *Node { 332 if s == nil { 333 Fatalf("newname nil") 334 } 335 n := nod(ONAME, nil, nil) 336 n.Sym = s 337 n.Addable = true 338 n.Ullman = 1 339 n.Xoffset = 0 340 return n 341 } 342 343 // newnoname returns a new ONONAME Node associated with symbol s. 344 func newnoname(s *Sym) *Node { 345 if s == nil { 346 Fatalf("newnoname nil") 347 } 348 n := nod(ONONAME, nil, nil) 349 n.Sym = s 350 n.Addable = true 351 n.Ullman = 1 352 n.Xoffset = 0 353 return n 354 } 355 356 // newfuncname generates a new name node for a function or method. 357 // TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360. 358 func newfuncname(s *Sym) *Node { 359 n := newname(s) 360 n.Func = new(Func) 361 n.Func.IsHiddenClosure = Curfn != nil 362 return n 363 } 364 365 // this generates a new name node for a name 366 // being declared. 367 func dclname(s *Sym) *Node { 368 n := newname(s) 369 n.Op = ONONAME // caller will correct it 370 return n 371 } 372 373 func typenod(t *Type) *Node { 374 // if we copied another type with *t = *u 375 // then t->nod might be out of date, so 376 // check t->nod->type too 377 if t.nod == nil || t.nod.Type != t { 378 t.nod = nod(OTYPE, nil, nil) 379 t.nod.Type = t 380 t.nod.Sym = t.Sym 381 } 382 383 return t.nod 384 } 385 386 func anonfield(typ *Type) *Node { 387 return nod(ODCLFIELD, nil, typenod(typ)) 388 } 389 390 func namedfield(s string, typ *Type) *Node { 391 return nod(ODCLFIELD, newname(lookup(s)), typenod(typ)) 392 } 393 394 // oldname returns the Node that declares symbol s in the current scope. 395 // If no such Node currently exists, an ONONAME Node is returned instead. 396 func oldname(s *Sym) *Node { 397 n := s.Def 398 if n == nil { 399 // Maybe a top-level declaration will come along later to 400 // define s. resolve will check s.Def again once all input 401 // source has been processed. 402 n = newnoname(s) 403 n.SetIota(iota_) // save current iota value in const declarations 404 return n 405 } 406 407 if Curfn != nil && n.Op == ONAME && n.Name.Funcdepth > 0 && n.Name.Funcdepth != funcdepth { 408 // Inner func is referring to var in outer func. 409 // 410 // TODO(rsc): If there is an outer variable x and we 411 // are parsing x := 5 inside the closure, until we get to 412 // the := it looks like a reference to the outer x so we'll 413 // make x a closure variable unnecessarily. 414 c := n.Name.Param.Innermost 415 if c == nil || c.Name.Funcdepth != funcdepth { 416 // Do not have a closure var for the active closure yet; make one. 417 c = nod(ONAME, nil, nil) 418 c.Sym = s 419 c.Class = PAUTOHEAP 420 c.setIsClosureVar(true) 421 c.Isddd = n.Isddd 422 c.Name.Defn = n 423 c.Addable = false 424 c.Ullman = 2 425 c.Name.Funcdepth = funcdepth 426 427 // Link into list of active closure variables. 428 // Popped from list in func closurebody. 429 c.Name.Param.Outer = n.Name.Param.Innermost 430 n.Name.Param.Innermost = c 431 432 c.Xoffset = 0 433 Curfn.Func.Cvars.Append(c) 434 } 435 436 // return ref to closure var, not original 437 return c 438 } 439 440 return n 441 } 442 443 // := declarations 444 func colasname(n *Node) bool { 445 switch n.Op { 446 case ONAME, 447 ONONAME, 448 OPACK, 449 OTYPE, 450 OLITERAL: 451 return n.Sym != nil 452 } 453 454 return false 455 } 456 457 func colasdefn(left []*Node, defn *Node) { 458 for _, n := range left { 459 if n.Sym != nil { 460 n.Sym.Flags |= SymUniq 461 } 462 } 463 464 var nnew, nerr int 465 for i, n := range left { 466 if isblank(n) { 467 continue 468 } 469 if !colasname(n) { 470 yyerrorl(defn.Lineno, "non-name %v on left side of :=", n) 471 nerr++ 472 continue 473 } 474 475 if n.Sym.Flags&SymUniq == 0 { 476 yyerrorl(defn.Lineno, "%v repeated on left side of :=", n.Sym) 477 n.Diag = true 478 nerr++ 479 continue 480 } 481 482 n.Sym.Flags &^= SymUniq 483 if n.Sym.Block == block { 484 continue 485 } 486 487 nnew++ 488 n = newname(n.Sym) 489 declare(n, dclcontext) 490 n.Name.Defn = defn 491 defn.Ninit.Append(nod(ODCL, n, nil)) 492 left[i] = n 493 } 494 495 if nnew == 0 && nerr == 0 { 496 yyerrorl(defn.Lineno, "no new variables on left side of :=") 497 } 498 } 499 500 // declare the arguments in an 501 // interface field declaration. 502 func ifacedcl(n *Node) { 503 if n.Op != ODCLFIELD || n.Right == nil { 504 Fatalf("ifacedcl") 505 } 506 507 if isblank(n.Left) { 508 yyerror("methods must have a unique non-blank name") 509 } 510 } 511 512 // declare the function proper 513 // and declare the arguments. 514 // called in extern-declaration context 515 // returns in auto-declaration context. 516 func funchdr(n *Node) { 517 // change the declaration context from extern to auto 518 if funcdepth == 0 && dclcontext != PEXTERN { 519 Fatalf("funchdr: dclcontext = %d", dclcontext) 520 } 521 522 if Ctxt.Flag_dynlink && importpkg == nil && n.Func.Nname != nil { 523 makefuncsym(n.Func.Nname.Sym) 524 } 525 526 dclcontext = PAUTO 527 funcstart(n) 528 529 if n.Func.Nname != nil { 530 funcargs(n.Func.Nname.Name.Param.Ntype) 531 } else if n.Func.Ntype != nil { 532 funcargs(n.Func.Ntype) 533 } else { 534 funcargs2(n.Type) 535 } 536 } 537 538 func funcargs(nt *Node) { 539 if nt.Op != OTFUNC { 540 Fatalf("funcargs %v", nt.Op) 541 } 542 543 // re-start the variable generation number 544 // we want to use small numbers for the return variables, 545 // so let them have the chunk starting at 1. 546 vargen = nt.Rlist.Len() 547 548 // declare the receiver and in arguments. 549 // no n->defn because type checking of func header 550 // will not fill in the types until later 551 if nt.Left != nil { 552 n := nt.Left 553 if n.Op != ODCLFIELD { 554 Fatalf("funcargs receiver %v", n.Op) 555 } 556 if n.Left != nil { 557 n.Left.Op = ONAME 558 n.Left.Name.Param.Ntype = n.Right 559 declare(n.Left, PPARAM) 560 if dclcontext == PAUTO { 561 vargen++ 562 n.Left.Name.Vargen = int32(vargen) 563 } 564 } 565 } 566 567 for _, n := range nt.List.Slice() { 568 if n.Op != ODCLFIELD { 569 Fatalf("funcargs in %v", n.Op) 570 } 571 if n.Left != nil { 572 n.Left.Op = ONAME 573 n.Left.Name.Param.Ntype = n.Right 574 declare(n.Left, PPARAM) 575 if dclcontext == PAUTO { 576 vargen++ 577 n.Left.Name.Vargen = int32(vargen) 578 } 579 } 580 } 581 582 // declare the out arguments. 583 gen := nt.List.Len() 584 var i int = 0 585 for _, n := range nt.Rlist.Slice() { 586 if n.Op != ODCLFIELD { 587 Fatalf("funcargs out %v", n.Op) 588 } 589 590 if n.Left == nil { 591 // Name so that escape analysis can track it. ~r stands for 'result'. 592 n.Left = newname(lookupN("~r", gen)) 593 gen++ 594 } 595 596 // TODO: n->left->missing = 1; 597 n.Left.Op = ONAME 598 599 if isblank(n.Left) { 600 // Give it a name so we can assign to it during return. ~b stands for 'blank'. 601 // The name must be different from ~r above because if you have 602 // func f() (_ int) 603 // func g() int 604 // f is allowed to use a plain 'return' with no arguments, while g is not. 605 // So the two cases must be distinguished. 606 // We do not record a pointer to the original node (n->orig). 607 // Having multiple names causes too much confusion in later passes. 608 nn := *n.Left 609 nn.Orig = &nn 610 nn.Sym = lookupN("~b", gen) 611 gen++ 612 n.Left = &nn 613 } 614 615 n.Left.Name.Param.Ntype = n.Right 616 declare(n.Left, PPARAMOUT) 617 if dclcontext == PAUTO { 618 i++ 619 n.Left.Name.Vargen = int32(i) 620 } 621 } 622 } 623 624 // Same as funcargs, except run over an already constructed TFUNC. 625 // This happens during import, where the hidden_fndcl rule has 626 // used functype directly to parse the function's type. 627 func funcargs2(t *Type) { 628 if t.Etype != TFUNC { 629 Fatalf("funcargs2 %v", t) 630 } 631 632 for _, ft := range t.Recvs().Fields().Slice() { 633 if ft.Nname == nil || ft.Nname.Sym == nil { 634 continue 635 } 636 n := ft.Nname // no need for newname(ft->nname->sym) 637 n.Type = ft.Type 638 declare(n, PPARAM) 639 } 640 641 for _, ft := range t.Params().Fields().Slice() { 642 if ft.Nname == nil || ft.Nname.Sym == nil { 643 continue 644 } 645 n := ft.Nname 646 n.Type = ft.Type 647 declare(n, PPARAM) 648 } 649 650 for _, ft := range t.Results().Fields().Slice() { 651 if ft.Nname == nil || ft.Nname.Sym == nil { 652 continue 653 } 654 n := ft.Nname 655 n.Type = ft.Type 656 declare(n, PPARAMOUT) 657 } 658 } 659 660 var funcstack []*Node // stack of previous values of Curfn 661 var funcdepth int32 // len(funcstack) during parsing, but then forced to be the same later during compilation 662 663 // start the function. 664 // called before funcargs; undone at end of funcbody. 665 func funcstart(n *Node) { 666 markdcl() 667 funcstack = append(funcstack, Curfn) 668 funcdepth++ 669 Curfn = n 670 } 671 672 // finish the body. 673 // called in auto-declaration context. 674 // returns in extern-declaration context. 675 func funcbody(n *Node) { 676 // change the declaration context from auto to extern 677 if dclcontext != PAUTO { 678 Fatalf("funcbody: unexpected dclcontext %d", dclcontext) 679 } 680 popdcl() 681 funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1] 682 funcdepth-- 683 if funcdepth == 0 { 684 dclcontext = PEXTERN 685 } 686 } 687 688 // new type being defined with name s. 689 func typedcl0(s *Sym) *Node { 690 n := newname(s) 691 n.Op = OTYPE 692 declare(n, dclcontext) 693 return n 694 } 695 696 // node n, which was returned by typedcl0 697 // is being declared to have uncompiled type t. 698 // return the ODCLTYPE node to use. 699 func typedcl1(n *Node, t *Node, local bool) *Node { 700 n.Name.Param.Ntype = t 701 n.Local = local 702 return nod(ODCLTYPE, n, nil) 703 } 704 705 // structs, functions, and methods. 706 // they don't belong here, but where do they belong? 707 func checkembeddedtype(t *Type) { 708 if t == nil { 709 return 710 } 711 712 if t.Sym == nil && t.IsPtr() { 713 t = t.Elem() 714 if t.IsInterface() { 715 yyerror("embedded type cannot be a pointer to interface") 716 } 717 } 718 719 if t.IsPtr() || t.IsUnsafePtr() { 720 yyerror("embedded type cannot be a pointer") 721 } else if t.Etype == TFORW && t.ForwardType().Embedlineno == 0 { 722 t.ForwardType().Embedlineno = lineno 723 } 724 } 725 726 func structfield(n *Node) *Field { 727 lno := lineno 728 lineno = n.Lineno 729 730 if n.Op != ODCLFIELD { 731 Fatalf("structfield: oops %v\n", n) 732 } 733 734 f := newField() 735 f.Isddd = n.Isddd 736 737 if n.Right != nil { 738 n.Right = typecheck(n.Right, Etype) 739 n.Type = n.Right.Type 740 if n.Left != nil { 741 n.Left.Type = n.Type 742 } 743 if n.Embedded != 0 { 744 checkembeddedtype(n.Type) 745 } 746 } 747 748 n.Right = nil 749 750 f.Type = n.Type 751 if f.Type == nil { 752 f.Broke = true 753 } 754 755 switch u := n.Val().U.(type) { 756 case string: 757 f.Note = u 758 default: 759 yyerror("field annotation must be string") 760 case nil: 761 // noop 762 } 763 764 if n.Left != nil && n.Left.Op == ONAME { 765 f.Nname = n.Left 766 f.Embedded = n.Embedded 767 f.Sym = f.Nname.Sym 768 } 769 770 lineno = lno 771 return f 772 } 773 774 // checkdupfields emits errors for duplicately named fields or methods in 775 // a list of struct or interface types. 776 func checkdupfields(what string, ts ...*Type) { 777 lno := lineno 778 779 seen := make(map[*Sym]bool) 780 for _, t := range ts { 781 for _, f := range t.Fields().Slice() { 782 if f.Sym == nil || f.Nname == nil || isblank(f.Nname) { 783 continue 784 } 785 if seen[f.Sym] { 786 lineno = f.Nname.Lineno 787 yyerror("duplicate %s %s", what, f.Sym.Name) 788 continue 789 } 790 seen[f.Sym] = true 791 } 792 } 793 794 lineno = lno 795 } 796 797 // convert a parsed id/type list into 798 // a type for struct/interface/arglist 799 func tostruct(l []*Node) *Type { 800 t := typ(TSTRUCT) 801 tostruct0(t, l) 802 return t 803 } 804 805 func tostruct0(t *Type, l []*Node) { 806 if t == nil || !t.IsStruct() { 807 Fatalf("struct expected") 808 } 809 810 fields := make([]*Field, len(l)) 811 for i, n := range l { 812 f := structfield(n) 813 if f.Broke { 814 t.Broke = true 815 } 816 fields[i] = f 817 } 818 t.SetFields(fields) 819 820 checkdupfields("field", t) 821 822 if !t.Broke { 823 checkwidth(t) 824 } 825 } 826 827 func tofunargs(l []*Node, funarg Funarg) *Type { 828 t := typ(TSTRUCT) 829 t.StructType().Funarg = funarg 830 831 fields := make([]*Field, len(l)) 832 for i, n := range l { 833 f := structfield(n) 834 f.Funarg = funarg 835 836 // esc.go needs to find f given a PPARAM to add the tag. 837 if n.Left != nil && n.Left.Class == PPARAM { 838 n.Left.Name.Param.Field = f 839 } 840 if f.Broke { 841 t.Broke = true 842 } 843 fields[i] = f 844 } 845 t.SetFields(fields) 846 return t 847 } 848 849 func tofunargsfield(fields []*Field, funarg Funarg) *Type { 850 t := typ(TSTRUCT) 851 t.StructType().Funarg = funarg 852 853 for _, f := range fields { 854 f.Funarg = funarg 855 856 // esc.go needs to find f given a PPARAM to add the tag. 857 if f.Nname != nil && f.Nname.Class == PPARAM { 858 f.Nname.Name.Param.Field = f 859 } 860 } 861 t.SetFields(fields) 862 return t 863 } 864 865 func interfacefield(n *Node) *Field { 866 lno := lineno 867 lineno = n.Lineno 868 869 if n.Op != ODCLFIELD { 870 Fatalf("interfacefield: oops %v\n", n) 871 } 872 873 if n.Val().Ctype() != CTxxx { 874 yyerror("interface method cannot have annotation") 875 } 876 877 f := newField() 878 f.Isddd = n.Isddd 879 880 if n.Right != nil { 881 if n.Left != nil { 882 // queue resolution of method type for later. 883 // right now all we need is the name list. 884 // avoids cycles for recursive interface types. 885 n.Type = typ(TINTERMETH) 886 n.Type.SetNname(n.Right) 887 n.Left.Type = n.Type 888 queuemethod(n) 889 890 if n.Left.Op == ONAME { 891 f.Nname = n.Left 892 f.Embedded = n.Embedded 893 f.Sym = f.Nname.Sym 894 } 895 } else { 896 n.Right = typecheck(n.Right, Etype) 897 n.Type = n.Right.Type 898 899 if n.Embedded != 0 { 900 checkembeddedtype(n.Type) 901 } 902 903 if n.Type != nil { 904 switch n.Type.Etype { 905 case TINTER: 906 break 907 908 case TFORW: 909 yyerror("interface type loop involving %v", n.Type) 910 f.Broke = true 911 912 default: 913 yyerror("interface contains embedded non-interface %v", n.Type) 914 f.Broke = true 915 } 916 } 917 } 918 } 919 920 n.Right = nil 921 922 f.Type = n.Type 923 if f.Type == nil { 924 f.Broke = true 925 } 926 927 lineno = lno 928 return f 929 } 930 931 func tointerface(l []*Node) *Type { 932 t := typ(TINTER) 933 tointerface0(t, l) 934 return t 935 } 936 937 func tointerface0(t *Type, l []*Node) *Type { 938 if t == nil || !t.IsInterface() { 939 Fatalf("interface expected") 940 } 941 942 var fields []*Field 943 for _, n := range l { 944 f := interfacefield(n) 945 946 if n.Left == nil && f.Type.IsInterface() { 947 // embedded interface, inline methods 948 for _, t1 := range f.Type.Fields().Slice() { 949 f = newField() 950 f.Type = t1.Type 951 f.Broke = t1.Broke 952 f.Sym = t1.Sym 953 if f.Sym != nil { 954 f.Nname = newname(f.Sym) 955 } 956 fields = append(fields, f) 957 } 958 } else { 959 fields = append(fields, f) 960 } 961 if f.Broke { 962 t.Broke = true 963 } 964 } 965 sort.Sort(methcmp(fields)) 966 t.SetFields(fields) 967 968 checkdupfields("method", t) 969 checkwidth(t) 970 971 return t 972 } 973 974 func embedded(s *Sym, pkg *Pkg) *Node { 975 const ( 976 CenterDot = 0xB7 977 ) 978 // Names sometimes have disambiguation junk 979 // appended after a center dot. Discard it when 980 // making the name for the embedded struct field. 981 name := s.Name 982 983 if i := strings.Index(s.Name, string(CenterDot)); i >= 0 { 984 name = s.Name[:i] 985 } 986 987 var n *Node 988 if exportname(name) { 989 n = newname(lookup(name)) 990 } else if s.Pkg == builtinpkg { 991 // The name of embedded builtins belongs to pkg. 992 n = newname(Pkglookup(name, pkg)) 993 } else { 994 n = newname(Pkglookup(name, s.Pkg)) 995 } 996 n = nod(ODCLFIELD, n, oldname(s)) 997 n.Embedded = 1 998 return n 999 } 1000 1001 // thisT is the singleton type used for interface method receivers. 1002 var thisT *Type 1003 1004 func fakethis() *Node { 1005 if thisT == nil { 1006 thisT = ptrto(typ(TSTRUCT)) 1007 } 1008 return nod(ODCLFIELD, nil, typenod(thisT)) 1009 } 1010 1011 func fakethisfield() *Field { 1012 if thisT == nil { 1013 thisT = ptrto(typ(TSTRUCT)) 1014 } 1015 f := newField() 1016 f.Type = thisT 1017 return f 1018 } 1019 1020 // Is this field a method on an interface? 1021 // Those methods have thisT as the receiver. 1022 // (See fakethis above.) 1023 func isifacemethod(f *Type) bool { 1024 return f.Recv().Type == thisT 1025 } 1026 1027 // turn a parsed function declaration into a type 1028 func functype(this *Node, in, out []*Node) *Type { 1029 t := typ(TFUNC) 1030 functype0(t, this, in, out) 1031 return t 1032 } 1033 1034 func functype0(t *Type, this *Node, in, out []*Node) { 1035 if t == nil || t.Etype != TFUNC { 1036 Fatalf("function type expected") 1037 } 1038 1039 var rcvr []*Node 1040 if this != nil { 1041 rcvr = []*Node{this} 1042 } 1043 t.FuncType().Receiver = tofunargs(rcvr, FunargRcvr) 1044 t.FuncType().Results = tofunargs(out, FunargResults) 1045 t.FuncType().Params = tofunargs(in, FunargParams) 1046 1047 checkdupfields("argument", t.Recvs(), t.Results(), t.Params()) 1048 1049 if t.Recvs().Broke || t.Results().Broke || t.Params().Broke { 1050 t.Broke = true 1051 } 1052 1053 t.FuncType().Outnamed = false 1054 if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil { 1055 s := out[0].Left.Orig.Sym 1056 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result 1057 t.FuncType().Outnamed = true 1058 } 1059 } 1060 } 1061 1062 func functypefield(this *Field, in, out []*Field) *Type { 1063 t := typ(TFUNC) 1064 functypefield0(t, this, in, out) 1065 return t 1066 } 1067 1068 func functypefield0(t *Type, this *Field, in, out []*Field) { 1069 var rcvr []*Field 1070 if this != nil { 1071 rcvr = []*Field{this} 1072 } 1073 t.FuncType().Receiver = tofunargsfield(rcvr, FunargRcvr) 1074 t.FuncType().Results = tofunargsfield(out, FunargRcvr) 1075 t.FuncType().Params = tofunargsfield(in, FunargRcvr) 1076 1077 t.FuncType().Outnamed = false 1078 if len(out) > 0 && out[0].Nname != nil && out[0].Nname.Orig != nil { 1079 s := out[0].Nname.Orig.Sym 1080 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result 1081 t.FuncType().Outnamed = true 1082 } 1083 } 1084 } 1085 1086 var methodsym_toppkg *Pkg 1087 1088 func methodsym(nsym *Sym, t0 *Type, iface int) *Sym { 1089 var s *Sym 1090 var p string 1091 var suffix string 1092 var spkg *Pkg 1093 1094 t := t0 1095 if t == nil { 1096 goto bad 1097 } 1098 s = t.Sym 1099 if s == nil && t.IsPtr() { 1100 t = t.Elem() 1101 if t == nil { 1102 goto bad 1103 } 1104 s = t.Sym 1105 } 1106 1107 spkg = nil 1108 if s != nil { 1109 spkg = s.Pkg 1110 } 1111 1112 // if t0 == *t and t0 has a sym, 1113 // we want to see *t, not t0, in the method name. 1114 if t != t0 && t0.Sym != nil { 1115 t0 = ptrto(t) 1116 } 1117 1118 suffix = "" 1119 if iface != 0 { 1120 dowidth(t0) 1121 if t0.Width < Types[Tptr].Width { 1122 suffix = "·i" 1123 } 1124 } 1125 1126 if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) { 1127 if t0.Sym == nil && t0.IsPtr() { 1128 p = fmt.Sprintf("(%-S).%s.%s%s", t0, nsym.Pkg.Prefix, nsym.Name, suffix) 1129 } else { 1130 p = fmt.Sprintf("%-S.%s.%s%s", t0, nsym.Pkg.Prefix, nsym.Name, suffix) 1131 } 1132 } else { 1133 if t0.Sym == nil && t0.IsPtr() { 1134 p = fmt.Sprintf("(%-S).%s%s", t0, nsym.Name, suffix) 1135 } else { 1136 p = fmt.Sprintf("%-S.%s%s", t0, nsym.Name, suffix) 1137 } 1138 } 1139 1140 if spkg == nil { 1141 if methodsym_toppkg == nil { 1142 methodsym_toppkg = mkpkg("go") 1143 } 1144 spkg = methodsym_toppkg 1145 } 1146 1147 s = Pkglookup(p, spkg) 1148 1149 return s 1150 1151 bad: 1152 yyerror("illegal receiver type: %v", t0) 1153 return nil 1154 } 1155 1156 func methodname(n *Node, t *Node) *Node { 1157 star := false 1158 if t.Op == OIND { 1159 star = true 1160 t = t.Left 1161 } 1162 1163 return methodname0(n.Sym, star, t.Sym) 1164 } 1165 1166 func methodname0(s *Sym, star bool, tsym *Sym) *Node { 1167 if tsym == nil || isblanksym(s) { 1168 return newfuncname(s) 1169 } 1170 1171 var p string 1172 if star { 1173 p = fmt.Sprintf("(*%v).%v", tsym, s) 1174 } else { 1175 p = fmt.Sprintf("%v.%v", tsym, s) 1176 } 1177 1178 if exportname(tsym.Name) { 1179 s = lookup(p) 1180 } else { 1181 s = Pkglookup(p, tsym.Pkg) 1182 } 1183 1184 return newfuncname(s) 1185 } 1186 1187 // Add a method, declared as a function. 1188 // - msym is the method symbol 1189 // - t is function type (with receiver) 1190 func addmethod(msym *Sym, t *Type, local, nointerface bool) { 1191 // get field sym 1192 if msym == nil { 1193 Fatalf("no method symbol") 1194 } 1195 1196 // get parent type sym 1197 rf := t.Recv() // ptr to this structure 1198 if rf == nil { 1199 yyerror("missing receiver") 1200 return 1201 } 1202 1203 mt := methtype(rf.Type) 1204 if mt == nil || mt.Sym == nil { 1205 pa := rf.Type 1206 t := pa 1207 if t != nil && t.IsPtr() { 1208 if t.Sym != nil { 1209 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 1210 return 1211 } 1212 t = t.Elem() 1213 } 1214 1215 switch { 1216 case t == nil || t.Broke: 1217 // rely on typecheck having complained before 1218 case t.Sym == nil: 1219 yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t) 1220 case t.IsPtr(): 1221 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t) 1222 case t.IsInterface(): 1223 yyerror("invalid receiver type %v (%v is an interface type)", pa, t) 1224 default: 1225 // Should have picked off all the reasons above, 1226 // but just in case, fall back to generic error. 1227 yyerror("invalid receiver type %v (%L / %L)", pa, pa, t) 1228 } 1229 return 1230 } 1231 1232 if local && !mt.Local { 1233 yyerror("cannot define new methods on non-local type %v", mt) 1234 return 1235 } 1236 1237 if isblanksym(msym) { 1238 return 1239 } 1240 1241 if mt.IsStruct() { 1242 for _, f := range mt.Fields().Slice() { 1243 if f.Sym == msym { 1244 yyerror("type %v has both field and method named %v", mt, msym) 1245 return 1246 } 1247 } 1248 } 1249 1250 for _, f := range mt.Methods().Slice() { 1251 if msym.Name != f.Sym.Name { 1252 continue 1253 } 1254 // eqtype only checks that incoming and result parameters match, 1255 // so explicitly check that the receiver parameters match too. 1256 if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) { 1257 yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t) 1258 } 1259 return 1260 } 1261 1262 f := newField() 1263 f.Sym = msym 1264 f.Nname = newname(msym) 1265 f.Type = t 1266 f.Nointerface = nointerface 1267 1268 mt.Methods().Append(f) 1269 } 1270 1271 func funccompile(n *Node) { 1272 Stksize = BADWIDTH 1273 Maxarg = 0 1274 1275 if n.Type == nil { 1276 if nerrors == 0 { 1277 Fatalf("funccompile missing type") 1278 } 1279 return 1280 } 1281 1282 // assign parameter offsets 1283 checkwidth(n.Type) 1284 1285 if Curfn != nil { 1286 Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym) 1287 } 1288 1289 Stksize = 0 1290 dclcontext = PAUTO 1291 funcdepth = n.Func.Depth + 1 1292 compile(n) 1293 Curfn = nil 1294 pc = nil 1295 funcdepth = 0 1296 dclcontext = PEXTERN 1297 if nerrors != 0 { 1298 // If we have compile errors, ignore any assembler/linker errors. 1299 Ctxt.DiagFunc = func(string, ...interface{}) {} 1300 } 1301 obj.Flushplist(Ctxt) // convert from Prog list to machine code 1302 } 1303 1304 func funcsym(s *Sym) *Sym { 1305 if s.Fsym != nil { 1306 return s.Fsym 1307 } 1308 1309 s1 := Pkglookup(s.Name+"·f", s.Pkg) 1310 if !Ctxt.Flag_dynlink && s1.Def == nil { 1311 s1.Def = newfuncname(s1) 1312 s1.Def.Func.Shortname = newname(s) 1313 funcsyms = append(funcsyms, s1.Def) 1314 } 1315 s.Fsym = s1 1316 return s1 1317 } 1318 1319 func makefuncsym(s *Sym) { 1320 if isblanksym(s) { 1321 return 1322 } 1323 if compiling_runtime && s.Name == "getg" { 1324 // runtime.getg() is not a real function and so does 1325 // not get a funcsym. 1326 return 1327 } 1328 s1 := funcsym(s) 1329 s1.Def = newfuncname(s1) 1330 s1.Def.Func.Shortname = newname(s) 1331 funcsyms = append(funcsyms, s1.Def) 1332 } 1333 1334 type nowritebarrierrecChecker struct { 1335 curfn *Node 1336 stable bool 1337 1338 // best maps from the ODCLFUNC of each visited function that 1339 // recursively invokes a write barrier to the called function 1340 // on the shortest path to a write barrier. 1341 best map[*Node]nowritebarrierrecCall 1342 } 1343 1344 type nowritebarrierrecCall struct { 1345 target *Node 1346 depth int 1347 lineno int32 1348 } 1349 1350 func checknowritebarrierrec() { 1351 c := nowritebarrierrecChecker{ 1352 best: make(map[*Node]nowritebarrierrecCall), 1353 } 1354 visitBottomUp(xtop, func(list []*Node, recursive bool) { 1355 // Functions with write barriers have depth 0. 1356 for _, n := range list { 1357 if n.Func.WBLineno != 0 && n.Func.Pragma&Yeswritebarrierrec == 0 { 1358 c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBLineno} 1359 } 1360 } 1361 1362 // Propagate write barrier depth up from callees. In 1363 // the recursive case, we have to update this at most 1364 // len(list) times and can stop when we an iteration 1365 // that doesn't change anything. 1366 for _ = range list { 1367 c.stable = false 1368 for _, n := range list { 1369 if n.Func.Pragma&Yeswritebarrierrec != 0 { 1370 // Don't propagate write 1371 // barrier up to a 1372 // yeswritebarrierrec function. 1373 continue 1374 } 1375 if n.Func.WBLineno == 0 { 1376 c.curfn = n 1377 c.visitcodelist(n.Nbody) 1378 } 1379 } 1380 if c.stable { 1381 break 1382 } 1383 } 1384 1385 // Check nowritebarrierrec functions. 1386 for _, n := range list { 1387 if n.Func.Pragma&Nowritebarrierrec == 0 { 1388 continue 1389 } 1390 call, hasWB := c.best[n] 1391 if !hasWB { 1392 continue 1393 } 1394 1395 // Build the error message in reverse. 1396 err := "" 1397 for call.target != nil { 1398 err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err) 1399 n = call.target 1400 call = c.best[n] 1401 } 1402 err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err) 1403 yyerrorl(n.Func.WBLineno, err) 1404 } 1405 }) 1406 } 1407 1408 func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) { 1409 for _, n := range l.Slice() { 1410 c.visitcode(n) 1411 } 1412 } 1413 1414 func (c *nowritebarrierrecChecker) visitcode(n *Node) { 1415 if n == nil { 1416 return 1417 } 1418 1419 if n.Op == OCALLFUNC || n.Op == OCALLMETH { 1420 c.visitcall(n) 1421 } 1422 1423 c.visitcodelist(n.Ninit) 1424 c.visitcode(n.Left) 1425 c.visitcode(n.Right) 1426 c.visitcodelist(n.List) 1427 c.visitcodelist(n.Nbody) 1428 c.visitcodelist(n.Rlist) 1429 } 1430 1431 func (c *nowritebarrierrecChecker) visitcall(n *Node) { 1432 fn := n.Left 1433 if n.Op == OCALLMETH { 1434 fn = n.Left.Sym.Def 1435 } 1436 if fn == nil || fn.Op != ONAME || fn.Class != PFUNC || fn.Name.Defn == nil { 1437 return 1438 } 1439 defn := fn.Name.Defn 1440 1441 fnbest, ok := c.best[defn] 1442 if !ok { 1443 return 1444 } 1445 best, ok := c.best[c.curfn] 1446 if ok && fnbest.depth+1 >= best.depth { 1447 return 1448 } 1449 c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Lineno} 1450 c.stable = false 1451 }