1
2
3
4
5 package noder
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/syntax"
11 "cmd/compile/internal/typecheck"
12 "cmd/compile/internal/types"
13 "cmd/compile/internal/types2"
14 "cmd/internal/src"
15 )
16
17 func (g *irgen) expr(expr syntax.Expr) ir.Node {
18 if expr == nil {
19 return nil
20 }
21
22 if expr, ok := expr.(*syntax.Name); ok && expr.Value == "_" {
23 return ir.BlankNode
24 }
25
26 tv, ok := g.info.Types[expr]
27 if !ok {
28 base.FatalfAt(g.pos(expr), "missing type for %v (%T)", expr, expr)
29 }
30 switch {
31 case tv.IsBuiltin():
32
33 if expr, ok := expr.(*syntax.SelectorExpr); ok {
34 if name, ok := expr.X.(*syntax.Name); ok {
35 if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
36 return g.use(expr.Sel)
37 }
38 }
39 }
40 return g.use(expr.(*syntax.Name))
41 case tv.IsType():
42 return ir.TypeNode(g.typ(tv.Type))
43 case tv.IsValue(), tv.IsVoid():
44
45 default:
46 base.FatalfAt(g.pos(expr), "unrecognized type-checker result")
47 }
48
49
50
51
52
53 typ := tv.Type
54 if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
55 switch basic.Kind() {
56 case types2.UntypedNil:
57
58
59 case types2.UntypedBool:
60 typ = types2.Typ[types2.Bool]
61 case types2.UntypedString:
62 typ = types2.Typ[types2.String]
63 default:
64 base.FatalfAt(g.pos(expr), "unexpected untyped type: %v", basic)
65 }
66 }
67
68
69 if tv.Value != nil {
70 return Const(g.pos(expr), g.typ(typ), tv.Value)
71 }
72
73 n := g.expr0(typ, expr)
74 if n.Typecheck() != 1 && n.Typecheck() != 3 {
75 base.FatalfAt(g.pos(expr), "missed typecheck: %+v", n)
76 }
77 if !g.match(n.Type(), typ, tv.HasOk()) {
78 base.FatalfAt(g.pos(expr), "expected %L to have type %v", n, typ)
79 }
80 return n
81 }
82
83 func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
84 pos := g.pos(expr)
85
86 switch expr := expr.(type) {
87 case *syntax.Name:
88 if _, isNil := g.info.Uses[expr].(*types2.Nil); isNil {
89 return Nil(pos, g.typ(typ))
90 }
91 return g.use(expr)
92
93 case *syntax.CompositeLit:
94 return g.compLit(typ, expr)
95
96 case *syntax.FuncLit:
97 return g.funcLit(typ, expr)
98
99 case *syntax.AssertExpr:
100 return Assert(pos, g.expr(expr.X), g.typeExpr(expr.Type))
101
102 case *syntax.CallExpr:
103 fun := g.expr(expr.Fun)
104
105
106
107
108 if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.Targs) > 0 {
109
110
111 targs := make([]ir.Node, len(inferred.Targs))
112 for i, targ := range inferred.Targs {
113 targs[i] = ir.TypeNode(g.typ(targ))
114 }
115 if fun.Op() == ir.OFUNCINST {
116
117
118 fun.(*ir.InstExpr).Targs = targs
119 } else {
120
121
122
123 inst := ir.NewInstExpr(pos, ir.OFUNCINST, fun, targs)
124 typed(fun.Type(), inst)
125 fun = inst
126 }
127
128 }
129 return Call(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots)
130
131 case *syntax.IndexExpr:
132 var targs []ir.Node
133
134 if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.Targs) > 0 {
135
136
137
138 targs = make([]ir.Node, len(inferred.Targs))
139 for i, targ := range inferred.Targs {
140 targs[i] = ir.TypeNode(g.typ(targ))
141 }
142 } else if _, ok := expr.Index.(*syntax.ListExpr); ok {
143 targs = g.exprList(expr.Index)
144 } else {
145 index := g.expr(expr.Index)
146 if index.Op() != ir.OTYPE {
147
148 return Index(pos, g.typ(typ), g.expr(expr.X), index)
149 }
150
151 targs = []ir.Node{index}
152 }
153
154
155
156 x := g.expr(expr.X)
157 if x.Op() != ir.ONAME || x.Type().Kind() != types.TFUNC {
158 panic("Incorrect argument for generic func instantiation")
159 }
160 n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs)
161 typed(g.typ(typ), n)
162 return n
163
164 case *syntax.ParenExpr:
165 return g.expr(expr.X)
166
167 case *syntax.SelectorExpr:
168
169 if name, ok := expr.X.(*syntax.Name); ok {
170 if _, ok := g.info.Uses[name].(*types2.PkgName); ok {
171 return g.use(expr.Sel)
172 }
173 }
174 return g.selectorExpr(pos, typ, expr)
175
176 case *syntax.SliceExpr:
177 return Slice(pos, g.typ(typ), g.expr(expr.X), g.expr(expr.Index[0]), g.expr(expr.Index[1]), g.expr(expr.Index[2]))
178
179 case *syntax.Operation:
180 if expr.Y == nil {
181 return Unary(pos, g.typ(typ), g.op(expr.Op, unOps[:]), g.expr(expr.X))
182 }
183 switch op := g.op(expr.Op, binOps[:]); op {
184 case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
185 return Compare(pos, g.typ(typ), op, g.expr(expr.X), g.expr(expr.Y))
186 default:
187 return Binary(pos, op, g.typ(typ), g.expr(expr.X), g.expr(expr.Y))
188 }
189
190 default:
191 g.unhandled("expression", expr)
192 panic("unreachable")
193 }
194 }
195
196
197
198
199 func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.SelectorExpr) ir.Node {
200 x := g.expr(expr.X)
201 if x.Type().HasTParam() {
202
203
204 n := ir.NewSelectorExpr(pos, ir.OXDOT, x, typecheck.Lookup(expr.Sel.Value))
205 typed(g.typ(typ), n)
206 return n
207 }
208
209 selinfo := g.info.Selections[expr]
210
211
212 index := selinfo.Index()
213 embeds, last := index[:len(index)-1], index[len(index)-1]
214
215 origx := x
216 for _, ix := range embeds {
217 x = Implicit(DotField(pos, x, ix))
218 }
219
220 kind := selinfo.Kind()
221 if kind == types2.FieldVal {
222 return DotField(pos, x, last)
223 }
224
225
226
227
228
229
230
231 var n ir.Node
232 method2 := selinfo.Obj().(*types2.Func)
233
234 if kind == types2.MethodExpr {
235
236
237
238
239
240
241 n = MethodExpr(pos, origx, x.Type(), last)
242 } else {
243
244 if x.Type().IsInterface() {
245 n = DotMethod(pos, x, last)
246 } else {
247 recvType2 := method2.Type().(*types2.Signature).Recv().Type()
248 _, wantPtr := recvType2.(*types2.Pointer)
249 havePtr := x.Type().IsPtr()
250
251 if havePtr != wantPtr {
252 if havePtr {
253 x = Implicit(Deref(pos, x.Type().Elem(), x))
254 } else {
255 x = Implicit(Addr(pos, x))
256 }
257 }
258 recvType2Base := recvType2
259 if wantPtr {
260 recvType2Base = types2.AsPointer(recvType2).Elem()
261 }
262 if len(types2.AsNamed(recvType2Base).TParams()) > 0 {
263
264
265
266 recvType2 = recvType2Base
267
268 method := g.obj(types2.AsNamed(recvType2).Method(last))
269 n = ir.NewSelectorExpr(pos, ir.OCALLPART, x, method.Sym())
270 n.(*ir.SelectorExpr).Selection = types.NewField(pos, method.Sym(), method.Type())
271 n.(*ir.SelectorExpr).Selection.Nname = method
272 typed(method.Type(), n)
273
274
275
276 targs2 := getTargs(selinfo)
277 targs := make([]ir.Node, len(targs2))
278 for i, targ2 := range targs2 {
279 targs[i] = ir.TypeNode(g.typ(targ2))
280 }
281
282
283
284 n = ir.NewInstExpr(pos, ir.OFUNCINST, n, targs)
285 typed(g.typ(typ), n)
286 return n
287 }
288
289 if !g.match(x.Type(), recvType2, false) {
290 base.FatalfAt(pos, "expected %L to have type %v", x, recvType2)
291 } else {
292 n = DotMethod(pos, x, last)
293 }
294 }
295 }
296 if have, want := n.Sym(), g.selector(method2); have != want {
297 base.FatalfAt(pos, "bad Sym: have %v, want %v", have, want)
298 }
299 return n
300 }
301
302
303 func getTargs(selinfo *types2.Selection) []types2.Type {
304 r := selinfo.Recv()
305 if p := types2.AsPointer(r); p != nil {
306 r = p.Elem()
307 }
308 n := types2.AsNamed(r)
309 if n == nil {
310 base.Fatalf("Incorrect type for selinfo %v", selinfo)
311 }
312 return n.TArgs()
313 }
314
315 func (g *irgen) exprList(expr syntax.Expr) []ir.Node {
316 switch expr := expr.(type) {
317 case nil:
318 return nil
319 case *syntax.ListExpr:
320 return g.exprs(expr.ElemList)
321 default:
322 return []ir.Node{g.expr(expr)}
323 }
324 }
325
326 func (g *irgen) exprs(exprs []syntax.Expr) []ir.Node {
327 nodes := make([]ir.Node, len(exprs))
328 for i, expr := range exprs {
329 nodes[i] = g.expr(expr)
330 }
331 return nodes
332 }
333
334 func (g *irgen) compLit(typ types2.Type, lit *syntax.CompositeLit) ir.Node {
335 if ptr, ok := typ.Underlying().(*types2.Pointer); ok {
336 n := ir.NewAddrExpr(g.pos(lit), g.compLit(ptr.Elem(), lit))
337 n.SetOp(ir.OPTRLIT)
338 return typed(g.typ(typ), n)
339 }
340
341 _, isStruct := typ.Underlying().(*types2.Struct)
342
343 exprs := make([]ir.Node, len(lit.ElemList))
344 for i, elem := range lit.ElemList {
345 switch elem := elem.(type) {
346 case *syntax.KeyValueExpr:
347 if isStruct {
348 exprs[i] = ir.NewStructKeyExpr(g.pos(elem), g.name(elem.Key.(*syntax.Name)), g.expr(elem.Value))
349 } else {
350 exprs[i] = ir.NewKeyExpr(g.pos(elem), g.expr(elem.Key), g.expr(elem.Value))
351 }
352 default:
353 exprs[i] = g.expr(elem)
354 }
355 }
356
357 n := ir.NewCompLitExpr(g.pos(lit), ir.OCOMPLIT, nil, exprs)
358 typed(g.typ(typ), n)
359 return transformCompLit(n)
360 }
361
362 func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
363 fn := ir.NewFunc(g.pos(expr))
364 fn.SetIsHiddenClosure(ir.CurFunc != nil)
365
366 fn.Nname = ir.NewNameAt(g.pos(expr), typecheck.ClosureName(ir.CurFunc))
367 ir.MarkFunc(fn.Nname)
368 typ := g.typ(typ2)
369 fn.Nname.Func = fn
370 fn.Nname.Defn = fn
371 typed(typ, fn.Nname)
372 fn.SetTypecheck(1)
373
374 fn.OClosure = ir.NewClosureExpr(g.pos(expr), fn)
375 typed(typ, fn.OClosure)
376
377 g.funcBody(fn, nil, expr.Type, expr.Body)
378
379 ir.FinishCaptureNames(fn.Pos(), ir.CurFunc, fn)
380
381
382
383 for _, cv := range fn.ClosureVars {
384 cv.SetType(cv.Canonical().Type())
385 cv.SetTypecheck(1)
386 cv.SetWalkdef(1)
387 }
388
389 g.target.Decls = append(g.target.Decls, fn)
390
391 return fn.OClosure
392 }
393
394 func (g *irgen) typeExpr(typ syntax.Expr) *types.Type {
395 n := g.expr(typ)
396 if n.Op() != ir.OTYPE {
397 base.FatalfAt(g.pos(typ), "expected type: %L", n)
398 }
399 return n.Type()
400 }
401
View as plain text