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//go:generate go run mknode.go
6
7package ir
8
9import (
10	"cmd/compile/internal/types"
11	"cmd/internal/src"
12	"fmt"
13	"go/constant"
14)
15
16// A miniNode is a minimal node implementation,
17// meant to be embedded as the first field in a larger node implementation,
18// at a cost of 8 bytes.
19//
20// A miniNode is NOT a valid Node by itself: the embedding struct
21// must at the least provide:
22//
23//	func (n *MyNode) String() string { return fmt.Sprint(n) }
24//	func (n *MyNode) rawCopy() Node { c := *n; return &c }
25//	func (n *MyNode) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
26//
27// The embedding struct should also fill in n.op in its constructor,
28// for more useful panic messages when invalid methods are called,
29// instead of implementing Op itself.
30type miniNode struct {
31	pos  src.XPos // uint32
32	op   Op       // uint8
33	bits bitset8
34	esc  uint16
35}
36
37// posOr returns pos if known, or else n.pos.
38// For use in DeepCopy.
39func (n *miniNode) posOr(pos src.XPos) src.XPos {
40	if pos.IsKnown() {
41		return pos
42	}
43	return n.pos
44}
45
46// op can be read, but not written.
47// An embedding implementation can provide a SetOp if desired.
48// (The panicking SetOp is with the other panics below.)
49func (n *miniNode) Op() Op            { return n.op }
50func (n *miniNode) Pos() src.XPos     { return n.pos }
51func (n *miniNode) SetPos(x src.XPos) { n.pos = x }
52func (n *miniNode) Esc() uint16       { return n.esc }
53func (n *miniNode) SetEsc(x uint16)   { n.esc = x }
54
55const (
56	miniTypecheckShift = 0
57	miniWalked         = 1 << 2 // to prevent/catch re-walking
58)
59
60func (n *miniNode) Typecheck() uint8 { return n.bits.get2(miniTypecheckShift) }
61func (n *miniNode) SetTypecheck(x uint8) {
62	if x > 2 {
63		panic(fmt.Sprintf("cannot SetTypecheck %d", x))
64	}
65	n.bits.set2(miniTypecheckShift, x)
66}
67
68func (n *miniNode) Walked() bool     { return n.bits&miniWalked != 0 }
69func (n *miniNode) SetWalked(x bool) { n.bits.set(miniWalked, x) }
70
71// Empty, immutable graph structure.
72
73func (n *miniNode) Init() Nodes { return Nodes{} }
74
75// Additional functionality unavailable.
76
77func (n *miniNode) no(name string) string { return "cannot " + name + " on " + n.op.String() }
78
79func (n *miniNode) Type() *types.Type       { return nil }
80func (n *miniNode) SetType(*types.Type)     { panic(n.no("SetType")) }
81func (n *miniNode) Name() *Name             { return nil }
82func (n *miniNode) Sym() *types.Sym         { return nil }
83func (n *miniNode) Val() constant.Value     { panic(n.no("Val")) }
84func (n *miniNode) SetVal(v constant.Value) { panic(n.no("SetVal")) }
85func (n *miniNode) NonNil() bool            { return false }
86func (n *miniNode) MarkNonNil()             { panic(n.no("MarkNonNil")) }
87