]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: separate typecheck more cleanly
authorRuss Cox <rsc@golang.org>
Mon, 21 Dec 2020 07:22:42 +0000 (02:22 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 22 Dec 2020 19:32:03 +0000 (19:32 +0000)
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>
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/walk.go

index 036a1e7491c82ae5f7603319ad38d5150f85b76b..46ae76d58d8f7231bfc591ace6dfcee4d7d99648 100644 (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)
index 343ad9d1d9b32dc2c1f0478a07ba4c26e57ea4cc..2a5ff3f5fda2d4a2eae6e1f9c526b1f26ce72903 100644 (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)
index 48cbd2505eaaa40a51daeadce3f004a3947e9854..0f6c7023f2855719ae2345aa1f4eb2d16a215955 100644 (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))
index 2d383ab49e974d4d402aff24535146e4f17a34ef..1aaa93fc3d4544ba9208a987f4ad13b95e1bb487 100644 (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())
        }
 }
 
index 7651bbca1052418f4988b31abc6ea43af35ef7cd..410155b3ea9d3f2b3c6ad427d722082eae464baf 100644 (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 {