mirror of
https://github.com/golang/go
synced 2024-09-23 19:20:13 -06:00
[dev.regabi] cmd/compile: make ir.Name the ONAME Node implementation
Before this CL, an ONAME Node was represented by three structs linked together: a node, a Name, and a Param. Previous CLs removed OLABEL and OPACK from the set of nodes that knew about Name. Now Name can be repurposed to *be* the ONAME Node implementation, replacing three linked structs totaling 152+64+88 = 304 bytes (64-bit) with a single 232-byte struct. Many expressions in the code become simpler as well, without having to use .Param. and sometimes even .Name(). (For a node n where n.Name() != nil, n.Name() == n.(*Name) now.) Passes buildall w/ toolstash -cmp. Change-Id: Ie719f1285c05623b9fd2faaa059e5b360a64b3be Reviewed-on: https://go-review.googlesource.com/c/go/+/274094 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
f6106d195d
commit
862f638a89
@ -22,6 +22,7 @@ package main_test
|
|||||||
var knownFormats = map[string]string{
|
var knownFormats = map[string]string{
|
||||||
"*bytes.Buffer %s": "",
|
"*bytes.Buffer %s": "",
|
||||||
"*cmd/compile/internal/gc.EscLocation %v": "",
|
"*cmd/compile/internal/gc.EscLocation %v": "",
|
||||||
|
"*cmd/compile/internal/ir.Name %v": "",
|
||||||
"*cmd/compile/internal/ir.node %v": "",
|
"*cmd/compile/internal/ir.node %v": "",
|
||||||
"*cmd/compile/internal/ssa.Block %s": "",
|
"*cmd/compile/internal/ssa.Block %s": "",
|
||||||
"*cmd/compile/internal/ssa.Block %v": "",
|
"*cmd/compile/internal/ssa.Block %v": "",
|
||||||
|
@ -311,7 +311,7 @@ func genhash(t *types.Type) *obj.LSym {
|
|||||||
hashel := hashfor(t.Elem())
|
hashel := hashfor(t.Elem())
|
||||||
|
|
||||||
n := ir.Nod(ir.ORANGE, nil, ir.Nod(ir.ODEREF, np, nil))
|
n := ir.Nod(ir.ORANGE, nil, ir.Nod(ir.ODEREF, np, nil))
|
||||||
ni := NewName(lookup("i"))
|
ni := ir.Node(NewName(lookup("i")))
|
||||||
ni.SetType(types.Types[types.TINT])
|
ni.SetType(types.Types[types.TINT])
|
||||||
n.PtrList().Set1(ni)
|
n.PtrList().Set1(ni)
|
||||||
n.SetColas(true)
|
n.SetColas(true)
|
||||||
|
@ -126,8 +126,8 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
|
|||||||
// NOTE(rsc): This comment may be stale.
|
// NOTE(rsc): This comment may be stale.
|
||||||
// It's possible the ordering has changed and this is
|
// It's possible the ordering has changed and this is
|
||||||
// now the common case. I'm not sure.
|
// now the common case. I'm not sure.
|
||||||
if n.Name().Param.Stackcopy != nil {
|
if n.Name().Stackcopy != nil {
|
||||||
n.Name().Param.Stackcopy.SetOffset(o)
|
n.Name().Stackcopy.SetOffset(o)
|
||||||
n.SetOffset(0)
|
n.SetOffset(0)
|
||||||
} else {
|
} else {
|
||||||
n.SetOffset(o)
|
n.SetOffset(o)
|
||||||
@ -198,8 +198,10 @@ func findTypeLoop(t *types.Type, path *[]*types.Type) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*path = append(*path, t)
|
*path = append(*path, t)
|
||||||
if p := ir.AsNode(t.Nod).Name().Param; p != nil && findTypeLoop(p.Ntype.Type(), path) {
|
if n := ir.AsNode(t.Nod); n != nil {
|
||||||
return true
|
if name := n.Name(); name != nil && name.Ntype != nil && findTypeLoop(name.Ntype.Type(), path) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*path = (*path)[:len(*path)-1]
|
*path = (*path)[:len(*path)-1]
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,7 +21,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
|
|||||||
fn := dcl.Func()
|
fn := dcl.Func()
|
||||||
fn.SetIsHiddenClosure(Curfn != nil)
|
fn.SetIsHiddenClosure(Curfn != nil)
|
||||||
fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure
|
fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym(), fn) // filled in by typecheckclosure
|
||||||
fn.Nname.Name().Param.Ntype = xtype
|
fn.Nname.Name().Ntype = xtype
|
||||||
fn.Nname.Name().Defn = dcl
|
fn.Nname.Name().Defn = dcl
|
||||||
|
|
||||||
clo := p.nod(expr, ir.OCLOSURE, nil, nil)
|
clo := p.nod(expr, ir.OCLOSURE, nil, nil)
|
||||||
@ -38,7 +38,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
|
|||||||
for _, v := range fn.ClosureVars.Slice() {
|
for _, v := range fn.ClosureVars.Slice() {
|
||||||
// Unlink from v1; see comment in syntax.go type Param for these fields.
|
// Unlink from v1; see comment in syntax.go type Param for these fields.
|
||||||
v1 := v.Name().Defn
|
v1 := v.Name().Defn
|
||||||
v1.Name().Param.Innermost = v.Name().Param.Outer
|
v1.Name().Innermost = v.Name().Outer
|
||||||
|
|
||||||
// If the closure usage of v is not dense,
|
// If the closure usage of v is not dense,
|
||||||
// we need to make it dense; now that we're out
|
// we need to make it dense; now that we're out
|
||||||
@ -68,7 +68,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
|
|||||||
// obtains f3's v, creating it if necessary (as it is in the example).
|
// obtains f3's v, creating it if necessary (as it is in the example).
|
||||||
//
|
//
|
||||||
// capturevars will decide whether to use v directly or &v.
|
// capturevars will decide whether to use v directly or &v.
|
||||||
v.Name().Param.Outer = oldname(v.Sym())
|
v.Name().Outer = oldname(v.Sym()).(*ir.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return clo
|
return clo
|
||||||
@ -194,7 +194,8 @@ func capturevars(dcl ir.Node) {
|
|||||||
// so that the outer frame also grabs them and knows they escape.
|
// so that the outer frame also grabs them and knows they escape.
|
||||||
dowidth(v.Type())
|
dowidth(v.Type())
|
||||||
|
|
||||||
outer := v.Name().Param.Outer
|
var outer ir.Node
|
||||||
|
outer = v.Name().Outer
|
||||||
outermost := v.Name().Defn
|
outermost := v.Name().Defn
|
||||||
|
|
||||||
// out parameters will be assigned to implicitly upon return.
|
// out parameters will be assigned to implicitly upon return.
|
||||||
@ -262,7 +263,7 @@ func transformclosure(dcl ir.Node) {
|
|||||||
// (accesses will implicitly deref &v).
|
// (accesses will implicitly deref &v).
|
||||||
addr := NewName(lookup("&" + v.Sym().Name))
|
addr := NewName(lookup("&" + v.Sym().Name))
|
||||||
addr.SetType(types.NewPtr(v.Type()))
|
addr.SetType(types.NewPtr(v.Type()))
|
||||||
v.Name().Param.Heapaddr = addr
|
v.Name().Heapaddr = addr
|
||||||
v = addr
|
v = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +313,7 @@ func transformclosure(dcl ir.Node) {
|
|||||||
addr.Name().SetUsed(true)
|
addr.Name().SetUsed(true)
|
||||||
addr.Name().Curfn = dcl
|
addr.Name().Curfn = dcl
|
||||||
fn.Dcl = append(fn.Dcl, addr)
|
fn.Dcl = append(fn.Dcl, addr)
|
||||||
v.Name().Param.Heapaddr = addr
|
v.Name().Heapaddr = addr
|
||||||
if v.Name().Byval() {
|
if v.Name().Byval() {
|
||||||
cv = ir.Nod(ir.OADDR, cv, nil)
|
cv = ir.Nod(ir.OADDR, cv, nil)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/constant"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -64,11 +63,6 @@ func declare(n ir.Node, ctxt ir.Class) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Name() == nil {
|
|
||||||
// named OLITERAL needs Name; most OLITERALs don't.
|
|
||||||
n.SetName(new(ir.Name))
|
|
||||||
}
|
|
||||||
|
|
||||||
s := n.Sym()
|
s := n.Sym()
|
||||||
|
|
||||||
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
||||||
@ -152,7 +146,7 @@ func variter(vl []ir.Node, t ir.Node, el []ir.Node) []ir.Node {
|
|||||||
for _, v := range vl {
|
for _, v := range vl {
|
||||||
v.SetOp(ir.ONAME)
|
v.SetOp(ir.ONAME)
|
||||||
declare(v, dclcontext)
|
declare(v, dclcontext)
|
||||||
v.Name().Param.Ntype = t
|
v.Name().Ntype = t
|
||||||
v.Name().Defn = as2
|
v.Name().Defn = as2
|
||||||
if Curfn != nil {
|
if Curfn != nil {
|
||||||
init = append(init, ir.Nod(ir.ODCL, v, nil))
|
init = append(init, ir.Nod(ir.ODCL, v, nil))
|
||||||
@ -176,7 +170,7 @@ func variter(vl []ir.Node, t ir.Node, el []ir.Node) []ir.Node {
|
|||||||
|
|
||||||
v.SetOp(ir.ONAME)
|
v.SetOp(ir.ONAME)
|
||||||
declare(v, dclcontext)
|
declare(v, dclcontext)
|
||||||
v.Name().Param.Ntype = t
|
v.Name().Ntype = t
|
||||||
|
|
||||||
if e != nil || Curfn != nil || ir.IsBlank(v) {
|
if e != nil || Curfn != nil || ir.IsBlank(v) {
|
||||||
if Curfn != nil {
|
if Curfn != nil {
|
||||||
@ -201,9 +195,8 @@ func newnoname(s *types.Sym) ir.Node {
|
|||||||
if s == nil {
|
if s == nil {
|
||||||
base.Fatalf("newnoname nil")
|
base.Fatalf("newnoname nil")
|
||||||
}
|
}
|
||||||
n := ir.Nod(ir.ONONAME, nil, nil)
|
n := ir.NewNameAt(base.Pos, s)
|
||||||
n.SetSym(s)
|
n.SetOp(ir.ONONAME)
|
||||||
n.SetOffset(0)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +213,7 @@ func newfuncnamel(pos src.XPos, s *types.Sym, fn *ir.Func) ir.Node {
|
|||||||
|
|
||||||
// this generates a new name node for a name
|
// this generates a new name node for a name
|
||||||
// being declared.
|
// being declared.
|
||||||
func dclname(s *types.Sym) ir.Node {
|
func dclname(s *types.Sym) *ir.Name {
|
||||||
n := NewName(s)
|
n := NewName(s)
|
||||||
n.SetOp(ir.ONONAME) // caller will correct it
|
n.SetOp(ir.ONONAME) // caller will correct it
|
||||||
return n
|
return n
|
||||||
@ -277,7 +270,7 @@ func oldname(s *types.Sym) ir.Node {
|
|||||||
// are parsing x := 5 inside the closure, until we get to
|
// are parsing x := 5 inside the closure, until we get to
|
||||||
// the := it looks like a reference to the outer x so we'll
|
// the := it looks like a reference to the outer x so we'll
|
||||||
// make x a closure variable unnecessarily.
|
// make x a closure variable unnecessarily.
|
||||||
c := n.Name().Param.Innermost
|
c := n.Name().Innermost
|
||||||
if c == nil || c.Name().Curfn != Curfn {
|
if c == nil || c.Name().Curfn != Curfn {
|
||||||
// Do not have a closure var for the active closure yet; make one.
|
// Do not have a closure var for the active closure yet; make one.
|
||||||
c = NewName(s)
|
c = NewName(s)
|
||||||
@ -288,8 +281,8 @@ func oldname(s *types.Sym) ir.Node {
|
|||||||
|
|
||||||
// Link into list of active closure variables.
|
// Link into list of active closure variables.
|
||||||
// Popped from list in func funcLit.
|
// Popped from list in func funcLit.
|
||||||
c.Name().Param.Outer = n.Name().Param.Innermost
|
c.Name().Outer = n.Name().Innermost
|
||||||
n.Name().Param.Innermost = c
|
n.Name().Innermost = c
|
||||||
|
|
||||||
Curfn.Func().ClosureVars.Append(c)
|
Curfn.Func().ClosureVars.Append(c)
|
||||||
}
|
}
|
||||||
@ -392,8 +385,8 @@ func funchdr(n ir.Node) {
|
|||||||
|
|
||||||
types.Markdcl()
|
types.Markdcl()
|
||||||
|
|
||||||
if n.Func().Nname != nil && n.Func().Nname.Name().Param.Ntype != nil {
|
if n.Func().Nname != nil && n.Func().Nname.Name().Ntype != nil {
|
||||||
funcargs(n.Func().Nname.Name().Param.Ntype)
|
funcargs(n.Func().Nname.Name().Ntype)
|
||||||
} else {
|
} else {
|
||||||
funcargs2(n.Type())
|
funcargs2(n.Type())
|
||||||
}
|
}
|
||||||
@ -458,7 +451,7 @@ func funcarg(n ir.Node, ctxt ir.Class) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
n.SetRight(ir.NewNameAt(n.Pos(), n.Sym()))
|
n.SetRight(ir.NewNameAt(n.Pos(), n.Sym()))
|
||||||
n.Right().Name().Param.Ntype = n.Left()
|
n.Right().Name().Ntype = n.Left()
|
||||||
n.Right().SetIsDDD(n.IsDDD())
|
n.Right().SetIsDDD(n.IsDDD())
|
||||||
declare(n.Right(), ctxt)
|
declare(n.Right(), ctxt)
|
||||||
|
|
||||||
@ -554,8 +547,8 @@ func structfield(n ir.Node) *types.Field {
|
|||||||
checkembeddedtype(n.Type())
|
checkembeddedtype(n.Type())
|
||||||
f.Embedded = 1
|
f.Embedded = 1
|
||||||
}
|
}
|
||||||
if n.HasVal() {
|
if n.Opt() != nil {
|
||||||
f.Note = constant.StringVal(n.Val())
|
f.Note = n.Opt().(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Pos = lno
|
base.Pos = lno
|
||||||
@ -640,7 +633,7 @@ func interfacefield(n ir.Node) *types.Field {
|
|||||||
base.Fatalf("interfacefield: oops %v\n", n)
|
base.Fatalf("interfacefield: oops %v\n", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.HasVal() {
|
if n.Opt() != nil {
|
||||||
base.Errorf("interface method cannot have annotation")
|
base.Errorf("interface method cannot have annotation")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,10 +945,10 @@ func dclfunc(sym *types.Sym, tfn ir.Node) ir.Node {
|
|||||||
fn := ir.Nod(ir.ODCLFUNC, nil, nil)
|
fn := ir.Nod(ir.ODCLFUNC, nil, nil)
|
||||||
fn.Func().Nname = newfuncnamel(base.Pos, sym, fn.Func())
|
fn.Func().Nname = newfuncnamel(base.Pos, sym, fn.Func())
|
||||||
fn.Func().Nname.Name().Defn = fn
|
fn.Func().Nname.Name().Defn = fn
|
||||||
fn.Func().Nname.Name().Param.Ntype = tfn
|
fn.Func().Nname.Name().Ntype = tfn
|
||||||
setNodeNameFunc(fn.Func().Nname)
|
setNodeNameFunc(fn.Func().Nname)
|
||||||
funchdr(fn)
|
funchdr(fn)
|
||||||
fn.Func().Nname.Name().Param.Ntype = typecheck(fn.Func().Nname.Name().Param.Ntype, ctxType)
|
fn.Func().Nname.Name().Ntype = typecheck(fn.Func().Nname.Name().Ntype, ctxType)
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,13 +115,13 @@ func varEmbed(p *noder, names []ir.Node, typ ir.Node, exprs []ir.Node, embeds []
|
|||||||
numLocalEmbed++
|
numLocalEmbed++
|
||||||
v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed))
|
v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed))
|
||||||
v.Sym().Def = v
|
v.Sym().Def = v
|
||||||
v.Name().Param.Ntype = typ
|
v.Name().Ntype = typ
|
||||||
v.SetClass(ir.PEXTERN)
|
v.SetClass(ir.PEXTERN)
|
||||||
externdcl = append(externdcl, v)
|
externdcl = append(externdcl, v)
|
||||||
exprs = []ir.Node{v}
|
exprs = []ir.Node{v}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Name().Param.SetEmbedFiles(list)
|
v.Name().SetEmbedFiles(list)
|
||||||
embedlist = append(embedlist, v)
|
embedlist = append(embedlist, v)
|
||||||
return exprs
|
return exprs
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ func dumpembeds() {
|
|||||||
// initEmbed emits the init data for a //go:embed variable,
|
// initEmbed emits the init data for a //go:embed variable,
|
||||||
// which is either a string, a []byte, or an embed.FS.
|
// which is either a string, a []byte, or an embed.FS.
|
||||||
func initEmbed(v ir.Node) {
|
func initEmbed(v ir.Node) {
|
||||||
files := v.Name().Param.EmbedFiles()
|
files := v.Name().EmbedFiles()
|
||||||
switch kind := embedKind(v.Type()); kind {
|
switch kind := embedKind(v.Type()); kind {
|
||||||
case embedUnknown:
|
case embedUnknown:
|
||||||
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
|
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
|
||||||
|
@ -1895,7 +1895,7 @@ func moveToHeap(n ir.Node) {
|
|||||||
stackcopy.SetType(n.Type())
|
stackcopy.SetType(n.Type())
|
||||||
stackcopy.SetOffset(n.Offset())
|
stackcopy.SetOffset(n.Offset())
|
||||||
stackcopy.SetClass(n.Class())
|
stackcopy.SetClass(n.Class())
|
||||||
stackcopy.Name().Param.Heapaddr = heapaddr
|
stackcopy.Name().Heapaddr = heapaddr
|
||||||
if n.Class() == ir.PPARAMOUT {
|
if n.Class() == ir.PPARAMOUT {
|
||||||
// Make sure the pointer to the heap copy is kept live throughout the function.
|
// Make sure the pointer to the heap copy is kept live throughout the function.
|
||||||
// The function could panic at any point, and then a defer could recover.
|
// The function could panic at any point, and then a defer could recover.
|
||||||
@ -1904,7 +1904,7 @@ func moveToHeap(n ir.Node) {
|
|||||||
// See issue 16095.
|
// See issue 16095.
|
||||||
heapaddr.Name().SetIsOutputParamHeapAddr(true)
|
heapaddr.Name().SetIsOutputParamHeapAddr(true)
|
||||||
}
|
}
|
||||||
n.Name().Param.Stackcopy = stackcopy
|
n.Name().Stackcopy = stackcopy
|
||||||
|
|
||||||
// Substitute the stackcopy into the function variable list so that
|
// Substitute the stackcopy into the function variable list so that
|
||||||
// liveness and other analyses use the underlying stack slot
|
// liveness and other analyses use the underlying stack slot
|
||||||
@ -1931,7 +1931,7 @@ func moveToHeap(n ir.Node) {
|
|||||||
// Modify n in place so that uses of n now mean indirection of the heapaddr.
|
// Modify n in place so that uses of n now mean indirection of the heapaddr.
|
||||||
n.SetClass(ir.PAUTOHEAP)
|
n.SetClass(ir.PAUTOHEAP)
|
||||||
n.SetOffset(0)
|
n.SetOffset(0)
|
||||||
n.Name().Param.Heapaddr = heapaddr
|
n.Name().Heapaddr = heapaddr
|
||||||
n.SetEsc(EscHeap)
|
n.SetEsc(EscHeap)
|
||||||
if base.Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
base.WarnfAt(n.Pos(), "moved to heap: %v", n)
|
base.WarnfAt(n.Pos(), "moved to heap: %v", n)
|
||||||
|
@ -31,13 +31,13 @@ func sysvar(name string) *obj.LSym {
|
|||||||
// isParamStackCopy reports whether this is the on-stack copy of a
|
// isParamStackCopy reports whether this is the on-stack copy of a
|
||||||
// function parameter that moved to the heap.
|
// function parameter that moved to the heap.
|
||||||
func isParamStackCopy(n ir.Node) bool {
|
func isParamStackCopy(n ir.Node) bool {
|
||||||
return n.Op() == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Name().Param.Heapaddr != nil
|
return n.Op() == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Name().Heapaddr != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// isParamHeapCopy reports whether this is the on-heap copy of
|
// isParamHeapCopy reports whether this is the on-heap copy of
|
||||||
// a function parameter that moved to the heap.
|
// a function parameter that moved to the heap.
|
||||||
func isParamHeapCopy(n ir.Node) bool {
|
func isParamHeapCopy(n ir.Node) bool {
|
||||||
return n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP && n.Name().Param.Stackcopy != nil
|
return n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP && n.Name().Stackcopy != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// autotmpname returns the name for an autotmp variable numbered n.
|
// autotmpname returns the name for an autotmp variable numbered n.
|
||||||
@ -52,7 +52,7 @@ func autotmpname(n int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make a new Node off the books
|
// make a new Node off the books
|
||||||
func tempAt(pos src.XPos, curfn ir.Node, t *types.Type) ir.Node {
|
func tempAt(pos src.XPos, curfn ir.Node, t *types.Type) *ir.Name {
|
||||||
if curfn == nil {
|
if curfn == nil {
|
||||||
base.Fatalf("no curfn for tempAt")
|
base.Fatalf("no curfn for tempAt")
|
||||||
}
|
}
|
||||||
@ -80,9 +80,9 @@ func tempAt(pos src.XPos, curfn ir.Node, t *types.Type) ir.Node {
|
|||||||
|
|
||||||
dowidth(t)
|
dowidth(t)
|
||||||
|
|
||||||
return ir.Orig(n)
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func temp(t *types.Type) ir.Node {
|
func temp(t *types.Type) *ir.Name {
|
||||||
return tempAt(base.Pos, Curfn, t)
|
return tempAt(base.Pos, Curfn, t)
|
||||||
}
|
}
|
||||||
|
@ -1463,7 +1463,7 @@ func (w *exportWriter) localName(n ir.Node) {
|
|||||||
// PPARAM/PPARAMOUT, because we only want to include vargen in
|
// PPARAM/PPARAMOUT, because we only want to include vargen in
|
||||||
// non-param names.
|
// non-param names.
|
||||||
var v int32
|
var v int32
|
||||||
if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name().Param.Stackcopy == nil) {
|
if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name().Stackcopy == nil) {
|
||||||
v = n.Name().Vargen
|
v = n.Name().Vargen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,7 +982,7 @@ func mkinlcall(n, fn ir.Node, maxCost int32, inlMap map[ir.Node]bool) ir.Node {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
o := v.Name().Param.Outer
|
o := v.Name().Outer
|
||||||
// make sure the outer param matches the inlining location
|
// make sure the outer param matches the inlining location
|
||||||
// NB: if we enabled inlining of functions containing OCLOSURE or refined
|
// NB: if we enabled inlining of functions containing OCLOSURE or refined
|
||||||
// the reassigned check via some sort of copy propagation this would most
|
// the reassigned check via some sort of copy propagation this would most
|
||||||
|
@ -253,7 +253,7 @@ func Main(archInit func(*Arch)) {
|
|||||||
timings.Start("fe", "typecheck", "top1")
|
timings.Start("fe", "typecheck", "top1")
|
||||||
for i := 0; i < len(xtop); i++ {
|
for i := 0; i < len(xtop); i++ {
|
||||||
n := xtop[i]
|
n := xtop[i]
|
||||||
if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.Left().Name().Param.Alias()) {
|
if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.Left().Name().Alias()) {
|
||||||
xtop[i] = typecheck(n, ctxStmt)
|
xtop[i] = typecheck(n, ctxStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ func Main(archInit func(*Arch)) {
|
|||||||
timings.Start("fe", "typecheck", "top2")
|
timings.Start("fe", "typecheck", "top2")
|
||||||
for i := 0; i < len(xtop); i++ {
|
for i := 0; i < len(xtop); i++ {
|
||||||
n := xtop[i]
|
n := xtop[i]
|
||||||
if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.Left().Name().Param.Alias() {
|
if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.Left().Name().Alias() {
|
||||||
xtop[i] = typecheck(n, ctxStmt)
|
xtop[i] = typecheck(n, ctxStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +456,7 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []ir.Node {
|
|||||||
n.SetOp(ir.OLITERAL)
|
n.SetOp(ir.OLITERAL)
|
||||||
declare(n, dclcontext)
|
declare(n, dclcontext)
|
||||||
|
|
||||||
n.Name().Param.Ntype = typ
|
n.Name().Ntype = typ
|
||||||
n.Name().Defn = v
|
n.Name().Defn = v
|
||||||
n.SetIota(cs.iota)
|
n.SetIota(cs.iota)
|
||||||
|
|
||||||
@ -480,19 +480,18 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) ir.Node {
|
|||||||
// decl.Type may be nil but in that case we got a syntax error during parsing
|
// decl.Type may be nil but in that case we got a syntax error during parsing
|
||||||
typ := p.typeExprOrNil(decl.Type)
|
typ := p.typeExprOrNil(decl.Type)
|
||||||
|
|
||||||
param := n.Name().Param
|
n.Ntype = typ
|
||||||
param.Ntype = typ
|
n.SetAlias(decl.Alias)
|
||||||
param.SetAlias(decl.Alias)
|
|
||||||
if pragma, ok := decl.Pragma.(*Pragma); ok {
|
if pragma, ok := decl.Pragma.(*Pragma); ok {
|
||||||
if !decl.Alias {
|
if !decl.Alias {
|
||||||
param.SetPragma(pragma.Flag & TypePragmas)
|
n.SetPragma(pragma.Flag & TypePragmas)
|
||||||
pragma.Flag &^= TypePragmas
|
pragma.Flag &^= TypePragmas
|
||||||
}
|
}
|
||||||
p.checkUnused(pragma)
|
p.checkUnused(pragma)
|
||||||
}
|
}
|
||||||
|
|
||||||
nod := p.nod(decl, ir.ODCLTYPE, n, nil)
|
nod := p.nod(decl, ir.ODCLTYPE, n, nil)
|
||||||
if param.Alias() && !langSupported(1, 9, ir.LocalPkg) {
|
if n.Alias() && !langSupported(1, 9, ir.LocalPkg) {
|
||||||
base.ErrorfAt(nod.Pos(), "type aliases only supported as of -lang=go1.9")
|
base.ErrorfAt(nod.Pos(), "type aliases only supported as of -lang=go1.9")
|
||||||
}
|
}
|
||||||
return nod
|
return nod
|
||||||
@ -506,7 +505,7 @@ func (p *noder) declNames(names []*syntax.Name) []ir.Node {
|
|||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) declName(name *syntax.Name) ir.Node {
|
func (p *noder) declName(name *syntax.Name) *ir.Name {
|
||||||
n := dclname(p.name(name))
|
n := dclname(p.name(name))
|
||||||
n.SetPos(p.pos(name))
|
n.SetPos(p.pos(name))
|
||||||
return n
|
return n
|
||||||
@ -537,7 +536,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) ir.Node {
|
|||||||
|
|
||||||
f.Func().Nname = newfuncnamel(p.pos(fun.Name), name, f.Func())
|
f.Func().Nname = newfuncnamel(p.pos(fun.Name), name, f.Func())
|
||||||
f.Func().Nname.Name().Defn = f
|
f.Func().Nname.Name().Defn = f
|
||||||
f.Func().Nname.Name().Param.Ntype = t
|
f.Func().Nname.Name().Ntype = t
|
||||||
|
|
||||||
if pragma, ok := fun.Pragma.(*Pragma); ok {
|
if pragma, ok := fun.Pragma.(*Pragma); ok {
|
||||||
f.Func().Pragma = pragma.Flag & FuncPragmas
|
f.Func().Pragma = pragma.Flag & FuncPragmas
|
||||||
@ -872,7 +871,7 @@ func (p *noder) structType(expr *syntax.StructType) ir.Node {
|
|||||||
n = p.nodSym(field, ir.ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
|
n = p.nodSym(field, ir.ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
|
||||||
}
|
}
|
||||||
if i < len(expr.TagList) && expr.TagList[i] != nil {
|
if i < len(expr.TagList) && expr.TagList[i] != nil {
|
||||||
n.SetVal(p.basicLit(expr.TagList[i]))
|
n.SetOpt(constant.StringVal(p.basicLit(expr.TagList[i])))
|
||||||
}
|
}
|
||||||
l = append(l, n)
|
l = append(l, n)
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []ir.
|
|||||||
// misleading location for the param (we want pointer-to-heap
|
// misleading location for the param (we want pointer-to-heap
|
||||||
// and not stack).
|
// and not stack).
|
||||||
// TODO(thanm): generate a better location expression
|
// TODO(thanm): generate a better location expression
|
||||||
stackcopy := n.Name().Param.Stackcopy
|
stackcopy := n.Name().Stackcopy
|
||||||
if stackcopy != nil && (stackcopy.Class() == ir.PPARAM || stackcopy.Class() == ir.PPARAMOUT) {
|
if stackcopy != nil && (stackcopy.Class() == ir.PPARAM || stackcopy.Class() == ir.PPARAMOUT) {
|
||||||
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
|
||||||
isReturnValue = (stackcopy.Class() == ir.PPARAMOUT)
|
isReturnValue = (stackcopy.Class() == ir.PPARAMOUT)
|
||||||
|
@ -795,7 +795,7 @@ func (lv *Liveness) epilogue() {
|
|||||||
// Just to be paranoid. Heap addresses are PAUTOs.
|
// Just to be paranoid. Heap addresses are PAUTOs.
|
||||||
base.Fatalf("variable %v both output param and heap output param", n)
|
base.Fatalf("variable %v both output param and heap output param", n)
|
||||||
}
|
}
|
||||||
if n.Name().Param.Heapaddr != nil {
|
if n.Name().Heapaddr != nil {
|
||||||
// If this variable moved to the heap, then
|
// If this variable moved to the heap, then
|
||||||
// its stack copy is not live.
|
// its stack copy is not live.
|
||||||
continue
|
continue
|
||||||
|
@ -136,7 +136,7 @@ func importdot(opkg *types.Pkg, pack *ir.PkgName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newname returns a new ONAME Node associated with symbol s.
|
// newname returns a new ONAME Node associated with symbol s.
|
||||||
func NewName(s *types.Sym) ir.Node {
|
func NewName(s *types.Sym) *ir.Name {
|
||||||
n := ir.NewNameAt(base.Pos, s)
|
n := ir.NewNameAt(base.Pos, s)
|
||||||
n.Name().Curfn = Curfn
|
n.Name().Curfn = Curfn
|
||||||
return n
|
return n
|
||||||
|
@ -259,12 +259,12 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
|
|||||||
// are substituted.
|
// are substituted.
|
||||||
cycle := cycleFor(n)
|
cycle := cycleFor(n)
|
||||||
for _, n1 := range cycle {
|
for _, n1 := range cycle {
|
||||||
if n1.Name() != nil && !n1.Name().Param.Alias() {
|
if n1.Name() != nil && !n1.Name().Alias() {
|
||||||
// Cycle is ok. But if n is an alias type and doesn't
|
// Cycle is ok. But if n is an alias type and doesn't
|
||||||
// have a type yet, we have a recursive type declaration
|
// have a type yet, we have a recursive type declaration
|
||||||
// with aliases that we can't handle properly yet.
|
// with aliases that we can't handle properly yet.
|
||||||
// Report an error rather than crashing later.
|
// Report an error rather than crashing later.
|
||||||
if n.Name() != nil && n.Name().Param.Alias() && n.Type() == nil {
|
if n.Name() != nil && n.Name().Alias() && n.Type() == nil {
|
||||||
base.Pos = n.Pos()
|
base.Pos = n.Pos()
|
||||||
base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
|
base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
|
||||||
}
|
}
|
||||||
@ -2412,9 +2412,6 @@ func typecheckMethodExpr(n ir.Node) (res ir.Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
n.SetOp(ir.OMETHEXPR)
|
n.SetOp(ir.OMETHEXPR)
|
||||||
if n.Name() == nil {
|
|
||||||
n.SetName(new(ir.Name))
|
|
||||||
}
|
|
||||||
n.SetRight(NewName(n.Sym()))
|
n.SetRight(NewName(n.Sym()))
|
||||||
n.SetSym(methodSym(t, n.Sym()))
|
n.SetSym(methodSym(t, n.Sym()))
|
||||||
n.SetType(methodfunc(m.Type, n.Left().Type()))
|
n.SetType(methodfunc(m.Type, n.Left().Type()))
|
||||||
@ -3228,7 +3225,7 @@ func typecheckas(n ir.Node) {
|
|||||||
// so that the conversion below happens).
|
// so that the conversion below happens).
|
||||||
n.SetLeft(resolve(n.Left()))
|
n.SetLeft(resolve(n.Left()))
|
||||||
|
|
||||||
if n.Left().Name() == nil || n.Left().Name().Defn != n || n.Left().Name().Param.Ntype != nil {
|
if n.Left().Name() == nil || n.Left().Name().Defn != n || n.Left().Name().Ntype != nil {
|
||||||
n.SetLeft(typecheck(n.Left(), ctxExpr|ctxAssign))
|
n.SetLeft(typecheck(n.Left(), ctxExpr|ctxAssign))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3247,7 +3244,7 @@ func typecheckas(n ir.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left().Name() != nil && n.Left().Name().Defn == n && n.Left().Name().Param.Ntype == nil {
|
if n.Left().Name() != nil && n.Left().Name().Defn == n && n.Left().Name().Ntype == nil {
|
||||||
n.SetRight(defaultlit(n.Right(), nil))
|
n.SetRight(defaultlit(n.Right(), nil))
|
||||||
n.Left().SetType(n.Right().Type())
|
n.Left().SetType(n.Right().Type())
|
||||||
}
|
}
|
||||||
@ -3283,7 +3280,7 @@ func typecheckas2(n ir.Node) {
|
|||||||
n1 = resolve(n1)
|
n1 = resolve(n1)
|
||||||
ls[i1] = n1
|
ls[i1] = n1
|
||||||
|
|
||||||
if n1.Name() == nil || n1.Name().Defn != n || n1.Name().Param.Ntype != nil {
|
if n1.Name() == nil || n1.Name().Defn != n || n1.Name().Ntype != nil {
|
||||||
ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
|
ls[i1] = typecheck(ls[i1], ctxExpr|ctxAssign)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3308,7 +3305,7 @@ func typecheckas2(n ir.Node) {
|
|||||||
if nl.Type() != nil && nr.Type() != nil {
|
if nl.Type() != nil && nr.Type() != nil {
|
||||||
rs[il] = assignconv(nr, nl.Type(), "assignment")
|
rs[il] = assignconv(nr, nl.Type(), "assignment")
|
||||||
}
|
}
|
||||||
if nl.Name() != nil && nl.Name().Defn == n && nl.Name().Param.Ntype == nil {
|
if nl.Name() != nil && nl.Name().Defn == n && nl.Name().Ntype == nil {
|
||||||
rs[il] = defaultlit(rs[il], nil)
|
rs[il] = defaultlit(rs[il], nil)
|
||||||
nl.SetType(rs[il].Type())
|
nl.SetType(rs[il].Type())
|
||||||
}
|
}
|
||||||
@ -3342,7 +3339,7 @@ func typecheckas2(n ir.Node) {
|
|||||||
if f.Type != nil && l.Type() != nil {
|
if f.Type != nil && l.Type() != nil {
|
||||||
checkassignto(f.Type, l)
|
checkassignto(f.Type, l)
|
||||||
}
|
}
|
||||||
if l.Name() != nil && l.Name().Defn == n && l.Name().Param.Ntype == nil {
|
if l.Name() != nil && l.Name().Defn == n && l.Name().Ntype == nil {
|
||||||
l.SetType(f.Type)
|
l.SetType(f.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3378,7 +3375,7 @@ func typecheckas2(n ir.Node) {
|
|||||||
if l.Type() != nil && !l.Type().IsBoolean() {
|
if l.Type() != nil && !l.Type().IsBoolean() {
|
||||||
checkassignto(types.Types[types.TBOOL], l)
|
checkassignto(types.Types[types.TBOOL], l)
|
||||||
}
|
}
|
||||||
if l.Name() != nil && l.Name().Defn == n && l.Name().Param.Ntype == nil {
|
if l.Name() != nil && l.Name().Defn == n && l.Name().Ntype == nil {
|
||||||
l.SetType(types.Types[types.TBOOL])
|
l.SetType(types.Types[types.TBOOL])
|
||||||
}
|
}
|
||||||
goto out
|
goto out
|
||||||
@ -3502,7 +3499,7 @@ func setUnderlying(t, underlying *types.Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Propagate go:notinheap pragma from the Name to the Type.
|
// Propagate go:notinheap pragma from the Name to the Type.
|
||||||
if n.Name() != nil && n.Name().Param != nil && n.Name().Param.Pragma()&ir.NotInHeap != 0 {
|
if n.Name() != nil && n.Name().Pragma()&ir.NotInHeap != 0 {
|
||||||
t.SetNotInHeap(true)
|
t.SetNotInHeap(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3525,8 +3522,8 @@ func typecheckdeftype(n ir.Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
n.SetTypecheck(1)
|
n.SetTypecheck(1)
|
||||||
n.Name().Param.Ntype = typecheck(n.Name().Param.Ntype, ctxType)
|
n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
|
||||||
t := n.Name().Param.Ntype.Type()
|
t := n.Name().Ntype.Type()
|
||||||
if t == nil {
|
if t == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
n.SetType(nil)
|
n.SetType(nil)
|
||||||
@ -3586,10 +3583,10 @@ func typecheckdef(n ir.Node) {
|
|||||||
base.Fatalf("typecheckdef %v", n.Op())
|
base.Fatalf("typecheckdef %v", n.Op())
|
||||||
|
|
||||||
case ir.OLITERAL:
|
case ir.OLITERAL:
|
||||||
if n.Name().Param.Ntype != nil {
|
if n.Name().Ntype != nil {
|
||||||
n.Name().Param.Ntype = typecheck(n.Name().Param.Ntype, ctxType)
|
n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
|
||||||
n.SetType(n.Name().Param.Ntype.Type())
|
n.SetType(n.Name().Ntype.Type())
|
||||||
n.Name().Param.Ntype = nil
|
n.Name().Ntype = nil
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
goto ret
|
goto ret
|
||||||
@ -3640,9 +3637,9 @@ func typecheckdef(n ir.Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
if n.Name().Param.Ntype != nil {
|
if n.Name().Ntype != nil {
|
||||||
n.Name().Param.Ntype = typecheck(n.Name().Param.Ntype, ctxType)
|
n.Name().Ntype = typecheck(n.Name().Ntype, ctxType)
|
||||||
n.SetType(n.Name().Param.Ntype.Type())
|
n.SetType(n.Name().Ntype.Type())
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
goto ret
|
goto ret
|
||||||
@ -3676,21 +3673,22 @@ func typecheckdef(n ir.Node) {
|
|||||||
n.Name().Defn = typecheck(n.Name().Defn, ctxStmt) // fills in n.Type
|
n.Name().Defn = typecheck(n.Name().Defn, ctxStmt) // fills in n.Type
|
||||||
|
|
||||||
case ir.OTYPE:
|
case ir.OTYPE:
|
||||||
if p := n.Name().Param; p.Alias() {
|
n := n.(*ir.Name)
|
||||||
|
if n.Alias() {
|
||||||
// Type alias declaration: Simply use the rhs type - no need
|
// Type alias declaration: Simply use the rhs type - no need
|
||||||
// to create a new type.
|
// to create a new type.
|
||||||
// If we have a syntax error, p.Ntype may be nil.
|
// If we have a syntax error, p.Ntype may be nil.
|
||||||
if p.Ntype != nil {
|
if n.Ntype != nil {
|
||||||
p.Ntype = typecheck(p.Ntype, ctxType)
|
n.Ntype = typecheck(n.Ntype, ctxType)
|
||||||
n.SetType(p.Ntype.Type())
|
n.SetType(n.Ntype.Type())
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
n.SetDiag(true)
|
n.SetDiag(true)
|
||||||
goto ret
|
goto ret
|
||||||
}
|
}
|
||||||
// For package-level type aliases, set n.Sym.Def so we can identify
|
// For package-level type aliases, set n.Sym.Def so we can identify
|
||||||
// it as a type alias during export. See also #31959.
|
// it as a type alias during export. See also #31959.
|
||||||
if n.Name().Curfn == nil {
|
if n.Curfn == nil {
|
||||||
n.Sym().Def = p.Ntype
|
n.Sym().Def = n.Ntype
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -110,7 +110,6 @@ func lexinit() {
|
|||||||
types.Types[etype] = t
|
types.Types[etype] = t
|
||||||
}
|
}
|
||||||
s2.Def = typenod(t)
|
s2.Def = typenod(t)
|
||||||
ir.AsNode(s2.Def).SetName(new(ir.Name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range &builtinFuncs {
|
for _, s := range &builtinFuncs {
|
||||||
@ -132,13 +131,11 @@ func lexinit() {
|
|||||||
s := ir.BuiltinPkg.Lookup("true")
|
s := ir.BuiltinPkg.Lookup("true")
|
||||||
s.Def = nodbool(true)
|
s.Def = nodbool(true)
|
||||||
ir.AsNode(s.Def).SetSym(lookup("true"))
|
ir.AsNode(s.Def).SetSym(lookup("true"))
|
||||||
ir.AsNode(s.Def).SetName(new(ir.Name))
|
|
||||||
ir.AsNode(s.Def).SetType(types.UntypedBool)
|
ir.AsNode(s.Def).SetType(types.UntypedBool)
|
||||||
|
|
||||||
s = ir.BuiltinPkg.Lookup("false")
|
s = ir.BuiltinPkg.Lookup("false")
|
||||||
s.Def = nodbool(false)
|
s.Def = nodbool(false)
|
||||||
ir.AsNode(s.Def).SetSym(lookup("false"))
|
ir.AsNode(s.Def).SetSym(lookup("false"))
|
||||||
ir.AsNode(s.Def).SetName(new(ir.Name))
|
|
||||||
ir.AsNode(s.Def).SetType(types.UntypedBool)
|
ir.AsNode(s.Def).SetType(types.UntypedBool)
|
||||||
|
|
||||||
s = lookup("_")
|
s = lookup("_")
|
||||||
@ -158,12 +155,10 @@ func lexinit() {
|
|||||||
s = ir.BuiltinPkg.Lookup("nil")
|
s = ir.BuiltinPkg.Lookup("nil")
|
||||||
s.Def = nodnil()
|
s.Def = nodnil()
|
||||||
ir.AsNode(s.Def).SetSym(s)
|
ir.AsNode(s.Def).SetSym(s)
|
||||||
ir.AsNode(s.Def).SetName(new(ir.Name))
|
|
||||||
|
|
||||||
s = ir.BuiltinPkg.Lookup("iota")
|
s = ir.BuiltinPkg.Lookup("iota")
|
||||||
s.Def = ir.Nod(ir.OIOTA, nil, nil)
|
s.Def = ir.Nod(ir.OIOTA, nil, nil)
|
||||||
ir.AsNode(s.Def).SetSym(s)
|
ir.AsNode(s.Def).SetSym(s)
|
||||||
ir.AsNode(s.Def).SetName(new(ir.Name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func typeinit() {
|
func typeinit() {
|
||||||
@ -182,7 +177,6 @@ func typeinit() {
|
|||||||
types.Types[types.TUNSAFEPTR] = t
|
types.Types[types.TUNSAFEPTR] = t
|
||||||
t.Sym = unsafepkg.Lookup("Pointer")
|
t.Sym = unsafepkg.Lookup("Pointer")
|
||||||
t.Sym.Def = typenod(t)
|
t.Sym.Def = typenod(t)
|
||||||
ir.AsNode(t.Sym.Def).SetName(new(ir.Name))
|
|
||||||
dowidth(types.Types[types.TUNSAFEPTR])
|
dowidth(types.Types[types.TUNSAFEPTR])
|
||||||
|
|
||||||
for et := types.TINT8; et <= types.TUINT64; et++ {
|
for et := types.TINT8; et <= types.TUINT64; et++ {
|
||||||
@ -359,7 +353,6 @@ func lexinit1() {
|
|||||||
types.Bytetype = types.New(types.TUINT8)
|
types.Bytetype = types.New(types.TUINT8)
|
||||||
types.Bytetype.Sym = s
|
types.Bytetype.Sym = s
|
||||||
s.Def = typenod(types.Bytetype)
|
s.Def = typenod(types.Bytetype)
|
||||||
ir.AsNode(s.Def).SetName(new(ir.Name))
|
|
||||||
dowidth(types.Bytetype)
|
dowidth(types.Bytetype)
|
||||||
|
|
||||||
// rune alias
|
// rune alias
|
||||||
@ -367,7 +360,6 @@ func lexinit1() {
|
|||||||
types.Runetype = types.New(types.TINT32)
|
types.Runetype = types.New(types.TINT32)
|
||||||
types.Runetype.Sym = s
|
types.Runetype.Sym = s
|
||||||
s.Def = typenod(types.Runetype)
|
s.Def = typenod(types.Runetype)
|
||||||
ir.AsNode(s.Def).SetName(new(ir.Name))
|
|
||||||
dowidth(types.Runetype)
|
dowidth(types.Runetype)
|
||||||
|
|
||||||
// backend-dependent builtin types (e.g. int).
|
// backend-dependent builtin types (e.g. int).
|
||||||
@ -385,7 +377,6 @@ func lexinit1() {
|
|||||||
t.Sym = s1
|
t.Sym = s1
|
||||||
types.Types[s.etype] = t
|
types.Types[s.etype] = t
|
||||||
s1.Def = typenod(t)
|
s1.Def = typenod(t)
|
||||||
ir.AsNode(s1.Def).SetName(new(ir.Name))
|
|
||||||
s1.Origpkg = ir.BuiltinPkg
|
s1.Origpkg = ir.BuiltinPkg
|
||||||
|
|
||||||
dowidth(t)
|
dowidth(t)
|
||||||
|
@ -196,7 +196,7 @@ func walkstmt(n ir.Node) ir.Node {
|
|||||||
if prealloc[v] == nil {
|
if prealloc[v] == nil {
|
||||||
prealloc[v] = callnew(v.Type())
|
prealloc[v] = callnew(v.Type())
|
||||||
}
|
}
|
||||||
nn := ir.Nod(ir.OAS, v.Name().Param.Heapaddr, prealloc[v])
|
nn := ir.Nod(ir.OAS, v.Name().Heapaddr, prealloc[v])
|
||||||
nn.SetColas(true)
|
nn.SetColas(true)
|
||||||
nn = typecheck(nn, ctxStmt)
|
nn = typecheck(nn, ctxStmt)
|
||||||
return walkstmt(nn)
|
return walkstmt(nn)
|
||||||
@ -286,7 +286,7 @@ func walkstmt(n ir.Node) ir.Node {
|
|||||||
}
|
}
|
||||||
if cl == ir.PPARAMOUT {
|
if cl == ir.PPARAMOUT {
|
||||||
if isParamStackCopy(ln) {
|
if isParamStackCopy(ln) {
|
||||||
ln = walkexpr(typecheck(ir.Nod(ir.ODEREF, ln.Name().Param.Heapaddr, nil), ctxExpr), nil)
|
ln = walkexpr(typecheck(ir.Nod(ir.ODEREF, ln.Name().Heapaddr, nil), ctxExpr), nil)
|
||||||
}
|
}
|
||||||
rl = append(rl, ln)
|
rl = append(rl, ln)
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ func walkstmt(n ir.Node) ir.Node {
|
|||||||
for i, nl := range lhs.FieldSlice() {
|
for i, nl := range lhs.FieldSlice() {
|
||||||
nname := ir.AsNode(nl.Nname)
|
nname := ir.AsNode(nl.Nname)
|
||||||
if isParamHeapCopy(nname) {
|
if isParamHeapCopy(nname) {
|
||||||
nname = nname.Name().Param.Stackcopy
|
nname = nname.Name().Stackcopy
|
||||||
}
|
}
|
||||||
a := ir.Nod(ir.OAS, nname, rhs[i])
|
a := ir.Nod(ir.OAS, nname, rhs[i])
|
||||||
res[i] = convas(a, n.PtrInit())
|
res[i] = convas(a, n.PtrInit())
|
||||||
@ -456,7 +456,7 @@ func walkexpr(n ir.Node, init *ir.Nodes) ir.Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP {
|
if n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP {
|
||||||
nn := ir.Nod(ir.ODEREF, n.Name().Param.Heapaddr, nil)
|
nn := ir.Nod(ir.ODEREF, n.Name().Heapaddr, nil)
|
||||||
nn = typecheck(nn, ctxExpr)
|
nn = typecheck(nn, ctxExpr)
|
||||||
nn = walkexpr(nn, init)
|
nn = walkexpr(nn, init)
|
||||||
nn.Left().MarkNonNil()
|
nn.Left().MarkNonNil()
|
||||||
@ -1160,7 +1160,7 @@ opswitch:
|
|||||||
if n.Type().Elem().Width >= maxImplicitStackVarSize {
|
if n.Type().Elem().Width >= maxImplicitStackVarSize {
|
||||||
base.Fatalf("large ONEW with EscNone: %v", n)
|
base.Fatalf("large ONEW with EscNone: %v", n)
|
||||||
}
|
}
|
||||||
r := temp(n.Type().Elem())
|
r := ir.Node(temp(n.Type().Elem()))
|
||||||
r = ir.Nod(ir.OAS, r, nil) // zero temp
|
r = ir.Nod(ir.OAS, r, nil) // zero temp
|
||||||
r = typecheck(r, ctxStmt)
|
r = typecheck(r, ctxStmt)
|
||||||
init.Append(r)
|
init.Append(r)
|
||||||
@ -1776,7 +1776,7 @@ func ascompatet(nl ir.Nodes, nr *types.Type) []ir.Node {
|
|||||||
// Any assignment to an lvalue that might cause a function call must be
|
// Any assignment to an lvalue that might cause a function call must be
|
||||||
// deferred until all the returned values have been read.
|
// deferred until all the returned values have been read.
|
||||||
if fncall(l, r.Type) {
|
if fncall(l, r.Type) {
|
||||||
tmp := temp(r.Type)
|
tmp := ir.Node(temp(r.Type))
|
||||||
tmp = typecheck(tmp, ctxExpr)
|
tmp = typecheck(tmp, ctxExpr)
|
||||||
a := ir.Nod(ir.OAS, l, tmp)
|
a := ir.Nod(ir.OAS, l, tmp)
|
||||||
a = convas(a, &mm)
|
a = convas(a, &mm)
|
||||||
@ -2174,7 +2174,7 @@ func reorder3save(n ir.Node, all []ir.Node, i int, early *[]ir.Node) ir.Node {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
q := temp(n.Type())
|
q := ir.Node(temp(n.Type()))
|
||||||
q = ir.Nod(ir.OAS, q, n)
|
q = ir.Nod(ir.OAS, q, n)
|
||||||
q = typecheck(q, ctxStmt)
|
q = typecheck(q, ctxStmt)
|
||||||
*early = append(*early, q)
|
*early = append(*early, q)
|
||||||
@ -2411,7 +2411,7 @@ func paramstoheap(params *types.Type) []ir.Node {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if stackcopy := v.Name().Param.Stackcopy; stackcopy != nil {
|
if stackcopy := v.Name().Stackcopy; stackcopy != nil {
|
||||||
nn = append(nn, walkstmt(ir.Nod(ir.ODCL, v, nil)))
|
nn = append(nn, walkstmt(ir.Nod(ir.ODCL, v, nil)))
|
||||||
if stackcopy.Class() == ir.PPARAM {
|
if stackcopy.Class() == ir.PPARAM {
|
||||||
nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, v, stackcopy), ctxStmt)))
|
nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, v, stackcopy), ctxStmt)))
|
||||||
@ -2432,7 +2432,7 @@ func paramstoheap(params *types.Type) []ir.Node {
|
|||||||
func zeroResults() {
|
func zeroResults() {
|
||||||
for _, f := range Curfn.Type().Results().Fields().Slice() {
|
for _, f := range Curfn.Type().Results().Fields().Slice() {
|
||||||
v := ir.AsNode(f.Nname)
|
v := ir.AsNode(f.Nname)
|
||||||
if v != nil && v.Name().Param.Heapaddr != nil {
|
if v != nil && v.Name().Heapaddr != nil {
|
||||||
// The local which points to the return value is the
|
// The local which points to the return value is the
|
||||||
// thing that needs zeroing. This is already handled
|
// thing that needs zeroing. This is already handled
|
||||||
// by a Needzero annotation in plive.go:livenessepilogue.
|
// by a Needzero annotation in plive.go:livenessepilogue.
|
||||||
@ -2445,7 +2445,7 @@ func zeroResults() {
|
|||||||
// I don't think the zeroing below matters.
|
// I don't think the zeroing below matters.
|
||||||
// The stack return value will never be marked as live anywhere in the function.
|
// The stack return value will never be marked as live anywhere in the function.
|
||||||
// It is not written to until deferreturn returns.
|
// It is not written to until deferreturn returns.
|
||||||
v = v.Name().Param.Stackcopy
|
v = v.Name().Stackcopy
|
||||||
}
|
}
|
||||||
// Zero the stack location containing f.
|
// Zero the stack location containing f.
|
||||||
Curfn.Func().Enter.Append(ir.NodAt(Curfn.Pos(), ir.OAS, v, nil))
|
Curfn.Func().Enter.Append(ir.NodAt(Curfn.Pos(), ir.OAS, v, nil))
|
||||||
@ -2461,7 +2461,7 @@ func returnsfromheap(params *types.Type) []ir.Node {
|
|||||||
if v == nil {
|
if v == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if stackcopy := v.Name().Param.Stackcopy; stackcopy != nil && stackcopy.Class() == ir.PPARAMOUT {
|
if stackcopy := v.Name().Stackcopy; stackcopy != nil && stackcopy.Class() == ir.PPARAMOUT {
|
||||||
nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, stackcopy, v), ctxStmt)))
|
nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, stackcopy, v), ctxStmt)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3155,7 +3155,7 @@ func copyany(n ir.Node, init *ir.Nodes, runtimecall bool) ir.Node {
|
|||||||
|
|
||||||
fn := syslook("memmove")
|
fn := syslook("memmove")
|
||||||
fn = substArgTypes(fn, nl.Type().Elem(), nl.Type().Elem())
|
fn = substArgTypes(fn, nl.Type().Elem(), nl.Type().Elem())
|
||||||
nwid := temp(types.Types[types.TUINTPTR])
|
nwid := ir.Node(temp(types.Types[types.TUINTPTR]))
|
||||||
setwid := ir.Nod(ir.OAS, nwid, conv(nlen, types.Types[types.TUINTPTR]))
|
setwid := ir.Nod(ir.OAS, nwid, conv(nlen, types.Types[types.TUINTPTR]))
|
||||||
ne.PtrBody().Append(setwid)
|
ne.PtrBody().Append(setwid)
|
||||||
nwid = ir.Nod(ir.OMUL, nwid, nodintconst(nl.Type().Elem().Width))
|
nwid = ir.Nod(ir.OMUL, nwid, nodintconst(nl.Type().Elem().Width))
|
||||||
|
47
src/cmd/compile/internal/ir/expr.go
Normal file
47
src/cmd/compile/internal/ir/expr.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A miniStmt is a miniNode with extra fields common to expressions.
|
||||||
|
// TODO(rsc): Once we are sure about the contents, compact the bools
|
||||||
|
// into a bit field and leave extra bits available for implementations
|
||||||
|
// embedding miniExpr. Right now there are ~60 unused bits sitting here.
|
||||||
|
type miniExpr struct {
|
||||||
|
miniNode
|
||||||
|
typ *types.Type
|
||||||
|
init Nodes // TODO(rsc): Don't require every Node to have an init
|
||||||
|
opt interface{} // TODO(rsc): Don't require every Node to have an opt?
|
||||||
|
flags bitset8
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
miniExprHasCall = 1 << iota
|
||||||
|
miniExprImplicit
|
||||||
|
miniExprNonNil
|
||||||
|
miniExprTransient
|
||||||
|
miniExprBounded
|
||||||
|
)
|
||||||
|
|
||||||
|
func (n *miniExpr) Type() *types.Type { return n.typ }
|
||||||
|
func (n *miniExpr) SetType(x *types.Type) { n.typ = x }
|
||||||
|
func (n *miniExpr) Opt() interface{} { return n.opt }
|
||||||
|
func (n *miniExpr) SetOpt(x interface{}) { n.opt = x }
|
||||||
|
func (n *miniExpr) HasCall() bool { return n.flags&miniExprHasCall != 0 }
|
||||||
|
func (n *miniExpr) SetHasCall(b bool) { n.flags.set(miniExprHasCall, b) }
|
||||||
|
func (n *miniExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
|
||||||
|
func (n *miniExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
|
||||||
|
func (n *miniExpr) NonNil() bool { return n.flags&miniExprNonNil != 0 }
|
||||||
|
func (n *miniExpr) MarkNonNil() { n.flags |= miniExprNonNil }
|
||||||
|
func (n *miniExpr) Transient() bool { return n.flags&miniExprTransient != 0 }
|
||||||
|
func (n *miniExpr) SetTransient(b bool) { n.flags.set(miniExprTransient, b) }
|
||||||
|
func (n *miniExpr) Bounded() bool { return n.flags&miniExprBounded != 0 }
|
||||||
|
func (n *miniExpr) SetBounded(b bool) { n.flags.set(miniExprBounded, b) }
|
||||||
|
func (n *miniExpr) Init() Nodes { return n.init }
|
||||||
|
func (n *miniExpr) PtrInit() *Nodes { return &n.init }
|
||||||
|
func (n *miniExpr) SetInit(x Nodes) { n.init = x }
|
@ -1615,9 +1615,9 @@ func nodeDumpFmt(n Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
|||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v%j", n.Op(), n)
|
mode.Fprintf(s, "%v%j", n.Op(), n)
|
||||||
}
|
}
|
||||||
if recur && n.Type() == nil && n.Name() != nil && n.Name().Param != nil && n.Name().Param.Ntype != nil {
|
if recur && n.Type() == nil && n.Name() != nil && n.Name().Ntype != nil {
|
||||||
indent(s)
|
indent(s)
|
||||||
mode.Fprintf(s, "%v-ntype%v", n.Op(), n.Name().Param.Ntype)
|
mode.Fprintf(s, "%v-ntype%v", n.Op(), n.Name().Ntype)
|
||||||
}
|
}
|
||||||
|
|
||||||
case OASOP:
|
case OASOP:
|
||||||
@ -1625,9 +1625,9 @@ func nodeDumpFmt(n Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
|||||||
|
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
mode.Fprintf(s, "%v %v%j type=%v", n.Op(), n.Sym(), n, n.Type())
|
mode.Fprintf(s, "%v %v%j type=%v", n.Op(), n.Sym(), n, n.Type())
|
||||||
if recur && n.Type() == nil && n.Name() != nil && n.Name().Param != nil && n.Name().Param.Ntype != nil {
|
if recur && n.Type() == nil && n.Name() != nil && n.Name().Ntype != nil {
|
||||||
indent(s)
|
indent(s)
|
||||||
mode.Fprintf(s, "%v-ntype%v", n.Op(), n.Name().Param.Ntype)
|
mode.Fprintf(s, "%v-ntype%v", n.Op(), n.Name().Ntype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,6 @@ func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) }
|
|||||||
func (n *miniNode) Func() *Func { return nil }
|
func (n *miniNode) Func() *Func { return nil }
|
||||||
func (n *miniNode) SetFunc(*Func) { panic(n.no("SetFunc")) }
|
func (n *miniNode) SetFunc(*Func) { panic(n.no("SetFunc")) }
|
||||||
func (n *miniNode) Name() *Name { return nil }
|
func (n *miniNode) Name() *Name { return nil }
|
||||||
func (n *miniNode) SetName(*Name) { panic(n.no("SetName")) }
|
|
||||||
func (n *miniNode) Sym() *types.Sym { return nil }
|
func (n *miniNode) Sym() *types.Sym { return nil }
|
||||||
func (n *miniNode) SetSym(*types.Sym) { panic(n.no("SetSym")) }
|
func (n *miniNode) SetSym(*types.Sym) { panic(n.no("SetSym")) }
|
||||||
func (n *miniNode) Offset() int64 { return types.BADWIDTH }
|
func (n *miniNode) Offset() int64 { return types.BADWIDTH }
|
||||||
@ -164,7 +163,6 @@ func (n *miniNode) SetIndexMapLValue(bool) { panic(n.no("SetIndexMapLValue"))
|
|||||||
func (n *miniNode) ResetAux() { panic(n.no("ResetAux")) }
|
func (n *miniNode) ResetAux() { panic(n.no("ResetAux")) }
|
||||||
func (n *miniNode) HasBreak() bool { panic(n.no("HasBreak")) }
|
func (n *miniNode) HasBreak() bool { panic(n.no("HasBreak")) }
|
||||||
func (n *miniNode) SetHasBreak(bool) { panic(n.no("SetHasBreak")) }
|
func (n *miniNode) SetHasBreak(bool) { panic(n.no("SetHasBreak")) }
|
||||||
func (n *miniNode) HasVal() bool { return false }
|
|
||||||
func (n *miniNode) Val() constant.Value { panic(n.no("Val")) }
|
func (n *miniNode) Val() constant.Value { panic(n.no("Val")) }
|
||||||
func (n *miniNode) SetVal(v constant.Value) { panic(n.no("SetVal")) }
|
func (n *miniNode) SetVal(v constant.Value) { panic(n.no("SetVal")) }
|
||||||
func (n *miniNode) Int64Val() int64 { panic(n.no("Int64Val")) }
|
func (n *miniNode) Int64Val() int64 { panic(n.no("Int64Val")) }
|
||||||
|
@ -15,29 +15,38 @@ import (
|
|||||||
|
|
||||||
// Name holds Node fields used only by named nodes (ONAME, OTYPE, some OLITERAL).
|
// Name holds Node fields used only by named nodes (ONAME, OTYPE, some OLITERAL).
|
||||||
type Name struct {
|
type Name struct {
|
||||||
|
miniExpr
|
||||||
|
subOp Op // uint8
|
||||||
|
class Class // uint8
|
||||||
|
flags bitset16
|
||||||
|
pragma PragmaFlag // int16
|
||||||
|
sym *types.Sym
|
||||||
|
typ *types.Type
|
||||||
|
fn *Func
|
||||||
|
offset int64
|
||||||
|
val constant.Value
|
||||||
|
orig Node
|
||||||
|
embedFiles *[]string // list of embedded files, for ONAME var
|
||||||
|
|
||||||
PkgName *PkgName // real package for import . names
|
PkgName *PkgName // real package for import . names
|
||||||
// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
|
// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
|
||||||
// For a closure var, the ONAME node of the outer captured variable
|
// For a closure var, the ONAME node of the outer captured variable
|
||||||
Defn Node
|
Defn Node
|
||||||
// The ODCLFUNC node (for a static function/method or a closure) in which
|
// The ODCLFUNC node (for a static function/method or a closure) in which
|
||||||
// local variable or param is declared.
|
// local variable or param is declared.
|
||||||
Curfn Node
|
Curfn Node
|
||||||
Param *Param // additional fields for ONAME, OTYPE
|
|
||||||
Decldepth int32 // declaration loop depth, increased for every loop or label
|
|
||||||
// Unique number for ONAME nodes within a function. Function outputs
|
// Unique number for ONAME nodes within a function. Function outputs
|
||||||
// (results) are numbered starting at one, followed by function inputs
|
// (results) are numbered starting at one, followed by function inputs
|
||||||
// (parameters), and then local variables. Vargen is used to distinguish
|
// (parameters), and then local variables. Vargen is used to distinguish
|
||||||
// local variables/params with the same name.
|
// local variables/params with the same name.
|
||||||
Vargen int32
|
Vargen int32
|
||||||
flags bitset16
|
Decldepth int32 // declaration loop depth, increased for every loop or label
|
||||||
}
|
|
||||||
|
|
||||||
type Param struct {
|
|
||||||
Ntype Node
|
Ntype Node
|
||||||
Heapaddr Node // temp holding heap address of param
|
Heapaddr *Name // temp holding heap address of param
|
||||||
|
|
||||||
// ONAME PAUTOHEAP
|
// ONAME PAUTOHEAP
|
||||||
Stackcopy Node // the PPARAM/PPARAMOUT on-stack slot (moved func params only)
|
Stackcopy *Name // the PPARAM/PPARAMOUT on-stack slot (moved func params only)
|
||||||
|
|
||||||
// ONAME closure linkage
|
// ONAME closure linkage
|
||||||
// Consider:
|
// Consider:
|
||||||
@ -108,114 +117,88 @@ type Param struct {
|
|||||||
//
|
//
|
||||||
// Because of the sharding of pieces of the node, x.Defn means x.Name.Defn
|
// Because of the sharding of pieces of the node, x.Defn means x.Name.Defn
|
||||||
// and x.Innermost/Outer means x.Name.Param.Innermost/Outer.
|
// and x.Innermost/Outer means x.Name.Param.Innermost/Outer.
|
||||||
Innermost Node
|
Innermost *Name
|
||||||
Outer Node
|
Outer *Name
|
||||||
|
|
||||||
// OTYPE & ONAME //go:embed info,
|
|
||||||
// sharing storage to reduce gc.Param size.
|
|
||||||
// Extra is nil, or else *Extra is a *paramType or an *embedFileList.
|
|
||||||
Extra *interface{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNameAt returns a new ONAME Node associated with symbol s at position pos.
|
// NewNameAt returns a new ONAME Node associated with symbol s at position pos.
|
||||||
// The caller is responsible for setting n.Name.Curfn.
|
// The caller is responsible for setting n.Name.Curfn.
|
||||||
func NewNameAt(pos src.XPos, s *types.Sym) Node {
|
func NewNameAt(pos src.XPos, sym *types.Sym) *Name {
|
||||||
if s == nil {
|
if sym == nil {
|
||||||
base.Fatalf("newnamel nil")
|
base.Fatalf("NewNameAt nil")
|
||||||
}
|
}
|
||||||
|
return newNameAt(pos, sym)
|
||||||
|
}
|
||||||
|
|
||||||
var x struct {
|
// newNameAt is like NewNameAt but allows sym == nil.
|
||||||
n node
|
func newNameAt(pos src.XPos, sym *types.Sym) *Name {
|
||||||
m Name
|
n := new(Name)
|
||||||
p Param
|
n.op = ONAME
|
||||||
}
|
n.pos = pos
|
||||||
n := &x.n
|
n.orig = n
|
||||||
n.SetName(&x.m)
|
n.sym = sym
|
||||||
n.Name().Param = &x.p
|
|
||||||
|
|
||||||
n.SetOp(ONAME)
|
|
||||||
n.SetPos(pos)
|
|
||||||
n.SetOrig(n)
|
|
||||||
|
|
||||||
n.SetSym(s)
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
type paramType struct {
|
func (n *Name) String() string { return fmt.Sprint(n) }
|
||||||
flag PragmaFlag
|
func (n *Name) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||||
alias bool
|
func (n *Name) RawCopy() Node { c := *n; return &c }
|
||||||
|
func (n *Name) Name() *Name { return n }
|
||||||
|
func (n *Name) Sym() *types.Sym { return n.sym }
|
||||||
|
func (n *Name) SetSym(x *types.Sym) { n.sym = x }
|
||||||
|
func (n *Name) Orig() Node { return n.orig }
|
||||||
|
func (n *Name) SetOrig(x Node) { n.orig = x }
|
||||||
|
func (n *Name) SubOp() Op { return n.subOp }
|
||||||
|
func (n *Name) SetSubOp(x Op) { n.subOp = x }
|
||||||
|
func (n *Name) Class() Class { return n.class }
|
||||||
|
func (n *Name) SetClass(x Class) { n.class = x }
|
||||||
|
func (n *Name) Func() *Func { return n.fn }
|
||||||
|
func (n *Name) SetFunc(x *Func) { n.fn = x }
|
||||||
|
func (n *Name) Offset() int64 { return n.offset }
|
||||||
|
func (n *Name) SetOffset(x int64) { n.offset = x }
|
||||||
|
func (n *Name) Iota() int64 { return n.offset }
|
||||||
|
func (n *Name) SetIota(x int64) { n.offset = x }
|
||||||
|
|
||||||
|
func (n *Name) SetOp(op Op) {
|
||||||
|
switch op {
|
||||||
|
default:
|
||||||
|
panic(n.no("SetOp " + op.String()))
|
||||||
|
case OLITERAL, ONONAME, ONAME, OTYPE, OIOTA:
|
||||||
|
n.op = op
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pragma returns the PragmaFlag for p, which must be for an OTYPE.
|
// Pragma returns the PragmaFlag for p, which must be for an OTYPE.
|
||||||
func (p *Param) Pragma() PragmaFlag {
|
func (n *Name) Pragma() PragmaFlag { return n.pragma }
|
||||||
if p.Extra == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return (*p.Extra).(*paramType).flag
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPragma sets the PragmaFlag for p, which must be for an OTYPE.
|
// SetPragma sets the PragmaFlag for p, which must be for an OTYPE.
|
||||||
func (p *Param) SetPragma(flag PragmaFlag) {
|
func (n *Name) SetPragma(flag PragmaFlag) { n.pragma = flag }
|
||||||
if p.Extra == nil {
|
|
||||||
if flag == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.Extra = new(interface{})
|
|
||||||
*p.Extra = ¶mType{flag: flag}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
(*p.Extra).(*paramType).flag = flag
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alias reports whether p, which must be for an OTYPE, is a type alias.
|
// Alias reports whether p, which must be for an OTYPE, is a type alias.
|
||||||
func (p *Param) Alias() bool {
|
func (n *Name) Alias() bool { return n.flags&nameAlias != 0 }
|
||||||
if p.Extra == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
t, ok := (*p.Extra).(*paramType)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return t.alias
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAlias sets whether p, which must be for an OTYPE, is a type alias.
|
// SetAlias sets whether p, which must be for an OTYPE, is a type alias.
|
||||||
func (p *Param) SetAlias(alias bool) {
|
func (n *Name) SetAlias(alias bool) { n.flags.set(nameAlias, alias) }
|
||||||
if p.Extra == nil {
|
|
||||||
if !alias {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.Extra = new(interface{})
|
|
||||||
*p.Extra = ¶mType{alias: alias}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
(*p.Extra).(*paramType).alias = alias
|
|
||||||
}
|
|
||||||
|
|
||||||
type embedFileList []string
|
|
||||||
|
|
||||||
// EmbedFiles returns the list of embedded files for p,
|
// EmbedFiles returns the list of embedded files for p,
|
||||||
// which must be for an ONAME var.
|
// which must be for an ONAME var.
|
||||||
func (p *Param) EmbedFiles() []string {
|
func (n *Name) EmbedFiles() []string {
|
||||||
if p.Extra == nil {
|
if n.embedFiles == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return *(*p.Extra).(*embedFileList)
|
return *n.embedFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEmbedFiles sets the list of embedded files for p,
|
// SetEmbedFiles sets the list of embedded files for p,
|
||||||
// which must be for an ONAME var.
|
// which must be for an ONAME var.
|
||||||
func (p *Param) SetEmbedFiles(list []string) {
|
func (n *Name) SetEmbedFiles(list []string) {
|
||||||
if p.Extra == nil {
|
if n.embedFiles == nil && list == nil {
|
||||||
if len(list) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f := embedFileList(list)
|
|
||||||
p.Extra = new(interface{})
|
|
||||||
*p.Extra = &f
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*(*p.Extra).(*embedFileList) = list
|
if n.embedFiles == nil {
|
||||||
|
n.embedFiles = new([]string)
|
||||||
|
}
|
||||||
|
*n.embedFiles = list
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -233,6 +216,8 @@ const (
|
|||||||
nameInlLocal // PAUTO created by inliner, derived from callee local
|
nameInlLocal // PAUTO created by inliner, derived from callee local
|
||||||
nameOpenDeferSlot // if temporary var storing info for open-coded defers
|
nameOpenDeferSlot // if temporary var storing info for open-coded defers
|
||||||
nameLibfuzzerExtraCounter // if PEXTERN should be assigned to __libfuzzer_extra_counters section
|
nameLibfuzzerExtraCounter // if PEXTERN should be assigned to __libfuzzer_extra_counters section
|
||||||
|
nameIsDDD // is function argument a ...
|
||||||
|
nameAlias // is type name an alias
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *Name) Captured() bool { return n.flags&nameCaptured != 0 }
|
func (n *Name) Captured() bool { return n.flags&nameCaptured != 0 }
|
||||||
@ -249,9 +234,10 @@ func (n *Name) InlFormal() bool { return n.flags&nameInlFormal != 0
|
|||||||
func (n *Name) InlLocal() bool { return n.flags&nameInlLocal != 0 }
|
func (n *Name) InlLocal() bool { return n.flags&nameInlLocal != 0 }
|
||||||
func (n *Name) OpenDeferSlot() bool { return n.flags&nameOpenDeferSlot != 0 }
|
func (n *Name) OpenDeferSlot() bool { return n.flags&nameOpenDeferSlot != 0 }
|
||||||
func (n *Name) LibfuzzerExtraCounter() bool { return n.flags&nameLibfuzzerExtraCounter != 0 }
|
func (n *Name) LibfuzzerExtraCounter() bool { return n.flags&nameLibfuzzerExtraCounter != 0 }
|
||||||
|
func (n *Name) IsDDD() bool { return n.flags&nameIsDDD != 0 }
|
||||||
|
|
||||||
func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) }
|
func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) }
|
||||||
func (n *Name) SetReadonly(b bool) { n.flags.set(nameReadonly, b) }
|
func (n *Name) setReadonly(b bool) { n.flags.set(nameReadonly, b) }
|
||||||
func (n *Name) SetByval(b bool) { n.flags.set(nameByval, b) }
|
func (n *Name) SetByval(b bool) { n.flags.set(nameByval, b) }
|
||||||
func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
|
func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
|
||||||
func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
|
func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
|
||||||
@ -264,13 +250,14 @@ func (n *Name) SetInlFormal(b bool) { n.flags.set(nameInlFormal, b)
|
|||||||
func (n *Name) SetInlLocal(b bool) { n.flags.set(nameInlLocal, b) }
|
func (n *Name) SetInlLocal(b bool) { n.flags.set(nameInlLocal, b) }
|
||||||
func (n *Name) SetOpenDeferSlot(b bool) { n.flags.set(nameOpenDeferSlot, b) }
|
func (n *Name) SetOpenDeferSlot(b bool) { n.flags.set(nameOpenDeferSlot, b) }
|
||||||
func (n *Name) SetLibfuzzerExtraCounter(b bool) { n.flags.set(nameLibfuzzerExtraCounter, b) }
|
func (n *Name) SetLibfuzzerExtraCounter(b bool) { n.flags.set(nameLibfuzzerExtraCounter, b) }
|
||||||
|
func (n *Name) SetIsDDD(b bool) { n.flags.set(nameIsDDD, b) }
|
||||||
|
|
||||||
// MarkReadonly indicates that n is an ONAME with readonly contents.
|
// MarkReadonly indicates that n is an ONAME with readonly contents.
|
||||||
func (n *node) MarkReadonly() {
|
func (n *Name) MarkReadonly() {
|
||||||
if n.Op() != ONAME {
|
if n.Op() != ONAME {
|
||||||
base.Fatalf("Node.MarkReadonly %v", n.Op())
|
base.Fatalf("Node.MarkReadonly %v", n.Op())
|
||||||
}
|
}
|
||||||
n.Name().SetReadonly(true)
|
n.Name().setReadonly(true)
|
||||||
// Mark the linksym as readonly immediately
|
// Mark the linksym as readonly immediately
|
||||||
// so that the SSA backend can use this information.
|
// so that the SSA backend can use this information.
|
||||||
// It will be overridden later during dumpglobls.
|
// It will be overridden later during dumpglobls.
|
||||||
@ -278,31 +265,26 @@ func (n *node) MarkReadonly() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Val returns the constant.Value for the node.
|
// Val returns the constant.Value for the node.
|
||||||
func (n *node) Val() constant.Value {
|
func (n *Name) Val() constant.Value {
|
||||||
if !n.HasVal() {
|
if n.val == nil {
|
||||||
return constant.MakeUnknown()
|
return constant.MakeUnknown()
|
||||||
}
|
}
|
||||||
return *n.e.(*constant.Value)
|
return n.val
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVal sets the constant.Value for the node,
|
// SetVal sets the constant.Value for the node,
|
||||||
// which must not have been used with SetOpt.
|
// which must not have been used with SetOpt.
|
||||||
func (n *node) SetVal(v constant.Value) {
|
func (n *Name) SetVal(v constant.Value) {
|
||||||
if n.hasOpt() {
|
if n.op != OLITERAL {
|
||||||
base.Flag.LowerH = 1
|
panic(n.no("SetVal"))
|
||||||
Dump("have Opt", n)
|
|
||||||
base.Fatalf("have Opt")
|
|
||||||
}
|
}
|
||||||
if n.Op() == OLITERAL {
|
AssertValidTypeForConst(n.Type(), v)
|
||||||
AssertValidTypeForConst(n.Type(), v)
|
n.val = v
|
||||||
}
|
|
||||||
n.setHasVal(true)
|
|
||||||
n.e = &v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64Val returns n as an int64.
|
// Int64Val returns n as an int64.
|
||||||
// n must be an integer or rune constant.
|
// n must be an integer or rune constant.
|
||||||
func (n *node) Int64Val() int64 {
|
func (n *Name) Int64Val() int64 {
|
||||||
if !IsConst(n, constant.Int) {
|
if !IsConst(n, constant.Int) {
|
||||||
base.Fatalf("Int64Val(%v)", n)
|
base.Fatalf("Int64Val(%v)", n)
|
||||||
}
|
}
|
||||||
@ -314,7 +296,7 @@ func (n *node) Int64Val() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CanInt64 reports whether it is safe to call Int64Val() on n.
|
// CanInt64 reports whether it is safe to call Int64Val() on n.
|
||||||
func (n *node) CanInt64() bool {
|
func (n *Name) CanInt64() bool {
|
||||||
if !IsConst(n, constant.Int) {
|
if !IsConst(n, constant.Int) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -327,7 +309,7 @@ func (n *node) CanInt64() bool {
|
|||||||
|
|
||||||
// Uint64Val returns n as an uint64.
|
// Uint64Val returns n as an uint64.
|
||||||
// n must be an integer or rune constant.
|
// n must be an integer or rune constant.
|
||||||
func (n *node) Uint64Val() uint64 {
|
func (n *Name) Uint64Val() uint64 {
|
||||||
if !IsConst(n, constant.Int) {
|
if !IsConst(n, constant.Int) {
|
||||||
base.Fatalf("Uint64Val(%v)", n)
|
base.Fatalf("Uint64Val(%v)", n)
|
||||||
}
|
}
|
||||||
@ -340,7 +322,7 @@ func (n *node) Uint64Val() uint64 {
|
|||||||
|
|
||||||
// BoolVal returns n as a bool.
|
// BoolVal returns n as a bool.
|
||||||
// n must be a boolean constant.
|
// n must be a boolean constant.
|
||||||
func (n *node) BoolVal() bool {
|
func (n *Name) BoolVal() bool {
|
||||||
if !IsConst(n, constant.Bool) {
|
if !IsConst(n, constant.Bool) {
|
||||||
base.Fatalf("BoolVal(%v)", n)
|
base.Fatalf("BoolVal(%v)", n)
|
||||||
}
|
}
|
||||||
@ -349,7 +331,7 @@ func (n *node) BoolVal() bool {
|
|||||||
|
|
||||||
// StringVal returns the value of a literal string Node as a string.
|
// StringVal returns the value of a literal string Node as a string.
|
||||||
// n must be a string constant.
|
// n must be a string constant.
|
||||||
func (n *node) StringVal() string {
|
func (n *Name) StringVal() string {
|
||||||
if !IsConst(n, constant.String) {
|
if !IsConst(n, constant.String) {
|
||||||
base.Fatalf("StringVal(%v)", n)
|
base.Fatalf("StringVal(%v)", n)
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,6 @@ type Node interface {
|
|||||||
Func() *Func
|
Func() *Func
|
||||||
SetFunc(x *Func)
|
SetFunc(x *Func)
|
||||||
Name() *Name
|
Name() *Name
|
||||||
SetName(x *Name)
|
|
||||||
Sym() *types.Sym
|
Sym() *types.Sym
|
||||||
SetSym(x *types.Sym)
|
SetSym(x *types.Sym)
|
||||||
Offset() int64
|
Offset() int64
|
||||||
@ -93,7 +92,6 @@ type Node interface {
|
|||||||
SetHasBreak(x bool)
|
SetHasBreak(x bool)
|
||||||
MarkReadonly()
|
MarkReadonly()
|
||||||
Val() constant.Value
|
Val() constant.Value
|
||||||
HasVal() bool
|
|
||||||
SetVal(v constant.Value)
|
SetVal(v constant.Value)
|
||||||
Int64Val() int64
|
Int64Val() int64
|
||||||
Uint64Val() uint64
|
Uint64Val() uint64
|
||||||
@ -149,11 +147,8 @@ type node struct {
|
|||||||
// func
|
// func
|
||||||
fn *Func
|
fn *Func
|
||||||
|
|
||||||
// ONAME, OTYPE, OPACK, OLABEL, some OLITERAL
|
sym *types.Sym // various
|
||||||
name *Name
|
opt interface{}
|
||||||
|
|
||||||
sym *types.Sym // various
|
|
||||||
e interface{} // Opt or Val, see methods below
|
|
||||||
|
|
||||||
// Various. Usually an offset into a struct. For example:
|
// Various. Usually an offset into a struct. For example:
|
||||||
// - ONAME nodes that refer to local variables use it to identify their stack frame position.
|
// - ONAME nodes that refer to local variables use it to identify their stack frame position.
|
||||||
@ -185,8 +180,7 @@ func (n *node) Type() *types.Type { return n.typ }
|
|||||||
func (n *node) SetType(x *types.Type) { n.typ = x }
|
func (n *node) SetType(x *types.Type) { n.typ = x }
|
||||||
func (n *node) Func() *Func { return n.fn }
|
func (n *node) Func() *Func { return n.fn }
|
||||||
func (n *node) SetFunc(x *Func) { n.fn = x }
|
func (n *node) SetFunc(x *Func) { n.fn = x }
|
||||||
func (n *node) Name() *Name { return n.name }
|
func (n *node) Name() *Name { return nil }
|
||||||
func (n *node) SetName(x *Name) { n.name = x }
|
|
||||||
func (n *node) Sym() *types.Sym { return n.sym }
|
func (n *node) Sym() *types.Sym { return n.sym }
|
||||||
func (n *node) SetSym(x *types.Sym) { n.sym = x }
|
func (n *node) SetSym(x *types.Sym) { n.sym = x }
|
||||||
func (n *node) Pos() src.XPos { return n.pos }
|
func (n *node) Pos() src.XPos { return n.pos }
|
||||||
@ -208,6 +202,14 @@ func (n *node) PtrList() *Nodes { return &n.list }
|
|||||||
func (n *node) Rlist() Nodes { return n.rlist }
|
func (n *node) Rlist() Nodes { return n.rlist }
|
||||||
func (n *node) SetRlist(x Nodes) { n.rlist = x }
|
func (n *node) SetRlist(x Nodes) { n.rlist = x }
|
||||||
func (n *node) PtrRlist() *Nodes { return &n.rlist }
|
func (n *node) PtrRlist() *Nodes { return &n.rlist }
|
||||||
|
func (n *node) MarkReadonly() { panic("node.MarkReadOnly") }
|
||||||
|
func (n *node) Val() constant.Value { panic("node.Val") }
|
||||||
|
func (n *node) SetVal(constant.Value) { panic("node.SetVal") }
|
||||||
|
func (n *node) Int64Val() int64 { panic("node.Int64Val") }
|
||||||
|
func (n *node) CanInt64() bool { return false }
|
||||||
|
func (n *node) Uint64Val() uint64 { panic("node.Uint64Val") }
|
||||||
|
func (n *node) BoolVal() bool { panic("node.BoolVal") }
|
||||||
|
func (n *node) StringVal() string { panic("node.StringVal") }
|
||||||
|
|
||||||
func (n *node) SetOp(op Op) {
|
func (n *node) SetOp(op Op) {
|
||||||
if !okForNod[op] {
|
if !okForNod[op] {
|
||||||
@ -305,8 +307,6 @@ const (
|
|||||||
_, nodeBounded // bounds check unnecessary
|
_, nodeBounded // bounds check unnecessary
|
||||||
_, nodeHasCall // expression contains a function call
|
_, nodeHasCall // expression contains a function call
|
||||||
_, nodeLikely // if statement condition likely
|
_, nodeLikely // if statement condition likely
|
||||||
_, nodeHasVal // node.E contains a Val
|
|
||||||
_, nodeHasOpt // node.E contains an Opt
|
|
||||||
_, nodeEmbedded // ODCLFIELD embedded type
|
_, nodeEmbedded // ODCLFIELD embedded type
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -326,8 +326,6 @@ func (n *node) Transient() bool { return n.flags&nodeTransient != 0 }
|
|||||||
func (n *node) Bounded() bool { return n.flags&nodeBounded != 0 }
|
func (n *node) Bounded() bool { return n.flags&nodeBounded != 0 }
|
||||||
func (n *node) HasCall() bool { return n.flags&nodeHasCall != 0 }
|
func (n *node) HasCall() bool { return n.flags&nodeHasCall != 0 }
|
||||||
func (n *node) Likely() bool { return n.flags&nodeLikely != 0 }
|
func (n *node) Likely() bool { return n.flags&nodeLikely != 0 }
|
||||||
func (n *node) HasVal() bool { return n.flags&nodeHasVal != 0 }
|
|
||||||
func (n *node) hasOpt() bool { return n.flags&nodeHasOpt != 0 }
|
|
||||||
func (n *node) Embedded() bool { return n.flags&nodeEmbedded != 0 }
|
func (n *node) Embedded() bool { return n.flags&nodeEmbedded != 0 }
|
||||||
|
|
||||||
func (n *node) SetClass(b Class) { n.flags.set3(nodeClass, uint8(b)) }
|
func (n *node) SetClass(b Class) { n.flags.set3(nodeClass, uint8(b)) }
|
||||||
@ -344,8 +342,6 @@ func (n *node) SetColas(b bool) { n.flags.set(nodeColas, b) }
|
|||||||
func (n *node) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
|
func (n *node) SetTransient(b bool) { n.flags.set(nodeTransient, b) }
|
||||||
func (n *node) SetHasCall(b bool) { n.flags.set(nodeHasCall, b) }
|
func (n *node) SetHasCall(b bool) { n.flags.set(nodeHasCall, b) }
|
||||||
func (n *node) SetLikely(b bool) { n.flags.set(nodeLikely, b) }
|
func (n *node) SetLikely(b bool) { n.flags.set(nodeLikely, b) }
|
||||||
func (n *node) setHasVal(b bool) { n.flags.set(nodeHasVal, b) }
|
|
||||||
func (n *node) setHasOpt(b bool) { n.flags.set(nodeHasOpt, b) }
|
|
||||||
func (n *node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) }
|
func (n *node) SetEmbedded(b bool) { n.flags.set(nodeEmbedded, b) }
|
||||||
|
|
||||||
// MarkNonNil marks a pointer n as being guaranteed non-nil,
|
// MarkNonNil marks a pointer n as being guaranteed non-nil,
|
||||||
@ -380,29 +376,13 @@ func (n *node) SetBounded(b bool) {
|
|||||||
|
|
||||||
// Opt returns the optimizer data for the node.
|
// Opt returns the optimizer data for the node.
|
||||||
func (n *node) Opt() interface{} {
|
func (n *node) Opt() interface{} {
|
||||||
if !n.hasOpt() {
|
return n.opt
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return n.e
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOpt sets the optimizer data for the node, which must not have been used with SetVal.
|
// SetOpt sets the optimizer data for the node, which must not have been used with SetVal.
|
||||||
// SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts.
|
// SetOpt(nil) is ignored for Vals to simplify call sites that are clearing Opts.
|
||||||
func (n *node) SetOpt(x interface{}) {
|
func (n *node) SetOpt(x interface{}) {
|
||||||
if x == nil {
|
n.opt = x
|
||||||
if n.hasOpt() {
|
|
||||||
n.setHasOpt(false)
|
|
||||||
n.e = nil
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n.HasVal() {
|
|
||||||
base.Flag.LowerH = 1
|
|
||||||
Dump("have Val", n)
|
|
||||||
base.Fatalf("have Val")
|
|
||||||
}
|
|
||||||
n.setHasOpt(true)
|
|
||||||
n.e = x
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) Iota() int64 {
|
func (n *node) Iota() int64 {
|
||||||
@ -1344,6 +1324,10 @@ func NodAt(pos src.XPos, op Op, nleft, nright Node) Node {
|
|||||||
return NewEmptyStmt(pos)
|
return NewEmptyStmt(pos)
|
||||||
case OBREAK, OCONTINUE, OFALL, OGOTO:
|
case OBREAK, OCONTINUE, OFALL, OGOTO:
|
||||||
return NewBranchStmt(pos, op, nil)
|
return NewBranchStmt(pos, op, nil)
|
||||||
|
case OLITERAL, OTYPE, OIOTA:
|
||||||
|
n := newNameAt(pos, nil)
|
||||||
|
n.SetOp(op)
|
||||||
|
return n
|
||||||
case OLABEL:
|
case OLABEL:
|
||||||
return NewLabelStmt(pos, nil)
|
return NewLabelStmt(pos, nil)
|
||||||
default:
|
default:
|
||||||
@ -1428,13 +1412,11 @@ var okForNod = [OEND]bool{
|
|||||||
OINDEXMAP: true,
|
OINDEXMAP: true,
|
||||||
OINLCALL: true,
|
OINLCALL: true,
|
||||||
OINLMARK: true,
|
OINLMARK: true,
|
||||||
OIOTA: true,
|
|
||||||
OITAB: true,
|
OITAB: true,
|
||||||
OKEY: true,
|
OKEY: true,
|
||||||
OLABEL: true,
|
OLABEL: true,
|
||||||
OLE: true,
|
OLE: true,
|
||||||
OLEN: true,
|
OLEN: true,
|
||||||
OLITERAL: true,
|
|
||||||
OLSH: true,
|
OLSH: true,
|
||||||
OLT: true,
|
OLT: true,
|
||||||
OMAKE: true,
|
OMAKE: true,
|
||||||
@ -1446,13 +1428,11 @@ var okForNod = [OEND]bool{
|
|||||||
OMETHEXPR: true,
|
OMETHEXPR: true,
|
||||||
OMOD: true,
|
OMOD: true,
|
||||||
OMUL: true,
|
OMUL: true,
|
||||||
ONAME: true,
|
|
||||||
ONE: true,
|
ONE: true,
|
||||||
ONEG: true,
|
ONEG: true,
|
||||||
ONEW: true,
|
ONEW: true,
|
||||||
ONEWOBJ: true,
|
ONEWOBJ: true,
|
||||||
ONIL: true,
|
ONIL: true,
|
||||||
ONONAME: true,
|
|
||||||
ONOT: true,
|
ONOT: true,
|
||||||
OOFFSETOF: true,
|
OOFFSETOF: true,
|
||||||
OOR: true,
|
OOR: true,
|
||||||
@ -1499,7 +1479,7 @@ var okForNod = [OEND]bool{
|
|||||||
OTINTER: true,
|
OTINTER: true,
|
||||||
OTMAP: true,
|
OTMAP: true,
|
||||||
OTSTRUCT: true,
|
OTSTRUCT: true,
|
||||||
OTYPE: true,
|
OTYPE: true, // TODO: Remove once setTypeNode is gone.
|
||||||
OTYPESW: true,
|
OTYPESW: true,
|
||||||
OVARDEF: true,
|
OVARDEF: true,
|
||||||
OVARKILL: true,
|
OVARKILL: true,
|
||||||
|
@ -21,9 +21,8 @@ func TestSizeof(t *testing.T) {
|
|||||||
_64bit uintptr // size on 64bit platforms
|
_64bit uintptr // size on 64bit platforms
|
||||||
}{
|
}{
|
||||||
{Func{}, 152, 280},
|
{Func{}, 152, 280},
|
||||||
{Name{}, 36, 64},
|
{Name{}, 132, 232},
|
||||||
{Param{}, 44, 88},
|
{node{}, 84, 144},
|
||||||
{node{}, 88, 152},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user