mirror of
https://github.com/golang/go
synced 2024-11-26 02:07:57 -07: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:
parent
7c8f5356ab
commit
3b12c6dc08
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user