summaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/closure.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/closure.go')
-rw-r--r--src/cmd/compile/internal/gc/closure.go32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
index 04f3e669e2..143e1969c7 100644
--- a/src/cmd/compile/internal/gc/closure.go
+++ b/src/cmd/compile/internal/gc/closure.go
@@ -5,19 +5,21 @@
package gc
import (
+ "cmd/compile/internal/syntax"
"cmd/compile/internal/types"
"fmt"
)
-// function literals aka closures
-func closurehdr(ntype *Node) {
- n := nod(OCLOSURE, nil, nil)
+func (p *noder) funcLit(expr *syntax.FuncLit) *Node {
+ ntype := p.typeExpr(expr.Type)
+
+ n := p.nod(expr, OCLOSURE, nil, nil)
n.Func.SetIsHiddenClosure(Curfn != nil)
n.Func.Ntype = ntype
n.Func.Depth = funcdepth
n.Func.Outerfunc = Curfn
- funchdr(n)
+ old := p.funchdr(n, expr.Pos())
// steal ntype's argument names and
// leave a fresh copy in their place.
@@ -25,8 +27,8 @@ func closurehdr(ntype *Node) {
// refer to the variables in the external
// function declared below; see walkclosure.
n.List.Set(ntype.List.Slice())
-
n.Rlist.Set(ntype.Rlist.Slice())
+
ntype.List.Set(nil)
ntype.Rlist.Set(nil)
for _, n1 := range n.List.Slice() {
@@ -48,23 +50,23 @@ func closurehdr(ntype *Node) {
}
ntype.Rlist.Append(nod(ODCLFIELD, name, n2.Right))
}
-}
-func closurebody(body []*Node) *Node {
+ body := p.stmts(expr.Body.List)
+
+ lineno = Ctxt.PosTable.XPos(expr.Body.Rbrace)
if len(body) == 0 {
body = []*Node{nod(OEMPTY, nil, nil)}
}
- func_ := Curfn
- func_.Nbody.Set(body)
- func_.Func.Endlineno = lineno
- funcbody(func_)
+ n.Nbody.Set(body)
+ n.Func.Endlineno = lineno
+ p.funcbody(n, expr.Body.Rbrace, old)
// closure-specific variables are hanging off the
// ordinary ones in the symbol table; see oldname.
// unhook them.
// make the list of pointers for the closure call.
- for _, v := range func_.Func.Cvars.Slice() {
+ for _, v := range n.Func.Cvars.Slice() {
// Unlink from v1; see comment in syntax.go type Param for these fields.
v1 := v.Name.Defn
v1.Name.Param.Innermost = v.Name.Param.Outer
@@ -100,7 +102,7 @@ func closurebody(body []*Node) *Node {
v.Name.Param.Outer = oldname(v.Sym)
}
- return func_
+ return n
}
func typecheckclosure(func_ *Node, top int) {
@@ -227,7 +229,11 @@ func makeclosure(func_ *Node) *Node {
xfunc.Nbody.Set(func_.Nbody.Slice())
xfunc.Func.Dcl = append(func_.Func.Dcl, xfunc.Func.Dcl...)
+ xfunc.Func.Parents = func_.Func.Parents
+ xfunc.Func.Marks = func_.Func.Marks
func_.Func.Dcl = nil
+ func_.Func.Parents = nil
+ func_.Func.Marks = nil
if xfunc.Nbody.Len() == 0 {
Fatalf("empty body - won't generate any code")
}