mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +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
3 changed files with 38 additions and 93 deletions
|
@ -22,7 +22,18 @@ func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.F
|
|||
fn.Nname.Func = fn
|
||||
fn.Nname.Defn = fn
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -91,20 +102,13 @@ func Export(n *ir.Name) {
|
|||
// and declare the arguments.
|
||||
// called in extern-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
|
||||
funcStack = append(funcStack, funcStackEnt{ir.CurFunc, DeclContext})
|
||||
ir.CurFunc = fn
|
||||
DeclContext = ir.PAUTO
|
||||
|
||||
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.
|
||||
|
@ -190,46 +194,44 @@ type funcStackEnt struct {
|
|||
dclcontext ir.Class
|
||||
}
|
||||
|
||||
func funcarg(n *ir.Field, ctxt ir.Class) {
|
||||
if n.Sym == nil {
|
||||
return
|
||||
func declareParams(ctxt ir.Class, l []*ir.Field) []*types.Field {
|
||||
fields := make([]*types.Field, len(l))
|
||||
for i, n := range l {
|
||||
fields[i] = declareParam(ctxt, i, n)
|
||||
}
|
||||
|
||||
name := ir.NewNameAt(n.Pos, n.Sym)
|
||||
n.Decl = name
|
||||
Declare(name, ctxt)
|
||||
return fields
|
||||
}
|
||||
|
||||
func funcargs(nt *ir.FuncType) {
|
||||
if nt.Op() != ir.OTFUNC {
|
||||
base.Fatalf("funcargs %v", nt.Op())
|
||||
}
|
||||
func declareParam(ctxt ir.Class, i int, param *ir.Field) *types.Field {
|
||||
f := types.NewField(param.Pos, param.Sym, param.Type)
|
||||
f.SetIsDDD(param.IsDDD)
|
||||
|
||||
// declare the receiver and in arguments.
|
||||
if nt.Recv != nil {
|
||||
funcarg(nt.Recv, ir.PPARAM)
|
||||
}
|
||||
for _, n := range nt.Params {
|
||||
funcarg(n, ir.PPARAM)
|
||||
}
|
||||
|
||||
// declare the out arguments.
|
||||
for i, n := range nt.Results {
|
||||
if n.Sym == nil {
|
||||
sym := param.Sym
|
||||
if ctxt == ir.PPARAMOUT {
|
||||
if sym == nil {
|
||||
// Name so that escape analysis can track it. ~r stands for 'result'.
|
||||
n.Sym = LookupNum("~r", i)
|
||||
} else if n.Sym.IsBlank() {
|
||||
sym = LookupNum("~r", i)
|
||||
} else if sym.IsBlank() {
|
||||
// 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
|
||||
// func f() (_ int)
|
||||
// func g() int
|
||||
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
||||
// 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 {
|
||||
|
|
|
@ -3,56 +3,3 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
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:
|
||||
return n
|
||||
|
||||
case ir.OTFUNC:
|
||||
n := n.(*ir.FuncType)
|
||||
return tcFuncType(n)
|
||||
|
||||
// type or expr
|
||||
case ir.ODEREF:
|
||||
n := n.(*ir.StarExpr)
|
||||
|
|
Loading…
Reference in a new issue