1
2
3
4
5 package noder
6
7 import (
8 "fmt"
9
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/ir"
12 "cmd/compile/internal/syntax"
13 "cmd/compile/internal/typecheck"
14 "cmd/compile/internal/types"
15 "cmd/compile/internal/types2"
16 "cmd/internal/src"
17 )
18
19 func (g *irgen) expr(expr syntax.Expr) ir.Node {
20 expr = unparen(expr)
21
22 if expr == nil {
23 return nil
24 }
25
26 if expr, ok := expr.(*syntax.Name); ok && expr.Value == "_" {
27 return ir.BlankNode
28 }
29
30 tv, ok := g.info.Types[expr]
31 if !ok {
32 base.FatalfAt(g.pos(expr), "missing type for %v (%T)", expr, expr)
33 }
34 switch {
35 case tv.IsBuiltin():
36
37 if expr, ok := expr.(*syntax.SelectorExpr); ok {
38 if name, ok := expr.X.(*syntax.Name); ok {
39 if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
40 return g.use(expr.Sel)
41 }
42 }
43 }
44 return g.use(expr.(*syntax.Name))
45 case tv.IsType():
46 return ir.TypeNode(g.typ(tv.Type))
47 case tv.IsValue(), tv.IsVoid():
48
49 default:
50 base.FatalfAt(g.pos(expr), "unrecognized type-checker result")
51 }
52
53 base.Assert(g.exprStmtOK)
54
55
56
57
58
59 typ := tv.Type
60 if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
61 switch basic.Kind() {
62 case types2.UntypedNil:
63
64
65 case types2.UntypedBool:
66 typ = types2.Typ[types2.Bool]
67 case types2.UntypedString:
68 typ = types2.Typ[types2.String]
69 default:
70 base.FatalfAt(g.pos(expr), "unexpected untyped type: %v", basic)
71 }
72 }
73
74
75 if tv.Value != nil {
76 typ := g.typ(typ)
77 value := FixValue(typ, tv.Value)
78 return OrigConst(g.pos(expr), typ, value, constExprOp(expr), syntax.String(expr))
79 }
80
81 n := g.expr0(typ, expr)
82 if n.Typecheck() != 1 && n.Typecheck() != 3 {
83 base.FatalfAt(g.pos(expr), "missed typecheck: %+v", n)
84 }
85 if n.Op() != ir.OFUNCINST && !g.match(n.Type(), typ, tv.HasOk()) {
86 base.FatalfAt(g.pos(expr), "expected %L to have type %v", n, typ)
87 }
88 return n
89 }
90
91 func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
92 pos := g.pos(expr)
93 assert(pos.IsKnown())
94
95
96
97 base.Pos = pos
98
99 switch expr := expr.(type) {
100 case *syntax.Name:
101 if _, isNil := g.info.Uses[expr].(*types2.Nil); isNil {
102 return Nil(pos, g.typ(typ))
103 }
104 return g.use(expr)
105
106 case *syntax.CompositeLit:
107 return g.compLit(typ, expr)
108
109 case *syntax.FuncLit:
110 return g.funcLit(typ, expr)
111
112 case *syntax.AssertExpr:
113 return Assert(pos, g.expr(expr.X), g.typeExpr(expr.Type))
114
115 case *syntax.CallExpr:
116 fun := g.expr(expr.Fun)
117 return g.callExpr(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots)
118
119 case *syntax.IndexExpr:
120 args := unpackListExpr(expr.Index)
121 if len(args) == 1 {
122 tv, ok := g.info.Types[args[0]]
123 assert(ok)
124 if tv.IsValue() {
125
126 n := Index(pos, g.typ(typ), g.expr(expr.X), g.expr(args[0]))
127 if !g.delayTransform() {
128
129 transformIndex(n)
130 }
131 return n
132 }
133 }
134
135
136
137 return g.expr(expr.X)
138
139 case *syntax.SelectorExpr:
140
141 if name, ok := expr.X.(*syntax.Name); ok {
142 if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
143 return g.use(expr.Sel)
144 }
145 }
146 return g.selectorExpr(pos, typ, expr)
147
148 case *syntax.SliceExpr:
149 n := Slice(pos, g.typ(typ), g.expr(expr.X), g.expr(expr.Index[0]), g.expr(expr.Index[1]), g.expr(expr.Index[2]))
150 if !g.delayTransform() {
151 transformSlice(n)
152 }
153 return n
154
155 case *syntax.Operation:
156 if expr.Y == nil {
157 n := Unary(pos, g.typ(typ), g.op(expr.Op, unOps[:]), g.expr(expr.X))
158 if n.Op() == ir.OADDR && !g.delayTransform() {
159 transformAddr(n.(*ir.AddrExpr))
160 }
161 return n
162 }
163 switch op := g.op(expr.Op, binOps[:]); op {
164 case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
165 n := Compare(pos, g.typ(typ), op, g.expr(expr.X), g.expr(expr.Y))
166 if !g.delayTransform() {
167 transformCompare(n)
168 }
169 return n
170 case ir.OANDAND, ir.OOROR:
171 x := g.expr(expr.X)
172 y := g.expr(expr.Y)
173 return typed(x.Type(), ir.NewLogicalExpr(pos, op, x, y))
174 default:
175 n := Binary(pos, op, g.typ(typ), g.expr(expr.X), g.expr(expr.Y))
176 if op == ir.OADD && !g.delayTransform() {
177 return transformAdd(n)
178 }
179 return n
180 }
181
182 default:
183 g.unhandled("expression", expr)
184 panic("unreachable")
185 }
186 }
187
188
189
190
191 func (g *irgen) substType(typ *types.Type, tparams *types.Type, targs []ir.Node) *types.Type {
192 fields := tparams.FieldSlice()
193 tparams1 := make([]*types.Type, len(fields))
194 for i, f := range fields {
195 tparams1[i] = f.Type
196 }
197 targs1 := make([]*types.Type, len(targs))
198 for i, n := range targs {
199 targs1[i] = n.Type()
200 }
201 ts := typecheck.Tsubster{
202 Tparams: tparams1,
203 Targs: targs1,
204 }
205 newt := ts.Typ(typ)
206 return newt
207 }
208
209
210
211
212 func (g *irgen) callExpr(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool) ir.Node {
213 n := ir.NewCallExpr(pos, ir.OCALL, fun, args)
214 n.IsDDD = dots
215 typed(typ, n)
216
217 if fun.Op() == ir.OTYPE {
218
219 if !g.delayTransform() {
220 return transformConvCall(n)
221 }
222 return n
223 }
224
225 if fun, ok := fun.(*ir.Name); ok && fun.BuiltinOp != 0 {
226 if !g.delayTransform() {
227 return transformBuiltin(n)
228 }
229 return n
230 }
231
232
233 switch fun := fun.(type) {
234 case *ir.SelectorExpr:
235 if fun.Op() == ir.OMETHVALUE {
236 op := ir.ODOTMETH
237 if fun.X.Type().IsInterface() {
238 op = ir.ODOTINTER
239 }
240 fun.SetOp(op)
241
242
243 fun.SetType(fun.Selection.Type)
244 }
245 }
246
247
248
249
250 if fun.Op() != ir.OFUNCINST && !g.delayTransform() {
251 transformCall(n)
252 }
253 return n
254 }
255
256
257
258
259 func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.SelectorExpr) ir.Node {
260 x := g.expr(expr.X)
261 if x.Type().HasTParam() {
262
263
264 n := ir.NewSelectorExpr(pos, ir.OXDOT, x, typecheck.Lookup(expr.Sel.Value))
265 typed(g.typ(typ), n)
266 return n
267 }
268
269 selinfo := g.info.Selections[expr]
270
271
272 index := selinfo.Index()
273 embeds, last := index[:len(index)-1], index[len(index)-1]
274
275 origx := x
276 for _, ix := range embeds {
277 x = Implicit(DotField(pos, x, ix))
278 }
279
280 kind := selinfo.Kind()
281 if kind == types2.FieldVal {
282 return DotField(pos, x, last)
283 }
284
285 var n ir.Node
286 method2 := selinfo.Obj().(*types2.Func)
287
288 if kind == types2.MethodExpr {
289
290
291
292
293
294
295 n = MethodExpr(pos, origx, x.Type(), last)
296 } else {
297
298 if x.Type().IsInterface() {
299 n = DotMethod(pos, x, last)
300 } else {
301 recvType2 := method2.Type().(*types2.Signature).Recv().Type()
302 _, wantPtr := recvType2.(*types2.Pointer)
303 havePtr := x.Type().IsPtr()
304
305 if havePtr != wantPtr {
306 if havePtr {
307 x = Implicit(Deref(pos, x.Type().Elem(), x))
308 } else {
309 x = Implicit(Addr(pos, x))
310 }
311 }
312 recvType2Base := recvType2
313 if wantPtr {
314 recvType2Base = types2.AsPointer(recvType2).Elem()
315 }
316 if recvType2Base.(*types2.Named).TypeParams().Len() > 0 {
317
318
319
320 recvType2 = recvType2Base
321 recvTypeSym := g.pkg(method2.Pkg()).Lookup(recvType2.(*types2.Named).Obj().Name())
322 recvType := recvTypeSym.Def.(*ir.Name).Type()
323
324
325
326 method := recvType.Methods().Index(last).Nname.(*ir.Name)
327 n = ir.NewSelectorExpr(pos, ir.OMETHVALUE, x, typecheck.Lookup(expr.Sel.Value))
328 n.(*ir.SelectorExpr).Selection = types.NewField(pos, method.Sym(), method.Type())
329 n.(*ir.SelectorExpr).Selection.Nname = method
330 typed(method.Type(), n)
331
332 xt := deref(x.Type())
333 targs := make([]ir.Node, len(xt.RParams()))
334 for i := range targs {
335 targs[i] = ir.TypeNode(xt.RParams()[i])
336 }
337
338
339
340 n = ir.NewInstExpr(pos, ir.OFUNCINST, n, targs)
341 typed(g.typ(typ), n)
342 return n
343 }
344
345 if !g.match(x.Type(), recvType2, false) {
346 base.FatalfAt(pos, "expected %L to have type %v", x, recvType2)
347 } else {
348 n = DotMethod(pos, x, last)
349 }
350 }
351 }
352 if have, want := n.Sym(), g.selector(method2); have != want {
353 base.FatalfAt(pos, "bad Sym: have %v, want %v", have, want)
354 }
355 return n
356 }
357
358 func (g *irgen) exprList(expr syntax.Expr) []ir.Node {
359 return g.exprs(unpackListExpr(expr))
360 }
361
362 func unpackListExpr(expr syntax.Expr) []syntax.Expr {
363 switch expr := expr.(type) {
364 case nil:
365 return nil
366 case *syntax.ListExpr:
367 return expr.ElemList
368 default:
369 return []syntax.Expr{expr}
370 }
371 }
372
373 func (g *irgen) exprs(exprs []syntax.Expr) []ir.Node {
374 nodes := make([]ir.Node, len(exprs))
375 for i, expr := range exprs {
376 nodes[i] = g.expr(expr)
377 }
378 return nodes
379 }
380
381 func (g *irgen) compLit(typ types2.Type, lit *syntax.CompositeLit) ir.Node {
382 if ptr, ok := types2.CoreType(typ).(*types2.Pointer); ok {
383 n := ir.NewAddrExpr(g.pos(lit), g.compLit(ptr.Elem(), lit))
384 n.SetOp(ir.OPTRLIT)
385 return typed(g.typ(typ), n)
386 }
387
388 _, isStruct := types2.CoreType(typ).(*types2.Struct)
389
390 exprs := make([]ir.Node, len(lit.ElemList))
391 for i, elem := range lit.ElemList {
392 switch elem := elem.(type) {
393 case *syntax.KeyValueExpr:
394 var key ir.Node
395 if isStruct {
396 key = ir.NewIdent(g.pos(elem.Key), g.name(elem.Key.(*syntax.Name)))
397 } else {
398 key = g.expr(elem.Key)
399 }
400 value := wrapname(g.pos(elem.Value), g.expr(elem.Value))
401 if value.Op() == ir.OPAREN {
402
403 typed(value.(*ir.ParenExpr).X.Type(), value)
404 }
405 exprs[i] = ir.NewKeyExpr(g.pos(elem), key, value)
406 default:
407 exprs[i] = wrapname(g.pos(elem), g.expr(elem))
408 if exprs[i].Op() == ir.OPAREN {
409
410 typed(exprs[i].(*ir.ParenExpr).X.Type(), exprs[i])
411 }
412 }
413 }
414
415 n := ir.NewCompLitExpr(g.pos(lit), ir.OCOMPLIT, nil, exprs)
416 typed(g.typ(typ), n)
417 var r ir.Node = n
418 if !g.delayTransform() {
419 r = transformCompLit(n)
420 }
421 return r
422 }
423
424 func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
425 fn := ir.NewClosureFunc(g.pos(expr), ir.CurFunc != nil)
426 ir.NameClosure(fn.OClosure, ir.CurFunc)
427
428 typ := g.typ(typ2)
429 typed(typ, fn.Nname)
430 typed(typ, fn.OClosure)
431 fn.SetTypecheck(1)
432
433 g.funcBody(fn, nil, expr.Type, expr.Body)
434
435 ir.FinishCaptureNames(fn.Pos(), ir.CurFunc, fn)
436
437
438
439 for _, cv := range fn.ClosureVars {
440 cv.SetType(cv.Canonical().Type())
441 cv.SetTypecheck(1)
442 cv.SetWalkdef(1)
443 }
444
445 if g.topFuncIsGeneric {
446
447
448
449 return ir.UseClosure(fn.OClosure, nil)
450 } else {
451 return ir.UseClosure(fn.OClosure, g.target)
452 }
453 }
454
455 func (g *irgen) typeExpr(typ syntax.Expr) *types.Type {
456 n := g.expr(typ)
457 if n.Op() != ir.OTYPE {
458 base.FatalfAt(g.pos(typ), "expected type: %L", n)
459 }
460 return n.Type()
461 }
462
463
464
465
466 func constExprOp(expr syntax.Expr) ir.Op {
467 switch expr := expr.(type) {
468 default:
469 panic(fmt.Sprintf("%s: unexpected expression: %T", expr.Pos(), expr))
470
471 case *syntax.BasicLit:
472 return ir.OLITERAL
473 case *syntax.Name, *syntax.SelectorExpr:
474 return ir.ONAME
475 case *syntax.CallExpr:
476 return ir.OCALL
477 case *syntax.Operation:
478 if expr.Y == nil {
479 return unOps[expr.Op]
480 }
481 return binOps[expr.Op]
482 }
483 }
484
485 func unparen(expr syntax.Expr) syntax.Expr {
486 for {
487 paren, ok := expr.(*syntax.ParenExpr)
488 if !ok {
489 return expr
490 }
491 expr = paren.X
492 }
493 }
494
View as plain text