]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/ir/expr.go
cea7c446d4ad1827fc514b9af53141d6211522b3
[gostls13.git] / src / cmd / compile / internal / ir / expr.go
1 // Copyright 2020 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package ir
6
7 import (
8         "bytes"
9         "cmd/compile/internal/base"
10         "cmd/compile/internal/types"
11         "cmd/internal/obj"
12         "cmd/internal/src"
13         "fmt"
14         "go/constant"
15         "go/token"
16 )
17
18 // An Expr is a Node that can appear as an expression.
19 type Expr interface {
20         Node
21         isExpr()
22 }
23
24 // A miniExpr is a miniNode with extra fields common to expressions.
25 // TODO(rsc): Once we are sure about the contents, compact the bools
26 // into a bit field and leave extra bits available for implementations
27 // embedding miniExpr. Right now there are ~60 unused bits sitting here.
28 type miniExpr struct {
29         miniNode
30         typ   *types.Type
31         init  Nodes // TODO(rsc): Don't require every Node to have an init
32         flags bitset8
33 }
34
35 const (
36         miniExprNonNil = 1 << iota
37         miniExprTransient
38         miniExprBounded
39         miniExprImplicit // for use by implementations; not supported by every Expr
40         miniExprCheckPtr
41 )
42
43 func (*miniExpr) isExpr() {}
44
45 func (n *miniExpr) Type() *types.Type     { return n.typ }
46 func (n *miniExpr) SetType(x *types.Type) { n.typ = x }
47 func (n *miniExpr) NonNil() bool          { return n.flags&miniExprNonNil != 0 }
48 func (n *miniExpr) MarkNonNil()           { n.flags |= miniExprNonNil }
49 func (n *miniExpr) Transient() bool       { return n.flags&miniExprTransient != 0 }
50 func (n *miniExpr) SetTransient(b bool)   { n.flags.set(miniExprTransient, b) }
51 func (n *miniExpr) Bounded() bool         { return n.flags&miniExprBounded != 0 }
52 func (n *miniExpr) SetBounded(b bool)     { n.flags.set(miniExprBounded, b) }
53 func (n *miniExpr) Init() Nodes           { return n.init }
54 func (n *miniExpr) PtrInit() *Nodes       { return &n.init }
55 func (n *miniExpr) SetInit(x Nodes)       { n.init = x }
56
57 // An AddStringExpr is a string concatenation Expr[0] + Exprs[1] + ... + Expr[len(Expr)-1].
58 type AddStringExpr struct {
59         miniExpr
60         List     Nodes
61         Prealloc *Name
62 }
63
64 func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
65         n := &AddStringExpr{}
66         n.pos = pos
67         n.op = OADDSTR
68         n.List = list
69         return n
70 }
71
72 // An AddrExpr is an address-of expression &X.
73 // It may end up being a normal address-of or an allocation of a composite literal.
74 type AddrExpr struct {
75         miniExpr
76         X        Node
77         Prealloc *Name // preallocated storage if any
78 }
79
80 func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
81         if x == nil || x.Typecheck() != 1 {
82                 base.FatalfAt(pos, "missed typecheck: %L", x)
83         }
84         n := &AddrExpr{X: x}
85         n.pos = pos
86
87         switch x.Op() {
88         case OARRAYLIT, OMAPLIT, OSLICELIT, OSTRUCTLIT:
89                 n.op = OPTRLIT
90
91         default:
92                 n.op = OADDR
93                 if r, ok := OuterValue(x).(*Name); ok && r.Op() == ONAME {
94                         r.SetAddrtaken(true)
95
96                         // If r is a closure variable, we need to mark its canonical
97                         // variable as addrtaken too, so that closure conversion
98                         // captures it by reference.
99                         //
100                         // Exception: if we've already marked the variable as
101                         // capture-by-value, then that means this variable isn't
102                         // logically modified, and we must be taking its address to pass
103                         // to a runtime function that won't mutate it. In that case, we
104                         // only need to make sure our own copy is addressable.
105                         if r.IsClosureVar() && !r.Byval() {
106                                 r.Canonical().SetAddrtaken(true)
107                         }
108                 }
109         }
110
111         n.SetType(types.NewPtr(x.Type()))
112         n.SetTypecheck(1)
113
114         return n
115 }
116
117 func (n *AddrExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
118 func (n *AddrExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
119
120 func (n *AddrExpr) SetOp(op Op) {
121         switch op {
122         default:
123                 panic(n.no("SetOp " + op.String()))
124         case OADDR, OPTRLIT:
125                 n.op = op
126         }
127 }
128
129 // A BasicLit is a literal of basic type.
130 type BasicLit struct {
131         miniExpr
132         val constant.Value
133 }
134
135 // NewBasicLit returns an OLITERAL representing val with the given type.
136 func NewBasicLit(pos src.XPos, typ *types.Type, val constant.Value) Node {
137         AssertValidTypeForConst(typ, val)
138
139         n := &BasicLit{val: val}
140         n.op = OLITERAL
141         n.pos = pos
142         n.SetType(typ)
143         n.SetTypecheck(1)
144         return n
145 }
146
147 func (n *BasicLit) Val() constant.Value       { return n.val }
148 func (n *BasicLit) SetVal(val constant.Value) { n.val = val }
149
150 // NewConstExpr returns an OLITERAL representing val, copying the
151 // position and type from orig.
152 func NewConstExpr(val constant.Value, orig Node) Node {
153         return NewBasicLit(orig.Pos(), orig.Type(), val)
154 }
155
156 // A BinaryExpr is a binary expression X Op Y,
157 // or Op(X, Y) for builtin functions that do not become calls.
158 type BinaryExpr struct {
159         miniExpr
160         X     Node
161         Y     Node
162         RType Node `mknode:"-"` // see reflectdata/helpers.go
163 }
164
165 func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
166         n := &BinaryExpr{X: x, Y: y}
167         n.pos = pos
168         n.SetOp(op)
169         return n
170 }
171
172 func (n *BinaryExpr) SetOp(op Op) {
173         switch op {
174         default:
175                 panic(n.no("SetOp " + op.String()))
176         case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
177                 OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
178                 OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE, OUNSAFESTRING,
179                 OMAKEFACE:
180                 n.op = op
181         }
182 }
183
184 // A CallExpr is a function call Fun(Args).
185 type CallExpr struct {
186         miniExpr
187         Fun       Node
188         Args      Nodes
189         DeferAt   Node
190         RType     Node    `mknode:"-"` // see reflectdata/helpers.go
191         KeepAlive []*Name // vars to be kept alive until call returns
192         IsDDD     bool
193         NoInline  bool
194 }
195
196 func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
197         n := &CallExpr{Fun: fun}
198         n.pos = pos
199         n.SetOp(op)
200         n.Args = args
201         return n
202 }
203
204 func (*CallExpr) isStmt() {}
205
206 func (n *CallExpr) SetOp(op Op) {
207         switch op {
208         default:
209                 panic(n.no("SetOp " + op.String()))
210         case OAPPEND,
211                 OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
212                 ODELETE,
213                 OGETG, OGETCALLERPC, OGETCALLERSP,
214                 OMAKE, OMAX, OMIN, OPRINT, OPRINTLN,
215                 ORECOVER, ORECOVERFP:
216                 n.op = op
217         }
218 }
219
220 // A ClosureExpr is a function literal expression.
221 type ClosureExpr struct {
222         miniExpr
223         Func     *Func `mknode:"-"`
224         Prealloc *Name
225         IsGoWrap bool // whether this is wrapper closure of a go statement
226 }
227
228 // A CompLitExpr is a composite literal Type{Vals}.
229 // Before type-checking, the type is Ntype.
230 type CompLitExpr struct {
231         miniExpr
232         List     Nodes // initialized values
233         RType    Node  `mknode:"-"` // *runtime._type for OMAPLIT map types
234         Prealloc *Name
235         // For OSLICELIT, Len is the backing array length.
236         // For OMAPLIT, Len is the number of entries that we've removed from List and
237         // generated explicit mapassign calls for. This is used to inform the map alloc hint.
238         Len int64
239 }
240
241 func NewCompLitExpr(pos src.XPos, op Op, typ *types.Type, list []Node) *CompLitExpr {
242         n := &CompLitExpr{List: list}
243         n.pos = pos
244         n.SetOp(op)
245         if typ != nil {
246                 n.SetType(typ)
247         }
248         return n
249 }
250
251 func (n *CompLitExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
252 func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
253
254 func (n *CompLitExpr) SetOp(op Op) {
255         switch op {
256         default:
257                 panic(n.no("SetOp " + op.String()))
258         case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
259                 n.op = op
260         }
261 }
262
263 // A ConvExpr is a conversion Type(X).
264 // It may end up being a value or a type.
265 type ConvExpr struct {
266         miniExpr
267         X Node
268
269         // For implementing OCONVIFACE expressions.
270         //
271         // TypeWord is an expression yielding a *runtime._type or
272         // *runtime.itab value to go in the type word of the iface/eface
273         // result. See reflectdata.ConvIfaceTypeWord for further details.
274         //
275         // SrcRType is an expression yielding a *runtime._type value for X,
276         // if it's not pointer-shaped and needs to be heap allocated.
277         TypeWord Node `mknode:"-"`
278         SrcRType Node `mknode:"-"`
279
280         // For -d=checkptr instrumentation of conversions from
281         // unsafe.Pointer to *Elem or *[Len]Elem.
282         //
283         // TODO(mdempsky): We only ever need one of these, but currently we
284         // don't decide which one until walk. Longer term, it probably makes
285         // sense to have a dedicated IR op for `(*[Len]Elem)(ptr)[:n:m]`
286         // expressions.
287         ElemRType     Node `mknode:"-"`
288         ElemElemRType Node `mknode:"-"`
289 }
290
291 func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
292         n := &ConvExpr{X: x}
293         n.pos = pos
294         n.typ = typ
295         n.SetOp(op)
296         return n
297 }
298
299 func (n *ConvExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
300 func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
301 func (n *ConvExpr) CheckPtr() bool     { return n.flags&miniExprCheckPtr != 0 }
302 func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
303
304 func (n *ConvExpr) SetOp(op Op) {
305         switch op {
306         default:
307                 panic(n.no("SetOp " + op.String()))
308         case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARR, OSLICE2ARRPTR:
309                 n.op = op
310         }
311 }
312
313 // An IndexExpr is an index expression X[Index].
314 type IndexExpr struct {
315         miniExpr
316         X        Node
317         Index    Node
318         RType    Node `mknode:"-"` // see reflectdata/helpers.go
319         Assigned bool
320 }
321
322 func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
323         n := &IndexExpr{X: x, Index: index}
324         n.pos = pos
325         n.op = OINDEX
326         return n
327 }
328
329 func (n *IndexExpr) SetOp(op Op) {
330         switch op {
331         default:
332                 panic(n.no("SetOp " + op.String()))
333         case OINDEX, OINDEXMAP:
334                 n.op = op
335         }
336 }
337
338 // A KeyExpr is a Key: Value composite literal key.
339 type KeyExpr struct {
340         miniExpr
341         Key   Node
342         Value Node
343 }
344
345 func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
346         n := &KeyExpr{Key: key, Value: value}
347         n.pos = pos
348         n.op = OKEY
349         return n
350 }
351
352 // A StructKeyExpr is an Field: Value composite literal key.
353 type StructKeyExpr struct {
354         miniExpr
355         Field *types.Field
356         Value Node
357 }
358
359 func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr {
360         n := &StructKeyExpr{Field: field, Value: value}
361         n.pos = pos
362         n.op = OSTRUCTKEY
363         return n
364 }
365
366 func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
367
368 // An InlinedCallExpr is an inlined function call.
369 type InlinedCallExpr struct {
370         miniExpr
371         Body       Nodes
372         ReturnVars Nodes // must be side-effect free
373 }
374
375 func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
376         n := &InlinedCallExpr{}
377         n.pos = pos
378         n.op = OINLCALL
379         n.Body = body
380         n.ReturnVars = retvars
381         return n
382 }
383
384 func (n *InlinedCallExpr) SingleResult() Node {
385         if have := len(n.ReturnVars); have != 1 {
386                 base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
387         }
388         if !n.Type().HasShape() && n.ReturnVars[0].Type().HasShape() {
389                 // If the type of the call is not a shape, but the type of the return value
390                 // is a shape, we need to do an implicit conversion, so the real type
391                 // of n is maintained.
392                 r := NewConvExpr(n.Pos(), OCONVNOP, n.Type(), n.ReturnVars[0])
393                 r.SetTypecheck(1)
394                 return r
395         }
396         return n.ReturnVars[0]
397 }
398
399 // A LogicalExpr is an expression X Op Y where Op is && or ||.
400 // It is separate from BinaryExpr to make room for statements
401 // that must be executed before Y but after X.
402 type LogicalExpr struct {
403         miniExpr
404         X Node
405         Y Node
406 }
407
408 func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
409         n := &LogicalExpr{X: x, Y: y}
410         n.pos = pos
411         n.SetOp(op)
412         return n
413 }
414
415 func (n *LogicalExpr) SetOp(op Op) {
416         switch op {
417         default:
418                 panic(n.no("SetOp " + op.String()))
419         case OANDAND, OOROR:
420                 n.op = op
421         }
422 }
423
424 // A MakeExpr is a make expression: make(Type[, Len[, Cap]]).
425 // Op is OMAKECHAN, OMAKEMAP, OMAKESLICE, or OMAKESLICECOPY,
426 // but *not* OMAKE (that's a pre-typechecking CallExpr).
427 type MakeExpr struct {
428         miniExpr
429         RType Node `mknode:"-"` // see reflectdata/helpers.go
430         Len   Node
431         Cap   Node
432 }
433
434 func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
435         n := &MakeExpr{Len: len, Cap: cap}
436         n.pos = pos
437         n.SetOp(op)
438         return n
439 }
440
441 func (n *MakeExpr) SetOp(op Op) {
442         switch op {
443         default:
444                 panic(n.no("SetOp " + op.String()))
445         case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
446                 n.op = op
447         }
448 }
449
450 // A NilExpr represents the predefined untyped constant nil.
451 type NilExpr struct {
452         miniExpr
453 }
454
455 func NewNilExpr(pos src.XPos, typ *types.Type) *NilExpr {
456         if typ == nil {
457                 base.FatalfAt(pos, "missing type")
458         }
459         n := &NilExpr{}
460         n.pos = pos
461         n.op = ONIL
462         n.SetType(typ)
463         n.SetTypecheck(1)
464         return n
465 }
466
467 // A ParenExpr is a parenthesized expression (X).
468 // It may end up being a value or a type.
469 type ParenExpr struct {
470         miniExpr
471         X Node
472 }
473
474 func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
475         n := &ParenExpr{X: x}
476         n.op = OPAREN
477         n.pos = pos
478         return n
479 }
480
481 func (n *ParenExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
482 func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
483
484 // A ResultExpr represents a direct access to a result.
485 type ResultExpr struct {
486         miniExpr
487         Index int64 // index of the result expr.
488 }
489
490 func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
491         n := &ResultExpr{Index: index}
492         n.pos = pos
493         n.op = ORESULT
494         n.typ = typ
495         return n
496 }
497
498 // A LinksymOffsetExpr refers to an offset within a global variable.
499 // It is like a SelectorExpr but without the field name.
500 type LinksymOffsetExpr struct {
501         miniExpr
502         Linksym *obj.LSym
503         Offset_ int64
504 }
505
506 func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
507         if typ == nil {
508                 base.FatalfAt(pos, "nil type")
509         }
510         n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
511         n.typ = typ
512         n.op = OLINKSYMOFFSET
513         n.SetTypecheck(1)
514         return n
515 }
516
517 // NewLinksymExpr is NewLinksymOffsetExpr, but with offset fixed at 0.
518 func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
519         return NewLinksymOffsetExpr(pos, lsym, 0, typ)
520 }
521
522 // NewNameOffsetExpr is NewLinksymOffsetExpr, but taking a *Name
523 // representing a global variable instead of an *obj.LSym directly.
524 func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
525         if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
526                 base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
527         }
528         return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
529 }
530
531 // A SelectorExpr is a selector expression X.Sel.
532 type SelectorExpr struct {
533         miniExpr
534         X Node
535         // Sel is the name of the field or method being selected, without (in the
536         // case of methods) any preceding type specifier. If the field/method is
537         // exported, than the Sym uses the local package regardless of the package
538         // of the containing type.
539         Sel *types.Sym
540         // The actual selected field - may not be filled in until typechecking.
541         Selection *types.Field
542         Prealloc  *Name // preallocated storage for OMETHVALUE, if any
543 }
544
545 func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
546         n := &SelectorExpr{X: x, Sel: sel}
547         n.pos = pos
548         n.SetOp(op)
549         return n
550 }
551
552 func (n *SelectorExpr) SetOp(op Op) {
553         switch op {
554         default:
555                 panic(n.no("SetOp " + op.String()))
556         case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OMETHVALUE, OMETHEXPR:
557                 n.op = op
558         }
559 }
560
561 func (n *SelectorExpr) Sym() *types.Sym    { return n.Sel }
562 func (n *SelectorExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
563 func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
564 func (n *SelectorExpr) Offset() int64      { return n.Selection.Offset }
565
566 func (n *SelectorExpr) FuncName() *Name {
567         if n.Op() != OMETHEXPR {
568                 panic(n.no("FuncName"))
569         }
570         fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel), n.Type())
571         fn.Class = PFUNC
572         if n.Selection.Nname != nil {
573                 // TODO(austin): Nname is nil for interface method
574                 // expressions (I.M), so we can't attach a Func to
575                 // those here.
576                 fn.Func = n.Selection.Nname.(*Name).Func
577         }
578         return fn
579 }
580
581 // A SliceExpr is a slice expression X[Low:High] or X[Low:High:Max].
582 type SliceExpr struct {
583         miniExpr
584         X    Node
585         Low  Node
586         High Node
587         Max  Node
588 }
589
590 func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
591         n := &SliceExpr{X: x, Low: low, High: high, Max: max}
592         n.pos = pos
593         n.op = op
594         return n
595 }
596
597 func (n *SliceExpr) SetOp(op Op) {
598         switch op {
599         default:
600                 panic(n.no("SetOp " + op.String()))
601         case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
602                 n.op = op
603         }
604 }
605
606 // IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
607 // o must be a slicing op.
608 func (o Op) IsSlice3() bool {
609         switch o {
610         case OSLICE, OSLICEARR, OSLICESTR:
611                 return false
612         case OSLICE3, OSLICE3ARR:
613                 return true
614         }
615         base.Fatalf("IsSlice3 op %v", o)
616         return false
617 }
618
619 // A SliceHeader expression constructs a slice header from its parts.
620 type SliceHeaderExpr struct {
621         miniExpr
622         Ptr Node
623         Len Node
624         Cap Node
625 }
626
627 func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
628         n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
629         n.pos = pos
630         n.op = OSLICEHEADER
631         n.typ = typ
632         return n
633 }
634
635 // A StringHeaderExpr expression constructs a string header from its parts.
636 type StringHeaderExpr struct {
637         miniExpr
638         Ptr Node
639         Len Node
640 }
641
642 func NewStringHeaderExpr(pos src.XPos, ptr, len Node) *StringHeaderExpr {
643         n := &StringHeaderExpr{Ptr: ptr, Len: len}
644         n.pos = pos
645         n.op = OSTRINGHEADER
646         n.typ = types.Types[types.TSTRING]
647         return n
648 }
649
650 // A StarExpr is a dereference expression *X.
651 // It may end up being a value or a type.
652 type StarExpr struct {
653         miniExpr
654         X Node
655 }
656
657 func NewStarExpr(pos src.XPos, x Node) *StarExpr {
658         n := &StarExpr{X: x}
659         n.op = ODEREF
660         n.pos = pos
661         return n
662 }
663
664 func (n *StarExpr) Implicit() bool     { return n.flags&miniExprImplicit != 0 }
665 func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
666
667 // A TypeAssertionExpr is a selector expression X.(Type).
668 // Before type-checking, the type is Ntype.
669 type TypeAssertExpr struct {
670         miniExpr
671         X Node
672
673         // Runtime type information provided by walkDotType for
674         // assertions from non-empty interface to concrete type.
675         ITab Node `mknode:"-"` // *runtime.itab for Type implementing X's type
676
677         // An internal/abi.TypeAssert descriptor to pass to the runtime.
678         Descriptor *obj.LSym
679 }
680
681 func NewTypeAssertExpr(pos src.XPos, x Node, typ *types.Type) *TypeAssertExpr {
682         n := &TypeAssertExpr{X: x}
683         n.pos = pos
684         n.op = ODOTTYPE
685         if typ != nil {
686                 n.SetType(typ)
687         }
688         return n
689 }
690
691 func (n *TypeAssertExpr) SetOp(op Op) {
692         switch op {
693         default:
694                 panic(n.no("SetOp " + op.String()))
695         case ODOTTYPE, ODOTTYPE2:
696                 n.op = op
697         }
698 }
699
700 // A DynamicTypeAssertExpr asserts that X is of dynamic type RType.
701 type DynamicTypeAssertExpr struct {
702         miniExpr
703         X Node
704
705         // SrcRType is an expression that yields a *runtime._type value
706         // representing X's type. It's used in failed assertion panic
707         // messages.
708         SrcRType Node
709
710         // RType is an expression that yields a *runtime._type value
711         // representing the asserted type.
712         //
713         // BUG(mdempsky): If ITab is non-nil, RType may be nil.
714         RType Node
715
716         // ITab is an expression that yields a *runtime.itab value
717         // representing the asserted type within the assertee expression's
718         // original interface type.
719         //
720         // ITab is only used for assertions from non-empty interface type to
721         // a concrete (i.e., non-interface) type. For all other assertions,
722         // ITab is nil.
723         ITab Node
724 }
725
726 func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, rtype Node) *DynamicTypeAssertExpr {
727         n := &DynamicTypeAssertExpr{X: x, RType: rtype}
728         n.pos = pos
729         n.op = op
730         return n
731 }
732
733 func (n *DynamicTypeAssertExpr) SetOp(op Op) {
734         switch op {
735         default:
736                 panic(n.no("SetOp " + op.String()))
737         case ODYNAMICDOTTYPE, ODYNAMICDOTTYPE2:
738                 n.op = op
739         }
740 }
741
742 // A UnaryExpr is a unary expression Op X,
743 // or Op(X) for a builtin function that does not end up being a call.
744 type UnaryExpr struct {
745         miniExpr
746         X Node
747 }
748
749 func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
750         n := &UnaryExpr{X: x}
751         n.pos = pos
752         n.SetOp(op)
753         return n
754 }
755
756 func (n *UnaryExpr) SetOp(op Op) {
757         switch op {
758         default:
759                 panic(n.no("SetOp " + op.String()))
760         case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
761                 OCAP, OCLEAR, OCLOSE, OIMAG, OLEN, ONEW, OPANIC, OREAL,
762                 OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR,
763                 OUNSAFESTRINGDATA, OUNSAFESLICEDATA:
764                 n.op = op
765         }
766 }
767
768 func IsZero(n Node) bool {
769         switch n.Op() {
770         case ONIL:
771                 return true
772
773         case OLITERAL:
774                 switch u := n.Val(); u.Kind() {
775                 case constant.String:
776                         return constant.StringVal(u) == ""
777                 case constant.Bool:
778                         return !constant.BoolVal(u)
779                 default:
780                         return constant.Sign(u) == 0
781                 }
782
783         case OARRAYLIT:
784                 n := n.(*CompLitExpr)
785                 for _, n1 := range n.List {
786                         if n1.Op() == OKEY {
787                                 n1 = n1.(*KeyExpr).Value
788                         }
789                         if !IsZero(n1) {
790                                 return false
791                         }
792                 }
793                 return true
794
795         case OSTRUCTLIT:
796                 n := n.(*CompLitExpr)
797                 for _, n1 := range n.List {
798                         n1 := n1.(*StructKeyExpr)
799                         if !IsZero(n1.Value) {
800                                 return false
801                         }
802                 }
803                 return true
804         }
805
806         return false
807 }
808
809 // lvalue etc
810 func IsAddressable(n Node) bool {
811         switch n.Op() {
812         case OINDEX:
813                 n := n.(*IndexExpr)
814                 if n.X.Type() != nil && n.X.Type().IsArray() {
815                         return IsAddressable(n.X)
816                 }
817                 if n.X.Type() != nil && n.X.Type().IsString() {
818                         return false
819                 }
820                 fallthrough
821         case ODEREF, ODOTPTR:
822                 return true
823
824         case ODOT:
825                 n := n.(*SelectorExpr)
826                 return IsAddressable(n.X)
827
828         case ONAME:
829                 n := n.(*Name)
830                 if n.Class == PFUNC {
831                         return false
832                 }
833                 return true
834
835         case OLINKSYMOFFSET:
836                 return true
837         }
838
839         return false
840 }
841
842 // StaticValue analyzes n to find the earliest expression that always
843 // evaluates to the same value as n, which might be from an enclosing
844 // function.
845 //
846 // For example, given:
847 //
848 //      var x int = g()
849 //      func() {
850 //              y := x
851 //              *p = int(y)
852 //      }
853 //
854 // calling StaticValue on the "int(y)" expression returns the outer
855 // "g()" expression.
856 func StaticValue(n Node) Node {
857         for {
858                 if n.Op() == OCONVNOP {
859                         n = n.(*ConvExpr).X
860                         continue
861                 }
862
863                 if n.Op() == OINLCALL {
864                         n = n.(*InlinedCallExpr).SingleResult()
865                         continue
866                 }
867
868                 n1 := staticValue1(n)
869                 if n1 == nil {
870                         return n
871                 }
872                 n = n1
873         }
874 }
875
876 func staticValue1(nn Node) Node {
877         if nn.Op() != ONAME {
878                 return nil
879         }
880         n := nn.(*Name).Canonical()
881         if n.Class != PAUTO {
882                 return nil
883         }
884
885         defn := n.Defn
886         if defn == nil {
887                 return nil
888         }
889
890         var rhs Node
891 FindRHS:
892         switch defn.Op() {
893         case OAS:
894                 defn := defn.(*AssignStmt)
895                 rhs = defn.Y
896         case OAS2:
897                 defn := defn.(*AssignListStmt)
898                 for i, lhs := range defn.Lhs {
899                         if lhs == n {
900                                 rhs = defn.Rhs[i]
901                                 break FindRHS
902                         }
903                 }
904                 base.Fatalf("%v missing from LHS of %v", n, defn)
905         default:
906                 return nil
907         }
908         if rhs == nil {
909                 base.Fatalf("RHS is nil: %v", defn)
910         }
911
912         if Reassigned(n) {
913                 return nil
914         }
915
916         return rhs
917 }
918
919 // Reassigned takes an ONAME node, walks the function in which it is
920 // defined, and returns a boolean indicating whether the name has any
921 // assignments other than its declaration.
922 // NB: global variables are always considered to be re-assigned.
923 // TODO: handle initial declaration not including an assignment and
924 // followed by a single assignment?
925 func Reassigned(name *Name) bool {
926         if name.Op() != ONAME {
927                 base.Fatalf("reassigned %v", name)
928         }
929         // no way to reliably check for no-reassignment of globals, assume it can be
930         if name.Curfn == nil {
931                 return true
932         }
933
934         if name.Addrtaken() {
935                 return true // conservatively assume it's reassigned indirectly
936         }
937
938         // TODO(mdempsky): This is inefficient and becoming increasingly
939         // unwieldy. Figure out a way to generalize escape analysis's
940         // reassignment detection for use by inlining and devirtualization.
941
942         // isName reports whether n is a reference to name.
943         isName := func(x Node) bool {
944                 if x == nil {
945                         return false
946                 }
947                 n, ok := OuterValue(x).(*Name)
948                 return ok && n.Canonical() == name
949         }
950
951         var do func(n Node) bool
952         do = func(n Node) bool {
953                 switch n.Op() {
954                 case OAS:
955                         n := n.(*AssignStmt)
956                         if isName(n.X) && n != name.Defn {
957                                 return true
958                         }
959                 case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
960                         n := n.(*AssignListStmt)
961                         for _, p := range n.Lhs {
962                                 if isName(p) && n != name.Defn {
963                                         return true
964                                 }
965                         }
966                 case OASOP:
967                         n := n.(*AssignOpStmt)
968                         if isName(n.X) {
969                                 return true
970                         }
971                 case OADDR:
972                         n := n.(*AddrExpr)
973                         if isName(n.X) {
974                                 base.FatalfAt(n.Pos(), "%v not marked addrtaken", name)
975                         }
976                 case ORANGE:
977                         n := n.(*RangeStmt)
978                         if isName(n.Key) || isName(n.Value) {
979                                 return true
980                         }
981                 case OCLOSURE:
982                         n := n.(*ClosureExpr)
983                         if Any(n.Func, do) {
984                                 return true
985                         }
986                 }
987                 return false
988         }
989         return Any(name.Curfn, do)
990 }
991
992 // StaticCalleeName returns the ONAME/PFUNC for n, if known.
993 func StaticCalleeName(n Node) *Name {
994         switch n.Op() {
995         case OMETHEXPR:
996                 n := n.(*SelectorExpr)
997                 return MethodExprName(n)
998         case ONAME:
999                 n := n.(*Name)
1000                 if n.Class == PFUNC {
1001                         return n
1002                 }
1003         case OCLOSURE:
1004                 return n.(*ClosureExpr).Func.Nname
1005         }
1006         return nil
1007 }
1008
1009 // IsIntrinsicCall reports whether the compiler back end will treat the call as an intrinsic operation.
1010 var IsIntrinsicCall = func(*CallExpr) bool { return false }
1011
1012 // SameSafeExpr checks whether it is safe to reuse one of l and r
1013 // instead of computing both. SameSafeExpr assumes that l and r are
1014 // used in the same statement or expression. In order for it to be
1015 // safe to reuse l or r, they must:
1016 //   - be the same expression
1017 //   - not have side-effects (no function calls, no channel ops);
1018 //     however, panics are ok
1019 //   - not cause inappropriate aliasing; e.g. two string to []byte
1020 //     conversions, must result in two distinct slices
1021 //
1022 // The handling of OINDEXMAP is subtle. OINDEXMAP can occur both
1023 // as an lvalue (map assignment) and an rvalue (map access). This is
1024 // currently OK, since the only place SameSafeExpr gets used on an
1025 // lvalue expression is for OSLICE and OAPPEND optimizations, and it
1026 // is correct in those settings.
1027 func SameSafeExpr(l Node, r Node) bool {
1028         for l.Op() == OCONVNOP {
1029                 l = l.(*ConvExpr).X
1030         }
1031         for r.Op() == OCONVNOP {
1032                 r = r.(*ConvExpr).X
1033         }
1034         if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
1035                 return false
1036         }
1037
1038         switch l.Op() {
1039         case ONAME:
1040                 return l == r
1041
1042         case ODOT, ODOTPTR:
1043                 l := l.(*SelectorExpr)
1044                 r := r.(*SelectorExpr)
1045                 return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
1046
1047         case ODEREF:
1048                 l := l.(*StarExpr)
1049                 r := r.(*StarExpr)
1050                 return SameSafeExpr(l.X, r.X)
1051
1052         case ONOT, OBITNOT, OPLUS, ONEG:
1053                 l := l.(*UnaryExpr)
1054                 r := r.(*UnaryExpr)
1055                 return SameSafeExpr(l.X, r.X)
1056
1057         case OCONV:
1058                 l := l.(*ConvExpr)
1059                 r := r.(*ConvExpr)
1060                 // Some conversions can't be reused, such as []byte(str).
1061                 // Allow only numeric-ish types. This is a bit conservative.
1062                 return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
1063
1064         case OINDEX, OINDEXMAP:
1065                 l := l.(*IndexExpr)
1066                 r := r.(*IndexExpr)
1067                 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
1068
1069         case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
1070                 l := l.(*BinaryExpr)
1071                 r := r.(*BinaryExpr)
1072                 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
1073
1074         case OLITERAL:
1075                 return constant.Compare(l.Val(), token.EQL, r.Val())
1076
1077         case ONIL:
1078                 return true
1079         }
1080
1081         return false
1082 }
1083
1084 // ShouldCheckPtr reports whether pointer checking should be enabled for
1085 // function fn at a given level. See debugHelpFooter for defined
1086 // levels.
1087 func ShouldCheckPtr(fn *Func, level int) bool {
1088         return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
1089 }
1090
1091 // ShouldAsanCheckPtr reports whether pointer checking should be enabled for
1092 // function fn when -asan is enabled.
1093 func ShouldAsanCheckPtr(fn *Func) bool {
1094         return base.Flag.ASan && fn.Pragma&NoCheckPtr == 0
1095 }
1096
1097 // IsReflectHeaderDataField reports whether l is an expression p.Data
1098 // where p has type reflect.SliceHeader or reflect.StringHeader.
1099 func IsReflectHeaderDataField(l Node) bool {
1100         if l.Type() != types.Types[types.TUINTPTR] {
1101                 return false
1102         }
1103
1104         var tsym *types.Sym
1105         switch l.Op() {
1106         case ODOT:
1107                 l := l.(*SelectorExpr)
1108                 tsym = l.X.Type().Sym()
1109         case ODOTPTR:
1110                 l := l.(*SelectorExpr)
1111                 tsym = l.X.Type().Elem().Sym()
1112         default:
1113                 return false
1114         }
1115
1116         if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
1117                 return false
1118         }
1119         return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
1120 }
1121
1122 func ParamNames(ft *types.Type) []Node {
1123         args := make([]Node, ft.NumParams())
1124         for i, f := range ft.Params() {
1125                 args[i] = f.Nname.(*Name)
1126         }
1127         return args
1128 }
1129
1130 // MethodSym returns the method symbol representing a method name
1131 // associated with a specific receiver type.
1132 //
1133 // Method symbols can be used to distinguish the same method appearing
1134 // in different method sets. For example, T.M and (*T).M have distinct
1135 // method symbols.
1136 //
1137 // The returned symbol will be marked as a function.
1138 func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
1139         sym := MethodSymSuffix(recv, msym, "")
1140         sym.SetFunc(true)
1141         return sym
1142 }
1143
1144 // MethodSymSuffix is like MethodSym, but allows attaching a
1145 // distinguisher suffix. To avoid collisions, the suffix must not
1146 // start with a letter, number, or period.
1147 func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
1148         if msym.IsBlank() {
1149                 base.Fatalf("blank method name")
1150         }
1151
1152         rsym := recv.Sym()
1153         if recv.IsPtr() {
1154                 if rsym != nil {
1155                         base.Fatalf("declared pointer receiver type: %v", recv)
1156                 }
1157                 rsym = recv.Elem().Sym()
1158         }
1159
1160         // Find the package the receiver type appeared in. For
1161         // anonymous receiver types (i.e., anonymous structs with
1162         // embedded fields), use the "go" pseudo-package instead.
1163         rpkg := Pkgs.Go
1164         if rsym != nil {
1165                 rpkg = rsym.Pkg
1166         }
1167
1168         var b bytes.Buffer
1169         if recv.IsPtr() {
1170                 // The parentheses aren't really necessary, but
1171                 // they're pretty traditional at this point.
1172                 fmt.Fprintf(&b, "(%-S)", recv)
1173         } else {
1174                 fmt.Fprintf(&b, "%-S", recv)
1175         }
1176
1177         // A particular receiver type may have multiple non-exported
1178         // methods with the same name. To disambiguate them, include a
1179         // package qualifier for names that came from a different
1180         // package than the receiver type.
1181         if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
1182                 b.WriteString(".")
1183                 b.WriteString(msym.Pkg.Prefix)
1184         }
1185
1186         b.WriteString(".")
1187         b.WriteString(msym.Name)
1188         b.WriteString(suffix)
1189         return rpkg.LookupBytes(b.Bytes())
1190 }
1191
1192 // LookupMethodSelector returns the types.Sym of the selector for a method
1193 // named in local symbol name, as well as the types.Sym of the receiver.
1194 //
1195 // TODO(prattmic): this does not attempt to handle method suffixes (wrappers).
1196 func LookupMethodSelector(pkg *types.Pkg, name string) (typ, meth *types.Sym, err error) {
1197         typeName, methName := splitType(name)
1198         if typeName == "" {
1199                 return nil, nil, fmt.Errorf("%s doesn't contain type split", name)
1200         }
1201
1202         if len(typeName) > 3 && typeName[:2] == "(*" && typeName[len(typeName)-1] == ')' {
1203                 // Symbol name is for a pointer receiver method. We just want
1204                 // the base type name.
1205                 typeName = typeName[2 : len(typeName)-1]
1206         }
1207
1208         typ = pkg.Lookup(typeName)
1209         meth = pkg.Selector(methName)
1210         return typ, meth, nil
1211 }
1212
1213 // splitType splits a local symbol name into type and method (fn). If this a
1214 // free function, typ == "".
1215 //
1216 // N.B. closures and methods can be ambiguous (e.g., bar.func1). These cases
1217 // are returned as methods.
1218 func splitType(name string) (typ, fn string) {
1219         // Types are split on the first dot, ignoring everything inside
1220         // brackets (instantiation of type parameter, usually including
1221         // "go.shape").
1222         bracket := 0
1223         for i, r := range name {
1224                 if r == '.' && bracket == 0 {
1225                         return name[:i], name[i+1:]
1226                 }
1227                 if r == '[' {
1228                         bracket++
1229                 }
1230                 if r == ']' {
1231                         bracket--
1232                 }
1233         }
1234         return "", name
1235 }
1236
1237 // MethodExprName returns the ONAME representing the method
1238 // referenced by expression n, which must be a method selector,
1239 // method expression, or method value.
1240 func MethodExprName(n Node) *Name {
1241         name, _ := MethodExprFunc(n).Nname.(*Name)
1242         return name
1243 }
1244
1245 // MethodExprFunc is like MethodExprName, but returns the types.Field instead.
1246 func MethodExprFunc(n Node) *types.Field {
1247         switch n.Op() {
1248         case ODOTMETH, OMETHEXPR, OMETHVALUE:
1249                 return n.(*SelectorExpr).Selection
1250         }
1251         base.Fatalf("unexpected node: %v (%v)", n, n.Op())
1252         panic("unreachable")
1253 }