mirror of
https://github.com/golang/go.git
synced 2025-05-28 19:02:22 +00:00
cmd/compile/internal/typecheck: simplify DeclFunc
This CL reworks DeclFunc so that we no longer need to internally create an ir.FuncType. The next CL will remove ir.FuncType entirely. Change-Id: I1c02b1b0c35221f2448d6d3ab35cb327a2da40e4 Reviewed-on: https://go-review.googlesource.com/c/go/+/403935 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
5073c1c740
commit
a7ab208cbb
@ -22,7 +22,18 @@ func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.F
|
|||||||
fn.Nname.Func = fn
|
fn.Nname.Func = fn
|
||||||
fn.Nname.Defn = fn
|
fn.Nname.Defn = fn
|
||||||
ir.MarkFunc(fn.Nname)
|
ir.MarkFunc(fn.Nname)
|
||||||
StartFuncBody(fn, recv, params, results)
|
StartFuncBody(fn)
|
||||||
|
|
||||||
|
var recv1 *types.Field
|
||||||
|
if recv != nil {
|
||||||
|
recv1 = declareParam(ir.PPARAM, -1, recv)
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := types.NewSignature(types.LocalPkg, recv1, nil, declareParams(ir.PPARAM, params), declareParams(ir.PPARAMOUT, results))
|
||||||
|
checkdupfields("argument", typ.Recvs().FieldSlice(), typ.Params().FieldSlice(), typ.Results().FieldSlice())
|
||||||
|
fn.Nname.SetType(typ)
|
||||||
|
fn.Nname.SetTypecheck(1)
|
||||||
|
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,20 +102,13 @@ func Export(n *ir.Name) {
|
|||||||
// and declare the arguments.
|
// and declare the arguments.
|
||||||
// called in extern-declaration context
|
// called in extern-declaration context
|
||||||
// returns in auto-declaration context.
|
// returns in auto-declaration context.
|
||||||
func StartFuncBody(fn *ir.Func, recv *ir.Field, params, results []*ir.Field) {
|
func StartFuncBody(fn *ir.Func) {
|
||||||
// change the declaration context from extern to auto
|
// change the declaration context from extern to auto
|
||||||
funcStack = append(funcStack, funcStackEnt{ir.CurFunc, DeclContext})
|
funcStack = append(funcStack, funcStackEnt{ir.CurFunc, DeclContext})
|
||||||
ir.CurFunc = fn
|
ir.CurFunc = fn
|
||||||
DeclContext = ir.PAUTO
|
DeclContext = ir.PAUTO
|
||||||
|
|
||||||
types.Markdcl()
|
types.Markdcl()
|
||||||
|
|
||||||
tfn := ir.NewFuncType(base.Pos, recv, params, results)
|
|
||||||
funcargs(tfn)
|
|
||||||
|
|
||||||
tfn = tcFuncType(tfn)
|
|
||||||
fn.Nname.SetType(tfn.Type())
|
|
||||||
fn.Nname.SetTypecheck(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish the body.
|
// finish the body.
|
||||||
@ -190,46 +194,44 @@ type funcStackEnt struct {
|
|||||||
dclcontext ir.Class
|
dclcontext ir.Class
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcarg(n *ir.Field, ctxt ir.Class) {
|
func declareParams(ctxt ir.Class, l []*ir.Field) []*types.Field {
|
||||||
if n.Sym == nil {
|
fields := make([]*types.Field, len(l))
|
||||||
return
|
for i, n := range l {
|
||||||
|
fields[i] = declareParam(ctxt, i, n)
|
||||||
}
|
}
|
||||||
|
return fields
|
||||||
name := ir.NewNameAt(n.Pos, n.Sym)
|
|
||||||
n.Decl = name
|
|
||||||
Declare(name, ctxt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcargs(nt *ir.FuncType) {
|
func declareParam(ctxt ir.Class, i int, param *ir.Field) *types.Field {
|
||||||
if nt.Op() != ir.OTFUNC {
|
f := types.NewField(param.Pos, param.Sym, param.Type)
|
||||||
base.Fatalf("funcargs %v", nt.Op())
|
f.SetIsDDD(param.IsDDD)
|
||||||
}
|
|
||||||
|
|
||||||
// declare the receiver and in arguments.
|
sym := param.Sym
|
||||||
if nt.Recv != nil {
|
if ctxt == ir.PPARAMOUT {
|
||||||
funcarg(nt.Recv, ir.PPARAM)
|
if sym == nil {
|
||||||
}
|
|
||||||
for _, n := range nt.Params {
|
|
||||||
funcarg(n, ir.PPARAM)
|
|
||||||
}
|
|
||||||
|
|
||||||
// declare the out arguments.
|
|
||||||
for i, n := range nt.Results {
|
|
||||||
if n.Sym == nil {
|
|
||||||
// Name so that escape analysis can track it. ~r stands for 'result'.
|
// Name so that escape analysis can track it. ~r stands for 'result'.
|
||||||
n.Sym = LookupNum("~r", i)
|
sym = LookupNum("~r", i)
|
||||||
} else if n.Sym.IsBlank() {
|
} else if sym.IsBlank() {
|
||||||
// Give it a name so we can assign to it during return. ~b stands for 'blank'.
|
// Give it a name so we can assign to it during return. ~b stands for 'blank'.
|
||||||
// The name must be different from ~r above because if you have
|
// The name must be different from ~r above because if you have
|
||||||
// func f() (_ int)
|
// func f() (_ int)
|
||||||
// func g() int
|
// func g() int
|
||||||
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
||||||
// So the two cases must be distinguished.
|
// So the two cases must be distinguished.
|
||||||
n.Sym = LookupNum("~b", i)
|
sym = LookupNum("~b", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
funcarg(n, ir.PPARAMOUT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sym != nil {
|
||||||
|
name := ir.NewNameAt(param.Pos, sym)
|
||||||
|
name.SetType(f.Type)
|
||||||
|
name.SetTypecheck(1)
|
||||||
|
Declare(name, ctxt)
|
||||||
|
|
||||||
|
f.Nname = name
|
||||||
|
}
|
||||||
|
|
||||||
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func Temp(t *types.Type) *ir.Name {
|
func Temp(t *types.Type) *ir.Name {
|
||||||
|
@ -3,56 +3,3 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package typecheck
|
package typecheck
|
||||||
|
|
||||||
import (
|
|
||||||
"cmd/compile/internal/base"
|
|
||||||
"cmd/compile/internal/ir"
|
|
||||||
"cmd/compile/internal/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// tcFuncType typechecks an OTFUNC node.
|
|
||||||
func tcFuncType(n *ir.FuncType) *ir.FuncType {
|
|
||||||
misc := func(f *types.Field, nf *ir.Field) {
|
|
||||||
f.SetIsDDD(nf.IsDDD)
|
|
||||||
if nf.Decl != nil {
|
|
||||||
nf.Decl.SetType(f.Type)
|
|
||||||
f.Nname = nf.Decl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lno := base.Pos
|
|
||||||
|
|
||||||
var recv *types.Field
|
|
||||||
if n.Recv != nil {
|
|
||||||
recv = tcField(n.Recv, misc)
|
|
||||||
}
|
|
||||||
|
|
||||||
t := types.NewSignature(types.LocalPkg, recv, nil, tcFields(n.Params, misc), tcFields(n.Results, misc))
|
|
||||||
checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
|
|
||||||
|
|
||||||
base.Pos = lno
|
|
||||||
|
|
||||||
n.SetOTYPE(t)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// tcField typechecks a generic Field.
|
|
||||||
// misc can be provided to handle specialized typechecking.
|
|
||||||
func tcField(n *ir.Field, misc func(*types.Field, *ir.Field)) *types.Field {
|
|
||||||
base.Pos = n.Pos
|
|
||||||
f := types.NewField(n.Pos, n.Sym, n.Type)
|
|
||||||
if misc != nil {
|
|
||||||
misc(f, n)
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// tcFields typechecks a slice of generic Fields.
|
|
||||||
// misc can be provided to handle specialized typechecking.
|
|
||||||
func tcFields(l []*ir.Field, misc func(*types.Field, *ir.Field)) []*types.Field {
|
|
||||||
fields := make([]*types.Field, len(l))
|
|
||||||
for i, n := range l {
|
|
||||||
fields[i] = tcField(n, misc)
|
|
||||||
}
|
|
||||||
return fields
|
|
||||||
}
|
|
||||||
|
@ -473,10 +473,6 @@ func typecheck1(n ir.Node, top int) ir.Node {
|
|||||||
case ir.OTYPE:
|
case ir.OTYPE:
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OTFUNC:
|
|
||||||
n := n.(*ir.FuncType)
|
|
||||||
return tcFuncType(n)
|
|
||||||
|
|
||||||
// type or expr
|
// type or expr
|
||||||
case ir.ODEREF:
|
case ir.ODEREF:
|
||||||
n := n.(*ir.StarExpr)
|
n := n.(*ir.StarExpr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user