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