mirror of
https://github.com/golang/go
synced 2024-11-22 14:44:50 -07:00
[dev.regabi] cmd/compile: adjust IR representations
Based on actually using the IR when prototyping adding type assertions, a few changes to improve it: - Merge DeferStmt and GoStmt, since they are variants of one thing. - Introduce LogicalExpr for && and ||, since they (alone) need an init list before Y. - Add an explicit op to various constructors to make them easier to use. - Add separate StructKeyExpr - it stores Value in a different abstract location (Left) than KeyExpr (Right). - Export all fields for use by rewrites (and later reflection). Passes buildall w/ toolstash -cmp. Change-Id: Iefbff2386d2bb9ef511ce53b7f92ff6c709dc991 Reviewed-on: https://go-review.googlesource.com/c/go/+/275883 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
0c49440664
commit
837b35cc55
@ -2010,18 +2010,13 @@ func typecheck1(n ir.Node, top int) (res ir.Node) {
|
||||
}
|
||||
return n
|
||||
|
||||
case ir.ODEFER:
|
||||
case ir.ODEFER, ir.OGO:
|
||||
n.SetLeft(typecheck(n.Left(), ctxStmt|ctxExpr))
|
||||
if !n.Left().Diag() {
|
||||
checkdefergo(n)
|
||||
}
|
||||
return n
|
||||
|
||||
case ir.OGO:
|
||||
n.SetLeft(typecheck(n.Left(), ctxStmt|ctxExpr))
|
||||
checkdefergo(n)
|
||||
return n
|
||||
|
||||
case ir.OFOR, ir.OFORUNTIL:
|
||||
typecheckslice(n.Init().Slice(), ctxStmt)
|
||||
decldepth++
|
||||
@ -2885,9 +2880,9 @@ func typecheckcomplit(n ir.Node) (res ir.Node) {
|
||||
if l.Op() == ir.OKEY {
|
||||
key := l.Left()
|
||||
|
||||
l.SetOp(ir.OSTRUCTKEY)
|
||||
l.SetLeft(l.Right())
|
||||
l.SetRight(nil)
|
||||
sk := ir.NewStructKeyExpr(l.Pos(), nil, l.Right())
|
||||
ls[i] = sk
|
||||
l = sk
|
||||
|
||||
// An OXDOT uses the Sym field to hold
|
||||
// the field to the right of the dot,
|
||||
@ -2895,7 +2890,7 @@ func typecheckcomplit(n ir.Node) (res ir.Node) {
|
||||
// is never a valid struct literal key.
|
||||
if key.Sym() == nil || key.Op() == ir.OXDOT || key.Sym().IsBlank() {
|
||||
base.Errorf("invalid field name %v in struct initializer", key)
|
||||
l.SetLeft(typecheck(l.Left(), ctxExpr))
|
||||
sk.SetLeft(typecheck(sk.Left(), ctxExpr))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -2909,7 +2904,7 @@ func typecheckcomplit(n ir.Node) (res ir.Node) {
|
||||
s = s1
|
||||
}
|
||||
}
|
||||
l.SetSym(s)
|
||||
sk.SetSym(s)
|
||||
}
|
||||
|
||||
if l.Op() != ir.OSTRUCTKEY {
|
||||
|
@ -202,8 +202,7 @@ func initUniverse() {
|
||||
ir.AsNode(s.Def).SetSym(s)
|
||||
|
||||
s = types.BuiltinPkg.Lookup("iota")
|
||||
s.Def = ir.Nod(ir.OIOTA, nil, nil)
|
||||
ir.AsNode(s.Def).SetSym(s)
|
||||
s.Def = ir.NewIota(base.Pos, s)
|
||||
|
||||
for et := types.TINT8; et <= types.TUINT64; et++ {
|
||||
isInt[et] = true
|
||||
|
@ -159,8 +159,8 @@ func (n *BinaryExpr) SetOp(op Op) {
|
||||
switch op {
|
||||
default:
|
||||
panic(n.no("SetOp " + op.String()))
|
||||
case OADD, OADDSTR, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
|
||||
OLSH, OLT, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSUB, OXOR,
|
||||
case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
|
||||
OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
|
||||
OCOPY, OCOMPLEX,
|
||||
OEFACE:
|
||||
n.op = op
|
||||
@ -181,21 +181,21 @@ const (
|
||||
// A CallExpr is a function call X(Args).
|
||||
type CallExpr struct {
|
||||
miniExpr
|
||||
orig Node
|
||||
X Node
|
||||
Args Nodes
|
||||
Rargs Nodes // TODO(rsc): Delete.
|
||||
Body_ Nodes // TODO(rsc): Delete.
|
||||
DDD bool
|
||||
Use CallUse
|
||||
noInline bool
|
||||
orig Node
|
||||
X Node
|
||||
Args Nodes
|
||||
Rargs Nodes // TODO(rsc): Delete.
|
||||
Body_ Nodes // TODO(rsc): Delete.
|
||||
DDD bool
|
||||
Use CallUse
|
||||
NoInline_ bool
|
||||
}
|
||||
|
||||
func NewCallExpr(pos src.XPos, fun Node, args []Node) *CallExpr {
|
||||
func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
|
||||
n := &CallExpr{X: fun}
|
||||
n.pos = pos
|
||||
n.orig = n
|
||||
n.op = OCALL
|
||||
n.SetOp(op)
|
||||
n.Args.Set(args)
|
||||
return n
|
||||
}
|
||||
@ -214,8 +214,8 @@ func (n *CallExpr) PtrRlist() *Nodes { return &n.Rargs }
|
||||
func (n *CallExpr) SetRlist(x Nodes) { n.Rargs = x }
|
||||
func (n *CallExpr) IsDDD() bool { return n.DDD }
|
||||
func (n *CallExpr) SetIsDDD(x bool) { n.DDD = x }
|
||||
func (n *CallExpr) NoInline() bool { return n.noInline }
|
||||
func (n *CallExpr) SetNoInline(x bool) { n.noInline = x }
|
||||
func (n *CallExpr) NoInline() bool { return n.NoInline_ }
|
||||
func (n *CallExpr) SetNoInline(x bool) { n.NoInline_ = x }
|
||||
func (n *CallExpr) Body() Nodes { return n.Body_ }
|
||||
func (n *CallExpr) PtrBody() *Nodes { return &n.Body_ }
|
||||
func (n *CallExpr) SetBody(x Nodes) { n.Body_ = x }
|
||||
@ -233,21 +233,21 @@ func (n *CallExpr) SetOp(op Op) {
|
||||
// A CallPartExpr is a method expression X.Method (uncalled).
|
||||
type CallPartExpr struct {
|
||||
miniExpr
|
||||
fn *Func
|
||||
Func_ *Func
|
||||
X Node
|
||||
Method *types.Field
|
||||
}
|
||||
|
||||
func NewCallPartExpr(pos src.XPos, x Node, method *types.Field, fn *Func) *CallPartExpr {
|
||||
n := &CallPartExpr{fn: fn, X: x, Method: method}
|
||||
n := &CallPartExpr{Func_: fn, X: x, Method: method}
|
||||
n.op = OCALLPART
|
||||
n.pos = pos
|
||||
n.typ = fn.Type()
|
||||
n.fn = fn
|
||||
n.Func_ = fn
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *CallPartExpr) Func() *Func { return n.fn }
|
||||
func (n *CallPartExpr) Func() *Func { return n.Func_ }
|
||||
func (n *CallPartExpr) Left() Node { return n.X }
|
||||
func (n *CallPartExpr) Sym() *types.Sym { return n.Method.Sym }
|
||||
func (n *CallPartExpr) SetLeft(x Node) { n.X = x }
|
||||
@ -268,20 +268,20 @@ func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
|
||||
func (n *ClosureExpr) Func() *Func { return n.Func_ }
|
||||
|
||||
// A ClosureRead denotes reading a variable stored within a closure struct.
|
||||
type ClosureRead struct {
|
||||
type ClosureReadExpr struct {
|
||||
miniExpr
|
||||
offset int64
|
||||
Offset_ int64
|
||||
}
|
||||
|
||||
func NewClosureRead(typ *types.Type, offset int64) *ClosureRead {
|
||||
n := &ClosureRead{offset: offset}
|
||||
func NewClosureRead(typ *types.Type, offset int64) *ClosureReadExpr {
|
||||
n := &ClosureReadExpr{Offset_: offset}
|
||||
n.typ = typ
|
||||
n.op = OCLOSUREREAD
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *ClosureRead) Type() *types.Type { return n.typ }
|
||||
func (n *ClosureRead) Offset() int64 { return n.offset }
|
||||
func (n *ClosureReadExpr) Type() *types.Type { return n.typ }
|
||||
func (n *ClosureReadExpr) Offset() int64 { return n.Offset_ }
|
||||
|
||||
// A CompLitExpr is a composite literal Type{Vals}.
|
||||
// Before type-checking, the type is Ntype.
|
||||
@ -292,10 +292,10 @@ type CompLitExpr struct {
|
||||
List_ Nodes // initialized values
|
||||
}
|
||||
|
||||
func NewCompLitExpr(pos src.XPos, typ Ntype, list []Node) *CompLitExpr {
|
||||
func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr {
|
||||
n := &CompLitExpr{Ntype: typ}
|
||||
n.pos = pos
|
||||
n.op = OCOMPLIT
|
||||
n.SetOp(op)
|
||||
n.List_.Set(list)
|
||||
n.orig = n
|
||||
return n
|
||||
@ -397,42 +397,48 @@ func (n *IndexExpr) SetOp(op Op) {
|
||||
}
|
||||
}
|
||||
|
||||
// A KeyExpr is an X:Y composite literal key.
|
||||
// After type-checking, a key for a struct sets Sym to the field.
|
||||
// A KeyExpr is a Key: Value composite literal key.
|
||||
type KeyExpr struct {
|
||||
miniExpr
|
||||
Key Node
|
||||
sym *types.Sym
|
||||
Value Node
|
||||
offset int64
|
||||
Key Node
|
||||
Value Node
|
||||
}
|
||||
|
||||
func NewKeyExpr(pos src.XPos, key, value Node) *KeyExpr {
|
||||
n := &KeyExpr{Key: key, Value: value}
|
||||
n.pos = pos
|
||||
n.op = OKEY
|
||||
n.offset = types.BADWIDTH
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *KeyExpr) Left() Node { return n.Key }
|
||||
func (n *KeyExpr) SetLeft(x Node) { n.Key = x }
|
||||
func (n *KeyExpr) Right() Node { return n.Value }
|
||||
func (n *KeyExpr) SetRight(y Node) { n.Value = y }
|
||||
func (n *KeyExpr) Sym() *types.Sym { return n.sym }
|
||||
func (n *KeyExpr) SetSym(x *types.Sym) { n.sym = x }
|
||||
func (n *KeyExpr) Offset() int64 { return n.offset }
|
||||
func (n *KeyExpr) SetOffset(x int64) { n.offset = x }
|
||||
func (n *KeyExpr) Left() Node { return n.Key }
|
||||
func (n *KeyExpr) SetLeft(x Node) { n.Key = x }
|
||||
func (n *KeyExpr) Right() Node { return n.Value }
|
||||
func (n *KeyExpr) SetRight(y Node) { n.Value = y }
|
||||
|
||||
func (n *KeyExpr) SetOp(op Op) {
|
||||
switch op {
|
||||
default:
|
||||
panic(n.no("SetOp " + op.String()))
|
||||
case OKEY, OSTRUCTKEY:
|
||||
n.op = op
|
||||
}
|
||||
// A StructKeyExpr is an Field: Value composite literal key.
|
||||
type StructKeyExpr struct {
|
||||
miniExpr
|
||||
Field *types.Sym
|
||||
Value Node
|
||||
Offset_ int64
|
||||
}
|
||||
|
||||
func NewStructKeyExpr(pos src.XPos, field *types.Sym, value Node) *StructKeyExpr {
|
||||
n := &StructKeyExpr{Field: field, Value: value}
|
||||
n.pos = pos
|
||||
n.op = OSTRUCTKEY
|
||||
n.Offset_ = types.BADWIDTH
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *StructKeyExpr) Sym() *types.Sym { return n.Field }
|
||||
func (n *StructKeyExpr) SetSym(x *types.Sym) { n.Field = x }
|
||||
func (n *StructKeyExpr) Left() Node { return n.Value }
|
||||
func (n *StructKeyExpr) SetLeft(x Node) { n.Value = x }
|
||||
func (n *StructKeyExpr) Offset() int64 { return n.Offset_ }
|
||||
func (n *StructKeyExpr) SetOffset(x int64) { n.Offset_ = x }
|
||||
|
||||
// An InlinedCallExpr is an inlined function call.
|
||||
type InlinedCallExpr struct {
|
||||
miniExpr
|
||||
@ -456,6 +462,36 @@ func (n *InlinedCallExpr) Rlist() Nodes { return n.ReturnVars }
|
||||
func (n *InlinedCallExpr) PtrRlist() *Nodes { return &n.ReturnVars }
|
||||
func (n *InlinedCallExpr) SetRlist(x Nodes) { n.ReturnVars = x }
|
||||
|
||||
// A LogicalExpr is a expression X Op Y where Op is && or ||.
|
||||
// It is separate from BinaryExpr to make room for statements
|
||||
// that must be executed before Y but after X.
|
||||
type LogicalExpr struct {
|
||||
miniExpr
|
||||
X Node
|
||||
Y Node
|
||||
}
|
||||
|
||||
func NewLogicalExpr(pos src.XPos, op Op, x, y Node) *LogicalExpr {
|
||||
n := &LogicalExpr{X: x, Y: y}
|
||||
n.pos = pos
|
||||
n.SetOp(op)
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *LogicalExpr) Left() Node { return n.X }
|
||||
func (n *LogicalExpr) SetLeft(x Node) { n.X = x }
|
||||
func (n *LogicalExpr) Right() Node { return n.Y }
|
||||
func (n *LogicalExpr) SetRight(y Node) { n.Y = y }
|
||||
|
||||
func (n *LogicalExpr) SetOp(op Op) {
|
||||
switch op {
|
||||
default:
|
||||
panic(n.no("SetOp " + op.String()))
|
||||
case OANDAND, OOROR:
|
||||
n.op = op
|
||||
}
|
||||
}
|
||||
|
||||
// A MakeExpr is a make expression: make(Type[, Len[, Cap]]).
|
||||
// Op is OMAKECHAN, OMAKEMAP, OMAKESLICE, or OMAKESLICECOPY,
|
||||
// but *not* OMAKE (that's a pre-typechecking CallExpr).
|
||||
@ -489,19 +525,19 @@ func (n *MakeExpr) SetOp(op Op) {
|
||||
// A MethodExpr is a method value X.M (where X is an expression, not a type).
|
||||
type MethodExpr struct {
|
||||
miniExpr
|
||||
X Node
|
||||
M Node
|
||||
sym *types.Sym
|
||||
offset int64
|
||||
class Class
|
||||
Method *types.Field
|
||||
X Node
|
||||
M Node
|
||||
Sym_ *types.Sym
|
||||
Offset_ int64
|
||||
Class_ Class
|
||||
Method *types.Field
|
||||
}
|
||||
|
||||
func NewMethodExpr(pos src.XPos, op Op, x, m Node) *MethodExpr {
|
||||
func NewMethodExpr(pos src.XPos, x, m Node) *MethodExpr {
|
||||
n := &MethodExpr{X: x, M: m}
|
||||
n.pos = pos
|
||||
n.op = OMETHEXPR
|
||||
n.offset = types.BADWIDTH
|
||||
n.Offset_ = types.BADWIDTH
|
||||
return n
|
||||
}
|
||||
|
||||
@ -509,18 +545,18 @@ func (n *MethodExpr) Left() Node { return n.X }
|
||||
func (n *MethodExpr) SetLeft(x Node) { n.X = x }
|
||||
func (n *MethodExpr) Right() Node { return n.M }
|
||||
func (n *MethodExpr) SetRight(y Node) { n.M = y }
|
||||
func (n *MethodExpr) Sym() *types.Sym { return n.sym }
|
||||
func (n *MethodExpr) SetSym(x *types.Sym) { n.sym = x }
|
||||
func (n *MethodExpr) Offset() int64 { return n.offset }
|
||||
func (n *MethodExpr) SetOffset(x int64) { n.offset = x }
|
||||
func (n *MethodExpr) Class() Class { return n.class }
|
||||
func (n *MethodExpr) SetClass(x Class) { n.class = x }
|
||||
func (n *MethodExpr) Sym() *types.Sym { return n.Sym_ }
|
||||
func (n *MethodExpr) SetSym(x *types.Sym) { n.Sym_ = x }
|
||||
func (n *MethodExpr) Offset() int64 { return n.Offset_ }
|
||||
func (n *MethodExpr) SetOffset(x int64) { n.Offset_ = x }
|
||||
func (n *MethodExpr) Class() Class { return n.Class_ }
|
||||
func (n *MethodExpr) SetClass(x Class) { n.Class_ = x }
|
||||
|
||||
// A NilExpr represents the predefined untyped constant nil.
|
||||
// (It may be copied and assigned a type, though.)
|
||||
type NilExpr struct {
|
||||
miniExpr
|
||||
sym *types.Sym // TODO: Remove
|
||||
Sym_ *types.Sym // TODO: Remove
|
||||
}
|
||||
|
||||
func NewNilExpr(pos src.XPos) *NilExpr {
|
||||
@ -530,8 +566,8 @@ func NewNilExpr(pos src.XPos) *NilExpr {
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *NilExpr) Sym() *types.Sym { return n.sym }
|
||||
func (n *NilExpr) SetSym(x *types.Sym) { n.sym = x }
|
||||
func (n *NilExpr) Sym() *types.Sym { return n.Sym_ }
|
||||
func (n *NilExpr) SetSym(x *types.Sym) { n.Sym_ = x }
|
||||
|
||||
// A ParenExpr is a parenthesized expression (X).
|
||||
// It may end up being a value or a type.
|
||||
@ -563,34 +599,34 @@ func (n *ParenExpr) SetOTYPE(t *types.Type) {
|
||||
// A ResultExpr represents a direct access to a result slot on the stack frame.
|
||||
type ResultExpr struct {
|
||||
miniExpr
|
||||
offset int64
|
||||
Offset_ int64
|
||||
}
|
||||
|
||||
func NewResultExpr(pos src.XPos, typ *types.Type, offset int64) *ResultExpr {
|
||||
n := &ResultExpr{offset: offset}
|
||||
n := &ResultExpr{Offset_: offset}
|
||||
n.pos = pos
|
||||
n.op = ORESULT
|
||||
n.typ = typ
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *ResultExpr) Offset() int64 { return n.offset }
|
||||
func (n *ResultExpr) SetOffset(x int64) { n.offset = x }
|
||||
func (n *ResultExpr) Offset() int64 { return n.Offset_ }
|
||||
func (n *ResultExpr) SetOffset(x int64) { n.Offset_ = x }
|
||||
|
||||
// A SelectorExpr is a selector expression X.Sym.
|
||||
type SelectorExpr struct {
|
||||
miniExpr
|
||||
X Node
|
||||
Sel *types.Sym
|
||||
offset int64
|
||||
Offset_ int64
|
||||
Selection *types.Field
|
||||
}
|
||||
|
||||
func NewSelectorExpr(pos src.XPos, x Node, sel *types.Sym) *SelectorExpr {
|
||||
func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
|
||||
n := &SelectorExpr{X: x, Sel: sel}
|
||||
n.pos = pos
|
||||
n.op = OXDOT
|
||||
n.offset = types.BADWIDTH
|
||||
n.Offset_ = types.BADWIDTH
|
||||
n.SetOp(op)
|
||||
return n
|
||||
}
|
||||
|
||||
@ -607,8 +643,8 @@ func (n *SelectorExpr) Left() Node { return n.X }
|
||||
func (n *SelectorExpr) SetLeft(x Node) { n.X = x }
|
||||
func (n *SelectorExpr) Sym() *types.Sym { return n.Sel }
|
||||
func (n *SelectorExpr) SetSym(x *types.Sym) { n.Sel = x }
|
||||
func (n *SelectorExpr) Offset() int64 { return n.offset }
|
||||
func (n *SelectorExpr) SetOffset(x int64) { n.offset = x }
|
||||
func (n *SelectorExpr) Offset() int64 { return n.Offset_ }
|
||||
func (n *SelectorExpr) SetOffset(x int64) { n.Offset_ = x }
|
||||
|
||||
// Before type-checking, bytes.Buffer is a SelectorExpr.
|
||||
// After type-checking it becomes a Name.
|
||||
|
@ -132,6 +132,14 @@ func NewNameAt(pos src.XPos, sym *types.Sym) *Name {
|
||||
return newNameAt(pos, ONAME, sym)
|
||||
}
|
||||
|
||||
// NewIota returns a new OIOTA Node.
|
||||
func NewIota(pos src.XPos, sym *types.Sym) *Name {
|
||||
if sym == nil {
|
||||
base.Fatalf("NewIota nil")
|
||||
}
|
||||
return newNameAt(pos, OIOTA, sym)
|
||||
}
|
||||
|
||||
// NewDeclNameAt returns a new ONONAME Node associated with symbol s at position pos.
|
||||
// The caller is responsible for setting Curfn.
|
||||
func NewDeclNameAt(pos src.XPos, sym *types.Sym) *Name {
|
||||
|
@ -681,30 +681,31 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
|
||||
switch op {
|
||||
default:
|
||||
panic("NodAt " + op.String())
|
||||
case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
|
||||
OLSH, OLT, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSUB, OXOR,
|
||||
case OADD, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
|
||||
OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
|
||||
OCOPY, OCOMPLEX,
|
||||
OEFACE:
|
||||
return NewBinaryExpr(pos, op, nleft, nright)
|
||||
case OADDR, OPTRLIT:
|
||||
case OADDR:
|
||||
return NewAddrExpr(pos, nleft)
|
||||
case OADDSTR:
|
||||
return NewAddStringExpr(pos, nil)
|
||||
case OANDAND, OOROR:
|
||||
return NewLogicalExpr(pos, op, nleft, nright)
|
||||
case OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OSLICELIT:
|
||||
var typ Ntype
|
||||
if nright != nil {
|
||||
typ = nright.(Ntype)
|
||||
}
|
||||
n := NewCompLitExpr(pos, typ, nil)
|
||||
n.SetOp(op)
|
||||
return n
|
||||
return NewCompLitExpr(pos, op, typ, nil)
|
||||
case OAS, OSELRECV:
|
||||
n := NewAssignStmt(pos, nleft, nright)
|
||||
n.SetOp(op)
|
||||
if op != OAS {
|
||||
n.SetOp(op)
|
||||
}
|
||||
return n
|
||||
case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, OSELRECV2:
|
||||
n := NewAssignListStmt(pos, nil, nil)
|
||||
n.SetOp(op)
|
||||
n := NewAssignListStmt(pos, op, nil, nil)
|
||||
return n
|
||||
case OASOP:
|
||||
return NewAssignOpStmt(pos, OXXX, nleft, nright)
|
||||
@ -722,9 +723,7 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
|
||||
return NewBranchStmt(pos, op, nil)
|
||||
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH,
|
||||
OAPPEND, ODELETE, OGETG, OMAKE, OPRINT, OPRINTN, ORECOVER:
|
||||
n := NewCallExpr(pos, nleft, nil)
|
||||
n.SetOp(op)
|
||||
return n
|
||||
return NewCallExpr(pos, op, nleft, nil)
|
||||
case OCASE:
|
||||
return NewCaseStmt(pos, nil, nil)
|
||||
case OCONV, OCONVIFACE, OCONVNOP, ORUNESTR:
|
||||
@ -733,38 +732,38 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
|
||||
return NewDecl(pos, op, nleft)
|
||||
case ODCLFUNC:
|
||||
return NewFunc(pos)
|
||||
case ODEFER:
|
||||
return NewDeferStmt(pos, nleft)
|
||||
case ODEFER, OGO:
|
||||
return NewGoDeferStmt(pos, op, nleft)
|
||||
case ODEREF:
|
||||
return NewStarExpr(pos, nleft)
|
||||
case ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT:
|
||||
n := NewSelectorExpr(pos, nleft, nil)
|
||||
n.SetOp(op)
|
||||
return n
|
||||
return NewSelectorExpr(pos, op, nleft, nil)
|
||||
case ODOTTYPE, ODOTTYPE2:
|
||||
var typ Ntype
|
||||
if nright != nil {
|
||||
typ = nright.(Ntype)
|
||||
}
|
||||
n := NewTypeAssertExpr(pos, nleft, typ)
|
||||
n.SetOp(op)
|
||||
if op != ODOTTYPE {
|
||||
n.SetOp(op)
|
||||
}
|
||||
return n
|
||||
case OFOR:
|
||||
return NewForStmt(pos, nil, nleft, nright, nil)
|
||||
case OGO:
|
||||
return NewGoStmt(pos, nleft)
|
||||
case OIF:
|
||||
return NewIfStmt(pos, nleft, nil, nil)
|
||||
case OINDEX, OINDEXMAP:
|
||||
n := NewIndexExpr(pos, nleft, nright)
|
||||
n.SetOp(op)
|
||||
if op != OINDEX {
|
||||
n.SetOp(op)
|
||||
}
|
||||
return n
|
||||
case OINLMARK:
|
||||
return NewInlineMarkStmt(pos, types.BADWIDTH)
|
||||
case OKEY, OSTRUCTKEY:
|
||||
n := NewKeyExpr(pos, nleft, nright)
|
||||
n.SetOp(op)
|
||||
return n
|
||||
case OKEY:
|
||||
return NewKeyExpr(pos, nleft, nright)
|
||||
case OSTRUCTKEY:
|
||||
return NewStructKeyExpr(pos, nil, nleft)
|
||||
case OLABEL:
|
||||
return NewLabelStmt(pos, nil)
|
||||
case OLITERAL, OTYPE, OIOTA:
|
||||
@ -772,7 +771,7 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
|
||||
case OMAKECHAN, OMAKEMAP, OMAKESLICE, OMAKESLICECOPY:
|
||||
return NewMakeExpr(pos, op, nleft, nright)
|
||||
case OMETHEXPR:
|
||||
return NewMethodExpr(pos, op, nleft, nright)
|
||||
return NewMethodExpr(pos, nleft, nright)
|
||||
case ONIL:
|
||||
return NewNilExpr(pos)
|
||||
case OPACK:
|
||||
|
@ -280,19 +280,19 @@ func (n *ClosureExpr) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
}
|
||||
|
||||
func (n *ClosureRead) String() string { return fmt.Sprint(n) }
|
||||
func (n *ClosureRead) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *ClosureRead) copy() Node {
|
||||
func (n *ClosureReadExpr) String() string { return fmt.Sprint(n) }
|
||||
func (n *ClosureReadExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *ClosureReadExpr) copy() Node {
|
||||
c := *n
|
||||
c.init = c.init.Copy()
|
||||
return &c
|
||||
}
|
||||
func (n *ClosureRead) doChildren(do func(Node) error) error {
|
||||
func (n *ClosureReadExpr) doChildren(do func(Node) error) error {
|
||||
var err error
|
||||
err = maybeDoList(n.init, err, do)
|
||||
return err
|
||||
}
|
||||
func (n *ClosureRead) editChildren(edit func(Node) Node) {
|
||||
func (n *ClosureReadExpr) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
}
|
||||
|
||||
@ -366,24 +366,6 @@ func (n *Decl) editChildren(edit func(Node) Node) {
|
||||
n.X = maybeEdit(n.X, edit)
|
||||
}
|
||||
|
||||
func (n *DeferStmt) String() string { return fmt.Sprint(n) }
|
||||
func (n *DeferStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *DeferStmt) copy() Node {
|
||||
c := *n
|
||||
c.init = c.init.Copy()
|
||||
return &c
|
||||
}
|
||||
func (n *DeferStmt) doChildren(do func(Node) error) error {
|
||||
var err error
|
||||
err = maybeDoList(n.init, err, do)
|
||||
err = maybeDo(n.Call, err, do)
|
||||
return err
|
||||
}
|
||||
func (n *DeferStmt) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
n.Call = maybeEdit(n.Call, edit)
|
||||
}
|
||||
|
||||
func (n *ForStmt) String() string { return fmt.Sprint(n) }
|
||||
func (n *ForStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *ForStmt) copy() Node {
|
||||
@ -450,20 +432,20 @@ func (n *FuncType) editChildren(edit func(Node) Node) {
|
||||
editFields(n.Results, edit)
|
||||
}
|
||||
|
||||
func (n *GoStmt) String() string { return fmt.Sprint(n) }
|
||||
func (n *GoStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *GoStmt) copy() Node {
|
||||
func (n *GoDeferStmt) String() string { return fmt.Sprint(n) }
|
||||
func (n *GoDeferStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *GoDeferStmt) copy() Node {
|
||||
c := *n
|
||||
c.init = c.init.Copy()
|
||||
return &c
|
||||
}
|
||||
func (n *GoStmt) doChildren(do func(Node) error) error {
|
||||
func (n *GoDeferStmt) doChildren(do func(Node) error) error {
|
||||
var err error
|
||||
err = maybeDoList(n.init, err, do)
|
||||
err = maybeDo(n.Call, err, do)
|
||||
return err
|
||||
}
|
||||
func (n *GoStmt) editChildren(edit func(Node) Node) {
|
||||
func (n *GoDeferStmt) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
n.Call = maybeEdit(n.Call, edit)
|
||||
}
|
||||
@ -602,6 +584,26 @@ func (n *LabelStmt) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
}
|
||||
|
||||
func (n *LogicalExpr) String() string { return fmt.Sprint(n) }
|
||||
func (n *LogicalExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *LogicalExpr) copy() Node {
|
||||
c := *n
|
||||
c.init = c.init.Copy()
|
||||
return &c
|
||||
}
|
||||
func (n *LogicalExpr) doChildren(do func(Node) error) error {
|
||||
var err error
|
||||
err = maybeDoList(n.init, err, do)
|
||||
err = maybeDo(n.X, err, do)
|
||||
err = maybeDo(n.Y, err, do)
|
||||
return err
|
||||
}
|
||||
func (n *LogicalExpr) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
n.X = maybeEdit(n.X, edit)
|
||||
n.Y = maybeEdit(n.Y, edit)
|
||||
}
|
||||
|
||||
func (n *MakeExpr) String() string { return fmt.Sprint(n) }
|
||||
func (n *MakeExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *MakeExpr) copy() Node {
|
||||
@ -913,6 +915,24 @@ func (n *StarExpr) editChildren(edit func(Node) Node) {
|
||||
n.X = maybeEdit(n.X, edit)
|
||||
}
|
||||
|
||||
func (n *StructKeyExpr) String() string { return fmt.Sprint(n) }
|
||||
func (n *StructKeyExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *StructKeyExpr) copy() Node {
|
||||
c := *n
|
||||
c.init = c.init.Copy()
|
||||
return &c
|
||||
}
|
||||
func (n *StructKeyExpr) doChildren(do func(Node) error) error {
|
||||
var err error
|
||||
err = maybeDoList(n.init, err, do)
|
||||
err = maybeDo(n.Value, err, do)
|
||||
return err
|
||||
}
|
||||
func (n *StructKeyExpr) editChildren(edit func(Node) Node) {
|
||||
editList(n.init, edit)
|
||||
n.Value = maybeEdit(n.Value, edit)
|
||||
}
|
||||
|
||||
func (n *StructType) String() string { return fmt.Sprint(n) }
|
||||
func (n *StructType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||
func (n *StructType) copy() Node {
|
||||
|
@ -63,19 +63,19 @@ func (n *miniStmt) SetHasCall(b bool) { n.bits.set(miniHasCall, b) }
|
||||
// If Def is true, the assignment is a :=.
|
||||
type AssignListStmt struct {
|
||||
miniStmt
|
||||
Lhs Nodes
|
||||
Def bool
|
||||
Rhs Nodes
|
||||
offset int64 // for initorder
|
||||
Lhs Nodes
|
||||
Def bool
|
||||
Rhs Nodes
|
||||
Offset_ int64 // for initorder
|
||||
}
|
||||
|
||||
func NewAssignListStmt(pos src.XPos, lhs, rhs []Node) *AssignListStmt {
|
||||
func NewAssignListStmt(pos src.XPos, op Op, lhs, rhs []Node) *AssignListStmt {
|
||||
n := &AssignListStmt{}
|
||||
n.pos = pos
|
||||
n.op = OAS2
|
||||
n.SetOp(op)
|
||||
n.Lhs.Set(lhs)
|
||||
n.Rhs.Set(rhs)
|
||||
n.offset = types.BADWIDTH
|
||||
n.Offset_ = types.BADWIDTH
|
||||
return n
|
||||
}
|
||||
|
||||
@ -87,8 +87,8 @@ func (n *AssignListStmt) PtrRlist() *Nodes { return &n.Rhs }
|
||||
func (n *AssignListStmt) SetRlist(x Nodes) { n.Rhs = x }
|
||||
func (n *AssignListStmt) Colas() bool { return n.Def }
|
||||
func (n *AssignListStmt) SetColas(x bool) { n.Def = x }
|
||||
func (n *AssignListStmt) Offset() int64 { return n.offset }
|
||||
func (n *AssignListStmt) SetOffset(x int64) { n.offset = x }
|
||||
func (n *AssignListStmt) Offset() int64 { return n.Offset_ }
|
||||
func (n *AssignListStmt) SetOffset(x int64) { n.Offset_ = x }
|
||||
|
||||
func (n *AssignListStmt) SetOp(op Op) {
|
||||
switch op {
|
||||
@ -103,17 +103,17 @@ func (n *AssignListStmt) SetOp(op Op) {
|
||||
// If Def is true, the assignment is a :=.
|
||||
type AssignStmt struct {
|
||||
miniStmt
|
||||
X Node
|
||||
Def bool
|
||||
Y Node
|
||||
offset int64 // for initorder
|
||||
X Node
|
||||
Def bool
|
||||
Y Node
|
||||
Offset_ int64 // for initorder
|
||||
}
|
||||
|
||||
func NewAssignStmt(pos src.XPos, x, y Node) *AssignStmt {
|
||||
n := &AssignStmt{X: x, Y: y}
|
||||
n.pos = pos
|
||||
n.op = OAS
|
||||
n.offset = types.BADWIDTH
|
||||
n.Offset_ = types.BADWIDTH
|
||||
return n
|
||||
}
|
||||
|
||||
@ -123,8 +123,8 @@ func (n *AssignStmt) Right() Node { return n.Y }
|
||||
func (n *AssignStmt) SetRight(y Node) { n.Y = y }
|
||||
func (n *AssignStmt) Colas() bool { return n.Def }
|
||||
func (n *AssignStmt) SetColas(x bool) { n.Def = x }
|
||||
func (n *AssignStmt) Offset() int64 { return n.offset }
|
||||
func (n *AssignStmt) SetOffset(x int64) { n.offset = x }
|
||||
func (n *AssignStmt) Offset() int64 { return n.Offset_ }
|
||||
func (n *AssignStmt) SetOffset(x int64) { n.Offset_ = x }
|
||||
|
||||
func (n *AssignStmt) SetOp(op Op) {
|
||||
switch op {
|
||||
@ -236,32 +236,16 @@ func (n *CaseStmt) SetRlist(x Nodes) { n.Vars = x }
|
||||
func (n *CaseStmt) Left() Node { return n.Comm }
|
||||
func (n *CaseStmt) SetLeft(x Node) { n.Comm = x }
|
||||
|
||||
// A DeferStmt is a defer statement: defer Call.
|
||||
type DeferStmt struct {
|
||||
miniStmt
|
||||
Call Node
|
||||
}
|
||||
|
||||
func NewDeferStmt(pos src.XPos, call Node) *DeferStmt {
|
||||
n := &DeferStmt{Call: call}
|
||||
n.pos = pos
|
||||
n.op = ODEFER
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *DeferStmt) Left() Node { return n.Call }
|
||||
func (n *DeferStmt) SetLeft(x Node) { n.Call = x }
|
||||
|
||||
// A ForStmt is a non-range for loop: for Init; Cond; Post { Body }
|
||||
// Op can be OFOR or OFORUNTIL (!Cond).
|
||||
type ForStmt struct {
|
||||
miniStmt
|
||||
Label *types.Sym
|
||||
Cond Node
|
||||
Late Nodes
|
||||
Post Node
|
||||
Body_ Nodes
|
||||
hasBreak bool
|
||||
Label *types.Sym
|
||||
Cond Node
|
||||
Late Nodes
|
||||
Post Node
|
||||
Body_ Nodes
|
||||
HasBreak_ bool
|
||||
}
|
||||
|
||||
func NewForStmt(pos src.XPos, init []Node, cond, post Node, body []Node) *ForStmt {
|
||||
@ -285,8 +269,8 @@ func (n *ForStmt) SetBody(x Nodes) { n.Body_ = x }
|
||||
func (n *ForStmt) List() Nodes { return n.Late }
|
||||
func (n *ForStmt) PtrList() *Nodes { return &n.Late }
|
||||
func (n *ForStmt) SetList(x Nodes) { n.Late = x }
|
||||
func (n *ForStmt) HasBreak() bool { return n.hasBreak }
|
||||
func (n *ForStmt) SetHasBreak(b bool) { n.hasBreak = b }
|
||||
func (n *ForStmt) HasBreak() bool { return n.HasBreak_ }
|
||||
func (n *ForStmt) SetHasBreak(b bool) { n.HasBreak_ = b }
|
||||
|
||||
func (n *ForStmt) SetOp(op Op) {
|
||||
if op != OFOR && op != OFORUNTIL {
|
||||
@ -295,29 +279,38 @@ func (n *ForStmt) SetOp(op Op) {
|
||||
n.op = op
|
||||
}
|
||||
|
||||
// A GoStmt is a go statement: go Call.
|
||||
type GoStmt struct {
|
||||
// A GoDeferStmt is a go or defer statement: go Call / defer Call.
|
||||
//
|
||||
// The two opcodes use a signle syntax because the implementations
|
||||
// are very similar: both are concerned with saving Call and running it
|
||||
// in a different context (a separate goroutine or a later time).
|
||||
type GoDeferStmt struct {
|
||||
miniStmt
|
||||
Call Node
|
||||
}
|
||||
|
||||
func NewGoStmt(pos src.XPos, call Node) *GoStmt {
|
||||
n := &GoStmt{Call: call}
|
||||
func NewGoDeferStmt(pos src.XPos, op Op, call Node) *GoDeferStmt {
|
||||
n := &GoDeferStmt{Call: call}
|
||||
n.pos = pos
|
||||
n.op = OGO
|
||||
switch op {
|
||||
case ODEFER, OGO:
|
||||
n.op = op
|
||||
default:
|
||||
panic("NewGoDeferStmt " + op.String())
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *GoStmt) Left() Node { return n.Call }
|
||||
func (n *GoStmt) SetLeft(x Node) { n.Call = x }
|
||||
func (n *GoDeferStmt) Left() Node { return n.Call }
|
||||
func (n *GoDeferStmt) SetLeft(x Node) { n.Call = x }
|
||||
|
||||
// A IfStmt is a return statement: if Init; Cond { Then } else { Else }.
|
||||
type IfStmt struct {
|
||||
miniStmt
|
||||
Cond Node
|
||||
Body_ Nodes
|
||||
Else Nodes
|
||||
likely bool // code layout hint
|
||||
Cond Node
|
||||
Body_ Nodes
|
||||
Else Nodes
|
||||
Likely_ bool // code layout hint
|
||||
}
|
||||
|
||||
func NewIfStmt(pos src.XPos, cond Node, body, els []Node) *IfStmt {
|
||||
@ -337,8 +330,8 @@ func (n *IfStmt) SetBody(x Nodes) { n.Body_ = x }
|
||||
func (n *IfStmt) Rlist() Nodes { return n.Else }
|
||||
func (n *IfStmt) PtrRlist() *Nodes { return &n.Else }
|
||||
func (n *IfStmt) SetRlist(x Nodes) { n.Else = x }
|
||||
func (n *IfStmt) Likely() bool { return n.likely }
|
||||
func (n *IfStmt) SetLikely(x bool) { n.likely = x }
|
||||
func (n *IfStmt) Likely() bool { return n.Likely_ }
|
||||
func (n *IfStmt) SetLikely(x bool) { n.Likely_ = x }
|
||||
|
||||
// An InlineMarkStmt is a marker placed just before an inlined body.
|
||||
type InlineMarkStmt struct {
|
||||
@ -376,13 +369,13 @@ func (n *LabelStmt) SetSym(x *types.Sym) { n.Label = x }
|
||||
// Op can be OFOR or OFORUNTIL (!Cond).
|
||||
type RangeStmt struct {
|
||||
miniStmt
|
||||
Label *types.Sym
|
||||
Vars Nodes // TODO(rsc): Replace with Key, Value Node
|
||||
Def bool
|
||||
X Node
|
||||
Body_ Nodes
|
||||
hasBreak bool
|
||||
typ *types.Type // TODO(rsc): Remove - use X.Type() instead
|
||||
Label *types.Sym
|
||||
Vars Nodes // TODO(rsc): Replace with Key, Value Node
|
||||
Def bool
|
||||
X Node
|
||||
Body_ Nodes
|
||||
HasBreak_ bool
|
||||
typ *types.Type // TODO(rsc): Remove - use X.Type() instead
|
||||
}
|
||||
|
||||
func NewRangeStmt(pos src.XPos, vars []Node, x Node, body []Node) *RangeStmt {
|
||||
@ -404,8 +397,8 @@ func (n *RangeStmt) SetBody(x Nodes) { n.Body_ = x }
|
||||
func (n *RangeStmt) List() Nodes { return n.Vars }
|
||||
func (n *RangeStmt) PtrList() *Nodes { return &n.Vars }
|
||||
func (n *RangeStmt) SetList(x Nodes) { n.Vars = x }
|
||||
func (n *RangeStmt) HasBreak() bool { return n.hasBreak }
|
||||
func (n *RangeStmt) SetHasBreak(b bool) { n.hasBreak = b }
|
||||
func (n *RangeStmt) HasBreak() bool { return n.HasBreak_ }
|
||||
func (n *RangeStmt) SetHasBreak(b bool) { n.HasBreak_ = b }
|
||||
func (n *RangeStmt) Colas() bool { return n.Def }
|
||||
func (n *RangeStmt) SetColas(b bool) { n.Def = b }
|
||||
func (n *RangeStmt) Type() *types.Type { return n.typ }
|
||||
@ -437,9 +430,9 @@ func (n *ReturnStmt) IsDDD() bool { return false } // typecheckargs asks
|
||||
// A SelectStmt is a block: { Cases }.
|
||||
type SelectStmt struct {
|
||||
miniStmt
|
||||
Label *types.Sym
|
||||
Cases Nodes
|
||||
hasBreak bool
|
||||
Label *types.Sym
|
||||
Cases Nodes
|
||||
HasBreak_ bool
|
||||
|
||||
// TODO(rsc): Instead of recording here, replace with a block?
|
||||
Compiled Nodes // compiled form, after walkswitch
|
||||
@ -458,8 +451,8 @@ func (n *SelectStmt) PtrList() *Nodes { return &n.Cases }
|
||||
func (n *SelectStmt) SetList(x Nodes) { n.Cases = x }
|
||||
func (n *SelectStmt) Sym() *types.Sym { return n.Label }
|
||||
func (n *SelectStmt) SetSym(x *types.Sym) { n.Label = x }
|
||||
func (n *SelectStmt) HasBreak() bool { return n.hasBreak }
|
||||
func (n *SelectStmt) SetHasBreak(x bool) { n.hasBreak = x }
|
||||
func (n *SelectStmt) HasBreak() bool { return n.HasBreak_ }
|
||||
func (n *SelectStmt) SetHasBreak(x bool) { n.HasBreak_ = x }
|
||||
func (n *SelectStmt) Body() Nodes { return n.Compiled }
|
||||
func (n *SelectStmt) PtrBody() *Nodes { return &n.Compiled }
|
||||
func (n *SelectStmt) SetBody(x Nodes) { n.Compiled = x }
|
||||
@ -486,10 +479,10 @@ func (n *SendStmt) SetRight(y Node) { n.Value = y }
|
||||
// A SwitchStmt is a switch statement: switch Init; Expr { Cases }.
|
||||
type SwitchStmt struct {
|
||||
miniStmt
|
||||
Tag Node
|
||||
Cases Nodes // list of *CaseStmt
|
||||
Label *types.Sym
|
||||
hasBreak bool
|
||||
Tag Node
|
||||
Cases Nodes // list of *CaseStmt
|
||||
Label *types.Sym
|
||||
HasBreak_ bool
|
||||
|
||||
// TODO(rsc): Instead of recording here, replace with a block?
|
||||
Compiled Nodes // compiled form, after walkswitch
|
||||
@ -513,8 +506,8 @@ func (n *SwitchStmt) PtrBody() *Nodes { return &n.Compiled }
|
||||
func (n *SwitchStmt) SetBody(x Nodes) { n.Compiled = x }
|
||||
func (n *SwitchStmt) Sym() *types.Sym { return n.Label }
|
||||
func (n *SwitchStmt) SetSym(x *types.Sym) { n.Label = x }
|
||||
func (n *SwitchStmt) HasBreak() bool { return n.hasBreak }
|
||||
func (n *SwitchStmt) SetHasBreak(x bool) { n.hasBreak = x }
|
||||
func (n *SwitchStmt) HasBreak() bool { return n.HasBreak_ }
|
||||
func (n *SwitchStmt) SetHasBreak(x bool) { n.HasBreak_ = x }
|
||||
|
||||
// A TypeSwitchGuard is the [Name :=] X.(type) in a type switch.
|
||||
type TypeSwitchGuard struct {
|
||||
|
@ -92,7 +92,7 @@ func ValidTypeForConst(t *types.Type, v constant.Value) bool {
|
||||
|
||||
// nodlit returns a new untyped constant with value v.
|
||||
func NewLiteral(v constant.Value) Node {
|
||||
n := Nod(OLITERAL, nil, nil)
|
||||
n := newNameAt(base.Pos, OLITERAL, nil)
|
||||
if k := v.Kind(); k != constant.Unknown {
|
||||
n.SetType(idealType(k))
|
||||
n.SetVal(v)
|
||||
|
Loading…
Reference in New Issue
Block a user