1
2
3
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
19 type Expr interface {
20 Node
21 isExpr()
22 }
23
24
25
26
27
28 type miniExpr struct {
29 miniNode
30 typ *types.Type
31 init Nodes
32 flags bitset8
33 }
34
35 const (
36 miniExprNonNil = 1 << iota
37 miniExprTransient
38 miniExprBounded
39 miniExprImplicit
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
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
73
74 type AddrExpr struct {
75 miniExpr
76 X Node
77 Prealloc *Name
78 }
79
80 func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
81 n := &AddrExpr{X: x}
82 n.op = OADDR
83 n.pos = pos
84 return n
85 }
86
87 func (n *AddrExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
88 func (n *AddrExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
89
90 func (n *AddrExpr) SetOp(op Op) {
91 switch op {
92 default:
93 panic(n.no("SetOp " + op.String()))
94 case OADDR, OPTRLIT:
95 n.op = op
96 }
97 }
98
99
100 type BasicLit struct {
101 miniExpr
102 val constant.Value
103 }
104
105 func NewBasicLit(pos src.XPos, val constant.Value) Node {
106 n := &BasicLit{val: val}
107 n.op = OLITERAL
108 n.pos = pos
109 if k := val.Kind(); k != constant.Unknown {
110 n.SetType(idealType(k))
111 }
112 return n
113 }
114
115 func (n *BasicLit) Val() constant.Value { return n.val }
116 func (n *BasicLit) SetVal(val constant.Value) { n.val = val }
117
118
119
120 type BinaryExpr struct {
121 miniExpr
122 X Node
123 Y Node
124 }
125
126 func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
127 n := &BinaryExpr{X: x, Y: y}
128 n.pos = pos
129 n.SetOp(op)
130 return n
131 }
132
133 func (n *BinaryExpr) SetOp(op Op) {
134 switch op {
135 default:
136 panic(n.no("SetOp " + op.String()))
137 case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
138 OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
139 OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE,
140 OEFACE:
141 n.op = op
142 }
143 }
144
145
146 type CallExpr struct {
147 miniExpr
148 origNode
149 X Node
150 Args Nodes
151 KeepAlive []*Name
152 IsDDD bool
153 NoInline bool
154 }
155
156 func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
157 n := &CallExpr{X: fun}
158 n.pos = pos
159 n.orig = n
160 n.SetOp(op)
161 n.Args = args
162 return n
163 }
164
165 func (*CallExpr) isStmt() {}
166
167 func (n *CallExpr) SetOp(op Op) {
168 switch op {
169 default:
170 panic(n.no("SetOp " + op.String()))
171 case OAPPEND,
172 OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
173 ODELETE,
174 OGETG, OGETCALLERPC, OGETCALLERSP,
175 OMAKE, OPRINT, OPRINTN,
176 ORECOVER, ORECOVERFP:
177 n.op = op
178 }
179 }
180
181
182 type ClosureExpr struct {
183 miniExpr
184 Func *Func `mknode:"-"`
185 Prealloc *Name
186 IsGoWrap bool
187 }
188
189
190 func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
191 n := &ClosureExpr{Func: fn}
192 n.op = OCLOSURE
193 n.pos = pos
194 return n
195 }
196
197
198
199 type CompLitExpr struct {
200 miniExpr
201 origNode
202 Ntype Ntype
203 List Nodes
204 Prealloc *Name
205 Len int64
206 }
207
208 func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr {
209 n := &CompLitExpr{Ntype: typ}
210 n.pos = pos
211 n.SetOp(op)
212 n.List = list
213 n.orig = n
214 return n
215 }
216
217 func (n *CompLitExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
218 func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
219
220 func (n *CompLitExpr) SetOp(op Op) {
221 switch op {
222 default:
223 panic(n.no("SetOp " + op.String()))
224 case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
225 n.op = op
226 }
227 }
228
229 type ConstExpr struct {
230 miniExpr
231 origNode
232 val constant.Value
233 }
234
235 func NewConstExpr(val constant.Value, orig Node) Node {
236 n := &ConstExpr{val: val}
237 n.op = OLITERAL
238 n.pos = orig.Pos()
239 n.orig = orig
240 n.SetType(orig.Type())
241 n.SetTypecheck(orig.Typecheck())
242 n.SetDiag(orig.Diag())
243 return n
244 }
245
246 func (n *ConstExpr) Sym() *types.Sym { return n.orig.Sym() }
247 func (n *ConstExpr) Val() constant.Value { return n.val }
248
249
250
251 type ConvExpr struct {
252 miniExpr
253 X Node
254 NonEscaping bool
255 }
256
257 func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
258 n := &ConvExpr{X: x}
259 n.pos = pos
260 n.typ = typ
261 n.SetOp(op)
262 return n
263 }
264
265 func (n *ConvExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
266 func (n *ConvExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
267 func (n *ConvExpr) CheckPtr() bool { return n.flags&miniExprCheckPtr != 0 }
268 func (n *ConvExpr) SetCheckPtr(b bool) { n.flags.set(miniExprCheckPtr, b) }
269
270 func (n *ConvExpr) SetOp(op Op) {
271 switch op {
272 default:
273 panic(n.no("SetOp " + op.String()))
274 case OCONV, OCONVIFACE, OCONVIDATA, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
275 n.op = op
276 }
277 }
278
279
280 type IndexExpr struct {
281 miniExpr
282 X Node
283 Index Node
284 Assigned bool
285 }
286
287 func NewIndexExpr(pos src.XPos, x, index Node) *IndexExpr {
288 n := &IndexExpr{X: x, Index: index}
289 n.pos = pos
290 n.op = OINDEX
291 return n
292 }
293
294 func (n *IndexExpr) SetOp(op Op) {
295 switch op {
296 default:
297 panic(n.no("SetOp " + op.String()))
298 case OINDEX, OINDEXMAP:
299 n.op = op
300 }
301 }
302
303
304 type KeyExpr struct {
305 miniExpr
306 Key Node
307 Value Node
308 }
309
310 func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
311 n := &KeyExpr{Key: key, Value: value}
312 n.pos = pos
313 n.op = OKEY
314 return n
315 }
316
317
318 type StructKeyExpr struct {
319 miniExpr
320 Field *types.Field
321 Value Node
322 }
323
324 func NewStructKeyExpr(pos src.XPos, field *types.Field, value Node) *StructKeyExpr {
325 n := &StructKeyExpr{Field: field, Value: value}
326 n.pos = pos
327 n.op = OSTRUCTKEY
328 return n
329 }
330
331 func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
332
333
334 type InlinedCallExpr struct {
335 miniExpr
336 Body Nodes
337 ReturnVars Nodes
338 }
339
340 func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
341 n := &InlinedCallExpr{}
342 n.pos = pos
343 n.op = OINLCALL
344 n.Body = body
345 n.ReturnVars = retvars
346 return n
347 }
348
349 func (n *InlinedCallExpr) SingleResult() Node {
350 if have := len(n.ReturnVars); have != 1 {
351 base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
352 }
353 if !n.Type().HasShape() && n.ReturnVars[0].Type().HasShape() {
354
355
356
357 r := NewConvExpr(n.Pos(), OCONVNOP, n.Type(), n.ReturnVars[0])
358 r.SetTypecheck(1)
359 return r
360 }
361 return n.ReturnVars[0]
362 }
363
364
365
366
367 type LogicalExpr struct {
368 miniExpr
369 X Node
370 Y Node
371 }
372
373 func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
374 n := &LogicalExpr{X: x, Y: y}
375 n.pos = pos
376 n.SetOp(op)
377 return n
378 }
379
380 func (n *LogicalExpr) SetOp(op Op) {
381 switch op {
382 default:
383 panic(n.no("SetOp " + op.String()))
384 case OANDAND, OOROR:
385 n.op = op
386 }
387 }
388
389
390
391
392 type MakeExpr struct {
393 miniExpr
394 Len Node
395 Cap Node
396 }
397
398 func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
399 n := &MakeExpr{Len: len, Cap: cap}
400 n.pos = pos
401 n.SetOp(op)
402 return n
403 }
404
405 func (n *MakeExpr) SetOp(op Op) {
406 switch op {
407 default:
408 panic(n.no("SetOp " + op.String()))
409 case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
410 n.op = op
411 }
412 }
413
414
415
416 type NilExpr struct {
417 miniExpr
418 Sym_ *types.Sym
419 }
420
421 func NewNilExpr(pos src.XPos) *NilExpr {
422 n := &NilExpr{}
423 n.pos = pos
424 n.op = ONIL
425 return n
426 }
427
428 func (n *NilExpr) Sym() *types.Sym { return n.Sym_ }
429 func (n *NilExpr) SetSym(x *types.Sym) { n.Sym_ = x }
430
431
432
433 type ParenExpr struct {
434 miniExpr
435 X Node
436 }
437
438 func NewParenExpr(pos src.XPos, x Node) *ParenExpr {
439 n := &ParenExpr{X: x}
440 n.op = OPAREN
441 n.pos = pos
442 return n
443 }
444
445 func (n *ParenExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
446 func (n *ParenExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
447
448 func (*ParenExpr) CanBeNtype() {}
449
450
451
452 func (n *ParenExpr) SetOTYPE(t *types.Type) {
453 n.op = OTYPE
454 n.typ = t
455 t.SetNod(n)
456 }
457
458
459
460 type RawOrigExpr struct {
461 miniExpr
462 Raw string
463 }
464
465 func NewRawOrigExpr(pos src.XPos, op Op, raw string) *RawOrigExpr {
466 n := &RawOrigExpr{Raw: raw}
467 n.pos = pos
468 n.op = op
469 return n
470 }
471
472
473 type ResultExpr struct {
474 miniExpr
475 Index int64
476 }
477
478 func NewResultExpr(pos src.XPos, typ *types.Type, index int64) *ResultExpr {
479 n := &ResultExpr{Index: index}
480 n.pos = pos
481 n.op = ORESULT
482 n.typ = typ
483 return n
484 }
485
486
487
488 type LinksymOffsetExpr struct {
489 miniExpr
490 Linksym *obj.LSym
491 Offset_ int64
492 }
493
494 func NewLinksymOffsetExpr(pos src.XPos, lsym *obj.LSym, offset int64, typ *types.Type) *LinksymOffsetExpr {
495 n := &LinksymOffsetExpr{Linksym: lsym, Offset_: offset}
496 n.typ = typ
497 n.op = OLINKSYMOFFSET
498 return n
499 }
500
501
502 func NewLinksymExpr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *LinksymOffsetExpr {
503 return NewLinksymOffsetExpr(pos, lsym, 0, typ)
504 }
505
506
507
508 func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type) *LinksymOffsetExpr {
509 if name == nil || IsBlank(name) || !(name.Op() == ONAME && name.Class == PEXTERN) {
510 base.FatalfAt(pos, "cannot take offset of nil, blank name or non-global variable: %v", name)
511 }
512 return NewLinksymOffsetExpr(pos, name.Linksym(), offset, typ)
513 }
514
515
516 type SelectorExpr struct {
517 miniExpr
518 X Node
519
520
521
522
523 Sel *types.Sym
524
525 Selection *types.Field
526 Prealloc *Name
527 }
528
529 func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
530 n := &SelectorExpr{X: x, Sel: sel}
531 n.pos = pos
532 n.SetOp(op)
533 return n
534 }
535
536 func (n *SelectorExpr) SetOp(op Op) {
537 switch op {
538 default:
539 panic(n.no("SetOp " + op.String()))
540 case OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OMETHVALUE, OMETHEXPR:
541 n.op = op
542 }
543 }
544
545 func (n *SelectorExpr) Sym() *types.Sym { return n.Sel }
546 func (n *SelectorExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
547 func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
548 func (n *SelectorExpr) Offset() int64 { return n.Selection.Offset }
549
550 func (n *SelectorExpr) FuncName() *Name {
551 if n.Op() != OMETHEXPR {
552 panic(n.no("FuncName"))
553 }
554 fn := NewNameAt(n.Selection.Pos, MethodSym(n.X.Type(), n.Sel))
555 fn.Class = PFUNC
556 fn.SetType(n.Type())
557 if n.Selection.Nname != nil {
558
559
560
561
562 fn.Func = n.Selection.Nname.(*Name).Func
563 }
564 return fn
565 }
566
567
568
569 func (*SelectorExpr) CanBeNtype() {}
570
571
572 type SliceExpr struct {
573 miniExpr
574 X Node
575 Low Node
576 High Node
577 Max Node
578 }
579
580 func NewSliceExpr(pos src.XPos, op Op, x, low, high, max Node) *SliceExpr {
581 n := &SliceExpr{X: x, Low: low, High: high, Max: max}
582 n.pos = pos
583 n.op = op
584 return n
585 }
586
587 func (n *SliceExpr) SetOp(op Op) {
588 switch op {
589 default:
590 panic(n.no("SetOp " + op.String()))
591 case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
592 n.op = op
593 }
594 }
595
596
597
598 func (o Op) IsSlice3() bool {
599 switch o {
600 case OSLICE, OSLICEARR, OSLICESTR:
601 return false
602 case OSLICE3, OSLICE3ARR:
603 return true
604 }
605 base.Fatalf("IsSlice3 op %v", o)
606 return false
607 }
608
609
610 type SliceHeaderExpr struct {
611 miniExpr
612 Ptr Node
613 Len Node
614 Cap Node
615 }
616
617 func NewSliceHeaderExpr(pos src.XPos, typ *types.Type, ptr, len, cap Node) *SliceHeaderExpr {
618 n := &SliceHeaderExpr{Ptr: ptr, Len: len, Cap: cap}
619 n.pos = pos
620 n.op = OSLICEHEADER
621 n.typ = typ
622 return n
623 }
624
625
626
627 type StarExpr struct {
628 miniExpr
629 X Node
630 }
631
632 func NewStarExpr(pos src.XPos, x Node) *StarExpr {
633 n := &StarExpr{X: x}
634 n.op = ODEREF
635 n.pos = pos
636 return n
637 }
638
639 func (n *StarExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
640 func (n *StarExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
641
642 func (*StarExpr) CanBeNtype() {}
643
644
645
646 func (n *StarExpr) SetOTYPE(t *types.Type) {
647 n.op = OTYPE
648 n.X = nil
649 n.typ = t
650 t.SetNod(n)
651 }
652
653
654
655 type TypeAssertExpr struct {
656 miniExpr
657 X Node
658 Ntype Ntype
659
660
661
662 Itab *AddrExpr `mknode:"-"`
663 }
664
665 func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr {
666 n := &TypeAssertExpr{X: x, Ntype: typ}
667 n.pos = pos
668 n.op = ODOTTYPE
669 return n
670 }
671
672 func (n *TypeAssertExpr) SetOp(op Op) {
673 switch op {
674 default:
675 panic(n.no("SetOp " + op.String()))
676 case ODOTTYPE, ODOTTYPE2:
677 n.op = op
678 }
679 }
680
681
682 type DynamicTypeAssertExpr struct {
683 miniExpr
684 X Node
685
686
687
688
689
690
691
692
693
694 T Node
695 }
696
697 func NewDynamicTypeAssertExpr(pos src.XPos, op Op, x, t Node) *DynamicTypeAssertExpr {
698 n := &DynamicTypeAssertExpr{X: x, T: t}
699 n.pos = pos
700 n.op = op
701 return n
702 }
703
704 func (n *DynamicTypeAssertExpr) SetOp(op Op) {
705 switch op {
706 default:
707 panic(n.no("SetOp " + op.String()))
708 case ODYNAMICDOTTYPE, ODYNAMICDOTTYPE2:
709 n.op = op
710 }
711 }
712
713
714
715 type UnaryExpr struct {
716 miniExpr
717 X Node
718 }
719
720 func NewUnaryExpr(pos src.XPos, op Op, x Node) *UnaryExpr {
721 n := &UnaryExpr{X: x}
722 n.pos = pos
723 n.SetOp(op)
724 return n
725 }
726
727 func (n *UnaryExpr) SetOp(op Op) {
728 switch op {
729 default:
730 panic(n.no("SetOp " + op.String()))
731 case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
732 OALIGNOF, OCAP, OCLOSE, OIMAG, OLEN, ONEW,
733 OOFFSETOF, OPANIC, OREAL, OSIZEOF,
734 OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR, OVARDEF, OVARKILL, OVARLIVE:
735 n.op = op
736 }
737 }
738
739
740
741 func (n *InstExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
742 func (n *InstExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
743
744
745 type InstExpr struct {
746 miniExpr
747 X Node
748 Targs []Node
749 }
750
751 func NewInstExpr(pos src.XPos, op Op, x Node, targs []Node) *InstExpr {
752 n := &InstExpr{X: x, Targs: targs}
753 n.pos = pos
754 n.op = op
755 return n
756 }
757
758 func IsZero(n Node) bool {
759 switch n.Op() {
760 case ONIL:
761 return true
762
763 case OLITERAL:
764 switch u := n.Val(); u.Kind() {
765 case constant.String:
766 return constant.StringVal(u) == ""
767 case constant.Bool:
768 return !constant.BoolVal(u)
769 default:
770 return constant.Sign(u) == 0
771 }
772
773 case OARRAYLIT:
774 n := n.(*CompLitExpr)
775 for _, n1 := range n.List {
776 if n1.Op() == OKEY {
777 n1 = n1.(*KeyExpr).Value
778 }
779 if !IsZero(n1) {
780 return false
781 }
782 }
783 return true
784
785 case OSTRUCTLIT:
786 n := n.(*CompLitExpr)
787 for _, n1 := range n.List {
788 n1 := n1.(*StructKeyExpr)
789 if !IsZero(n1.Value) {
790 return false
791 }
792 }
793 return true
794 }
795
796 return false
797 }
798
799
800 func IsAddressable(n Node) bool {
801 switch n.Op() {
802 case OINDEX:
803 n := n.(*IndexExpr)
804 if n.X.Type() != nil && n.X.Type().IsArray() {
805 return IsAddressable(n.X)
806 }
807 if n.X.Type() != nil && n.X.Type().IsString() {
808 return false
809 }
810 fallthrough
811 case ODEREF, ODOTPTR:
812 return true
813
814 case ODOT:
815 n := n.(*SelectorExpr)
816 return IsAddressable(n.X)
817
818 case ONAME:
819 n := n.(*Name)
820 if n.Class == PFUNC {
821 return false
822 }
823 return true
824
825 case OLINKSYMOFFSET:
826 return true
827 }
828
829 return false
830 }
831
832 func StaticValue(n Node) Node {
833 for {
834 if n.Op() == OCONVNOP {
835 n = n.(*ConvExpr).X
836 continue
837 }
838
839 if n.Op() == OINLCALL {
840 n = n.(*InlinedCallExpr).SingleResult()
841 continue
842 }
843
844 n1 := staticValue1(n)
845 if n1 == nil {
846 return n
847 }
848 n = n1
849 }
850 }
851
852
853
854
855 func staticValue1(nn Node) Node {
856 if nn.Op() != ONAME {
857 return nil
858 }
859 n := nn.(*Name)
860 if n.Class != PAUTO {
861 return nil
862 }
863
864 defn := n.Defn
865 if defn == nil {
866 return nil
867 }
868
869 var rhs Node
870 FindRHS:
871 switch defn.Op() {
872 case OAS:
873 defn := defn.(*AssignStmt)
874 rhs = defn.Y
875 case OAS2:
876 defn := defn.(*AssignListStmt)
877 for i, lhs := range defn.Lhs {
878 if lhs == n {
879 rhs = defn.Rhs[i]
880 break FindRHS
881 }
882 }
883 base.Fatalf("%v missing from LHS of %v", n, defn)
884 default:
885 return nil
886 }
887 if rhs == nil {
888 base.Fatalf("RHS is nil: %v", defn)
889 }
890
891 if reassigned(n) {
892 return nil
893 }
894
895 return rhs
896 }
897
898
899
900
901
902
903
904 func reassigned(name *Name) bool {
905 if name.Op() != ONAME {
906 base.Fatalf("reassigned %v", name)
907 }
908
909 if name.Curfn == nil {
910 return true
911 }
912
913
914
915
916
917
918 isName := func(x Node) bool {
919 n, ok := x.(*Name)
920 return ok && n.Canonical() == name
921 }
922
923 var do func(n Node) bool
924 do = func(n Node) bool {
925 switch n.Op() {
926 case OAS:
927 n := n.(*AssignStmt)
928 if isName(n.X) && n != name.Defn {
929 return true
930 }
931 case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV, OSELRECV2:
932 n := n.(*AssignListStmt)
933 for _, p := range n.Lhs {
934 if isName(p) && n != name.Defn {
935 return true
936 }
937 }
938 case OADDR:
939 n := n.(*AddrExpr)
940 if isName(OuterValue(n.X)) {
941 return true
942 }
943 case OCLOSURE:
944 n := n.(*ClosureExpr)
945 if Any(n.Func, do) {
946 return true
947 }
948 }
949 return false
950 }
951 return Any(name.Curfn, do)
952 }
953
954
955 var IsIntrinsicCall = func(*CallExpr) bool { return false }
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972 func SameSafeExpr(l Node, r Node) bool {
973 if l.Op() != r.Op() || !types.Identical(l.Type(), r.Type()) {
974 return false
975 }
976
977 switch l.Op() {
978 case ONAME:
979 return l == r
980
981 case ODOT, ODOTPTR:
982 l := l.(*SelectorExpr)
983 r := r.(*SelectorExpr)
984 return l.Sel != nil && r.Sel != nil && l.Sel == r.Sel && SameSafeExpr(l.X, r.X)
985
986 case ODEREF:
987 l := l.(*StarExpr)
988 r := r.(*StarExpr)
989 return SameSafeExpr(l.X, r.X)
990
991 case ONOT, OBITNOT, OPLUS, ONEG:
992 l := l.(*UnaryExpr)
993 r := r.(*UnaryExpr)
994 return SameSafeExpr(l.X, r.X)
995
996 case OCONVNOP:
997 l := l.(*ConvExpr)
998 r := r.(*ConvExpr)
999 return SameSafeExpr(l.X, r.X)
1000
1001 case OCONV:
1002 l := l.(*ConvExpr)
1003 r := r.(*ConvExpr)
1004
1005
1006 return types.IsSimple[l.Type().Kind()] && SameSafeExpr(l.X, r.X)
1007
1008 case OINDEX, OINDEXMAP:
1009 l := l.(*IndexExpr)
1010 r := r.(*IndexExpr)
1011 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Index, r.Index)
1012
1013 case OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
1014 l := l.(*BinaryExpr)
1015 r := r.(*BinaryExpr)
1016 return SameSafeExpr(l.X, r.X) && SameSafeExpr(l.Y, r.Y)
1017
1018 case OLITERAL:
1019 return constant.Compare(l.Val(), token.EQL, r.Val())
1020
1021 case ONIL:
1022 return true
1023 }
1024
1025 return false
1026 }
1027
1028
1029
1030
1031 func ShouldCheckPtr(fn *Func, level int) bool {
1032 return base.Debug.Checkptr >= level && fn.Pragma&NoCheckPtr == 0
1033 }
1034
1035
1036
1037 func IsReflectHeaderDataField(l Node) bool {
1038 if l.Type() != types.Types[types.TUINTPTR] {
1039 return false
1040 }
1041
1042 var tsym *types.Sym
1043 switch l.Op() {
1044 case ODOT:
1045 l := l.(*SelectorExpr)
1046 tsym = l.X.Type().Sym()
1047 case ODOTPTR:
1048 l := l.(*SelectorExpr)
1049 tsym = l.X.Type().Elem().Sym()
1050 default:
1051 return false
1052 }
1053
1054 if tsym == nil || l.Sym().Name != "Data" || tsym.Pkg.Path != "reflect" {
1055 return false
1056 }
1057 return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
1058 }
1059
1060 func ParamNames(ft *types.Type) []Node {
1061 args := make([]Node, ft.NumParams())
1062 for i, f := range ft.Params().FieldSlice() {
1063 args[i] = AsNode(f.Nname)
1064 }
1065 return args
1066 }
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076 func MethodSym(recv *types.Type, msym *types.Sym) *types.Sym {
1077 sym := MethodSymSuffix(recv, msym, "")
1078 sym.SetFunc(true)
1079 return sym
1080 }
1081
1082
1083
1084
1085 func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sym {
1086 if msym.IsBlank() {
1087 base.Fatalf("blank method name")
1088 }
1089
1090 rsym := recv.Sym()
1091 if recv.IsPtr() {
1092 if rsym != nil {
1093 base.Fatalf("declared pointer receiver type: %v", recv)
1094 }
1095 rsym = recv.Elem().Sym()
1096 }
1097
1098
1099
1100
1101 rpkg := Pkgs.Go
1102 if rsym != nil {
1103 rpkg = rsym.Pkg
1104 }
1105
1106 var b bytes.Buffer
1107 if recv.IsPtr() {
1108
1109
1110 fmt.Fprintf(&b, "(%-S)", recv)
1111 } else {
1112 fmt.Fprintf(&b, "%-S", recv)
1113 }
1114
1115
1116
1117
1118
1119 if !types.IsExported(msym.Name) && msym.Pkg != rpkg {
1120 b.WriteString(".")
1121 b.WriteString(msym.Pkg.Prefix)
1122 }
1123
1124 b.WriteString(".")
1125 b.WriteString(msym.Name)
1126 b.WriteString(suffix)
1127
1128 return rpkg.LookupBytes(b.Bytes())
1129 }
1130
1131
1132
1133
1134 func MethodExprName(n Node) *Name {
1135 name, _ := MethodExprFunc(n).Nname.(*Name)
1136 return name
1137 }
1138
1139
1140 func MethodExprFunc(n Node) *types.Field {
1141 switch n.Op() {
1142 case ODOTMETH, OMETHEXPR, OMETHVALUE:
1143 return n.(*SelectorExpr).Selection
1144 }
1145 base.Fatalf("unexpected node: %v (%v)", n, n.Op())
1146 panic("unreachable")
1147 }
1148
View as plain text