mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: add transform functions for OXDOT and builtins
Pull out the tranformation part of the typechecking functions for: - selector expressions (OXDOT) - calls to builtin functions (which go through the typechecker loop twice, once for the call and once for each different kind of builtin). Some of the transformation functions create new nodes that should have the same type as the original node. For consistency, now each of the transformation functions requires that the node passed in has its type and typecheck flag set. If the transformation function replaces or adds new nodes, it will set the type and typecheck flag for those new nodes. As usual, passes all the gotests, even with -G=3 enabled. Change-Id: Ic48b0ce5f58425f4a358afa78315bfc7c28066c4 Reviewed-on: https://go-review.googlesource.com/c/go/+/304729 Trust: Dan Scales <danscales@google.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
374b190475
commit
b587b050ca
5 changed files with 342 additions and 51 deletions
|
|
@ -369,12 +369,12 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
if x.Typecheck() == 3 {
|
||||
// These are nodes whose transforms were delayed until
|
||||
// their instantiated type was known.
|
||||
m.SetTypecheck(1)
|
||||
if typecheck.IsCmp(x.Op()) {
|
||||
transformCompare(m.(*ir.BinaryExpr))
|
||||
} else {
|
||||
switch x.Op() {
|
||||
case ir.OSLICE:
|
||||
case ir.OSLICE3:
|
||||
case ir.OSLICE, ir.OSLICE3:
|
||||
transformSlice(m.(*ir.SliceExpr))
|
||||
|
||||
case ir.OADD:
|
||||
|
|
@ -400,7 +400,6 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
base.Fatalf("Unexpected node with Typecheck() == 3")
|
||||
}
|
||||
}
|
||||
m.SetTypecheck(1)
|
||||
}
|
||||
|
||||
switch x.Op() {
|
||||
|
|
@ -421,15 +420,18 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
}
|
||||
|
||||
case ir.OXDOT:
|
||||
// A method value/call via a type param will have been left as an
|
||||
// OXDOT. When we see this during stenciling, finish the
|
||||
// typechecking, now that we have the instantiated receiver type.
|
||||
// We need to do this now, since the access/selection to the
|
||||
// method for the real type is very different from the selection
|
||||
// for the type param.
|
||||
m.SetTypecheck(0)
|
||||
// m will transform to an OCALLPART
|
||||
typecheck.Expr(m)
|
||||
// A method value/call via a type param will have been
|
||||
// left as an OXDOT. When we see this during stenciling,
|
||||
// finish the transformation, now that we have the
|
||||
// instantiated receiver type. We need to do this now,
|
||||
// since the access/selection to the method for the real
|
||||
// type is very different from the selection for the type
|
||||
// param. m will be transformed to an OCALLPART node. It
|
||||
// will be transformed to an ODOTMETH or ODOTINTER node if
|
||||
// we find in the OCALL case below that the method value
|
||||
// is actually called.
|
||||
transformDot(m.(*ir.SelectorExpr), false)
|
||||
m.SetTypecheck(1)
|
||||
|
||||
case ir.OCALL:
|
||||
call := m.(*ir.CallExpr)
|
||||
|
|
@ -437,15 +439,12 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
// Transform the conversion, now that we know the
|
||||
// type argument.
|
||||
m = transformConvCall(m.(*ir.CallExpr))
|
||||
m.SetTypecheck(1)
|
||||
} else if call.X.Op() == ir.OCALLPART {
|
||||
// Redo the typechecking of OXDOT, now that we
|
||||
// Redo the transformation of OXDOT, now that we
|
||||
// know the method value is being called. Then
|
||||
// transform the call.
|
||||
call.X.(*ir.SelectorExpr).SetOp(ir.OXDOT)
|
||||
call.X.SetTypecheck(0)
|
||||
call.X.SetType(nil)
|
||||
typecheck.Callee(call.X)
|
||||
transformDot(call.X.(*ir.SelectorExpr), true)
|
||||
transformCall(call)
|
||||
} else if call.X.Op() == ir.ODOT || call.X.Op() == ir.ODOTPTR {
|
||||
// An OXDOT for a generic receiver was resolved to
|
||||
|
|
@ -456,11 +455,9 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
} else if name := call.X.Name(); name != nil {
|
||||
switch name.BuiltinOp {
|
||||
case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OLEN, ir.OCAP, ir.OAPPEND:
|
||||
// Call old typechecker (to do any
|
||||
// transformations) now that we know the
|
||||
// type of the args.
|
||||
m.SetTypecheck(0)
|
||||
m = typecheck.Expr(m)
|
||||
// Transform these builtins now that we
|
||||
// know the type of the args.
|
||||
m = transformBuiltin(call)
|
||||
default:
|
||||
base.FatalfAt(call.Pos(), "Unexpected builtin op")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue