]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/gc/dcl.go
all: merge dev.typealias into master
[gostls13.git] / src / cmd / compile / internal / gc / dcl.go
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         dclcontext = PAUTO
523         funcstart(n)
524
525         if n.Func.Nname != nil {
526                 funcargs(n.Func.Nname.Name.Param.Ntype)
527         } else if n.Func.Ntype != nil {
528                 funcargs(n.Func.Ntype)
529         } else {
530                 funcargs2(n.Type)
531         }
532 }
533
534 func funcargs(nt *Node) {
535         if nt.Op != OTFUNC {
536                 Fatalf("funcargs %v", nt.Op)
537         }
538
539         // re-start the variable generation number
540         // we want to use small numbers for the return variables,
541         // so let them have the chunk starting at 1.
542         vargen = nt.Rlist.Len()
543
544         // declare the receiver and in arguments.
545         // no n->defn because type checking of func header
546         // will not fill in the types until later
547         if nt.Left != nil {
548                 n := nt.Left
549                 if n.Op != ODCLFIELD {
550                         Fatalf("funcargs receiver %v", n.Op)
551                 }
552                 if n.Left != nil {
553                         n.Left.Op = ONAME
554                         n.Left.Name.Param.Ntype = n.Right
555                         declare(n.Left, PPARAM)
556                         if dclcontext == PAUTO {
557                                 vargen++
558                                 n.Left.Name.Vargen = int32(vargen)
559                         }
560                 }
561         }
562
563         for _, n := range nt.List.Slice() {
564                 if n.Op != ODCLFIELD {
565                         Fatalf("funcargs in %v", n.Op)
566                 }
567                 if n.Left != nil {
568                         n.Left.Op = ONAME
569                         n.Left.Name.Param.Ntype = n.Right
570                         declare(n.Left, PPARAM)
571                         if dclcontext == PAUTO {
572                                 vargen++
573                                 n.Left.Name.Vargen = int32(vargen)
574                         }
575                 }
576         }
577
578         // declare the out arguments.
579         gen := nt.List.Len()
580         var i int = 0
581         for _, n := range nt.Rlist.Slice() {
582                 if n.Op != ODCLFIELD {
583                         Fatalf("funcargs out %v", n.Op)
584                 }
585
586                 if n.Left == nil {
587                         // Name so that escape analysis can track it. ~r stands for 'result'.
588                         n.Left = newname(lookupN("~r", gen))
589                         gen++
590                 }
591
592                 // TODO: n->left->missing = 1;
593                 n.Left.Op = ONAME
594
595                 if isblank(n.Left) {
596                         // Give it a name so we can assign to it during return. ~b stands for 'blank'.
597                         // The name must be different from ~r above because if you have
598                         //      func f() (_ int)
599                         //      func g() int
600                         // f is allowed to use a plain 'return' with no arguments, while g is not.
601                         // So the two cases must be distinguished.
602                         // We do not record a pointer to the original node (n->orig).
603                         // Having multiple names causes too much confusion in later passes.
604                         nn := *n.Left
605                         nn.Orig = &nn
606                         nn.Sym = lookupN("~b", gen)
607                         gen++
608                         n.Left = &nn
609                 }
610
611                 n.Left.Name.Param.Ntype = n.Right
612                 declare(n.Left, PPARAMOUT)
613                 if dclcontext == PAUTO {
614                         i++
615                         n.Left.Name.Vargen = int32(i)
616                 }
617         }
618 }
619
620 // Same as funcargs, except run over an already constructed TFUNC.
621 // This happens during import, where the hidden_fndcl rule has
622 // used functype directly to parse the function's type.
623 func funcargs2(t *Type) {
624         if t.Etype != TFUNC {
625                 Fatalf("funcargs2 %v", t)
626         }
627
628         for _, ft := range t.Recvs().Fields().Slice() {
629                 if ft.Nname == nil || ft.Nname.Sym == nil {
630                         continue
631                 }
632                 n := ft.Nname // no need for newname(ft->nname->sym)
633                 n.Type = ft.Type
634                 declare(n, PPARAM)
635         }
636
637         for _, ft := range t.Params().Fields().Slice() {
638                 if ft.Nname == nil || ft.Nname.Sym == nil {
639                         continue
640                 }
641                 n := ft.Nname
642                 n.Type = ft.Type
643                 declare(n, PPARAM)
644         }
645
646         for _, ft := range t.Results().Fields().Slice() {
647                 if ft.Nname == nil || ft.Nname.Sym == nil {
648                         continue
649                 }
650                 n := ft.Nname
651                 n.Type = ft.Type
652                 declare(n, PPARAMOUT)
653         }
654 }
655
656 var funcstack []*Node // stack of previous values of Curfn
657 var funcdepth int32   // len(funcstack) during parsing, but then forced to be the same later during compilation
658
659 // start the function.
660 // called before funcargs; undone at end of funcbody.
661 func funcstart(n *Node) {
662         markdcl()
663         funcstack = append(funcstack, Curfn)
664         funcdepth++
665         Curfn = n
666 }
667
668 // finish the body.
669 // called in auto-declaration context.
670 // returns in extern-declaration context.
671 func funcbody(n *Node) {
672         // change the declaration context from auto to extern
673         if dclcontext != PAUTO {
674                 Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
675         }
676         popdcl()
677         funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
678         funcdepth--
679         if funcdepth == 0 {
680                 dclcontext = PEXTERN
681         }
682 }
683
684 // new type being defined with name s.
685 func typedcl0(s *Sym) *Node {
686         n := newname(s)
687         n.Op = OTYPE
688         declare(n, dclcontext)
689         return n
690 }
691
692 // node n, which was returned by typedcl0
693 // is being declared to have uncompiled type t.
694 // returns the ODCLTYPE node to use.
695 func typedcl1(n *Node, t *Node, pragma Pragma, alias bool) *Node {
696         if pragma != 0 && alias {
697                 yyerror("cannot specify directive with type alias")
698                 pragma = 0
699         }
700
701         n.Local = true
702
703         p := n.Name.Param
704         p.Ntype = t
705         p.Pragma = pragma
706         p.Alias = alias
707
708         return nod(ODCLTYPE, n, nil)
709 }
710
711 // structs, functions, and methods.
712 // they don't belong here, but where do they belong?
713 func checkembeddedtype(t *Type) {
714         if t == nil {
715                 return
716         }
717
718         if t.Sym == nil && t.IsPtr() {
719                 t = t.Elem()
720                 if t.IsInterface() {
721                         yyerror("embedded type cannot be a pointer to interface")
722                 }
723         }
724
725         if t.IsPtr() || t.IsUnsafePtr() {
726                 yyerror("embedded type cannot be a pointer")
727         } else if t.Etype == TFORW && t.ForwardType().Embedlineno == 0 {
728                 t.ForwardType().Embedlineno = lineno
729         }
730 }
731
732 func structfield(n *Node) *Field {
733         lno := lineno
734         lineno = n.Lineno
735
736         if n.Op != ODCLFIELD {
737                 Fatalf("structfield: oops %v\n", n)
738         }
739
740         f := newField()
741         f.Isddd = n.Isddd
742
743         if n.Right != nil {
744                 n.Right = typecheck(n.Right, Etype)
745                 n.Type = n.Right.Type
746                 if n.Left != nil {
747                         n.Left.Type = n.Type
748                 }
749                 if n.Embedded != 0 {
750                         checkembeddedtype(n.Type)
751                 }
752         }
753
754         n.Right = nil
755
756         f.Type = n.Type
757         if f.Type == nil {
758                 f.Broke = true
759         }
760
761         switch u := n.Val().U.(type) {
762         case string:
763                 f.Note = u
764         default:
765                 yyerror("field annotation must be string")
766         case nil:
767                 // noop
768         }
769
770         if n.Left != nil && n.Left.Op == ONAME {
771                 f.Nname = n.Left
772                 f.Embedded = n.Embedded
773                 f.Sym = f.Nname.Sym
774         }
775
776         lineno = lno
777         return f
778 }
779
780 // checkdupfields emits errors for duplicately named fields or methods in
781 // a list of struct or interface types.
782 func checkdupfields(what string, ts ...*Type) {
783         lno := lineno
784
785         seen := make(map[*Sym]bool)
786         for _, t := range ts {
787                 for _, f := range t.Fields().Slice() {
788                         if f.Sym == nil || f.Nname == nil || isblank(f.Nname) {
789                                 continue
790                         }
791                         if seen[f.Sym] {
792                                 lineno = f.Nname.Lineno
793                                 yyerror("duplicate %s %s", what, f.Sym.Name)
794                                 continue
795                         }
796                         seen[f.Sym] = true
797                 }
798         }
799
800         lineno = lno
801 }
802
803 // convert a parsed id/type list into
804 // a type for struct/interface/arglist
805 func tostruct(l []*Node) *Type {
806         t := typ(TSTRUCT)
807         tostruct0(t, l)
808         return t
809 }
810
811 func tostruct0(t *Type, l []*Node) {
812         if t == nil || !t.IsStruct() {
813                 Fatalf("struct expected")
814         }
815
816         fields := make([]*Field, len(l))
817         for i, n := range l {
818                 f := structfield(n)
819                 if f.Broke {
820                         t.Broke = true
821                 }
822                 fields[i] = f
823         }
824         t.SetFields(fields)
825
826         checkdupfields("field", t)
827
828         if !t.Broke {
829                 checkwidth(t)
830         }
831 }
832
833 func tofunargs(l []*Node, funarg Funarg) *Type {
834         t := typ(TSTRUCT)
835         t.StructType().Funarg = funarg
836
837         fields := make([]*Field, len(l))
838         for i, n := range l {
839                 f := structfield(n)
840                 f.Funarg = funarg
841
842                 // esc.go needs to find f given a PPARAM to add the tag.
843                 if n.Left != nil && n.Left.Class == PPARAM {
844                         n.Left.Name.Param.Field = f
845                 }
846                 if f.Broke {
847                         t.Broke = true
848                 }
849                 fields[i] = f
850         }
851         t.SetFields(fields)
852         return t
853 }
854
855 func tofunargsfield(fields []*Field, funarg Funarg) *Type {
856         t := typ(TSTRUCT)
857         t.StructType().Funarg = funarg
858
859         for _, f := range fields {
860                 f.Funarg = funarg
861
862                 // esc.go needs to find f given a PPARAM to add the tag.
863                 if f.Nname != nil && f.Nname.Class == PPARAM {
864                         f.Nname.Name.Param.Field = f
865                 }
866         }
867         t.SetFields(fields)
868         return t
869 }
870
871 func interfacefield(n *Node) *Field {
872         lno := lineno
873         lineno = n.Lineno
874
875         if n.Op != ODCLFIELD {
876                 Fatalf("interfacefield: oops %v\n", n)
877         }
878
879         if n.Val().Ctype() != CTxxx {
880                 yyerror("interface method cannot have annotation")
881         }
882
883         f := newField()
884         f.Isddd = n.Isddd
885
886         if n.Right != nil {
887                 if n.Left != nil {
888                         // queue resolution of method type for later.
889                         // right now all we need is the name list.
890                         // avoids cycles for recursive interface types.
891                         n.Type = typ(TINTERMETH)
892                         n.Type.SetNname(n.Right)
893                         n.Left.Type = n.Type
894                         queuemethod(n)
895
896                         if n.Left.Op == ONAME {
897                                 f.Nname = n.Left
898                                 f.Embedded = n.Embedded
899                                 f.Sym = f.Nname.Sym
900                         }
901                 } else {
902                         n.Right = typecheck(n.Right, Etype)
903                         n.Type = n.Right.Type
904
905                         if n.Embedded != 0 {
906                                 checkembeddedtype(n.Type)
907                         }
908
909                         if n.Type != nil {
910                                 switch n.Type.Etype {
911                                 case TINTER:
912                                         break
913
914                                 case TFORW:
915                                         yyerror("interface type loop involving %v", n.Type)
916                                         f.Broke = true
917
918                                 default:
919                                         yyerror("interface contains embedded non-interface %v", n.Type)
920                                         f.Broke = true
921                                 }
922                         }
923                 }
924         }
925
926         n.Right = nil
927
928         f.Type = n.Type
929         if f.Type == nil {
930                 f.Broke = true
931         }
932
933         lineno = lno
934         return f
935 }
936
937 func tointerface(l []*Node) *Type {
938         t := typ(TINTER)
939         tointerface0(t, l)
940         return t
941 }
942
943 func tointerface0(t *Type, l []*Node) *Type {
944         if t == nil || !t.IsInterface() {
945                 Fatalf("interface expected")
946         }
947
948         var fields []*Field
949         for _, n := range l {
950                 f := interfacefield(n)
951
952                 if n.Left == nil && f.Type.IsInterface() {
953                         // embedded interface, inline methods
954                         for _, t1 := range f.Type.Fields().Slice() {
955                                 f = newField()
956                                 f.Type = t1.Type
957                                 f.Broke = t1.Broke
958                                 f.Sym = t1.Sym
959                                 if f.Sym != nil {
960                                         f.Nname = newname(f.Sym)
961                                 }
962                                 fields = append(fields, f)
963                         }
964                 } else {
965                         fields = append(fields, f)
966                 }
967                 if f.Broke {
968                         t.Broke = true
969                 }
970         }
971         sort.Sort(methcmp(fields))
972         t.SetFields(fields)
973
974         checkdupfields("method", t)
975         checkwidth(t)
976
977         return t
978 }
979
980 func embedded(s *Sym, pkg *Pkg) *Node {
981         const (
982                 CenterDot = 0xB7
983         )
984         // Names sometimes have disambiguation junk
985         // appended after a center dot. Discard it when
986         // making the name for the embedded struct field.
987         name := s.Name
988
989         if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
990                 name = s.Name[:i]
991         }
992
993         var n *Node
994         if exportname(name) {
995                 n = newname(lookup(name))
996         } else if s.Pkg == builtinpkg {
997                 // The name of embedded builtins belongs to pkg.
998                 n = newname(Pkglookup(name, pkg))
999         } else {
1000                 n = newname(Pkglookup(name, s.Pkg))
1001         }
1002         n = nod(ODCLFIELD, n, oldname(s))
1003         n.Embedded = 1
1004         return n
1005 }
1006
1007 // thisT is the singleton type used for interface method receivers.
1008 var thisT *Type
1009
1010 func fakethis() *Node {
1011         if thisT == nil {
1012                 thisT = ptrto(typ(TSTRUCT))
1013         }
1014         return nod(ODCLFIELD, nil, typenod(thisT))
1015 }
1016
1017 func fakethisfield() *Field {
1018         if thisT == nil {
1019                 thisT = ptrto(typ(TSTRUCT))
1020         }
1021         f := newField()
1022         f.Type = thisT
1023         return f
1024 }
1025
1026 // Is this field a method on an interface?
1027 // Those methods have thisT as the receiver.
1028 // (See fakethis above.)
1029 func isifacemethod(f *Type) bool {
1030         return f.Recv().Type == thisT
1031 }
1032
1033 // turn a parsed function declaration into a type
1034 func functype(this *Node, in, out []*Node) *Type {
1035         t := typ(TFUNC)
1036         functype0(t, this, in, out)
1037         return t
1038 }
1039
1040 func functype0(t *Type, this *Node, in, out []*Node) {
1041         if t == nil || t.Etype != TFUNC {
1042                 Fatalf("function type expected")
1043         }
1044
1045         var rcvr []*Node
1046         if this != nil {
1047                 rcvr = []*Node{this}
1048         }
1049         t.FuncType().Receiver = tofunargs(rcvr, FunargRcvr)
1050         t.FuncType().Results = tofunargs(out, FunargResults)
1051         t.FuncType().Params = tofunargs(in, FunargParams)
1052
1053         checkdupfields("argument", t.Recvs(), t.Results(), t.Params())
1054
1055         if t.Recvs().Broke || t.Results().Broke || t.Params().Broke {
1056                 t.Broke = true
1057         }
1058
1059         t.FuncType().Outnamed = false
1060         if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
1061                 s := out[0].Left.Orig.Sym
1062                 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
1063                         t.FuncType().Outnamed = true
1064                 }
1065         }
1066 }
1067
1068 func functypefield(this *Field, in, out []*Field) *Type {
1069         t := typ(TFUNC)
1070         functypefield0(t, this, in, out)
1071         return t
1072 }
1073
1074 func functypefield0(t *Type, this *Field, in, out []*Field) {
1075         var rcvr []*Field
1076         if this != nil {
1077                 rcvr = []*Field{this}
1078         }
1079         t.FuncType().Receiver = tofunargsfield(rcvr, FunargRcvr)
1080         t.FuncType().Results = tofunargsfield(out, FunargRcvr)
1081         t.FuncType().Params = tofunargsfield(in, FunargRcvr)
1082
1083         t.FuncType().Outnamed = false
1084         if len(out) > 0 && out[0].Nname != nil && out[0].Nname.Orig != nil {
1085                 s := out[0].Nname.Orig.Sym
1086                 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
1087                         t.FuncType().Outnamed = true
1088                 }
1089         }
1090 }
1091
1092 var methodsym_toppkg *Pkg
1093
1094 func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
1095         var s *Sym
1096         var p string
1097         var suffix string
1098         var spkg *Pkg
1099
1100         t := t0
1101         if t == nil {
1102                 goto bad
1103         }
1104         s = t.Sym
1105         if s == nil && t.IsPtr() {
1106                 t = t.Elem()
1107                 if t == nil {
1108                         goto bad
1109                 }
1110                 s = t.Sym
1111         }
1112
1113         spkg = nil
1114         if s != nil {
1115                 spkg = s.Pkg
1116         }
1117
1118         // if t0 == *t and t0 has a sym,
1119         // we want to see *t, not t0, in the method name.
1120         if t != t0 && t0.Sym != nil {
1121                 t0 = ptrto(t)
1122         }
1123
1124         suffix = ""
1125         if iface != 0 {
1126                 dowidth(t0)
1127                 if t0.Width < Types[Tptr].Width {
1128                         suffix = "·i"
1129                 }
1130         }
1131
1132         if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) {
1133                 if t0.Sym == nil && t0.IsPtr() {
1134                         p = fmt.Sprintf("(%-S).%s.%s%s", t0, nsym.Pkg.Prefix, nsym.Name, suffix)
1135                 } else {
1136                         p = fmt.Sprintf("%-S.%s.%s%s", t0, nsym.Pkg.Prefix, nsym.Name, suffix)
1137                 }
1138         } else {
1139                 if t0.Sym == nil && t0.IsPtr() {
1140                         p = fmt.Sprintf("(%-S).%s%s", t0, nsym.Name, suffix)
1141                 } else {
1142                         p = fmt.Sprintf("%-S.%s%s", t0, nsym.Name, suffix)
1143                 }
1144         }
1145
1146         if spkg == nil {
1147                 if methodsym_toppkg == nil {
1148                         methodsym_toppkg = mkpkg("go")
1149                 }
1150                 spkg = methodsym_toppkg
1151         }
1152
1153         s = Pkglookup(p, spkg)
1154
1155         return s
1156
1157 bad:
1158         yyerror("illegal receiver type: %v", t0)
1159         return nil
1160 }
1161
1162 // methodname is a misnomer because this now returns a Sym, rather
1163 // than an ONAME.
1164 // TODO(mdempsky): Reconcile with methodsym.
1165 func methodname(s *Sym, recv *Type) *Sym {
1166         star := false
1167         if recv.IsPtr() {
1168                 star = true
1169                 recv = recv.Elem()
1170         }
1171
1172         tsym := recv.Sym
1173         if tsym == nil || isblanksym(s) {
1174                 return s
1175         }
1176
1177         var p string
1178         if star {
1179                 p = fmt.Sprintf("(*%v).%v", tsym, s)
1180         } else {
1181                 p = fmt.Sprintf("%v.%v", tsym, s)
1182         }
1183
1184         if exportname(tsym.Name) {
1185                 s = lookup(p)
1186         } else {
1187                 s = Pkglookup(p, tsym.Pkg)
1188         }
1189
1190         return s
1191 }
1192
1193 // Add a method, declared as a function.
1194 // - msym is the method symbol
1195 // - t is function type (with receiver)
1196 func addmethod(msym *Sym, t *Type, local, nointerface bool) {
1197         if msym == nil {
1198                 Fatalf("no method symbol")
1199         }
1200
1201         // get parent type sym
1202         rf := t.Recv() // ptr to this structure
1203         if rf == nil {
1204                 yyerror("missing receiver")
1205                 return
1206         }
1207
1208         mt := methtype(rf.Type)
1209         if mt == nil || mt.Sym == nil {
1210                 pa := rf.Type
1211                 t := pa
1212                 if t != nil && t.IsPtr() {
1213                         if t.Sym != nil {
1214                                 yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
1215                                 return
1216                         }
1217                         t = t.Elem()
1218                 }
1219
1220                 switch {
1221                 case t == nil || t.Broke:
1222                         // rely on typecheck having complained before
1223                 case t.Sym == nil:
1224                         yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
1225                 case t.IsPtr():
1226                         yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
1227                 case t.IsInterface():
1228                         yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
1229                 default:
1230                         // Should have picked off all the reasons above,
1231                         // but just in case, fall back to generic error.
1232                         yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
1233                 }
1234                 return
1235         }
1236
1237         if local && !mt.Local {
1238                 yyerror("cannot define new methods on non-local type %v", mt)
1239                 return
1240         }
1241
1242         if isblanksym(msym) {
1243                 return
1244         }
1245
1246         if mt.IsStruct() {
1247                 for _, f := range mt.Fields().Slice() {
1248                         if f.Sym == msym {
1249                                 yyerror("type %v has both field and method named %v", mt, msym)
1250                                 return
1251                         }
1252                 }
1253         }
1254
1255         for _, f := range mt.Methods().Slice() {
1256                 if msym.Name != f.Sym.Name {
1257                         continue
1258                 }
1259                 // eqtype only checks that incoming and result parameters match,
1260                 // so explicitly check that the receiver parameters match too.
1261                 if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
1262                         yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
1263                 }
1264                 return
1265         }
1266
1267         f := newField()
1268         f.Sym = msym
1269         f.Nname = newname(msym)
1270         f.Type = t
1271         f.Nointerface = nointerface
1272
1273         mt.Methods().Append(f)
1274 }
1275
1276 func funccompile(n *Node) {
1277         Stksize = BADWIDTH
1278         Maxarg = 0
1279
1280         if n.Type == nil {
1281                 if nerrors == 0 {
1282                         Fatalf("funccompile missing type")
1283                 }
1284                 return
1285         }
1286
1287         // assign parameter offsets
1288         checkwidth(n.Type)
1289
1290         if Curfn != nil {
1291                 Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym)
1292         }
1293
1294         Stksize = 0
1295         dclcontext = PAUTO
1296         funcdepth = n.Func.Depth + 1
1297         compile(n)
1298         Curfn = nil
1299         pc = nil
1300         funcdepth = 0
1301         dclcontext = PEXTERN
1302         if nerrors != 0 {
1303                 // If we have compile errors, ignore any assembler/linker errors.
1304                 Ctxt.DiagFunc = func(string, ...interface{}) {}
1305         }
1306         obj.Flushplist(Ctxt) // convert from Prog list to machine code
1307 }
1308
1309 func funcsym(s *Sym) *Sym {
1310         if s.Fsym != nil {
1311                 return s.Fsym
1312         }
1313
1314         s1 := Pkglookup(s.Name+"·f", s.Pkg)
1315         if !Ctxt.Flag_dynlink && s1.Def == nil {
1316                 s1.Def = newfuncname(s1)
1317                 s1.Def.Func.Shortname = s
1318                 funcsyms = append(funcsyms, s1.Def)
1319         }
1320         s.Fsym = s1
1321         return s1
1322 }
1323
1324 func makefuncsym(s *Sym) {
1325         if isblanksym(s) {
1326                 return
1327         }
1328         if compiling_runtime && s.Name == "getg" {
1329                 // runtime.getg() is not a real function and so does
1330                 // not get a funcsym.
1331                 return
1332         }
1333         s1 := funcsym(s)
1334         if s1.Def != nil {
1335                 return
1336         }
1337         s1.Def = newfuncname(s1)
1338         s1.Def.Func.Shortname = s
1339         funcsyms = append(funcsyms, s1.Def)
1340 }
1341
1342 type nowritebarrierrecChecker struct {
1343         curfn  *Node
1344         stable bool
1345
1346         // best maps from the ODCLFUNC of each visited function that
1347         // recursively invokes a write barrier to the called function
1348         // on the shortest path to a write barrier.
1349         best map[*Node]nowritebarrierrecCall
1350 }
1351
1352 type nowritebarrierrecCall struct {
1353         target *Node
1354         depth  int
1355         lineno int32
1356 }
1357
1358 func checknowritebarrierrec() {
1359         c := nowritebarrierrecChecker{
1360                 best: make(map[*Node]nowritebarrierrecCall),
1361         }
1362         visitBottomUp(xtop, func(list []*Node, recursive bool) {
1363                 // Functions with write barriers have depth 0.
1364                 for _, n := range list {
1365                         if n.Func.WBLineno != 0 && n.Func.Pragma&Yeswritebarrierrec == 0 {
1366                                 c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBLineno}
1367                         }
1368                 }
1369
1370                 // Propagate write barrier depth up from callees. In
1371                 // the recursive case, we have to update this at most
1372                 // len(list) times and can stop when we an iteration
1373                 // that doesn't change anything.
1374                 for _ = range list {
1375                         c.stable = false
1376                         for _, n := range list {
1377                                 if n.Func.Pragma&Yeswritebarrierrec != 0 {
1378                                         // Don't propagate write
1379                                         // barrier up to a
1380                                         // yeswritebarrierrec function.
1381                                         continue
1382                                 }
1383                                 if n.Func.WBLineno == 0 {
1384                                         c.curfn = n
1385                                         c.visitcodelist(n.Nbody)
1386                                 }
1387                         }
1388                         if c.stable {
1389                                 break
1390                         }
1391                 }
1392
1393                 // Check nowritebarrierrec functions.
1394                 for _, n := range list {
1395                         if n.Func.Pragma&Nowritebarrierrec == 0 {
1396                                 continue
1397                         }
1398                         call, hasWB := c.best[n]
1399                         if !hasWB {
1400                                 continue
1401                         }
1402
1403                         // Build the error message in reverse.
1404                         err := ""
1405                         for call.target != nil {
1406                                 err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err)
1407                                 n = call.target
1408                                 call = c.best[n]
1409                         }
1410                         err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err)
1411                         yyerrorl(n.Func.WBLineno, err)
1412                 }
1413         })
1414 }
1415
1416 func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) {
1417         for _, n := range l.Slice() {
1418                 c.visitcode(n)
1419         }
1420 }
1421
1422 func (c *nowritebarrierrecChecker) visitcode(n *Node) {
1423         if n == nil {
1424                 return
1425         }
1426
1427         if n.Op == OCALLFUNC || n.Op == OCALLMETH {
1428                 c.visitcall(n)
1429         }
1430
1431         c.visitcodelist(n.Ninit)
1432         c.visitcode(n.Left)
1433         c.visitcode(n.Right)
1434         c.visitcodelist(n.List)
1435         c.visitcodelist(n.Nbody)
1436         c.visitcodelist(n.Rlist)
1437 }
1438
1439 func (c *nowritebarrierrecChecker) visitcall(n *Node) {
1440         fn := n.Left
1441         if n.Op == OCALLMETH {
1442                 fn = n.Left.Sym.Def
1443         }
1444         if fn == nil || fn.Op != ONAME || fn.Class != PFUNC || fn.Name.Defn == nil {
1445                 return
1446         }
1447         defn := fn.Name.Defn
1448
1449         fnbest, ok := c.best[defn]
1450         if !ok {
1451                 return
1452         }
1453         best, ok := c.best[c.curfn]
1454         if ok && fnbest.depth+1 >= best.depth {
1455                 return
1456         }
1457         c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Lineno}
1458         c.stable = false
1459 }