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