1
2
3
4
5 package typecheck
6
7 import (
8 "fmt"
9 "strconv"
10
11 "cmd/compile/internal/base"
12 "cmd/compile/internal/ir"
13 "cmd/compile/internal/types"
14 "cmd/internal/src"
15 )
16
17 var DeclContext ir.Class = ir.PEXTERN
18
19 func DeclFunc(sym *types.Sym, tfn ir.Ntype) *ir.Func {
20 if tfn.Op() != ir.OTFUNC {
21 base.Fatalf("expected OTFUNC node, got %v", tfn)
22 }
23
24 fn := ir.NewFunc(base.Pos)
25 fn.Nname = ir.NewNameAt(base.Pos, sym)
26 fn.Nname.Func = fn
27 fn.Nname.Defn = fn
28 fn.Nname.Ntype = tfn
29 ir.MarkFunc(fn.Nname)
30 StartFuncBody(fn)
31 fn.Nname.Ntype = typecheckNtype(fn.Nname.Ntype)
32 return fn
33 }
34
35
36
37 func Declare(n *ir.Name, ctxt ir.Class) {
38 if ir.IsBlank(n) {
39 return
40 }
41
42 s := n.Sym()
43
44
45 if !inimport && !TypecheckAllowed && s.Pkg != types.LocalPkg {
46 base.ErrorfAt(n.Pos(), "cannot declare name %v", s)
47 }
48
49 if ctxt == ir.PEXTERN {
50 if s.Name == "init" {
51 base.ErrorfAt(n.Pos(), "cannot declare init - must be func")
52 }
53 if s.Name == "main" && s.Pkg.Name == "main" {
54 base.ErrorfAt(n.Pos(), "cannot declare main - must be func")
55 }
56 Target.Externs = append(Target.Externs, n)
57 } else {
58 if ir.CurFunc == nil && ctxt == ir.PAUTO {
59 base.Pos = n.Pos()
60 base.Fatalf("automatic outside function")
61 }
62 if ir.CurFunc != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME {
63 ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
64 }
65 types.Pushdcl(s)
66 n.Curfn = ir.CurFunc
67 }
68
69 if ctxt == ir.PAUTO {
70 n.SetFrameOffset(0)
71 }
72
73 if s.Block == types.Block {
74
75
76 if ctxt != ir.PPARAM && ctxt != ir.PPARAMOUT {
77 Redeclared(n.Pos(), s, "in this block")
78 }
79 }
80
81 s.Block = types.Block
82 s.Lastlineno = base.Pos
83 s.Def = n
84 n.Class = ctxt
85 if ctxt == ir.PFUNC {
86 n.Sym().SetFunc(true)
87 }
88
89 autoexport(n, ctxt)
90 }
91
92
93 func Export(n *ir.Name) {
94 if n.Sym().OnExportList() {
95 return
96 }
97 n.Sym().SetOnExportList(true)
98
99 if base.Flag.E != 0 {
100 fmt.Printf("export symbol %v\n", n.Sym())
101 }
102
103 Target.Exports = append(Target.Exports, n)
104 }
105
106
107 func Redeclared(pos src.XPos, s *types.Sym, where string) {
108 if !s.Lastlineno.IsKnown() {
109 var pkgName *ir.PkgName
110 if s.Def == nil {
111 for id, pkg := range DotImportRefs {
112 if id.Sym().Name == s.Name {
113 pkgName = pkg
114 break
115 }
116 }
117 } else {
118 pkgName = DotImportRefs[s.Def.(*ir.Ident)]
119 }
120 base.ErrorfAt(pos, "%v redeclared %s\n"+
121 "\t%v: previous declaration during import %q", s, where, base.FmtPos(pkgName.Pos()), pkgName.Pkg.Path)
122 } else {
123 prevPos := s.Lastlineno
124
125
126
127
128
129 if s.Def == nil {
130 pos, prevPos = prevPos, pos
131 }
132
133 base.ErrorfAt(pos, "%v redeclared %s\n"+
134 "\t%v: previous declaration", s, where, base.FmtPos(prevPos))
135 }
136 }
137
138
139
140
141
142 func StartFuncBody(fn *ir.Func) {
143
144 funcStack = append(funcStack, funcStackEnt{ir.CurFunc, DeclContext})
145 ir.CurFunc = fn
146 DeclContext = ir.PAUTO
147
148 types.Markdcl()
149
150 if fn.Nname.Ntype != nil {
151 funcargs(fn.Nname.Ntype.(*ir.FuncType))
152 } else {
153 funcargs2(fn.Type())
154 }
155 }
156
157
158
159
160 func FinishFuncBody() {
161
162 types.Popdcl()
163 var e funcStackEnt
164 funcStack, e = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
165 ir.CurFunc, DeclContext = e.curfn, e.dclcontext
166 }
167
168 func CheckFuncStack() {
169 if len(funcStack) != 0 {
170 base.Fatalf("funcStack is non-empty: %v", len(funcStack))
171 }
172 }
173
174
175
176
177
178 func addmethod(n *ir.Func, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
179 if msym == nil {
180 base.Fatalf("no method symbol")
181 }
182
183
184 rf := t.Recv()
185 if rf == nil {
186 base.Errorf("missing receiver")
187 return nil
188 }
189
190 mt := types.ReceiverBaseType(rf.Type)
191 if mt == nil || mt.Sym() == nil {
192 pa := rf.Type
193 t := pa
194 if t != nil && t.IsPtr() {
195 if t.Sym() != nil {
196 base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
197 return nil
198 }
199 t = t.Elem()
200 }
201
202 switch {
203 case t == nil || t.Broke():
204
205 case t.Sym() == nil:
206 base.Errorf("invalid receiver type %v (%v is not a defined type)", pa, t)
207 case t.IsPtr():
208 base.Errorf("invalid receiver type %v (%v is a pointer type)", pa, t)
209 case t.IsInterface():
210 base.Errorf("invalid receiver type %v (%v is an interface type)", pa, t)
211 default:
212
213
214 base.Errorf("invalid receiver type %v (%L / %L)", pa, pa, t)
215 }
216 return nil
217 }
218
219 if local && mt.Sym().Pkg != types.LocalPkg {
220 base.Errorf("cannot define new methods on non-local type %v", mt)
221 return nil
222 }
223
224 if msym.IsBlank() {
225 return nil
226 }
227
228 if mt.IsStruct() {
229 for _, f := range mt.Fields().Slice() {
230 if f.Sym == msym {
231 base.Errorf("type %v has both field and method named %v", mt, msym)
232 f.SetBroke(true)
233 return nil
234 }
235 }
236 }
237
238 for _, f := range mt.Methods().Slice() {
239 if msym.Name != f.Sym.Name {
240 continue
241 }
242
243
244 if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
245 base.Errorf("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
246 }
247 return f
248 }
249
250 f := types.NewField(base.Pos, msym, t)
251 f.Nname = n.Nname
252 f.SetNointerface(nointerface)
253
254 mt.Methods().Append(f)
255 return f
256 }
257
258 func autoexport(n *ir.Name, ctxt ir.Class) {
259 if n.Sym().Pkg != types.LocalPkg {
260 return
261 }
262 if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || DeclContext != ir.PEXTERN {
263 return
264 }
265 if n.Type() != nil && n.Type().IsKind(types.TFUNC) && ir.IsMethod(n) {
266 return
267 }
268
269 if types.IsExported(n.Sym().Name) || n.Sym().Name == "init" {
270 Export(n)
271 }
272 if base.Flag.AsmHdr != "" && !n.Sym().Asm() {
273 n.Sym().SetAsm(true)
274 Target.Asms = append(Target.Asms, n)
275 }
276 }
277
278
279
280 func checkdupfields(what string, fss ...[]*types.Field) {
281 seen := make(map[*types.Sym]bool)
282 for _, fs := range fss {
283 for _, f := range fs {
284 if f.Sym == nil || f.Sym.IsBlank() {
285 continue
286 }
287 if seen[f.Sym] {
288 base.ErrorfAt(f.Pos, "duplicate %s %s", what, f.Sym.Name)
289 continue
290 }
291 seen[f.Sym] = true
292 }
293 }
294 }
295
296
297
298 func checkembeddedtype(t *types.Type) {
299 if t == nil {
300 return
301 }
302
303 if t.Sym() == nil && t.IsPtr() {
304 t = t.Elem()
305 if t.IsInterface() {
306 base.Errorf("embedded type cannot be a pointer to interface")
307 }
308 }
309
310 if t.IsPtr() || t.IsUnsafePtr() {
311 base.Errorf("embedded type cannot be a pointer")
312 } else if t.Kind() == types.TFORW && !t.ForwardType().Embedlineno.IsKnown() {
313 t.ForwardType().Embedlineno = base.Pos
314 }
315 }
316
317
318 func FakeRecv() *types.Field {
319 return types.NewField(src.NoXPos, nil, types.FakeRecvType())
320 }
321
322 var fakeRecvField = FakeRecv
323
324 var funcStack []funcStackEnt
325
326 type funcStackEnt struct {
327 curfn *ir.Func
328 dclcontext ir.Class
329 }
330
331 func funcarg(n *ir.Field, ctxt ir.Class) {
332 if n.Sym == nil {
333 return
334 }
335
336 name := ir.NewNameAt(n.Pos, n.Sym)
337 n.Decl = name
338 name.Ntype = n.Ntype
339 Declare(name, ctxt)
340 }
341
342 func funcarg2(f *types.Field, ctxt ir.Class) {
343 if f.Sym == nil {
344 return
345 }
346 n := ir.NewNameAt(f.Pos, f.Sym)
347 f.Nname = n
348 n.SetType(f.Type)
349 Declare(n, ctxt)
350 }
351
352 func funcargs(nt *ir.FuncType) {
353 if nt.Op() != ir.OTFUNC {
354 base.Fatalf("funcargs %v", nt.Op())
355 }
356
357
358 if nt.Recv != nil {
359 funcarg(nt.Recv, ir.PPARAM)
360 }
361 for _, n := range nt.Params {
362 funcarg(n, ir.PPARAM)
363 }
364
365
366 gen := len(nt.Params)
367 for _, n := range nt.Results {
368 if n.Sym == nil {
369
370 n.Sym = LookupNum("~r", gen)
371 gen++
372 }
373 if n.Sym.IsBlank() {
374
375
376
377
378
379
380 n.Sym = LookupNum("~b", gen)
381 gen++
382 }
383
384 funcarg(n, ir.PPARAMOUT)
385 }
386 }
387
388
389
390
391 func funcargs2(t *types.Type) {
392 if t.Kind() != types.TFUNC {
393 base.Fatalf("funcargs2 %v", t)
394 }
395
396 for _, f := range t.Recvs().Fields().Slice() {
397 funcarg2(f, ir.PPARAM)
398 }
399 for _, f := range t.Params().Fields().Slice() {
400 funcarg2(f, ir.PPARAM)
401 }
402 for _, f := range t.Results().Fields().Slice() {
403 funcarg2(f, ir.PPARAMOUT)
404 }
405 }
406
407 func Temp(t *types.Type) *ir.Name {
408 return TempAt(base.Pos, ir.CurFunc, t)
409 }
410
411
412 func TempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name {
413 if curfn == nil {
414 base.Fatalf("no curfn for TempAt")
415 }
416 if curfn.Op() == ir.OCLOSURE {
417 ir.Dump("TempAt", curfn)
418 base.Fatalf("adding TempAt to wrong closure function")
419 }
420 if t == nil {
421 base.Fatalf("TempAt called with nil type")
422 }
423 if t.Kind() == types.TFUNC && t.Recv() != nil {
424 base.Fatalf("misuse of method type: %v", t)
425 }
426
427 s := &types.Sym{
428 Name: autotmpname(len(curfn.Dcl)),
429 Pkg: types.LocalPkg,
430 }
431 n := ir.NewNameAt(pos, s)
432 s.Def = n
433 n.SetType(t)
434 n.Class = ir.PAUTO
435 n.SetEsc(ir.EscNever)
436 n.Curfn = curfn
437 n.SetUsed(true)
438 n.SetAutoTemp(true)
439 curfn.Dcl = append(curfn.Dcl, n)
440
441 types.CalcSize(t)
442
443 return n
444 }
445
446
447 func autotmpname(n int) string {
448
449
450 const prefix = ".autotmp_"
451
452 b := []byte(prefix + " ")[:len(prefix)]
453 b = strconv.AppendInt(b, int64(n), 10)
454 return types.InternString(b)
455 }
456
457
458
459 func NewMethodType(sig *types.Type, recv *types.Type) *types.Type {
460 nrecvs := 0
461 if recv != nil {
462 nrecvs++
463 }
464
465
466
467
468 params := make([]*types.Field, nrecvs+sig.Params().Fields().Len())
469 if recv != nil {
470 params[0] = types.NewField(base.Pos, nil, recv)
471 }
472 for i, param := range sig.Params().Fields().Slice() {
473 d := types.NewField(base.Pos, nil, param.Type)
474 d.SetIsDDD(param.IsDDD())
475 params[nrecvs+i] = d
476 }
477
478 results := make([]*types.Field, sig.Results().Fields().Len())
479 for i, t := range sig.Results().Fields().Slice() {
480 results[i] = types.NewField(base.Pos, nil, t.Type)
481 }
482
483 return types.NewSignature(types.LocalPkg, nil, nil, params, results)
484 }
485
View as plain text