blob: 06092742fa95bc00b6f7ea136068729113802b5d [file] [log] [blame]
Russ Cox8c195bd2015-02-13 14:40:36 -05001// 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
5package gc
6
7import (
8 "cmd/internal/obj"
9 "fmt"
10 "strings"
11)
12
Russ Coxdc7b54b2015-02-17 22:13:49 -050013func dflag() bool {
14 if Debug['d'] == 0 {
15 return false
Russ Cox8c195bd2015-02-13 14:40:36 -050016 }
17 if Debug['y'] != 0 {
Russ Coxdc7b54b2015-02-17 22:13:49 -050018 return true
Russ Cox8c195bd2015-02-13 14:40:36 -050019 }
20 if incannedimport != 0 {
Russ Coxdc7b54b2015-02-17 22:13:49 -050021 return false
Russ Cox8c195bd2015-02-13 14:40:36 -050022 }
Russ Coxdc7b54b2015-02-17 22:13:49 -050023 return true
Russ Cox8c195bd2015-02-13 14:40:36 -050024}
25
26/*
27 * declaration stack & operations
28 */
29func dcopy(a *Sym, b *Sym) {
30 a.Pkg = b.Pkg
31 a.Name = b.Name
32 a.Def = b.Def
33 a.Block = b.Block
34 a.Lastlineno = b.Lastlineno
35}
36
37func push() *Sym {
Russ Cox382b44e2015-02-23 16:07:24 -050038 d := new(Sym)
Russ Cox8c195bd2015-02-13 14:40:36 -050039 d.Lastlineno = lineno
40 d.Link = dclstack
41 dclstack = d
42 return d
43}
44
45func pushdcl(s *Sym) *Sym {
Russ Cox382b44e2015-02-23 16:07:24 -050046 d := push()
Russ Cox8c195bd2015-02-13 14:40:36 -050047 dcopy(d, s)
Russ Coxdc7b54b2015-02-17 22:13:49 -050048 if dflag() {
Russ Cox17228f42015-04-17 12:03:22 -040049 fmt.Printf("\t%v push %v %p\n", Ctxt.Line(int(lineno)), s, s.Def)
Russ Cox8c195bd2015-02-13 14:40:36 -050050 }
51 return d
52}
53
54func popdcl() {
55 var d *Sym
56 var s *Sym
57 var lno int
58
59 // if(dflag())
60 // print("revert\n");
61
62 for d = dclstack; d != nil; d = d.Link {
63 if d.Name == "" {
64 break
65 }
66 s = Pkglookup(d.Name, d.Pkg)
67 lno = int(s.Lastlineno)
68 dcopy(s, d)
69 d.Lastlineno = int32(lno)
Russ Coxdc7b54b2015-02-17 22:13:49 -050070 if dflag() {
Russ Cox17228f42015-04-17 12:03:22 -040071 fmt.Printf("\t%v pop %v %p\n", Ctxt.Line(int(lineno)), s, s.Def)
Russ Cox8c195bd2015-02-13 14:40:36 -050072 }
73 }
74
75 if d == nil {
Håvard Haugen3c9fa382015-08-30 23:10:03 +020076 Fatalf("popdcl: no mark")
Russ Cox8c195bd2015-02-13 14:40:36 -050077 }
78 dclstack = d.Link
79 block = d.Block
80}
81
82func poptodcl() {
83 // pop the old marker and push a new one
84 // (cannot reuse the existing one)
85 // because we use the markers to identify blocks
86 // for the goto restriction checks.
87 popdcl()
88
89 markdcl()
90}
91
92func markdcl() {
Russ Cox382b44e2015-02-23 16:07:24 -050093 d := push()
Russ Cox8c195bd2015-02-13 14:40:36 -050094 d.Name = "" // used as a mark in fifo
95 d.Block = block
96
97 blockgen++
98 block = blockgen
99}
100
101// if(dflag())
102// print("markdcl\n");
103func dumpdcl(st string) {
104 var s *Sym
Russ Cox8c195bd2015-02-13 14:40:36 -0500105
Russ Cox382b44e2015-02-23 16:07:24 -0500106 i := 0
107 for d := dclstack; d != nil; d = d.Link {
Russ Cox8c195bd2015-02-13 14:40:36 -0500108 i++
109 fmt.Printf(" %.2d %p", i, d)
110 if d.Name == "" {
111 fmt.Printf("\n")
112 continue
113 }
114
115 fmt.Printf(" '%s'", d.Name)
116 s = Pkglookup(d.Name, d.Pkg)
Russ Cox17228f42015-04-17 12:03:22 -0400117 fmt.Printf(" %v\n", s)
Russ Cox8c195bd2015-02-13 14:40:36 -0500118 }
119}
120
121func testdclstack() {
Russ Cox382b44e2015-02-23 16:07:24 -0500122 for d := dclstack; d != nil; d = d.Link {
Russ Cox8c195bd2015-02-13 14:40:36 -0500123 if d.Name == "" {
124 if nerrors != 0 {
125 errorexit()
126 }
127 Yyerror("mark left on the stack")
128 continue
129 }
130 }
131}
132
133func redeclare(s *Sym, where string) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500134 if s.Lastlineno == 0 {
Russ Coxbed1f902015-03-02 16:03:26 -0500135 var tmp string
Russ Cox8c195bd2015-02-13 14:40:36 -0500136 if s.Origpkg != nil {
137 tmp = s.Origpkg.Path
138 } else {
139 tmp = s.Pkg.Path
140 }
Russ Cox382b44e2015-02-23 16:07:24 -0500141 pkgstr := tmp
Russ Cox17228f42015-04-17 12:03:22 -0400142 Yyerror("%v redeclared %s\n"+"\tprevious declaration during import %q", s, where, pkgstr)
Russ Cox8c195bd2015-02-13 14:40:36 -0500143 } else {
Russ Cox382b44e2015-02-23 16:07:24 -0500144 line1 := parserline()
145 line2 := int(s.Lastlineno)
Russ Cox8c195bd2015-02-13 14:40:36 -0500146
147 // When an import and a declaration collide in separate files,
148 // present the import as the "redeclared", because the declaration
149 // is visible where the import is, but not vice versa.
150 // See issue 4510.
151 if s.Def == nil {
152 line2 = line1
153 line1 = int(s.Lastlineno)
154 }
155
Russ Cox17228f42015-04-17 12:03:22 -0400156 yyerrorl(int(line1), "%v redeclared %s\n"+"\tprevious declaration at %v", s, where, Ctxt.Line(line2))
Russ Cox8c195bd2015-02-13 14:40:36 -0500157 }
158}
159
160var vargen int
161
162/*
163 * declare individual names - var, typ, const
164 */
165
166var declare_typegen int
167
Josh Bleecher Snyder102b8062015-03-27 12:00:07 -0700168func declare(n *Node, ctxt uint8) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500169 if ctxt == PDISCARD {
170 return
171 }
172
173 if isblank(n) {
174 return
175 }
176
Russ Cox140ef3c2015-05-26 23:08:39 -0400177 if n.Name == nil {
178 // named OLITERAL needs Name; most OLITERALs don't.
179 n.Name = new(Name)
180 }
Russ Cox8c195bd2015-02-13 14:40:36 -0500181 n.Lineno = int32(parserline())
Russ Cox382b44e2015-02-23 16:07:24 -0500182 s := n.Sym
Russ Cox8c195bd2015-02-13 14:40:36 -0500183
184 // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
Håvard Haugendc3540d2015-08-30 23:56:40 +0200185 if importpkg == nil && !typecheckok && s.Pkg != localpkg {
Russ Cox17228f42015-04-17 12:03:22 -0400186 Yyerror("cannot declare name %v", s)
Russ Cox8c195bd2015-02-13 14:40:36 -0500187 }
188
189 if ctxt == PEXTERN && s.Name == "init" {
Shenghou Mab3fb0fd2015-05-13 19:05:50 -0400190 Yyerror("cannot declare init - must be func")
Russ Cox8c195bd2015-02-13 14:40:36 -0500191 }
192
Russ Cox382b44e2015-02-23 16:07:24 -0500193 gen := 0
Russ Cox8c195bd2015-02-13 14:40:36 -0500194 if ctxt == PEXTERN {
195 externdcl = list(externdcl, n)
Russ Coxdc7b54b2015-02-17 22:13:49 -0500196 if dflag() {
Russ Cox17228f42015-04-17 12:03:22 -0400197 fmt.Printf("\t%v global decl %v %p\n", Ctxt.Line(int(lineno)), s, n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500198 }
199 } else {
200 if Curfn == nil && ctxt == PAUTO {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200201 Fatalf("automatic outside function")
Russ Cox8c195bd2015-02-13 14:40:36 -0500202 }
203 if Curfn != nil {
Josh Bleecher Snyder3ed9e4c2015-03-25 19:33:01 -0700204 Curfn.Func.Dcl = list(Curfn.Func.Dcl, n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500205 }
206 if n.Op == OTYPE {
207 declare_typegen++
208 gen = declare_typegen
209 } else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
210 vargen++
211 gen = vargen
212 }
213 pushdcl(s)
Russ Coxfd2154f2015-05-27 07:31:56 -0400214 n.Name.Curfn = Curfn
Russ Cox8c195bd2015-02-13 14:40:36 -0500215 }
216
217 if ctxt == PAUTO {
218 n.Xoffset = 0
219 }
220
221 if s.Block == block {
222 // functype will print errors about duplicate function arguments.
223 // Don't repeat the error here.
224 if ctxt != PPARAM && ctxt != PPARAMOUT {
225 redeclare(s, "in this block")
226 }
227 }
228
229 s.Block = block
230 s.Lastlineno = int32(parserline())
231 s.Def = n
Russ Cox11322d42015-05-26 23:56:14 -0400232 n.Name.Vargen = int32(gen)
Russ Cox3c3019a2015-05-27 00:44:05 -0400233 n.Name.Funcdepth = Funcdepth
Russ Cox8c195bd2015-02-13 14:40:36 -0500234 n.Class = uint8(ctxt)
235
236 autoexport(n, ctxt)
237}
238
Josh Bleecher Snyder102b8062015-03-27 12:00:07 -0700239func addvar(n *Node, t *Type, ctxt uint8) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500240 if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200241 Fatalf("addvar: n=%v t=%v nil", n, t)
Russ Cox8c195bd2015-02-13 14:40:36 -0500242 }
243
244 n.Op = ONAME
245 declare(n, ctxt)
246 n.Type = t
247}
248
249/*
250 * declare variables from grammar
251 * new_name_list (type | [type] = expr_list)
252 */
253func variter(vl *NodeList, t *Node, el *NodeList) *NodeList {
Russ Cox175929b2015-03-02 14:22:05 -0500254 var init *NodeList
Russ Cox382b44e2015-02-23 16:07:24 -0500255 doexpr := el != nil
Russ Cox8c195bd2015-02-13 14:40:36 -0500256
257 if count(el) == 1 && count(vl) > 1 {
Russ Cox382b44e2015-02-23 16:07:24 -0500258 e := el.N
259 as2 := Nod(OAS2, nil, nil)
Russ Cox8c195bd2015-02-13 14:40:36 -0500260 as2.List = vl
261 as2.Rlist = list1(e)
Russ Cox382b44e2015-02-23 16:07:24 -0500262 var v *Node
Russ Cox8c195bd2015-02-13 14:40:36 -0500263 for ; vl != nil; vl = vl.Next {
264 v = vl.N
265 v.Op = ONAME
266 declare(v, dclcontext)
Russ Cox3c3019a2015-05-27 00:44:05 -0400267 v.Name.Param.Ntype = t
Russ Cox4fdd5362015-05-26 22:19:27 -0400268 v.Name.Defn = as2
Russ Cox8c195bd2015-02-13 14:40:36 -0500269 if Funcdepth > 0 {
270 init = list(init, Nod(ODCL, v, nil))
271 }
272 }
273
274 return list(init, as2)
275 }
276
Russ Cox382b44e2015-02-23 16:07:24 -0500277 var v *Node
278 var e *Node
Russ Cox8c195bd2015-02-13 14:40:36 -0500279 for ; vl != nil; vl = vl.Next {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500280 if doexpr {
Russ Cox8c195bd2015-02-13 14:40:36 -0500281 if el == nil {
282 Yyerror("missing expression in var declaration")
283 break
284 }
285
286 e = el.N
287 el = el.Next
288 } else {
289 e = nil
290 }
291
292 v = vl.N
293 v.Op = ONAME
294 declare(v, dclcontext)
Russ Cox3c3019a2015-05-27 00:44:05 -0400295 v.Name.Param.Ntype = t
Russ Cox8c195bd2015-02-13 14:40:36 -0500296
297 if e != nil || Funcdepth > 0 || isblank(v) {
298 if Funcdepth > 0 {
299 init = list(init, Nod(ODCL, v, nil))
300 }
301 e = Nod(OAS, v, e)
302 init = list(init, e)
303 if e.Right != nil {
Russ Cox4fdd5362015-05-26 22:19:27 -0400304 v.Name.Defn = e
Russ Cox8c195bd2015-02-13 14:40:36 -0500305 }
306 }
307 }
308
309 if el != nil {
310 Yyerror("extra expression in var declaration")
311 }
312 return init
313}
314
315/*
316 * declare constants from grammar
317 * new_name_list [[type] = expr_list]
318 */
319func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
David Chase05d8f1d2015-05-22 22:01:01 -0400320 lno := int32(0) // default is to leave line number alone in listtreecopy
Russ Cox8c195bd2015-02-13 14:40:36 -0500321 if cl == nil {
322 if t != nil {
323 Yyerror("const declaration cannot have type without expression")
324 }
325 cl = lastconst
326 t = lasttype
David Chase05d8f1d2015-05-22 22:01:01 -0400327 lno = vl.N.Lineno
Russ Cox8c195bd2015-02-13 14:40:36 -0500328 } else {
329 lastconst = cl
330 lasttype = t
331 }
David Chase05d8f1d2015-05-22 22:01:01 -0400332 cl = listtreecopy(cl, lno)
Russ Cox8c195bd2015-02-13 14:40:36 -0500333
Russ Cox382b44e2015-02-23 16:07:24 -0500334 var v *Node
335 var c *Node
Russ Cox44928112015-03-02 20:34:22 -0500336 var vv *NodeList
Russ Cox8c195bd2015-02-13 14:40:36 -0500337 for ; vl != nil; vl = vl.Next {
338 if cl == nil {
339 Yyerror("missing value in const declaration")
340 break
341 }
342
343 c = cl.N
344 cl = cl.Next
345
346 v = vl.N
347 v.Op = OLITERAL
348 declare(v, dclcontext)
349
Russ Cox3c3019a2015-05-27 00:44:05 -0400350 v.Name.Param.Ntype = t
Russ Cox4fdd5362015-05-26 22:19:27 -0400351 v.Name.Defn = c
Russ Cox8c195bd2015-02-13 14:40:36 -0500352
353 vv = list(vv, Nod(ODCLCONST, v, nil))
354 }
355
356 if cl != nil {
357 Yyerror("extra expression in const declaration")
358 }
359 iota_ += 1
360 return vv
361}
362
363/*
364 * this generates a new name node,
365 * typically for labels or other one-off names.
366 */
367func newname(s *Sym) *Node {
Russ Cox8c195bd2015-02-13 14:40:36 -0500368 if s == nil {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200369 Fatalf("newname nil")
Russ Cox8c195bd2015-02-13 14:40:36 -0500370 }
371
Russ Cox382b44e2015-02-23 16:07:24 -0500372 n := Nod(ONAME, nil, nil)
Russ Cox8c195bd2015-02-13 14:40:36 -0500373 n.Sym = s
374 n.Type = nil
Josh Bleecher Snyder75883ba2015-04-02 19:58:37 -0700375 n.Addable = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500376 n.Ullman = 1
377 n.Xoffset = 0
378 return n
379}
380
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -0700381// newfuncname generates a new name node for a function or method.
382// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
383func newfuncname(s *Sym) *Node {
384 n := newname(s)
385 n.Func = new(Func)
Russ Coxfd2154f2015-05-27 07:31:56 -0400386 n.Func.FCurfn = Curfn
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -0700387 return n
388}
389
Russ Cox8c195bd2015-02-13 14:40:36 -0500390/*
391 * this generates a new name node for a name
392 * being declared.
393 */
394func dclname(s *Sym) *Node {
Russ Cox382b44e2015-02-23 16:07:24 -0500395 n := newname(s)
Russ Cox8c195bd2015-02-13 14:40:36 -0500396 n.Op = ONONAME // caller will correct it
397 return n
398}
399
400func typenod(t *Type) *Node {
401 // if we copied another type with *t = *u
402 // then t->nod might be out of date, so
403 // check t->nod->type too
404 if t.Nod == nil || t.Nod.Type != t {
405 t.Nod = Nod(OTYPE, nil, nil)
406 t.Nod.Type = t
407 t.Nod.Sym = t.Sym
408 }
409
410 return t.Nod
411}
412
413/*
414 * this will return an old name
415 * that has already been pushed on the
416 * declaration list. a diagnostic is
417 * generated if no name has been defined.
418 */
419func oldname(s *Sym) *Node {
Russ Cox382b44e2015-02-23 16:07:24 -0500420 n := s.Def
Russ Cox8c195bd2015-02-13 14:40:36 -0500421 if n == nil {
422 // maybe a top-level name will come along
423 // to give this a definition later.
424 // walkdef will check s->def again once
425 // all the input source has been processed.
426 n = newname(s)
Russ Cox8c195bd2015-02-13 14:40:36 -0500427 n.Op = ONONAME
Russ Cox11322d42015-05-26 23:56:14 -0400428 n.Name.Iota = iota_ // save current iota value in const declarations
Russ Cox8c195bd2015-02-13 14:40:36 -0500429 }
430
Russ Cox3c3019a2015-05-27 00:44:05 -0400431 if Curfn != nil && n.Op == ONAME && n.Name.Funcdepth > 0 && n.Name.Funcdepth != Funcdepth {
Russ Cox8c195bd2015-02-13 14:40:36 -0500432 // inner func is referring to var in outer func.
433 //
434 // TODO(rsc): If there is an outer variable x and we
435 // are parsing x := 5 inside the closure, until we get to
436 // the := it looks like a reference to the outer x so we'll
437 // make x a closure variable unnecessarily.
Russ Cox3c3019a2015-05-27 00:44:05 -0400438 if n.Name.Param.Closure == nil || n.Name.Param.Closure.Name.Funcdepth != Funcdepth {
Russ Cox8c195bd2015-02-13 14:40:36 -0500439 // create new closure var.
Russ Cox382b44e2015-02-23 16:07:24 -0500440 c := Nod(ONAME, nil, nil)
Russ Cox8c195bd2015-02-13 14:40:36 -0500441
442 c.Sym = s
443 c.Class = PPARAMREF
444 c.Isddd = n.Isddd
Russ Cox4fdd5362015-05-26 22:19:27 -0400445 c.Name.Defn = n
Josh Bleecher Snyder75883ba2015-04-02 19:58:37 -0700446 c.Addable = false
Russ Cox8c195bd2015-02-13 14:40:36 -0500447 c.Ullman = 2
Russ Cox3c3019a2015-05-27 00:44:05 -0400448 c.Name.Funcdepth = Funcdepth
449 c.Name.Param.Outer = n.Name.Param.Closure
450 n.Name.Param.Closure = c
451 c.Name.Param.Closure = n
Russ Cox8c195bd2015-02-13 14:40:36 -0500452 c.Xoffset = 0
Josh Bleecher Snyder3ed9e4c2015-03-25 19:33:01 -0700453 Curfn.Func.Cvars = list(Curfn.Func.Cvars, c)
Russ Cox8c195bd2015-02-13 14:40:36 -0500454 }
455
456 // return ref to closure var, not original
Russ Cox3c3019a2015-05-27 00:44:05 -0400457 return n.Name.Param.Closure
Russ Cox8c195bd2015-02-13 14:40:36 -0500458 }
459
460 return n
461}
462
463/*
464 * := declarations
465 */
Russ Coxdc7b54b2015-02-17 22:13:49 -0500466func colasname(n *Node) bool {
Russ Cox8c195bd2015-02-13 14:40:36 -0500467 switch n.Op {
468 case ONAME,
469 ONONAME,
470 OPACK,
471 OTYPE,
472 OLITERAL:
Russ Coxdc7b54b2015-02-17 22:13:49 -0500473 return n.Sym != nil
Russ Cox8c195bd2015-02-13 14:40:36 -0500474 }
475
Russ Coxdc7b54b2015-02-17 22:13:49 -0500476 return false
Russ Cox8c195bd2015-02-13 14:40:36 -0500477}
478
479func colasdefn(left *NodeList, defn *Node) {
Russ Cox382b44e2015-02-23 16:07:24 -0500480 for l := left; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -0500481 if l.N.Sym != nil {
482 l.N.Sym.Flags |= SymUniq
483 }
484 }
485
Russ Cox382b44e2015-02-23 16:07:24 -0500486 nnew := 0
487 nerr := 0
488 var n *Node
489 for l := left; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -0500490 n = l.N
491 if isblank(n) {
492 continue
493 }
Russ Coxdc7b54b2015-02-17 22:13:49 -0500494 if !colasname(n) {
Russ Cox17228f42015-04-17 12:03:22 -0400495 yyerrorl(int(defn.Lineno), "non-name %v on left side of :=", n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500496 nerr++
497 continue
498 }
499
500 if n.Sym.Flags&SymUniq == 0 {
Russ Cox17228f42015-04-17 12:03:22 -0400501 yyerrorl(int(defn.Lineno), "%v repeated on left side of :=", n.Sym)
Russ Cox8c195bd2015-02-13 14:40:36 -0500502 n.Diag++
503 nerr++
504 continue
505 }
506
507 n.Sym.Flags &^= SymUniq
508 if n.Sym.Block == block {
509 continue
510 }
511
512 nnew++
513 n = newname(n.Sym)
514 declare(n, dclcontext)
Russ Cox4fdd5362015-05-26 22:19:27 -0400515 n.Name.Defn = defn
Russ Cox8c195bd2015-02-13 14:40:36 -0500516 defn.Ninit = list(defn.Ninit, Nod(ODCL, n, nil))
517 l.N = n
518 }
519
520 if nnew == 0 && nerr == 0 {
521 yyerrorl(int(defn.Lineno), "no new variables on left side of :=")
522 }
523}
524
525func colas(left *NodeList, right *NodeList, lno int32) *Node {
Russ Cox382b44e2015-02-23 16:07:24 -0500526 as := Nod(OAS2, nil, nil)
Russ Cox8c195bd2015-02-13 14:40:36 -0500527 as.List = left
528 as.Rlist = right
Josh Bleecher Snyder75883ba2015-04-02 19:58:37 -0700529 as.Colas = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500530 as.Lineno = lno
531 colasdefn(left, as)
532
533 // make the tree prettier; not necessary
534 if count(left) == 1 && count(right) == 1 {
535 as.Left = as.List.N
536 as.Right = as.Rlist.N
537 as.List = nil
538 as.Rlist = nil
539 as.Op = OAS
540 }
541
542 return as
543}
544
545/*
546 * declare the arguments in an
547 * interface field declaration.
548 */
549func ifacedcl(n *Node) {
550 if n.Op != ODCLFIELD || n.Right == nil {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200551 Fatalf("ifacedcl")
Russ Cox8c195bd2015-02-13 14:40:36 -0500552 }
553
554 if isblank(n.Left) {
555 Yyerror("methods must have a unique non-blank name")
556 }
557
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -0700558 n.Func = new(Func)
Russ Coxfd2154f2015-05-27 07:31:56 -0400559 n.Func.FCurfn = Curfn
Russ Cox8c195bd2015-02-13 14:40:36 -0500560 dclcontext = PPARAM
561 markdcl()
562 Funcdepth++
Russ Cox3c3019a2015-05-27 00:44:05 -0400563 n.Func.Outer = Curfn
Russ Cox8c195bd2015-02-13 14:40:36 -0500564 Curfn = n
565 funcargs(n.Right)
566
567 // funcbody is normally called after the parser has
568 // seen the body of a function but since an interface
569 // field declaration does not have a body, we must
570 // call it now to pop the current declaration context.
571 dclcontext = PAUTO
572
573 funcbody(n)
574}
575
576/*
577 * declare the function proper
578 * and declare the arguments.
579 * called in extern-declaration context
580 * returns in auto-declaration context.
581 */
582func funchdr(n *Node) {
583 // change the declaration context from extern to auto
584 if Funcdepth == 0 && dclcontext != PEXTERN {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200585 Fatalf("funchdr: dclcontext")
Russ Cox8c195bd2015-02-13 14:40:36 -0500586 }
587
Michael Hudson-Doyle1125cd42015-07-15 11:31:30 +1200588 if importpkg == nil && n.Func.Nname != nil {
589 makefuncsym(n.Func.Nname.Sym)
590 }
591
Russ Cox8c195bd2015-02-13 14:40:36 -0500592 dclcontext = PAUTO
593 markdcl()
594 Funcdepth++
595
Russ Cox3c3019a2015-05-27 00:44:05 -0400596 n.Func.Outer = Curfn
Russ Cox8c195bd2015-02-13 14:40:36 -0500597 Curfn = n
598
Russ Coxbd4fff62015-05-27 10:42:55 -0400599 if n.Func.Nname != nil {
600 funcargs(n.Func.Nname.Name.Param.Ntype)
Russ Cox3c3019a2015-05-27 00:44:05 -0400601 } else if n.Func.Ntype != nil {
602 funcargs(n.Func.Ntype)
Russ Cox8c195bd2015-02-13 14:40:36 -0500603 } else {
604 funcargs2(n.Type)
605 }
606}
607
608func funcargs(nt *Node) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500609 if nt.Op != OTFUNC {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200610 Fatalf("funcargs %v", Oconv(int(nt.Op), 0))
Russ Cox8c195bd2015-02-13 14:40:36 -0500611 }
612
613 // re-start the variable generation number
614 // we want to use small numbers for the return variables,
615 // so let them have the chunk starting at 1.
616 vargen = count(nt.Rlist)
617
618 // declare the receiver and in arguments.
619 // no n->defn because type checking of func header
620 // will not fill in the types until later
621 if nt.Left != nil {
Russ Cox382b44e2015-02-23 16:07:24 -0500622 n := nt.Left
Russ Cox8c195bd2015-02-13 14:40:36 -0500623 if n.Op != ODCLFIELD {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200624 Fatalf("funcargs receiver %v", Oconv(int(n.Op), 0))
Russ Cox8c195bd2015-02-13 14:40:36 -0500625 }
626 if n.Left != nil {
627 n.Left.Op = ONAME
Russ Cox3c3019a2015-05-27 00:44:05 -0400628 n.Left.Name.Param.Ntype = n.Right
Russ Cox8c195bd2015-02-13 14:40:36 -0500629 declare(n.Left, PPARAM)
630 if dclcontext == PAUTO {
631 vargen++
Russ Cox11322d42015-05-26 23:56:14 -0400632 n.Left.Name.Vargen = int32(vargen)
Russ Cox8c195bd2015-02-13 14:40:36 -0500633 }
634 }
635 }
636
Russ Cox382b44e2015-02-23 16:07:24 -0500637 var n *Node
638 for l := nt.List; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -0500639 n = l.N
640 if n.Op != ODCLFIELD {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200641 Fatalf("funcargs in %v", Oconv(int(n.Op), 0))
Russ Cox8c195bd2015-02-13 14:40:36 -0500642 }
643 if n.Left != nil {
644 n.Left.Op = ONAME
Russ Cox3c3019a2015-05-27 00:44:05 -0400645 n.Left.Name.Param.Ntype = n.Right
Russ Cox8c195bd2015-02-13 14:40:36 -0500646 declare(n.Left, PPARAM)
647 if dclcontext == PAUTO {
648 vargen++
Russ Cox11322d42015-05-26 23:56:14 -0400649 n.Left.Name.Vargen = int32(vargen)
Russ Cox8c195bd2015-02-13 14:40:36 -0500650 }
651 }
652 }
653
654 // declare the out arguments.
Russ Cox382b44e2015-02-23 16:07:24 -0500655 gen := count(nt.List)
Russ Cox8c195bd2015-02-13 14:40:36 -0500656 var i int = 0
Russ Cox382b44e2015-02-23 16:07:24 -0500657 var nn *Node
658 for l := nt.Rlist; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -0500659 n = l.N
660
661 if n.Op != ODCLFIELD {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200662 Fatalf("funcargs out %v", Oconv(int(n.Op), 0))
Russ Cox8c195bd2015-02-13 14:40:36 -0500663 }
664
665 if n.Left == nil {
666 // Name so that escape analysis can track it. ~r stands for 'result'.
Matthew Dempsky8b3670f2015-03-06 12:02:24 -0800667 n.Left = newname(Lookupf("~r%d", gen))
Russ Cox8c195bd2015-02-13 14:40:36 -0500668 gen++
Russ Cox8c195bd2015-02-13 14:40:36 -0500669 }
670
671 // TODO: n->left->missing = 1;
672 n.Left.Op = ONAME
673
674 if isblank(n.Left) {
675 // Give it a name so we can assign to it during return. ~b stands for 'blank'.
676 // The name must be different from ~r above because if you have
677 // func f() (_ int)
678 // func g() int
679 // f is allowed to use a plain 'return' with no arguments, while g is not.
680 // So the two cases must be distinguished.
681 // We do not record a pointer to the original node (n->orig).
682 // Having multiple names causes too much confusion in later passes.
683 nn = Nod(OXXX, nil, nil)
684
685 *nn = *n.Left
686 nn.Orig = nn
Matthew Dempsky8b3670f2015-03-06 12:02:24 -0800687 nn.Sym = Lookupf("~b%d", gen)
Russ Cox8c195bd2015-02-13 14:40:36 -0500688 gen++
Russ Cox8c195bd2015-02-13 14:40:36 -0500689 n.Left = nn
690 }
691
Russ Cox3c3019a2015-05-27 00:44:05 -0400692 n.Left.Name.Param.Ntype = n.Right
Russ Cox8c195bd2015-02-13 14:40:36 -0500693 declare(n.Left, PPARAMOUT)
694 if dclcontext == PAUTO {
695 i++
Russ Cox11322d42015-05-26 23:56:14 -0400696 n.Left.Name.Vargen = int32(i)
Russ Cox8c195bd2015-02-13 14:40:36 -0500697 }
698 }
699}
700
701/*
702 * Same as funcargs, except run over an already constructed TFUNC.
703 * This happens during import, where the hidden_fndcl rule has
704 * used functype directly to parse the function's type.
705 */
706func funcargs2(t *Type) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500707 if t.Etype != TFUNC {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200708 Fatalf("funcargs2 %v", t)
Russ Cox8c195bd2015-02-13 14:40:36 -0500709 }
710
711 if t.Thistuple != 0 {
Russ Cox382b44e2015-02-23 16:07:24 -0500712 var n *Node
713 for ft := getthisx(t).Type; ft != nil; ft = ft.Down {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500714 if ft.Nname == nil || ft.Nname.Sym == nil {
Russ Cox8c195bd2015-02-13 14:40:36 -0500715 continue
716 }
717 n = ft.Nname // no need for newname(ft->nname->sym)
718 n.Type = ft.Type
719 declare(n, PPARAM)
720 }
721 }
722
723 if t.Intuple != 0 {
Russ Cox382b44e2015-02-23 16:07:24 -0500724 var n *Node
725 for ft := getinargx(t).Type; ft != nil; ft = ft.Down {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500726 if ft.Nname == nil || ft.Nname.Sym == nil {
Russ Cox8c195bd2015-02-13 14:40:36 -0500727 continue
728 }
729 n = ft.Nname
730 n.Type = ft.Type
731 declare(n, PPARAM)
732 }
733 }
734
735 if t.Outtuple != 0 {
Russ Cox382b44e2015-02-23 16:07:24 -0500736 var n *Node
737 for ft := getoutargx(t).Type; ft != nil; ft = ft.Down {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500738 if ft.Nname == nil || ft.Nname.Sym == nil {
Russ Cox8c195bd2015-02-13 14:40:36 -0500739 continue
740 }
741 n = ft.Nname
742 n.Type = ft.Type
743 declare(n, PPARAMOUT)
744 }
745 }
746}
747
748/*
749 * finish the body.
750 * called in auto-declaration context.
751 * returns in extern-declaration context.
752 */
753func funcbody(n *Node) {
754 // change the declaration context from auto to extern
755 if dclcontext != PAUTO {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200756 Fatalf("funcbody: dclcontext")
Russ Cox8c195bd2015-02-13 14:40:36 -0500757 }
758 popdcl()
759 Funcdepth--
Russ Cox3c3019a2015-05-27 00:44:05 -0400760 Curfn = n.Func.Outer
761 n.Func.Outer = nil
Russ Cox8c195bd2015-02-13 14:40:36 -0500762 if Funcdepth == 0 {
763 dclcontext = PEXTERN
764 }
765}
766
767/*
768 * new type being defined with name s.
769 */
770func typedcl0(s *Sym) *Node {
Russ Cox382b44e2015-02-23 16:07:24 -0500771 n := newname(s)
Russ Cox8c195bd2015-02-13 14:40:36 -0500772 n.Op = OTYPE
773 declare(n, dclcontext)
774 return n
775}
776
777/*
778 * node n, which was returned by typedcl0
779 * is being declared to have uncompiled type t.
780 * return the ODCLTYPE node to use.
781 */
Dave Cheneye4981812015-03-10 09:58:01 +1100782func typedcl1(n *Node, t *Node, local bool) *Node {
Russ Cox3c3019a2015-05-27 00:44:05 -0400783 n.Name.Param.Ntype = t
Dave Cheneye4981812015-03-10 09:58:01 +1100784 n.Local = local
Russ Cox8c195bd2015-02-13 14:40:36 -0500785 return Nod(ODCLTYPE, n, nil)
786}
787
788/*
789 * structs, functions, and methods.
790 * they don't belong here, but where do they belong?
791 */
792func checkembeddedtype(t *Type) {
793 if t == nil {
794 return
795 }
796
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000797 if t.Sym == nil && Isptr[t.Etype] {
Russ Cox8c195bd2015-02-13 14:40:36 -0500798 t = t.Type
799 if t.Etype == TINTER {
800 Yyerror("embedded type cannot be a pointer to interface")
801 }
802 }
803
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000804 if Isptr[t.Etype] {
Russ Cox8c195bd2015-02-13 14:40:36 -0500805 Yyerror("embedded type cannot be a pointer")
806 } else if t.Etype == TFORW && t.Embedlineno == 0 {
807 t.Embedlineno = lineno
808 }
809}
810
811func structfield(n *Node) *Type {
Russ Cox382b44e2015-02-23 16:07:24 -0500812 lno := int(lineno)
Russ Cox8c195bd2015-02-13 14:40:36 -0500813 lineno = n.Lineno
814
815 if n.Op != ODCLFIELD {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200816 Fatalf("structfield: oops %v\n", n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500817 }
818
Russ Cox382b44e2015-02-23 16:07:24 -0500819 f := typ(TFIELD)
Russ Cox8c195bd2015-02-13 14:40:36 -0500820 f.Isddd = n.Isddd
821
822 if n.Right != nil {
823 typecheck(&n.Right, Etype)
824 n.Type = n.Right.Type
825 if n.Left != nil {
826 n.Left.Type = n.Type
827 }
828 if n.Embedded != 0 {
829 checkembeddedtype(n.Type)
830 }
831 }
832
833 n.Right = nil
834
835 f.Type = n.Type
836 if f.Type == nil {
Dave Cheney89377802015-09-07 10:37:26 +1000837 f.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500838 }
839
Russ Cox81d58102015-05-27 00:47:05 -0400840 switch n.Val().Ctype() {
Russ Cox8c195bd2015-02-13 14:40:36 -0500841 case CTSTR:
Russ Coxbed1f902015-03-02 16:03:26 -0500842 f.Note = new(string)
Russ Cox81d58102015-05-27 00:47:05 -0400843 *f.Note = n.Val().U.(string)
Russ Cox8c195bd2015-02-13 14:40:36 -0500844
845 default:
846 Yyerror("field annotation must be string")
847 fallthrough
848
Russ Cox8c195bd2015-02-13 14:40:36 -0500849 case CTxxx:
850 f.Note = nil
851 }
852
853 if n.Left != nil && n.Left.Op == ONAME {
854 f.Nname = n.Left
855 f.Embedded = n.Embedded
856 f.Sym = f.Nname.Sym
857 }
858
859 lineno = int32(lno)
860 return f
861}
862
863var uniqgen uint32
864
865func checkdupfields(t *Type, what string) {
Russ Cox382b44e2015-02-23 16:07:24 -0500866 lno := int(lineno)
Russ Cox8c195bd2015-02-13 14:40:36 -0500867
868 for ; t != nil; t = t.Down {
869 if t.Sym != nil && t.Nname != nil && !isblank(t.Nname) {
870 if t.Sym.Uniqgen == uniqgen {
871 lineno = t.Nname.Lineno
872 Yyerror("duplicate %s %s", what, t.Sym.Name)
873 } else {
874 t.Sym.Uniqgen = uniqgen
875 }
876 }
877 }
878
879 lineno = int32(lno)
880}
881
882/*
883 * convert a parsed id/type list into
884 * a type for struct/interface/arglist
885 */
886func tostruct(l *NodeList) *Type {
Russ Cox8c195bd2015-02-13 14:40:36 -0500887 var f *Type
Russ Cox382b44e2015-02-23 16:07:24 -0500888 t := typ(TSTRUCT)
Russ Cox8c195bd2015-02-13 14:40:36 -0500889
Russ Cox382b44e2015-02-23 16:07:24 -0500890 for tp := &t.Type; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -0500891 f = structfield(l.N)
892
893 *tp = f
894 tp = &f.Down
895 }
896
Dave Cheney89377802015-09-07 10:37:26 +1000897 for f := t.Type; f != nil && !t.Broke; f = f.Down {
898 if f.Broke {
899 t.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500900 }
901 }
902
903 uniqgen++
904 checkdupfields(t.Type, "field")
905
Dave Cheney89377802015-09-07 10:37:26 +1000906 if !t.Broke {
Russ Cox8c195bd2015-02-13 14:40:36 -0500907 checkwidth(t)
908 }
909
910 return t
911}
912
913func tofunargs(l *NodeList) *Type {
Russ Cox8c195bd2015-02-13 14:40:36 -0500914 var f *Type
Russ Cox8c195bd2015-02-13 14:40:36 -0500915
Russ Cox382b44e2015-02-23 16:07:24 -0500916 t := typ(TSTRUCT)
Marvin Stenger9ac0fff2015-09-08 03:51:30 +0200917 t.Funarg = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500918
Russ Cox382b44e2015-02-23 16:07:24 -0500919 for tp := &t.Type; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -0500920 f = structfield(l.N)
Marvin Stenger9ac0fff2015-09-08 03:51:30 +0200921 f.Funarg = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500922
923 // esc.c needs to find f given a PPARAM to add the tag.
924 if l.N.Left != nil && l.N.Left.Class == PPARAM {
Russ Cox3c3019a2015-05-27 00:44:05 -0400925 l.N.Left.Name.Param.Field = f
Russ Cox8c195bd2015-02-13 14:40:36 -0500926 }
927
928 *tp = f
929 tp = &f.Down
930 }
931
Dave Cheney89377802015-09-07 10:37:26 +1000932 for f := t.Type; f != nil && !t.Broke; f = f.Down {
933 if f.Broke {
934 t.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500935 }
936 }
937
938 return t
939}
940
941func interfacefield(n *Node) *Type {
Russ Cox382b44e2015-02-23 16:07:24 -0500942 lno := int(lineno)
Russ Cox8c195bd2015-02-13 14:40:36 -0500943 lineno = n.Lineno
944
945 if n.Op != ODCLFIELD {
Håvard Haugen3c9fa382015-08-30 23:10:03 +0200946 Fatalf("interfacefield: oops %v\n", n)
Russ Cox8c195bd2015-02-13 14:40:36 -0500947 }
948
Russ Cox81d58102015-05-27 00:47:05 -0400949 if n.Val().Ctype() != CTxxx {
Russ Cox8c195bd2015-02-13 14:40:36 -0500950 Yyerror("interface method cannot have annotation")
951 }
952
Russ Cox382b44e2015-02-23 16:07:24 -0500953 f := typ(TFIELD)
Russ Cox8c195bd2015-02-13 14:40:36 -0500954 f.Isddd = n.Isddd
955
956 if n.Right != nil {
957 if n.Left != nil {
958 // queue resolution of method type for later.
959 // right now all we need is the name list.
960 // avoids cycles for recursive interface types.
961 n.Type = typ(TINTERMETH)
962
963 n.Type.Nname = n.Right
964 n.Left.Type = n.Type
965 queuemethod(n)
966
967 if n.Left.Op == ONAME {
968 f.Nname = n.Left
969 f.Embedded = n.Embedded
970 f.Sym = f.Nname.Sym
971 }
972 } else {
973 typecheck(&n.Right, Etype)
974 n.Type = n.Right.Type
975
976 if n.Embedded != 0 {
977 checkembeddedtype(n.Type)
978 }
979
980 if n.Type != nil {
981 switch n.Type.Etype {
982 case TINTER:
983 break
984
985 case TFORW:
Russ Cox17228f42015-04-17 12:03:22 -0400986 Yyerror("interface type loop involving %v", n.Type)
Dave Cheney89377802015-09-07 10:37:26 +1000987 f.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500988
989 default:
Russ Cox17228f42015-04-17 12:03:22 -0400990 Yyerror("interface contains embedded non-interface %v", n.Type)
Dave Cheney89377802015-09-07 10:37:26 +1000991 f.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -0500992 }
993 }
994 }
995 }
996
997 n.Right = nil
998
999 f.Type = n.Type
1000 if f.Type == nil {
Dave Cheney89377802015-09-07 10:37:26 +10001001 f.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -05001002 }
1003
1004 lineno = int32(lno)
1005 return f
1006}
1007
1008func tointerface(l *NodeList) *Type {
Russ Cox8c195bd2015-02-13 14:40:36 -05001009 var f *Type
Russ Cox8c195bd2015-02-13 14:40:36 -05001010 var t1 *Type
1011
Russ Cox382b44e2015-02-23 16:07:24 -05001012 t := typ(TINTER)
Russ Cox8c195bd2015-02-13 14:40:36 -05001013
Russ Cox382b44e2015-02-23 16:07:24 -05001014 tp := &t.Type
Russ Cox8c195bd2015-02-13 14:40:36 -05001015 for ; l != nil; l = l.Next {
1016 f = interfacefield(l.N)
1017
1018 if l.N.Left == nil && f.Type.Etype == TINTER {
1019 // embedded interface, inline methods
1020 for t1 = f.Type.Type; t1 != nil; t1 = t1.Down {
1021 f = typ(TFIELD)
1022 f.Type = t1.Type
1023 f.Broke = t1.Broke
1024 f.Sym = t1.Sym
1025 if f.Sym != nil {
1026 f.Nname = newname(f.Sym)
1027 }
1028 *tp = f
1029 tp = &f.Down
1030 }
1031 } else {
1032 *tp = f
1033 tp = &f.Down
1034 }
1035 }
1036
Dave Cheney89377802015-09-07 10:37:26 +10001037 for f := t.Type; f != nil && !t.Broke; f = f.Down {
1038 if f.Broke {
1039 t.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -05001040 }
1041 }
1042
1043 uniqgen++
1044 checkdupfields(t.Type, "method")
1045 t = sortinter(t)
1046 checkwidth(t)
1047
1048 return t
1049}
1050
1051func embedded(s *Sym, pkg *Pkg) *Node {
Russ Cox8c195bd2015-02-13 14:40:36 -05001052 const (
1053 CenterDot = 0xB7
1054 )
1055 // Names sometimes have disambiguation junk
1056 // appended after a center dot. Discard it when
1057 // making the name for the embedded struct field.
Russ Cox382b44e2015-02-23 16:07:24 -05001058 name := s.Name
Russ Cox8c195bd2015-02-13 14:40:36 -05001059
1060 if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
1061 name = s.Name[:i]
1062 }
1063
Russ Cox382b44e2015-02-23 16:07:24 -05001064 var n *Node
Russ Cox8c195bd2015-02-13 14:40:36 -05001065 if exportname(name) {
1066 n = newname(Lookup(name))
1067 } else if s.Pkg == builtinpkg {
1068 // The name of embedded builtins belongs to pkg.
1069 n = newname(Pkglookup(name, pkg))
1070 } else {
1071 n = newname(Pkglookup(name, s.Pkg))
1072 }
1073 n = Nod(ODCLFIELD, n, oldname(s))
1074 n.Embedded = 1
1075 return n
1076}
1077
1078/*
1079 * check that the list of declarations is either all anonymous or all named
1080 */
1081func findtype(l *NodeList) *Node {
1082 for ; l != nil; l = l.Next {
1083 if l.N.Op == OKEY {
1084 return l.N.Right
1085 }
1086 }
1087 return nil
1088}
1089
1090func checkarglist(all *NodeList, input int) *NodeList {
Russ Cox382b44e2015-02-23 16:07:24 -05001091 named := 0
1092 for l := all; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -05001093 if l.N.Op == OKEY {
1094 named = 1
1095 break
1096 }
1097 }
1098
1099 if named != 0 {
Russ Cox175929b2015-03-02 14:22:05 -05001100 var n *Node
Russ Cox382b44e2015-02-23 16:07:24 -05001101 var l *NodeList
Russ Cox8c195bd2015-02-13 14:40:36 -05001102 for l = all; l != nil; l = l.Next {
1103 n = l.N
1104 if n.Op != OKEY && n.Sym == nil {
1105 Yyerror("mixed named and unnamed function parameters")
1106 break
1107 }
1108 }
1109
1110 if l == nil && n != nil && n.Op != OKEY {
1111 Yyerror("final function parameter must have type")
1112 }
1113 }
1114
Russ Cox175929b2015-03-02 14:22:05 -05001115 var nextt *Node
Russ Cox382b44e2015-02-23 16:07:24 -05001116 var t *Node
1117 var n *Node
1118 for l := all; l != nil; l = l.Next {
Russ Cox8c195bd2015-02-13 14:40:36 -05001119 // can cache result from findtype to avoid
1120 // quadratic behavior here, but unlikely to matter.
1121 n = l.N
1122
1123 if named != 0 {
1124 if n.Op == OKEY {
1125 t = n.Right
1126 n = n.Left
1127 nextt = nil
1128 } else {
1129 if nextt == nil {
1130 nextt = findtype(l)
1131 }
1132 t = nextt
1133 }
1134 } else {
1135 t = n
1136 n = nil
1137 }
1138
1139 // during import l->n->op is OKEY, but l->n->left->sym == S
1140 // means it was a '?', not that it was
1141 // a lone type This doesn't matter for the exported
1142 // declarations, which are parsed by rules that don't
1143 // use checkargs, but can happen for func literals in
1144 // the inline bodies.
1145 // TODO(rsc) this can go when typefmt case TFIELD in exportmode fmt.c prints _ instead of ?
1146 if importpkg != nil && n.Sym == nil {
1147 n = nil
1148 }
1149
1150 if n != nil && n.Sym == nil {
1151 t = n
1152 n = nil
1153 }
1154
1155 if n != nil {
1156 n = newname(n.Sym)
1157 }
1158 n = Nod(ODCLFIELD, n, t)
1159 if n.Right != nil && n.Right.Op == ODDD {
Russ Coxdc7b54b2015-02-17 22:13:49 -05001160 if input == 0 {
Russ Cox8c195bd2015-02-13 14:40:36 -05001161 Yyerror("cannot use ... in output argument list")
1162 } else if l.Next != nil {
1163 Yyerror("can only use ... as final argument in list")
1164 }
1165 n.Right.Op = OTARRAY
1166 n.Right.Right = n.Right.Left
1167 n.Right.Left = nil
Dave Cheneyd3287562015-03-09 16:24:07 +11001168 n.Isddd = true
Russ Cox8c195bd2015-02-13 14:40:36 -05001169 if n.Left != nil {
Dave Cheneyd3287562015-03-09 16:24:07 +11001170 n.Left.Isddd = true
Russ Cox8c195bd2015-02-13 14:40:36 -05001171 }
1172 }
1173
1174 l.N = n
1175 }
1176
1177 return all
1178}
1179
1180func fakethis() *Node {
Russ Cox382b44e2015-02-23 16:07:24 -05001181 n := Nod(ODCLFIELD, nil, typenod(Ptrto(typ(TSTRUCT))))
Russ Cox8c195bd2015-02-13 14:40:36 -05001182 return n
1183}
1184
1185/*
1186 * Is this field a method on an interface?
1187 * Those methods have an anonymous
1188 * *struct{} as the receiver.
1189 * (See fakethis above.)
1190 */
Russ Coxdc7b54b2015-02-17 22:13:49 -05001191func isifacemethod(f *Type) bool {
Russ Cox382b44e2015-02-23 16:07:24 -05001192 rcvr := getthisx(f).Type
Russ Cox8c195bd2015-02-13 14:40:36 -05001193 if rcvr.Sym != nil {
Russ Coxdc7b54b2015-02-17 22:13:49 -05001194 return false
Russ Cox8c195bd2015-02-13 14:40:36 -05001195 }
Russ Cox382b44e2015-02-23 16:07:24 -05001196 t := rcvr.Type
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +00001197 if !Isptr[t.Etype] {
Russ Coxdc7b54b2015-02-17 22:13:49 -05001198 return false
Russ Cox8c195bd2015-02-13 14:40:36 -05001199 }
1200 t = t.Type
1201 if t.Sym != nil || t.Etype != TSTRUCT || t.Type != nil {
Russ Coxdc7b54b2015-02-17 22:13:49 -05001202 return false
Russ Cox8c195bd2015-02-13 14:40:36 -05001203 }
Russ Coxdc7b54b2015-02-17 22:13:49 -05001204 return true
Russ Cox8c195bd2015-02-13 14:40:36 -05001205}
1206
1207/*
1208 * turn a parsed function declaration
1209 * into a type
1210 */
1211func functype(this *Node, in *NodeList, out *NodeList) *Type {
Russ Cox382b44e2015-02-23 16:07:24 -05001212 t := typ(TFUNC)
Russ Cox8c195bd2015-02-13 14:40:36 -05001213
Russ Cox175929b2015-03-02 14:22:05 -05001214 var rcvr *NodeList
Russ Cox8c195bd2015-02-13 14:40:36 -05001215 if this != nil {
1216 rcvr = list1(this)
1217 }
1218 t.Type = tofunargs(rcvr)
1219 t.Type.Down = tofunargs(out)
1220 t.Type.Down.Down = tofunargs(in)
1221
1222 uniqgen++
1223 checkdupfields(t.Type.Type, "argument")
1224 checkdupfields(t.Type.Down.Type, "argument")
1225 checkdupfields(t.Type.Down.Down.Type, "argument")
1226
Dave Cheney89377802015-09-07 10:37:26 +10001227 if t.Type.Broke || t.Type.Down.Broke || t.Type.Down.Down.Broke {
1228 t.Broke = true
Russ Cox8c195bd2015-02-13 14:40:36 -05001229 }
1230
1231 if this != nil {
1232 t.Thistuple = 1
1233 }
1234 t.Outtuple = count(out)
1235 t.Intuple = count(in)
Marvin Stenger9ac0fff2015-09-08 03:51:30 +02001236 t.Outnamed = false
Russ Cox8c195bd2015-02-13 14:40:36 -05001237 if t.Outtuple > 0 && out.N.Left != nil && out.N.Left.Orig != nil {
Russ Cox382b44e2015-02-23 16:07:24 -05001238 s := out.N.Left.Orig.Sym
Russ Cox8c195bd2015-02-13 14:40:36 -05001239 if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
Marvin Stenger9ac0fff2015-09-08 03:51:30 +02001240 t.Outnamed = true
Russ Cox8c195bd2015-02-13 14:40:36 -05001241 }
1242 }
1243
1244 return t
1245}
1246
1247var methodsym_toppkg *Pkg
1248
1249func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
1250 var s *Sym
1251 var p string
Russ Cox8c195bd2015-02-13 14:40:36 -05001252 var suffix string
1253 var spkg *Pkg
1254
Russ Cox382b44e2015-02-23 16:07:24 -05001255 t := t0
Russ Cox8c195bd2015-02-13 14:40:36 -05001256 if t == nil {
1257 goto bad
1258 }
1259 s = t.Sym
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +00001260 if s == nil && Isptr[t.Etype] {
Russ Cox8c195bd2015-02-13 14:40:36 -05001261 t = t.Type
1262 if t == nil {
1263 goto bad
1264 }
1265 s = t.Sym
1266 }
1267
1268 spkg = nil
1269 if s != nil {
1270 spkg = s.Pkg
1271 }
1272
1273 // if t0 == *t and t0 has a sym,
1274 // we want to see *t, not t0, in the method name.
1275 if t != t0 && t0.Sym != nil {
1276 t0 = Ptrto(t)
1277 }
1278
1279 suffix = ""
1280 if iface != 0 {
1281 dowidth(t0)
1282 if t0.Width < Types[Tptr].Width {
1283 suffix = "·i"
1284 }
1285 }
1286
1287 if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) {
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +00001288 if t0.Sym == nil && Isptr[t0.Etype] {
Russ Cox8c195bd2015-02-13 14:40:36 -05001289 p = fmt.Sprintf("(%v).%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
1290 } else {
1291 p = fmt.Sprintf("%v.%s.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Pkg.Prefix, nsym.Name, suffix)
1292 }
1293 } else {
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +00001294 if t0.Sym == nil && Isptr[t0.Etype] {
Russ Cox8c195bd2015-02-13 14:40:36 -05001295 p = fmt.Sprintf("(%v).%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix)
1296 } else {
1297 p = fmt.Sprintf("%v.%s%s", Tconv(t0, obj.FmtLeft|obj.FmtShort), nsym.Name, suffix)
1298 }
1299 }
1300
1301 if spkg == nil {
1302 if methodsym_toppkg == nil {
Russ Coxbed1f902015-03-02 16:03:26 -05001303 methodsym_toppkg = mkpkg("go")
Russ Cox8c195bd2015-02-13 14:40:36 -05001304 }
1305 spkg = methodsym_toppkg
1306 }
1307
1308 s = Pkglookup(p, spkg)
1309
1310 return s
1311
1312bad:
Russ Cox17228f42015-04-17 12:03:22 -04001313 Yyerror("illegal receiver type: %v", t0)
Russ Cox8c195bd2015-02-13 14:40:36 -05001314 return nil
1315}
1316
1317func methodname(n *Node, t *Type) *Node {
Russ Cox382b44e2015-02-23 16:07:24 -05001318 s := methodsym(n.Sym, t, 0)
Russ Cox8c195bd2015-02-13 14:40:36 -05001319 if s == nil {
1320 return n
1321 }
1322 return newname(s)
1323}
1324
1325func methodname1(n *Node, t *Node) *Node {
Russ Cox382b44e2015-02-23 16:07:24 -05001326 star := ""
Russ Cox8c195bd2015-02-13 14:40:36 -05001327 if t.Op == OIND {
1328 star = "*"
1329 t = t.Left
1330 }
1331
1332 if t.Sym == nil || isblank(n) {
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -07001333 return newfuncname(n.Sym)
Russ Cox8c195bd2015-02-13 14:40:36 -05001334 }
1335
Russ Cox382b44e2015-02-23 16:07:24 -05001336 var p string
Russ Cox8c195bd2015-02-13 14:40:36 -05001337 if star != "" {
Russ Cox17228f42015-04-17 12:03:22 -04001338 p = fmt.Sprintf("(%s%v).%v", star, t.Sym, n.Sym)
Russ Cox8c195bd2015-02-13 14:40:36 -05001339 } else {
Russ Cox17228f42015-04-17 12:03:22 -04001340 p = fmt.Sprintf("%v.%v", t.Sym, n.Sym)
Russ Cox8c195bd2015-02-13 14:40:36 -05001341 }
1342
1343 if exportname(t.Sym.Name) {
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -07001344 n = newfuncname(Lookup(p))
Russ Cox8c195bd2015-02-13 14:40:36 -05001345 } else {
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -07001346 n = newfuncname(Pkglookup(p, t.Sym.Pkg))
Russ Cox8c195bd2015-02-13 14:40:36 -05001347 }
1348
1349 return n
1350}
1351
1352/*
1353 * add a method, declared as a function,
1354 * n is fieldname, pa is base type, t is function type
1355 */
1356func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
Russ Cox8c195bd2015-02-13 14:40:36 -05001357 // get field sym
1358 if sf == nil {
Håvard Haugen3c9fa382015-08-30 23:10:03 +02001359 Fatalf("no method symbol")
Russ Cox8c195bd2015-02-13 14:40:36 -05001360 }
1361
1362 // get parent type sym
Russ Cox382b44e2015-02-23 16:07:24 -05001363 pa := getthisx(t).Type // ptr to this structure
Russ Cox8c195bd2015-02-13 14:40:36 -05001364 if pa == nil {
1365 Yyerror("missing receiver")
1366 return
1367 }
1368
1369 pa = pa.Type
Russ Cox382b44e2015-02-23 16:07:24 -05001370 f := methtype(pa, 1)
Russ Cox8c195bd2015-02-13 14:40:36 -05001371 if f == nil {
1372 t = pa
1373 if t == nil { // rely on typecheck having complained before
1374 return
1375 }
1376 if t != nil {
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +00001377 if Isptr[t.Etype] {
Russ Cox8c195bd2015-02-13 14:40:36 -05001378 if t.Sym != nil {
Russ Cox17228f42015-04-17 12:03:22 -04001379 Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
Russ Cox8c195bd2015-02-13 14:40:36 -05001380 return
1381 }
1382
1383 t = t.Type
1384 }
1385
Dave Cheney89377802015-09-07 10:37:26 +10001386 if t.Broke { // rely on typecheck having complained before
Russ Cox8c195bd2015-02-13 14:40:36 -05001387 return
1388 }
1389 if t.Sym == nil {
Russ Cox17228f42015-04-17 12:03:22 -04001390 Yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
Russ Cox8c195bd2015-02-13 14:40:36 -05001391 return
1392 }
1393
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +00001394 if Isptr[t.Etype] {
Russ Cox17228f42015-04-17 12:03:22 -04001395 Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
Russ Cox8c195bd2015-02-13 14:40:36 -05001396 return
1397 }
1398
1399 if t.Etype == TINTER {
Russ Cox17228f42015-04-17 12:03:22 -04001400 Yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
Russ Cox8c195bd2015-02-13 14:40:36 -05001401 return
1402 }
1403 }
1404
1405 // Should have picked off all the reasons above,
1406 // but just in case, fall back to generic error.
Russ Cox17228f42015-04-17 12:03:22 -04001407 Yyerror("invalid receiver type %v (%v / %v)", pa, Tconv(pa, obj.FmtLong), Tconv(t, obj.FmtLong))
Russ Cox8c195bd2015-02-13 14:40:36 -05001408
1409 return
1410 }
1411
1412 pa = f
1413 if pa.Etype == TSTRUCT {
Russ Cox382b44e2015-02-23 16:07:24 -05001414 for f := pa.Type; f != nil; f = f.Down {
Russ Cox8c195bd2015-02-13 14:40:36 -05001415 if f.Sym == sf {
Russ Cox17228f42015-04-17 12:03:22 -04001416 Yyerror("type %v has both field and method named %v", pa, sf)
Russ Cox8c195bd2015-02-13 14:40:36 -05001417 return
1418 }
1419 }
1420 }
1421
Dave Cheneye4981812015-03-10 09:58:01 +11001422 if local && !pa.Local {
Russ Cox8c195bd2015-02-13 14:40:36 -05001423 // defining method on non-local type.
Russ Cox17228f42015-04-17 12:03:22 -04001424 Yyerror("cannot define new methods on non-local type %v", pa)
Russ Cox8c195bd2015-02-13 14:40:36 -05001425
1426 return
1427 }
1428
Russ Cox382b44e2015-02-23 16:07:24 -05001429 n := Nod(ODCLFIELD, newname(sf), nil)
Russ Cox8c195bd2015-02-13 14:40:36 -05001430 n.Type = t
1431
Russ Cox175929b2015-03-02 14:22:05 -05001432 var d *Type // last found
Russ Cox382b44e2015-02-23 16:07:24 -05001433 for f := pa.Method; f != nil; f = f.Down {
Russ Cox8c195bd2015-02-13 14:40:36 -05001434 d = f
1435 if f.Etype != TFIELD {
Håvard Haugen3c9fa382015-08-30 23:10:03 +02001436 Fatalf("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong))
Russ Cox8c195bd2015-02-13 14:40:36 -05001437 }
1438 if sf.Name != f.Sym.Name {
1439 continue
1440 }
1441 if !Eqtype(t, f.Type) {
Russ Cox17228f42015-04-17 12:03:22 -04001442 Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", pa, sf, f.Type, t)
Russ Cox8c195bd2015-02-13 14:40:36 -05001443 }
1444 return
1445 }
1446
1447 f = structfield(n)
Russ Coxdc7b54b2015-02-17 22:13:49 -05001448 f.Nointerface = nointerface
Russ Cox8c195bd2015-02-13 14:40:36 -05001449
1450 // during import unexported method names should be in the type's package
1451 if importpkg != nil && f.Sym != nil && !exportname(f.Sym.Name) && f.Sym.Pkg != structpkg {
Håvard Haugen3c9fa382015-08-30 23:10:03 +02001452 Fatalf("imported method name %v in wrong package %s\n", Sconv(f.Sym, obj.FmtSign), structpkg.Name)
Russ Cox8c195bd2015-02-13 14:40:36 -05001453 }
1454
1455 if d == nil {
1456 pa.Method = f
1457 } else {
1458 d.Down = f
1459 }
1460 return
1461}
1462
1463func funccompile(n *Node) {
1464 Stksize = BADWIDTH
1465 Maxarg = 0
1466
1467 if n.Type == nil {
1468 if nerrors == 0 {
Håvard Haugen3c9fa382015-08-30 23:10:03 +02001469 Fatalf("funccompile missing type")
Russ Cox8c195bd2015-02-13 14:40:36 -05001470 }
1471 return
1472 }
1473
1474 // assign parameter offsets
1475 checkwidth(n.Type)
1476
1477 if Curfn != nil {
Håvard Haugen3c9fa382015-08-30 23:10:03 +02001478 Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym)
Russ Cox8c195bd2015-02-13 14:40:36 -05001479 }
1480
1481 Stksize = 0
1482 dclcontext = PAUTO
Russ Cox3c3019a2015-05-27 00:44:05 -04001483 Funcdepth = n.Func.Depth + 1
Russ Cox8c195bd2015-02-13 14:40:36 -05001484 compile(n)
1485 Curfn = nil
1486 Funcdepth = 0
1487 dclcontext = PEXTERN
1488}
1489
1490func funcsym(s *Sym) *Sym {
Russ Coxc8198342015-03-12 18:45:30 -04001491 if s.Fsym != nil {
1492 return s.Fsym
1493 }
Russ Cox8c195bd2015-02-13 14:40:36 -05001494
Russ Coxc8198342015-03-12 18:45:30 -04001495 s1 := Pkglookup(s.Name+"·f", s.Pkg)
Russ Coxea918ef2015-07-15 04:11:26 +00001496 s.Fsym = s1
Russ Coxea918ef2015-07-15 04:11:26 +00001497 return s1
Russ Coxfa1ea492015-07-13 20:50:51 -04001498}
Michael Hudson-Doyle1125cd42015-07-15 11:31:30 +12001499
1500func makefuncsym(s *Sym) {
1501 if isblanksym(s) {
1502 return
1503 }
1504 if compiling_runtime != 0 && s.Name == "getg" {
1505 // runtime.getg() is not a real function and so does
1506 // not get a funcsym.
1507 return
1508 }
1509 s1 := funcsym(s)
1510 s1.Def = newfuncname(s1)
1511 s1.Def.Func.Shortname = newname(s)
1512 funcsyms = list(funcsyms, s1.Def)
1513}