From be3d8b40b5447f787174015260e85b5198e8f7e6 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 28 Nov 2020 00:43:50 -0500 Subject: [PATCH] [dev.regabi] cmd/compile: ir.BranchStmt, add ir.EmptyStmt, ir.LabelStmt These are the first three specific implementations of Node. They are both a bit of a warmup and also working toward removing references to Name from Node types other than the proper named things - ONAME, ONONAME, OTYPE, OLITERAL. (In this case, BranchStmt and LabelStmt.) Passes buildall w/ toolstash -cmp. Change-Id: Ide816b162025ee4c858dd061d7c29ed633fb7baf Reviewed-on: https://go-review.googlesource.com/c/go/+/274091 Trust: Russ Cox Run-TryBot: Russ Cox Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/ir/mini.go | 4 +- src/cmd/compile/internal/ir/node.go | 13 ++--- src/cmd/compile/internal/ir/stmt.go | 83 +++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 src/cmd/compile/internal/ir/stmt.go diff --git a/src/cmd/compile/internal/ir/mini.go b/src/cmd/compile/internal/ir/mini.go index 48dccf6a5f..608c2bed81 100644 --- a/src/cmd/compile/internal/ir/mini.go +++ b/src/cmd/compile/internal/ir/mini.go @@ -127,7 +127,7 @@ func (n *miniNode) SubOp() Op { panic(n.no("SubOp")) } func (n *miniNode) SetSubOp(Op) { panic(n.no("SetSubOp")) } func (n *miniNode) Type() *types.Type { return nil } func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) } -func (n *miniNode) Func() *Func { panic(n.no("Func")) } +func (n *miniNode) Func() *Func { return nil } func (n *miniNode) SetFunc(*Func) { panic(n.no("SetFunc")) } func (n *miniNode) Name() *Name { return nil } func (n *miniNode) SetName(*Name) { panic(n.no("SetName")) } @@ -172,7 +172,7 @@ func (n *miniNode) Uint64Val() uint64 { panic(n.no("Uint64Val")) } func (n *miniNode) CanInt64() bool { panic(n.no("CanInt64")) } func (n *miniNode) BoolVal() bool { panic(n.no("BoolVal")) } func (n *miniNode) StringVal() string { panic(n.no("StringVal")) } -func (n *miniNode) HasCall() bool { panic(n.no("HasCall")) } +func (n *miniNode) HasCall() bool { return false } func (n *miniNode) SetHasCall(bool) { panic(n.no("SetHasCall")) } func (n *miniNode) NonNil() bool { return false } func (n *miniNode) MarkNonNil() { panic(n.no("MarkNonNil")) } diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go index 7e46673eab..cafe47493b 100644 --- a/src/cmd/compile/internal/ir/node.go +++ b/src/cmd/compile/internal/ir/node.go @@ -1702,13 +1702,19 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node { n = &x.n n.SetFunc(&x.f) n.Func().Decl = n - case OLABEL, OPACK: + case OPACK: var x struct { n node m Name } n = &x.n n.SetName(&x.m) + case OEMPTY: + return NewEmptyStmt(pos) + case OBREAK, OCONTINUE, OFALL, OGOTO: + return NewBranchStmt(pos, op, nil) + case OLABEL: + return NewLabelStmt(pos, nil) default: n = new(node) } @@ -1740,7 +1746,6 @@ var okForNod = [OEND]bool{ OASOP: true, OBITNOT: true, OBLOCK: true, - OBREAK: true, OBYTES2STR: true, OBYTES2STRTMP: true, OCALL: true, @@ -1757,7 +1762,6 @@ var okForNod = [OEND]bool{ OCLOSUREVAR: true, OCOMPLEX: true, OCOMPLIT: true, - OCONTINUE: true, OCONV: true, OCONVIFACE: true, OCONVNOP: true, @@ -1779,15 +1783,12 @@ var okForNod = [OEND]bool{ ODOTTYPE: true, ODOTTYPE2: true, OEFACE: true, - OEMPTY: true, OEQ: true, - OFALL: true, OFOR: true, OFORUNTIL: true, OGE: true, OGETG: true, OGO: true, - OGOTO: true, OGT: true, OIDATA: true, OIF: true, diff --git a/src/cmd/compile/internal/ir/stmt.go b/src/cmd/compile/internal/ir/stmt.go new file mode 100644 index 0000000000..5b89ff27a4 --- /dev/null +++ b/src/cmd/compile/internal/ir/stmt.go @@ -0,0 +1,83 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ir + +import ( + "cmd/compile/internal/types" + "cmd/internal/src" + "fmt" +) + +// A miniStmt is a miniNode with extra fields common to statements. +type miniStmt struct { + miniNode + init Nodes +} + +func (n *miniStmt) Init() Nodes { return n.init } +func (n *miniStmt) SetInit(x Nodes) { n.init = x } +func (n *miniStmt) PtrInit() *Nodes { return &n.init } +func (n *miniStmt) HasCall() bool { return n.bits&miniHasCall != 0 } +func (n *miniStmt) SetHasCall(b bool) { n.bits.set(miniHasCall, b) } + +// A BranchStmt is a break, continue, fallthrough, or goto statement. +type BranchStmt struct { + miniStmt + Label *types.Sym // label if present +} + +func NewBranchStmt(pos src.XPos, op Op, label *types.Sym) *BranchStmt { + switch op { + case OBREAK, OCONTINUE, OFALL, OGOTO: + // ok + default: + panic("NewBranch " + op.String()) + } + n := &BranchStmt{Label: label} + n.pos = pos + n.op = op + return n +} + +func (n *BranchStmt) String() string { return fmt.Sprint(n) } +func (n *BranchStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) } +func (n *BranchStmt) RawCopy() Node { c := *n; return &c } +func (n *BranchStmt) Sym() *types.Sym { return n.Label } +func (n *BranchStmt) SetSym(sym *types.Sym) { n.Label = sym } + +// An EmptyStmt is an empty statement +type EmptyStmt struct { + miniStmt +} + +func NewEmptyStmt(pos src.XPos) *EmptyStmt { + n := &EmptyStmt{} + n.pos = pos + n.op = OEMPTY + return n +} + +func (n *EmptyStmt) String() string { return fmt.Sprint(n) } +func (n *EmptyStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) } +func (n *EmptyStmt) RawCopy() Node { c := *n; return &c } + +// A LabelStmt is a label statement (just the label, not including the statement it labels). +type LabelStmt struct { + miniStmt + Label *types.Sym // "Label:" +} + +func NewLabelStmt(pos src.XPos, label *types.Sym) *LabelStmt { + n := &LabelStmt{Label: label} + n.pos = pos + n.op = OLABEL + return n +} + +func (n *LabelStmt) String() string { return fmt.Sprint(n) } +func (n *LabelStmt) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) } +func (n *LabelStmt) RawCopy() Node { c := *n; return &c } +func (n *LabelStmt) Sym() *types.Sym { return n.Label } +func (n *LabelStmt) SetSym(x *types.Sym) { n.Label = x } -- 2.48.1