1
0
mirror of https://github.com/golang/go synced 2024-09-28 18:04:28 -06:00

[dev.regabi] cmd/compile: separate typecheck more cleanly

Abstract the typecheck API a bit more so that it is
easier to move into a new package.

Change-Id: Ia0a0146151fa7f6073113e68a2c3f6e42a5d0ad8
Reviewed-on: https://go-review.googlesource.com/c/go/+/279303
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-12-21 02:22:42 -05:00
parent 7c8f5356ab
commit 3b12c6dc08
5 changed files with 47 additions and 17 deletions

View File

@ -816,7 +816,7 @@ func eqstring(s, t ir.Node) (eqlen *ir.BinaryExpr, eqmem *ir.CallExpr) {
fn := syslook("memequal")
fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, []ir.Node{sptr, tptr, ir.Copy(slen)})
call = typecheck(call, ctxExpr|ctxMultiOK).(*ir.CallExpr)
TypecheckCall(call)
cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, slen, tlen)
cmp = typecheck(cmp, ctxExpr).(*ir.BinaryExpr)
@ -853,7 +853,7 @@ func eqinterface(s, t ir.Node) (eqtab *ir.BinaryExpr, eqdata *ir.CallExpr) {
tdata.SetTypecheck(1)
call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, []ir.Node{stab, sdata, tdata})
call = typecheck(call, ctxExpr|ctxMultiOK).(*ir.CallExpr)
TypecheckCall(call)
cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, stab, ttab)
cmp = typecheck(cmp, ctxExpr).(*ir.BinaryExpr)

View File

@ -212,6 +212,10 @@ func Main(archInit func(*Arch)) {
Target = new(ir.Package)
NeedFuncSym = makefuncsym
NeedITab = func(t, iface *types.Type) { itabname(t, iface) }
NeedRuntimeType = addsignat // TODO(rsc): typenamesym for lock?
// initialize types package
// (we need to do this to break dependencies that otherwise
// would lead to import cycles)

View File

@ -309,7 +309,7 @@ func assignop(src, dst *types.Type) (ir.Op, string) {
// us to de-virtualize calls through this
// type/interface pair later. See peekitabs in reflect.go
if isdirectiface(src) && !dst.IsEmptyInterface() {
itabname(src, dst)
NeedITab(src, dst)
}
return ir.OCONVIFACE, ""
@ -1011,6 +1011,7 @@ func adddot(n *ir.SelectorExpr) *ir.SelectorExpr {
for c := len(path) - 1; c >= 0; c-- {
dot := nodSym(ir.ODOT, n.Left(), path[c].field.Sym)
dot.SetImplicit(true)
dot.SetType(path[c].field.Type)
n.SetLeft(dot)
}
case ambig:
@ -1240,8 +1241,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
if !instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !isifacemethod(method.Type) && !(thearch.LinkArch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) {
// generate tail call: adjust pointer receiver and jump to embedded method.
left := dot.Left() // skip final .M
// TODO(mdempsky): Remove dependency on dotlist.
if !dotlist[0].field.Type.IsPtr() {
if !left.Type().IsPtr() {
left = nodAddr(left)
}
as := ir.Nod(ir.OAS, nthis, convnop(left, rcvr))

View File

@ -14,6 +14,37 @@ import (
"strings"
)
var (
NeedFuncSym = func(*types.Sym) {}
NeedITab = func(t, itype *types.Type) {}
NeedRuntimeType = func(*types.Type) {}
)
func TypecheckAssignExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr|ctxAssign) }
func TypecheckExpr(n ir.Node) ir.Node { return typecheck(n, ctxExpr) }
func TypecheckStmt(n ir.Node) ir.Node { return typecheck(n, ctxStmt) }
func TypecheckExprs(exprs []ir.Node) { typecheckslice(exprs, ctxExpr) }
func TypecheckStmts(stmts []ir.Node) { typecheckslice(stmts, ctxStmt) }
func TypecheckCall(call *ir.CallExpr) {
t := call.X.Type()
if t == nil {
panic("misuse of Call")
}
ctx := ctxStmt
if t.NumResults() > 0 {
ctx = ctxExpr | ctxMultiOK
}
if typecheck(call, ctx) != call {
panic("bad typecheck")
}
}
func TypecheckCallee(n ir.Node) ir.Node {
return typecheck(n, ctxExpr|ctxCallee)
}
// To enable tracing support (-t flag), set enableTrace to true.
const enableTrace = false
@ -2384,7 +2415,7 @@ func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
// to make sure to generate wrappers for anonymous
// receiver types too.
if mt.Sym() == nil {
addsignat(t)
NeedRuntimeType(t)
}
}
@ -2417,7 +2448,7 @@ func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
// Issue 25065. Make sure that we emit the symbol for a local method.
if base.Ctxt.Flag_dynlink && !inimport && (t.Sym() == nil || t.Sym().Pkg == types.LocalPkg) {
makefuncsym(me.FuncName_.Sym())
NeedFuncSym(me.FuncName_.Sym())
}
return me
@ -3451,7 +3482,7 @@ func typecheckfunc(n *ir.Func) {
}
if base.Ctxt.Flag_dynlink && !inimport && n.Nname != nil {
makefuncsym(n.Sym())
NeedFuncSym(n.Sym())
}
}

View File

@ -2520,15 +2520,10 @@ func vmkcall(fn ir.Node, t *types.Type, init *ir.Nodes, va []ir.Node) *ir.CallEx
base.Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va))
}
call := ir.Nod(ir.OCALL, fn, nil)
call.PtrList().Set(va)
ctx := ctxStmt
if fn.Type().NumResults() > 0 {
ctx = ctxExpr | ctxMultiOK
}
r1 := typecheck(call, ctx)
r1.SetType(t)
return walkexpr(r1, init).(*ir.CallExpr)
call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, va)
TypecheckCall(call)
call.SetType(t)
return walkexpr(call, init).(*ir.CallExpr)
}
func mkcall(name string, t *types.Type, init *ir.Nodes, args ...ir.Node) *ir.CallExpr {