1
2
3
4
5 package noder
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/typecheck"
11 "cmd/compile/internal/types"
12 "cmd/compile/internal/types2"
13 "cmd/internal/src"
14 "strings"
15 )
16
17 func (g *irgen) pkg(pkg *types2.Package) *types.Pkg {
18 switch pkg {
19 case nil:
20 return types.BuiltinPkg
21 case g.self:
22 return types.LocalPkg
23 case types2.Unsafe:
24 return types.UnsafePkg
25 }
26 return types.NewPkg(pkg.Path(), pkg.Name())
27 }
28
29 var universeAny = types2.Universe.Lookup("any").Type()
30
31
32
33 func (g *irgen) typ(typ types2.Type) *types.Type {
34
35
36 types.DeferCheckSize()
37 res := g.typ1(typ)
38 types.ResumeCheckSize()
39
40
41
42
43 for len(g.typesToFinalize) > 0 {
44 l := len(g.typesToFinalize)
45 info := g.typesToFinalize[l-1]
46 g.typesToFinalize = g.typesToFinalize[:l-1]
47 types.DeferCheckSize()
48 g.fillinMethods(info.typ, info.ntyp)
49 types.ResumeCheckSize()
50 }
51 return res
52 }
53
54
55
56
57 func (g *irgen) typ1(typ types2.Type) *types.Type {
58
59
60
61 if typ == universeAny {
62 return types.AnyType
63 }
64
65
66
67
68 res, ok := g.typs[typ]
69 if !ok {
70 res = g.typ0(typ)
71
72
73
74 if res != nil && !res.IsUntyped() && !res.IsFuncArgStruct() && !res.HasTParam() {
75 types.CheckSize(res)
76 }
77 g.typs[typ] = res
78 }
79 return res
80 }
81
82
83
84 func (g *irgen) instTypeName2(name string, targs *types2.TypeList) string {
85 rparams := make([]*types.Type, targs.Len())
86 for i := range rparams {
87 rparams[i] = g.typ(targs.At(i))
88 }
89 return typecheck.InstTypeName(name, rparams)
90 }
91
92
93
94 func (g *irgen) typ0(typ types2.Type) *types.Type {
95 switch typ := typ.(type) {
96 case *types2.Basic:
97 return g.basic(typ)
98 case *types2.Named:
99
100
101
102
103
104 if typ.TypeParams() != nil && typ.TypeArgs() != nil {
105
106
107
108
109
110
111
112
113
114 instName := g.instTypeName2(typ.Obj().Name(), typ.TypeArgs())
115 s := g.pkg(typ.Obj().Pkg()).Lookup(instName)
116
117
118
119
120
121
122
123 base := g.obj(typ.Origin().Obj())
124
125 if s.Def != nil {
126
127
128
129 return s.Def.Type()
130 }
131
132 if base.Class == ir.PAUTO {
133
134
135
136
137 types.Pushdcl(s)
138 }
139
140
141
142
143
144
145
146 ntyp := typecheck.NewIncompleteNamedType(g.pos(typ.Obj().Pos()), s)
147 g.typs[typ] = ntyp
148
149
150
151
152
153
154
155
156
157
158
159
160 targs := typ.TypeArgs()
161 rparams := make([]*types.Type, targs.Len())
162 for i := range rparams {
163 rparams[i] = g.typ1(targs.At(i))
164 }
165 ntyp.SetRParams(rparams)
166
167
168
169 ntyp.SetOrigType(base.Type())
170 ntyp.SetUnderlying(g.typ1(typ.Underlying()))
171 if typ.NumMethods() != 0 {
172
173
174
175 g.typesToFinalize = append(g.typesToFinalize,
176 &typeDelayInfo{
177 typ: typ,
178 ntyp: ntyp,
179 })
180 }
181 return ntyp
182 }
183 obj := g.obj(typ.Obj())
184 if obj.Op() != ir.OTYPE {
185 base.FatalfAt(obj.Pos(), "expected type: %L", obj)
186 }
187 return obj.Type()
188
189 case *types2.Array:
190 return types.NewArray(g.typ1(typ.Elem()), typ.Len())
191 case *types2.Chan:
192 return types.NewChan(g.typ1(typ.Elem()), dirs[typ.Dir()])
193 case *types2.Map:
194 return types.NewMap(g.typ1(typ.Key()), g.typ1(typ.Elem()))
195 case *types2.Pointer:
196 return types.NewPtr(g.typ1(typ.Elem()))
197 case *types2.Signature:
198 return g.signature(nil, typ)
199 case *types2.Slice:
200 return types.NewSlice(g.typ1(typ.Elem()))
201
202 case *types2.Struct:
203 fields := make([]*types.Field, typ.NumFields())
204 for i := range fields {
205 v := typ.Field(i)
206 f := types.NewField(g.pos(v), g.selector(v), g.typ1(v.Type()))
207 f.Note = typ.Tag(i)
208 if v.Embedded() {
209 f.Embedded = 1
210 }
211 fields[i] = f
212 }
213 return types.NewStruct(g.tpkg(typ), fields)
214
215 case *types2.Interface:
216 embeddeds := make([]*types.Field, typ.NumEmbeddeds())
217 j := 0
218 for i := range embeddeds {
219
220 e := typ.EmbeddedType(i)
221
222
223
224 embeddeds[j] = types.NewField(src.NoXPos, nil, g.typ1(e))
225 j++
226 }
227 embeddeds = embeddeds[:j]
228
229 methods := make([]*types.Field, typ.NumExplicitMethods())
230 for i := range methods {
231 m := typ.ExplicitMethod(i)
232 mtyp := g.signature(types.FakeRecv(), m.Type().(*types2.Signature))
233 methods[i] = types.NewField(g.pos(m), g.selector(m), mtyp)
234 }
235
236 return types.NewInterface(g.tpkg(typ), append(embeddeds, methods...), typ.IsImplicit())
237
238 case *types2.TypeParam:
239
240
241 pkg := g.tpkg(typ)
242
243
244
245
246
247 assert(g.curDecl != "")
248 nm := typecheck.TparamExportName(g.curDecl, typ.Obj().Name(), typ.Index())
249 sym := pkg.Lookup(nm)
250 if sym.Def != nil {
251
252
253
254 return sym.Def.Type()
255 }
256 tp := types.NewTypeParam(sym, typ.Index())
257 nname := ir.NewDeclNameAt(g.pos(typ.Obj().Pos()), ir.OTYPE, sym)
258 sym.Def = nname
259 nname.SetType(tp)
260 tp.SetNod(nname)
261
262 g.typs[typ] = tp
263
264 bound := g.typ1(typ.Constraint())
265 tp.SetBound(bound)
266 return tp
267
268 case *types2.Union:
269 nt := typ.Len()
270 tlist := make([]*types.Type, nt)
271 tildes := make([]bool, nt)
272 for i := range tlist {
273 t := typ.Term(i)
274 tlist[i] = g.typ1(t.Type())
275 tildes[i] = t.Tilde()
276 }
277 return types.NewUnion(tlist, tildes)
278
279 case *types2.Tuple:
280
281
282 if typ == nil {
283 return (*types.Type)(nil)
284 }
285 fields := make([]*types.Field, typ.Len())
286 for i := range fields {
287 fields[i] = g.param(typ.At(i))
288 }
289 t := types.NewStruct(types.LocalPkg, fields)
290 t.StructType().Funarg = types.FunargResults
291 return t
292
293 default:
294 base.FatalfAt(src.NoXPos, "unhandled type: %v (%T)", typ, typ)
295 panic("unreachable")
296 }
297 }
298
299
300
301
302
303 func (g *irgen) fillinMethods(typ *types2.Named, ntyp *types.Type) {
304 targs2 := typ.TypeArgs()
305 targs := make([]*types.Type, targs2.Len())
306 for i := range targs {
307 targs[i] = g.typ1(targs2.At(i))
308 }
309
310 methods := make([]*types.Field, typ.NumMethods())
311 for i := range methods {
312 m := typ.Method(i)
313 recvType := deref2(types2.AsSignature(m.Type()).Recv().Type())
314 var meth *ir.Name
315 imported := false
316 if m.Pkg() != g.self {
317
318
319
320 meth = g.obj(recvType.(*types2.Named).Obj()).Type().Methods().Index(i).Nname.(*ir.Name)
321
322
323 imported = true
324 } else {
325 meth = g.obj(m)
326 }
327 assert(recvType == types2.Type(typ))
328 if imported {
329
330
331
332
333 inst2 := g.instTypeName2("", typ.TypeArgs())
334 name := meth.Sym().Name
335 i1 := strings.Index(name, "[")
336 i2 := strings.Index(name[i1:], "]")
337 assert(i1 >= 0 && i2 >= 0)
338
339 name = name[0:i1] + inst2 + name[i1+i2+1:]
340 newsym := meth.Sym().Pkg.Lookup(name)
341 var meth2 *ir.Name
342 if newsym.Def != nil {
343 meth2 = newsym.Def.(*ir.Name)
344 } else {
345 meth2 = ir.NewNameAt(meth.Pos(), newsym)
346 rparams := types2.AsSignature(m.Type()).RecvTypeParams()
347 tparams := make([]*types.Type, rparams.Len())
348
349
350
351
352
353 savedCurDecl := g.curDecl
354 g.curDecl = typ.Obj().Name() + "." + m.Name()
355 for i := range tparams {
356 tparams[i] = g.typ1(rparams.At(i))
357 }
358 g.curDecl = savedCurDecl
359 assert(len(tparams) == len(targs))
360 ts := typecheck.Tsubster{
361 Tparams: tparams,
362 Targs: targs,
363 }
364
365 meth2.SetType(ts.Typ(meth.Type()))
366 newsym.Def = meth2
367 }
368 meth = meth2
369 }
370 methods[i] = types.NewField(meth.Pos(), g.selector(m), meth.Type())
371 methods[i].Nname = meth
372 }
373 ntyp.Methods().Set(methods)
374 if !ntyp.HasTParam() && !ntyp.HasShape() {
375
376 typecheck.NeedInstType(ntyp)
377 }
378 }
379
380 func (g *irgen) signature(recv *types.Field, sig *types2.Signature) *types.Type {
381 tparams2 := sig.TypeParams()
382 tparams := make([]*types.Field, tparams2.Len())
383 for i := range tparams {
384 tp := tparams2.At(i).Obj()
385 tparams[i] = types.NewField(g.pos(tp), g.sym(tp), g.typ1(tp.Type()))
386 }
387
388 do := func(typ *types2.Tuple) []*types.Field {
389 fields := make([]*types.Field, typ.Len())
390 for i := range fields {
391 fields[i] = g.param(typ.At(i))
392 }
393 return fields
394 }
395 params := do(sig.Params())
396 results := do(sig.Results())
397 if sig.Variadic() {
398 params[len(params)-1].SetIsDDD(true)
399 }
400
401 return types.NewSignature(g.tpkg(sig), recv, tparams, params, results)
402 }
403
404 func (g *irgen) param(v *types2.Var) *types.Field {
405 return types.NewField(g.pos(v), g.sym(v), g.typ1(v.Type()))
406 }
407
408 func (g *irgen) sym(obj types2.Object) *types.Sym {
409 if name := obj.Name(); name != "" {
410 return g.pkg(obj.Pkg()).Lookup(obj.Name())
411 }
412 return nil
413 }
414
415 func (g *irgen) selector(obj types2.Object) *types.Sym {
416 pkg, name := g.pkg(obj.Pkg()), obj.Name()
417 if types.IsExported(name) {
418 pkg = types.LocalPkg
419 }
420 return pkg.Lookup(name)
421 }
422
423
424
425
426
427
428
429
430
431
432 func (g *irgen) tpkg(typ types2.Type) *types.Pkg {
433 if obj := anyObj(typ); obj != nil {
434 return g.pkg(obj.Pkg())
435 }
436 return types.LocalPkg
437 }
438
439
440 func anyObj(typ types2.Type) types2.Object {
441 switch typ := typ.(type) {
442 case *types2.Signature:
443 if recv := typ.Recv(); recv != nil {
444 return recv
445 }
446 if params := typ.Params(); params.Len() > 0 {
447 return params.At(0)
448 }
449 if results := typ.Results(); results.Len() > 0 {
450 return results.At(0)
451 }
452 case *types2.Struct:
453 if typ.NumFields() > 0 {
454 return typ.Field(0)
455 }
456 case *types2.Interface:
457 if typ.NumExplicitMethods() > 0 {
458 return typ.ExplicitMethod(0)
459 }
460 case *types2.TypeParam:
461 return typ.Obj()
462 }
463 return nil
464 }
465
466 func (g *irgen) basic(typ *types2.Basic) *types.Type {
467 switch typ.Name() {
468 case "byte":
469 return types.ByteType
470 case "rune":
471 return types.RuneType
472 }
473 return *basics[typ.Kind()]
474 }
475
476 var basics = [...]**types.Type{
477 types2.Invalid: new(*types.Type),
478 types2.Bool: &types.Types[types.TBOOL],
479 types2.Int: &types.Types[types.TINT],
480 types2.Int8: &types.Types[types.TINT8],
481 types2.Int16: &types.Types[types.TINT16],
482 types2.Int32: &types.Types[types.TINT32],
483 types2.Int64: &types.Types[types.TINT64],
484 types2.Uint: &types.Types[types.TUINT],
485 types2.Uint8: &types.Types[types.TUINT8],
486 types2.Uint16: &types.Types[types.TUINT16],
487 types2.Uint32: &types.Types[types.TUINT32],
488 types2.Uint64: &types.Types[types.TUINT64],
489 types2.Uintptr: &types.Types[types.TUINTPTR],
490 types2.Float32: &types.Types[types.TFLOAT32],
491 types2.Float64: &types.Types[types.TFLOAT64],
492 types2.Complex64: &types.Types[types.TCOMPLEX64],
493 types2.Complex128: &types.Types[types.TCOMPLEX128],
494 types2.String: &types.Types[types.TSTRING],
495 types2.UnsafePointer: &types.Types[types.TUNSAFEPTR],
496 types2.UntypedBool: &types.UntypedBool,
497 types2.UntypedInt: &types.UntypedInt,
498 types2.UntypedRune: &types.UntypedRune,
499 types2.UntypedFloat: &types.UntypedFloat,
500 types2.UntypedComplex: &types.UntypedComplex,
501 types2.UntypedString: &types.UntypedString,
502 types2.UntypedNil: &types.Types[types.TNIL],
503 }
504
505 var dirs = [...]types.ChanDir{
506 types2.SendRecv: types.Cboth,
507 types2.SendOnly: types.Csend,
508 types2.RecvOnly: types.Crecv,
509 }
510
511
512 func deref2(t types2.Type) types2.Type {
513 if ptr := types2.AsPointer(t); ptr != nil {
514 t = ptr.Elem()
515 }
516 return t
517 }
518
View as plain text