// in typecheck.c. usually addrescapes runs after
// widstruct, in which case we could drop this,
// but function closure functions are the exception.
- if f.Nname.Param.Stackparam != nil {
- f.Nname.Param.Stackparam.Xoffset = o
+ if f.Nname.Name.Param.Stackparam != nil {
+ f.Nname.Name.Param.Stackparam.Xoffset = o
f.Nname.Xoffset = 0
} else {
f.Nname.Xoffset = o
case ONAME:
// should only get here with names in this func.
- if n.Funcdepth > 0 && n.Funcdepth != Funcdepth {
+ if n.Name.Funcdepth > 0 && n.Name.Funcdepth != Funcdepth {
Dump("bad agen", n)
- Fatal("agen: bad ONAME funcdepth %d != %d", n.Funcdepth, Funcdepth)
+ Fatal("agen: bad ONAME funcdepth %d != %d", n.Name.Funcdepth, Funcdepth)
}
// should only get here for heap vars or paramref
var a *Node
n := Nod(OCLOSURE, nil, nil)
- n.Param.Ntype = ntype
- n.Funcdepth = Funcdepth
+ n.Func.Ntype = ntype
+ n.Func.Depth = Funcdepth
n.Func.Outerfunc = Curfn
funchdr(n)
var v *Node
for l := func_.Func.Cvars; l != nil; l = l.Next {
v = l.N
- v.Param.Closure.Param.Closure = v.Param.Outer
- v.Param.Outerexpr = oldname(v.Sym)
+ v.Name.Param.Closure.Name.Closure = v.Name.Outer
+ v.Name.Param.Outerexpr = oldname(v.Sym)
}
return func_
var n *Node
for l := func_.Func.Cvars; l != nil; l = l.Next {
- n = l.N.Param.Closure
+ n = l.N.Name.Param.Closure
if !n.Name.Captured {
n.Name.Captured = true
if n.Name.Decldepth == 0 {
}
oldfn := Curfn
- typecheck(&func_.Param.Ntype, Etype)
- func_.Type = func_.Param.Ntype.Type
- func_.Param.Top = top
+ typecheck(&func_.Func.Ntype, Etype)
+ func_.Type = func_.Func.Ntype.Type
+ func_.Func.Top = top
// Type check the body now, but only if we're inside a function.
// At top level (in a variable initialization: curfn==nil) we're not
xfunc.Nname = newfuncname(closurename(func_))
xfunc.Nname.Sym.Flags |= SymExported // disable export
- xfunc.Nname.Param.Ntype = xtype
+ xfunc.Nname.Name.Param.Ntype = xtype
xfunc.Nname.Name.Defn = xfunc
declare(xfunc.Nname, PFUNC)
- xfunc.Nname.Funcdepth = func_.Funcdepth
- xfunc.Funcdepth = func_.Funcdepth
+ xfunc.Nname.Name.Funcdepth = func_.Func.Depth
+ xfunc.Func.Depth = func_.Func.Depth
xfunc.Func.Endlineno = func_.Func.Endlineno
xfunc.Nbody = func_.Nbody
}
typecheck(&xfunc, Etop)
- xfunc.Param.Closure = func_
- func_.Param.Closure = xfunc
+ xfunc.Func.Closure = func_
+ func_.Func.Closure = xfunc
func_.Nbody = nil
func_.List = nil
lno := int(lineno)
lineno = xfunc.Lineno
- func_ := xfunc.Param.Closure
+ func_ := xfunc.Func.Closure
func_.Func.Enter = nil
for l := func_.Func.Cvars; l != nil; l = l.Next {
v = l.N
// so that the outer frame also grabs them and knows they escape.
dowidth(v.Type)
- outer = v.Param.Outerexpr
- v.Param.Outerexpr = nil
+ outer = v.Name.Param.Outerexpr
+ v.Name.Param.Outerexpr = nil
// out parameters will be assigned to implicitly upon return.
- if outer.Class != PPARAMOUT && !v.Param.Closure.Addrtaken && !v.Param.Closure.Assigned && v.Type.Width <= 128 {
+ if outer.Class != PPARAMOUT && !v.Name.Param.Closure.Addrtaken && !v.Name.Param.Closure.Assigned && v.Type.Width <= 128 {
v.Name.Byval = true
} else {
- v.Param.Closure.Addrtaken = true
+ v.Name.Param.Closure.Addrtaken = true
outer = Nod(OADDR, outer, nil)
}
if v.Name.Byval {
how = "value"
}
- Warnl(int(v.Lineno), "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, v.Param.Closure.Addrtaken, v.Param.Closure.Assigned, int32(v.Type.Width))
+ Warnl(int(v.Lineno), "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, v.Name.Param.Closure.Addrtaken, v.Name.Param.Closure.Assigned, int32(v.Type.Width))
}
typecheck(&outer, Erv)
func transformclosure(xfunc *Node) {
lno := int(lineno)
lineno = xfunc.Lineno
- func_ := xfunc.Param.Closure
+ func_ := xfunc.Func.Closure
- if func_.Param.Top&Ecall != 0 {
+ if func_.Func.Top&Ecall != 0 {
// If the closure is directly called, we transform it to a plain function call
// with variables passed as args. This avoids allocation of a closure object.
// Here we do only a part of the transformation. Walk of OCALLFUNC(OCLOSURE)
// Declare variable holding addresses taken from closure
// and initialize in entry prologue.
addr = newname(Lookupf("&%s", v.Sym.Name))
- addr.Param.Ntype = Nod(OIND, typenod(v.Type), nil)
+ addr.Name.Param.Ntype = Nod(OIND, typenod(v.Type), nil)
addr.Class = PAUTO
addr.Used = true
addr.Curfn = xfunc
func walkclosure(func_ *Node, init **NodeList) *Node {
// If no closure vars, don't bother wrapping.
if func_.Func.Cvars == nil {
- return func_.Param.Closure.Nname
+ return func_.Func.Closure.Nname
}
// Create closure in the form of a composite literal.
clos := Nod(OCOMPLIT, nil, Nod(OIND, typ, nil))
clos.Esc = func_.Esc
clos.Right.Implicit = true
- clos.List = concat(list1(Nod(OCFUNC, func_.Param.Closure.Nname, nil)), func_.Func.Enter)
+ clos.List = concat(list1(Nod(OCFUNC, func_.Func.Closure.Nname, nil)), func_.Func.Enter)
// Force type conversion from *struct to the func type.
clos = Nod(OCONVNOP, clos, nil)
xfunc.Func.Dupok = true
xfunc.Nname = newfuncname(sym)
xfunc.Nname.Sym.Flags |= SymExported // disable export
- xfunc.Nname.Param.Ntype = xtype
+ xfunc.Nname.Name.Param.Ntype = xtype
xfunc.Nname.Name.Defn = xfunc
declare(xfunc.Nname, PFUNC)
xfunc.Func.Dcl = list(xfunc.Func.Dcl, ptr)
var body *NodeList
if Isptr[rcvrtype.Etype] || Isinter(rcvrtype) {
- ptr.Param.Ntype = typenod(rcvrtype)
+ ptr.Name.Param.Ntype = typenod(rcvrtype)
body = list(body, Nod(OAS, ptr, cv))
} else {
- ptr.Param.Ntype = typenod(Ptrto(rcvrtype))
+ ptr.Name.Param.Ntype = typenod(Ptrto(rcvrtype))
body = list(body, Nod(OAS, ptr, Nod(OADDR, cv, nil)))
}
s.Lastlineno = int32(parserline())
s.Def = n
n.Name.Vargen = int32(gen)
- n.Funcdepth = Funcdepth
+ n.Name.Funcdepth = Funcdepth
n.Class = uint8(ctxt)
autoexport(n, ctxt)
v = vl.N
v.Op = ONAME
declare(v, dclcontext)
- v.Param.Ntype = t
+ v.Name.Param.Ntype = t
v.Name.Defn = as2
if Funcdepth > 0 {
init = list(init, Nod(ODCL, v, nil))
v = vl.N
v.Op = ONAME
declare(v, dclcontext)
- v.Param.Ntype = t
+ v.Name.Param.Ntype = t
if e != nil || Funcdepth > 0 || isblank(v) {
if Funcdepth > 0 {
v.Op = OLITERAL
declare(v, dclcontext)
- v.Param.Ntype = t
+ v.Name.Param.Ntype = t
v.Name.Defn = c
vv = list(vv, Nod(ODCLCONST, v, nil))
n.Name.Iota = iota_ // save current iota value in const declarations
}
- if Curfn != nil && n.Funcdepth > 0 && n.Funcdepth != Funcdepth && n.Op == ONAME {
+ if Curfn != nil && n.Op == ONAME && n.Name.Funcdepth > 0 && n.Name.Funcdepth != Funcdepth {
// inner func is referring to var in outer func.
//
// TODO(rsc): If there is an outer variable x and we
// are parsing x := 5 inside the closure, until we get to
// the := it looks like a reference to the outer x so we'll
// make x a closure variable unnecessarily.
- if n.Param.Closure == nil || n.Param.Closure.Funcdepth != Funcdepth {
+ if n.Name.Param.Closure == nil || n.Name.Param.Closure.Name.Funcdepth != Funcdepth {
// create new closure var.
c := Nod(ONAME, nil, nil)
c.Name.Defn = n
c.Addable = false
c.Ullman = 2
- c.Funcdepth = Funcdepth
- c.Param.Outer = n.Param.Closure
- n.Param.Closure = c
- c.Param.Closure = n
+ c.Name.Funcdepth = Funcdepth
+ c.Name.Param.Outer = n.Name.Param.Closure
+ n.Name.Param.Closure = c
+ c.Name.Param.Closure = n
c.Xoffset = 0
Curfn.Func.Cvars = list(Curfn.Func.Cvars, c)
}
// return ref to closure var, not original
- return n.Param.Closure
+ return n.Name.Param.Closure
}
return n
dclcontext = PPARAM
markdcl()
Funcdepth++
- n.Param.Outer = Curfn
+ n.Func.Outer = Curfn
Curfn = n
funcargs(n.Right)
markdcl()
Funcdepth++
- n.Param.Outer = Curfn
+ n.Func.Outer = Curfn
Curfn = n
if n.Nname != nil {
- funcargs(n.Nname.Param.Ntype)
- } else if n.Param.Ntype != nil {
- funcargs(n.Param.Ntype)
+ funcargs(n.Nname.Name.Param.Ntype)
+ } else if n.Func.Ntype != nil {
+ funcargs(n.Func.Ntype)
} else {
funcargs2(n.Type)
}
}
if n.Left != nil {
n.Left.Op = ONAME
- n.Left.Param.Ntype = n.Right
+ n.Left.Name.Param.Ntype = n.Right
declare(n.Left, PPARAM)
if dclcontext == PAUTO {
vargen++
}
if n.Left != nil {
n.Left.Op = ONAME
- n.Left.Param.Ntype = n.Right
+ n.Left.Name.Param.Ntype = n.Right
declare(n.Left, PPARAM)
if dclcontext == PAUTO {
vargen++
n.Left = nn
}
- n.Left.Param.Ntype = n.Right
+ n.Left.Name.Param.Ntype = n.Right
declare(n.Left, PPARAMOUT)
if dclcontext == PAUTO {
i++
}
popdcl()
Funcdepth--
- Curfn = n.Param.Outer
- n.Param.Outer = nil
+ Curfn = n.Func.Outer
+ n.Func.Outer = nil
if Funcdepth == 0 {
dclcontext = PEXTERN
}
* return the ODCLTYPE node to use.
*/
func typedcl1(n *Node, t *Node, local bool) *Node {
- n.Param.Ntype = t
+ n.Name.Param.Ntype = t
n.Local = local
return Nod(ODCLTYPE, n, nil)
}
// esc.c needs to find f given a PPARAM to add the tag.
if l.N.Left != nil && l.N.Left.Class == PPARAM {
- l.N.Left.Param.Field = f
+ l.N.Left.Name.Param.Field = f
}
*tp = f
Stksize = 0
dclcontext = PAUTO
- Funcdepth = n.Funcdepth + 1
+ Funcdepth = n.Func.Depth + 1
compile(n)
Curfn = nil
Funcdepth = 0
// more precise when analyzing a single non-recursive function than
// when analyzing a set of mutually recursive functions.
-// TODO(rsc): Look into using a map[*Node]bool instead of walkgen,
-// to allow analysis passes to use walkgen themselves.
-
type bottomUpVisitor struct {
analyze func(*NodeList, bool)
visitgen uint32
+ nodeID map[*Node]uint32
stack *NodeList
}
// If recursive is true, the list may still contain only a single function,
// if that function is itself recursive.
func visitBottomUp(list *NodeList, analyze func(list *NodeList, recursive bool)) {
- for l := list; l != nil; l = l.Next {
- l.N.Walkgen = 0
- }
-
var v bottomUpVisitor
v.analyze = analyze
+ v.nodeID = make(map[*Node]uint32)
for l := list; l != nil; l = l.Next {
if l.N.Op == ODCLFUNC && l.N.Curfn == nil {
v.visit(l.N)
}
}
-
- for l := list; l != nil; l = l.Next {
- l.N.Walkgen = 0
- }
}
func (v *bottomUpVisitor) visit(n *Node) uint32 {
- if n.Walkgen > 0 {
+ if id := v.nodeID[n]; id > 0 {
// already visited
- return n.Walkgen
+ return id
}
v.visitgen++
- n.Walkgen = v.visitgen
+ id := v.visitgen
+ v.nodeID[n] = id
v.visitgen++
min := v.visitgen
l.N = n
v.stack = l
min = v.visitcodelist(n.Nbody, min)
- if (min == n.Walkgen || min == n.Walkgen+1) && n.Curfn == nil {
+ if (min == id || min == id+1) && n.Curfn == nil {
// This node is the root of a strongly connected component.
// The original min passed to visitcodelist was n->walkgen+1.
// If visitcodelist found its way back to n->walkgen, then this
// block is a set of mutually recursive functions.
// Otherwise it's just a lone function that does not recurse.
- recursive := min == n.Walkgen
+ recursive := min == id
// Remove connected component from stack.
// Mark walkgen so that future visits return a large number
var l *NodeList
for l = v.stack; l.N != n; l = l.Next {
- l.N.Walkgen = ^uint32(0)
+ v.nodeID[l.N] = ^uint32(0)
}
- n.Walkgen = ^uint32(0)
+ v.nodeID[n] = ^uint32(0)
v.stack = l.Next
l.Next = nil
}
if n.Op == OCLOSURE {
- m := v.visit(n.Param.Closure)
+ m := v.visit(n.Func.Closure)
if m < min {
min = m
}
Escretval *NodeList // on OCALLxxx, list of dummy return values
Escloopdepth int32 // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
Esclevel Level
+ Walkgen uint32
}
func (e *EscState) nodeEscState(n *Node) *NodeEscState {
noesc *NodeList // list of possible non-escaping nodes, for printing
recursive bool // recursive function or group of mutually recursive functions.
opts []*Node // nodes with .Opt initialized
+ walkgen uint32
}
// funcSym returns n.Nname.Sym if no nils are encountered along the way.
if v.Op == OXXX { // unnamed out argument; see dcl.c:/^funcargs
continue
}
- a = v.Param.Closure
+ a = v.Name.Param.Closure
if !v.Name.Byval {
a = Nod(OADDR, a, nil)
a.Lineno = v.Lineno
nE := e.nodeEscState(n)
if fn != nil && fn.Op == ONAME && fn.Class == PFUNC &&
- fn.Name.Defn != nil && fn.Name.Defn.Nbody != nil && fn.Param.Ntype != nil && fn.Name.Defn.Esc < EscFuncTagged {
+ fn.Name.Defn != nil && fn.Name.Defn.Nbody != nil && fn.Name.Param.Ntype != nil && fn.Name.Defn.Esc < EscFuncTagged {
if Debug['m'] > 2 {
fmt.Printf("%v::esccall:: %v in recursive group\n", Ctxt.Line(int(lineno)), Nconv(n, obj.FmtShort))
}
}
// set up out list on this call node
- for lr := fn.Param.Ntype.Rlist; lr != nil; lr = lr.Next {
+ for lr := fn.Name.Param.Ntype.Rlist; lr != nil; lr = lr.Next {
nE.Escretval = list(nE.Escretval, lr.N.Left) // type.rlist -> dclfield -> ONAME (PPARAMOUT)
}
// Receiver.
if n.Op != OCALLFUNC {
- escassign(e, fn.Param.Ntype.Left.Left, n.Left.Left)
+ escassign(e, fn.Name.Param.Ntype.Left.Left, n.Left.Left)
}
var src *Node
- for lr := fn.Param.Ntype.List; ll != nil && lr != nil; ll, lr = ll.Next, lr.Next {
+ for lr := fn.Name.Param.Ntype.List; ll != nil && lr != nil; ll, lr = ll.Next, lr.Next {
src = ll.N
if lr.N.Isddd && !n.Isddd {
// Introduce ODDDARG node to represent ... allocation.
dstE := e.nodeEscState(dst)
if Debug['m'] > 1 {
- fmt.Printf("\nescflood:%d: dst %v scope:%v[%d]\n", walkgen, Nconv(dst, obj.FmtShort), curfnSym(dst), dstE.Escloopdepth)
+ fmt.Printf("\nescflood:%d: dst %v scope:%v[%d]\n", e.walkgen, Nconv(dst, obj.FmtShort), curfnSym(dst), dstE.Escloopdepth)
}
for l := dstE.Escflowsrc; l != nil; l = l.Next {
- walkgen++
+ e.walkgen++
escwalk(e, levelFrom(0), dst, l.N)
}
}
func escwalk(e *EscState, level Level, dst *Node, src *Node) {
srcE := e.nodeEscState(src)
- if src.Walkgen == walkgen {
+ if srcE.Walkgen == e.walkgen {
// Esclevels are vectors, do not compare as integers,
// and must use "min" of old and new to guarantee
// convergence.
}
}
- src.Walkgen = walkgen
+ srcE.Walkgen = e.walkgen
srcE.Esclevel = level
if Debug['m'] > 1 {
if leaks && Debug['m'] != 0 {
Warnl(int(src.Lineno), "leaking closure reference %v", Nconv(src, obj.FmtShort))
}
- escwalk(e, level, dst, src.Param.Closure)
+ escwalk(e, level, dst, src.Name.Param.Closure)
}
case OPTRLIT, OADDR:
case EscNone, // not touched by escflood
EscReturn:
if haspointers(ll.N.Type) { // don't bother tagging for scalars
- ll.N.Param.Field.Note = mktag(int(ll.N.Esc))
+ ll.N.Name.Param.Field.Note = mktag(int(ll.N.Esc))
}
case EscHeap, // touched by escflood, moved to heap
if (ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN {
return
}
- if n.Param != nil && n.Param.Ntype != nil && n.Param.Ntype.Op == OTFUNC && n.Param.Ntype.Left != nil { // method
+ if n.Name.Param != nil && n.Name.Param.Ntype != nil && n.Name.Param.Ntype.Op == OTFUNC && n.Name.Param.Ntype.Left != nil { // method
return
}
fmt.Fprintf(&buf, " colas(%v)", n.Colas)
}
- if n.Funcdepth != 0 {
- fmt.Fprintf(&buf, " f(%d)", n.Funcdepth)
+ if n.Name != nil && n.Name.Funcdepth != 0 {
+ fmt.Fprintf(&buf, " f(%d)", n.Name.Funcdepth)
}
switch n.Esc {
if n.Nbody != nil {
return fmt.Sprintf("%v { %v }", n.Type, n.Nbody)
}
- return fmt.Sprintf("%v { %v }", n.Type, n.Param.Closure.Nbody)
+ return fmt.Sprintf("%v { %v }", n.Type, n.Name.Param.Closure.Nbody)
case OCOMPLIT:
ptrlit := n.Right != nil && n.Right.Implicit && n.Right.Type != nil && Isptr[n.Right.Type.Etype]
} else {
fmt.Fprintf(&buf, "%v%v", Oconv(int(n.Op), 0), Jconv(n, 0))
}
- if recur && n.Type == nil && n.Param.Ntype != nil {
+ if recur && n.Type == nil && n.Name.Param.Ntype != nil {
indent(&buf)
- fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), n.Param.Ntype)
+ fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), n.Name.Param.Ntype)
}
case OASOP:
case OTYPE:
fmt.Fprintf(&buf, "%v %v%v type=%v", Oconv(int(n.Op), 0), n.Sym, Jconv(n, 0), n.Type)
- if recur && n.Type == nil && n.Param.Ntype != nil {
+ if recur && n.Type == nil && n.Name.Param.Ntype != nil {
indent(&buf)
- fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), n.Param.Ntype)
+ fmt.Fprintf(&buf, "%v-ntype%v", Oconv(int(n.Op), 0), n.Name.Param.Ntype)
}
}
// expression to refer to stack copy
case PPARAM, PPARAMOUT:
- n.Param.Stackparam = Nod(OPARAM, n, nil)
+ n.Name.Param.Stackparam = Nod(OPARAM, n, nil)
- n.Param.Stackparam.Type = n.Type
- n.Param.Stackparam.Addable = true
+ n.Name.Param.Stackparam.Type = n.Type
+ n.Name.Param.Stackparam.Addable = true
if n.Xoffset == BADWIDTH {
Fatal("addrescapes before param assignment")
}
- n.Param.Stackparam.Xoffset = n.Xoffset
+ n.Name.Param.Stackparam.Xoffset = n.Xoffset
fallthrough
case PAUTO:
initsym := Lookup("init")
fn.Nname = newname(initsym)
fn.Nname.Name.Defn = fn
- fn.Nname.Param.Ntype = Nod(OTFUNC, nil, nil)
+ fn.Nname.Name.Param.Ntype = Nod(OTFUNC, nil, nil)
declare(fn.Nname, PFUNC)
funchdr(fn)
// This needs to run before escape analysis,
// because variables captured by value do not escape.
for l := xtop; l != nil; l = l.Next {
- if l.N.Op == ODCLFUNC && l.N.Param.Closure != nil {
+ if l.N.Op == ODCLFUNC && l.N.Func.Closure != nil {
Curfn = l.N
capturevars(l.N)
}
// This needs to happen before walk, because closures must be transformed
// before walk reaches a call of a closure.
for l := xtop; l != nil; l = l.Next {
- if l.N.Op == ODCLFUNC && l.N.Param.Closure != nil {
+ if l.N.Op == ODCLFUNC && l.N.Func.Closure != nil {
Curfn = l.N
transformclosure(l.N)
}
init2list(n.Nbody, out)
if n.Op == OCLOSURE {
- init2list(n.Param.Closure.Nbody, out)
+ init2list(n.Func.Closure.Nbody, out)
}
if n.Op == ODOTMETH || n.Op == OCALLPART {
init2(n.Type.Nname, out)
switch op {
case OCLOSURE, ODCLFUNC:
n.Func = new(Func)
- n.Param = new(Param)
case ONAME:
n.Name = new(Name)
- n.Param = new(Param)
+ n.Name.Param = new(Param)
case OLABEL, OPACK:
n.Name = new(Name)
case ODCLFIELD:
- n.Param = new(Param)
+ if nleft != nil {
+ n.Name = nleft.Name
+ } else {
+ n.Name = new(Name)
+ n.Name.Param = new(Param)
+ }
}
return n
}
if lineno != -1 {
m.Lineno = lineno
}
- if m.Name != nil {
+ if m.Name != nil && n.Op != ODCLFIELD {
Dump("treecopy", n)
Fatal("treecopy Name")
}
markdcl()
this := Nod(ODCLFIELD, newname(Lookup(".this")), typenod(rcvr))
- this.Left.Param.Ntype = this.Right
+ this.Left.Name.Param.Ntype = this.Right
in := structargs(getinarg(method.Type), 1)
out := structargs(Getoutarg(method.Type), 0)
fn := Nod(ODCLFUNC, nil, nil)
fn.Nname = newname(newnam)
fn.Nname.Name.Defn = fn
- fn.Nname.Param.Ntype = t
+ fn.Nname.Name.Param.Ntype = t
declare(fn.Nname, PFUNC)
funchdr(fn)
fn.Nname = newname(sym)
fn.Nname.Class = PFUNC
tfn := Nod(OTFUNC, nil, nil)
- fn.Nname.Param.Ntype = tfn
+ fn.Nname.Name.Param.Ntype = tfn
n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t)))
tfn.List = list(tfn.List, n)
tfn.Rlist = list(tfn.Rlist, n)
funchdr(fn)
- typecheck(&fn.Nname.Param.Ntype, Etype)
+ typecheck(&fn.Nname.Name.Param.Ntype, Etype)
// genhash is only called for types that have equality but
// cannot be handled by the standard algorithms,
fn.Nname = newname(sym)
fn.Nname.Class = PFUNC
tfn := Nod(OTFUNC, nil, nil)
- fn.Nname.Param.Ntype = tfn
+ fn.Nname.Name.Param.Ntype = tfn
n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t)))
tfn.List = list(tfn.List, n)
if nvar != nil {
if ll != nil && ll.Next == nil && ll.N.Type != nil && !Istype(ll.N.Type, TNIL) {
// single entry type switch
- nvar.Param.Ntype = typenod(ll.N.Type)
+ nvar.Name.Param.Ntype = typenod(ll.N.Type)
} else {
// multiple entry type switch or default
- nvar.Param.Ntype = typenod(n.Type)
+ nvar.Name.Param.Ntype = typenod(n.Type)
}
typecheck(&nvar, Erv|Easgn)
// ONAME
Name *Name
Curfn *Node // function for local variables
- Param *Param
Sym *Sym // various
Xoffset int64
- Lineno int32
- Walkgen uint32
-
- Funcdepth int32
+ Lineno int32
// OREGISTER, OINDREG
Reg int16
// Name holds Node fields used only by named nodes (ONAME, OPACK, some OLITERAL).
type Name struct {
- Pack *Node // real package for import . names
- Pkg *Pkg // pkg for OPACK nodes
- Heapaddr *Node // temp holding heap address of param
- Inlvar *Node // ONAME substitute while inlining
- Defn *Node // initializing assignment
+ Pack *Node // real package for import . names
+ Pkg *Pkg // pkg for OPACK nodes
+ Heapaddr *Node // temp holding heap address of param
+ Inlvar *Node // ONAME substitute while inlining
+ Defn *Node // initializing assignment
+ *Param
Decldepth int32 // declaration loop depth, increased for every loop or label
Vargen int32 // unique name for OTYPE/ONAME within a function. Function outputs are numbered starting at one.
Iota int32 // value if this name is iota
- Method bool // OCALLMETH name
+ Funcdepth int32
+ Method bool // OCALLMETH name
Readonly bool
Captured bool // is the variable captured by a closure
Byval bool // is the variable captured by value or by reference
// ONAME closure param with PPARAMREF
Outer *Node // outer PPARAMREF in nested closure
Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF
- Top int // top context (Ecall, Eproc, etc)
}
// Func holds Node fields used only with function-like nodes.
Closgen int
Outerfunc *Node
Fieldtrack []*Type
+ Outer *Node // outer func for closure
+ Ntype *Node // signature
+ Top int // top context (Ecall, Eproc, etc)
+ Closure *Node // OCLOSURE <-> ODCLFUNC
Inl *NodeList // copy of the body for use in inlining
InlCost int32
+ Depth int32
Endlineno int32
OEND
)
-/*
- * Every node has a walkgen field.
- * If you want to do a traversal of a node graph that
- * might contain duplicates and want to avoid
- * visiting the same nodes twice, increment walkgen
- * before starting. Then before processing a node, do
- *
- * if(n->walkgen == walkgen)
- * return;
- * n->walkgen = walkgen;
- *
- * Such a walk cannot call another such walk recursively,
- * because of the use of the global walkgen.
- */
-var walkgen uint32
-
// A NodeList is a linked list of nodes.
// TODO(rsc): Some uses of NodeList should be made into slices.
// The remaining ones probably just need a simple linked list,
var l *Node
for l = n.Left; l != r; l = l.Left {
l.Addrtaken = true
- if l.Param != nil && l.Param.Closure != nil {
- l.Param.Closure.Addrtaken = true
+ if l.Name != nil && l.Name.Param != nil && l.Name.Param.Closure != nil {
+ l.Name.Param.Closure.Addrtaken = true
}
}
Fatal("found non-orig name node %v", l)
}
l.Addrtaken = true
- if l.Param != nil && l.Param.Closure != nil {
- l.Param.Closure.Addrtaken = true
+ if l.Name != nil && l.Name.Param != nil && l.Name.Param.Closure != nil {
+ l.Name.Closure.Addrtaken = true
}
defaultlit(&n.Left, nil)
l = n.Left
var l *Node
for l = n; l != r; l = l.Left {
l.Assigned = true
- if l.Param != nil && l.Param.Closure != nil {
- l.Param.Closure.Assigned = true
+ if l.Name != nil && l.Name.Param != nil && l.Name.Param.Closure != nil {
+ l.Name.Param.Closure.Assigned = true
}
}
l.Assigned = true
- if l.Param != nil && l.Param.Closure != nil {
- l.Param.Closure.Assigned = true
+ if l.Name != nil && l.Name.Param != nil && l.Name.Param.Closure != nil {
+ l.Name.Param.Closure.Assigned = true
}
}
// so that the conversion below happens).
n.Left = resolve(n.Left)
- if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Param.Ntype != nil {
+ if n.Left.Name == nil || n.Left.Name.Defn != n || n.Left.Name.Param.Ntype != nil {
typecheck(&n.Left, Erv|Easgn)
}
}
}
- if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Param.Ntype == nil {
+ if n.Left.Name != nil && n.Left.Name.Defn == n && n.Left.Name.Param.Ntype == nil {
defaultlit(&n.Right, nil)
n.Left.Type = n.Right.Type
}
// delicate little dance.
ll.N = resolve(ll.N)
- if ll.N.Name == nil || ll.N.Name.Defn != n || ll.N.Param.Ntype != nil {
+ if ll.N.Name == nil || ll.N.Name.Defn != n || ll.N.Name.Param.Ntype != nil {
typecheck(&ll.N, Erv|Easgn)
}
}
if ll.N.Type != nil && lr.N.Type != nil {
lr.N = assignconv(lr.N, ll.N.Type, "assignment")
}
- if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Param.Ntype == nil {
+ if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil {
defaultlit(&lr.N, nil)
ll.N.Type = lr.N.Type
}
if t.Type != nil && ll.N.Type != nil {
checkassignto(t.Type, ll.N)
}
- if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Param.Ntype == nil {
+ if ll.N.Name != nil && ll.N.Name.Defn == n && ll.N.Name.Param.Ntype == nil {
ll.N.Type = t.Type
}
t = structnext(&s)
if l.Type != nil && l.Type.Etype != TBOOL {
checkassignto(Types[TBOOL], l)
}
- if l.Name != nil && l.Name.Defn == n && l.Param.Ntype == nil {
+ if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
l.Type = Types[TBOOL]
}
goto out
setlineno(n)
n.Type.Sym = n.Sym
n.Typecheck = 1
- typecheck(&n.Param.Ntype, Etype)
- t := n.Param.Ntype.Type
+ typecheck(&n.Name.Param.Ntype, Etype)
+ t := n.Name.Param.Ntype.Type
if t == nil {
n.Diag = 1
n.Type = nil
break
case OLITERAL:
- if n.Param.Ntype != nil {
- typecheck(&n.Param.Ntype, Etype)
- n.Type = n.Param.Ntype.Type
- n.Param.Ntype = nil
+ if n.Name.Param.Ntype != nil {
+ typecheck(&n.Name.Param.Ntype, Etype)
+ n.Type = n.Name.Param.Ntype.Type
+ n.Name.Param.Ntype = nil
if n.Type == nil {
n.Diag = 1
goto ret
n.Type = e.Type
case ONAME:
- if n.Param.Ntype != nil {
- typecheck(&n.Param.Ntype, Etype)
- n.Type = n.Param.Ntype.Type
-
+ if n.Name.Param.Ntype != nil {
+ typecheck(&n.Name.Param.Ntype, Etype)
+ n.Type = n.Name.Param.Ntype.Type
if n.Type == nil {
n.Diag = 1
goto ret
n.Left.Func.Enter = nil
// Replace OCLOSURE with ONAME/PFUNC.
- n.Left = n.Left.Param.Closure.Nname
+ n.Left = n.Left.Func.Closure.Nname
// Update type of OCALLFUNC node.
// Output arguments had not changed, but their offsets could.
case ONEW:
if n.Esc == EscNone {
if n.Type.Type.Width >= 1<<16 {
- Fatal("Large ONEW with EscNone, %v", n)
+ Fatal("large ONEW with EscNone: %v", n)
}
r := temp(n.Type.Type)
r = Nod(OAS, r, nil) // zero temp
t := n.Type
if n.Esc == EscNone {
if !isSmallMakeSlice(n) {
- Fatal("Non-small OMAKESLICE with EscNone, %v", n)
+ Fatal("non-small OMAKESLICE with EscNone: %v", n)
}
// var arr [r]T
// n = arr[:l]
}
nn = list(nn, Nod(OAS, v.Name.Heapaddr, prealloc[v]))
if v.Class&^PHEAP != PPARAMOUT {
- as = Nod(OAS, v, v.Param.Stackparam)
- v.Param.Stackparam.Typecheck = 1
+ as = Nod(OAS, v, v.Name.Stackparam)
+ v.Name.Param.Stackparam.Typecheck = 1
typecheck(&as, Etop)
as = applywritebarrier(as, &nn)
nn = list(nn, as)
if v == nil || v.Class != PHEAP|PPARAMOUT {
continue
}
- nn = list(nn, Nod(OAS, v.Param.Stackparam, v))
+ nn = list(nn, Nod(OAS, v.Name.Param.Stackparam, v))
}
return nn
buf = fmt.Sprintf("print·%d", walkprintfunc_prgen)
fn.Nname = newname(Lookup(buf))
fn.Nname.Name.Defn = fn
- fn.Nname.Param.Ntype = t
+ fn.Nname.Name.Param.Ntype = t
declare(fn.Nname, PFUNC)
oldfn := Curfn
yyVAL.node = Nod(ODCLFUNC, nil, nil)
yyVAL.node.Nname = newfuncname(yyDollar[1].sym)
yyVAL.node.Nname.Name.Defn = yyVAL.node
- yyVAL.node.Nname.Param.Ntype = t // TODO: check if nname already has an ntype
+ yyVAL.node.Nname.Name.Param.Ntype = t // TODO: check if nname already has an ntype
declare(yyVAL.node.Nname, PFUNC)
funchdr(yyVAL.node)
yyVAL.node.Func.Shortname = newfuncname(yyDollar[4].sym)
yyVAL.node.Nname = methodname1(yyVAL.node.Func.Shortname, rcvr.Right)
yyVAL.node.Nname.Name.Defn = yyVAL.node
- yyVAL.node.Nname.Param.Ntype = t
+ yyVAL.node.Nname.Name.Param.Ntype = t
yyVAL.node.Nname.Nointerface = nointerface
declare(yyVAL.node.Nname, PFUNC)