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:
Dan Scales 2021-03-24 14:50:02 -07:00
parent 374b190475
commit b587b050ca
5 changed files with 342 additions and 51 deletions

View file

@ -81,8 +81,8 @@ func Binary(pos src.XPos, op ir.Op, typ *types.Type, x, y ir.Node) ir.Node {
n.SetTypecheck(3)
return n
}
n1 := transformAdd(n)
return typed(typ, n1)
typed(typ, n)
return transformAdd(n)
default:
return typed(x.Type(), ir.NewBinaryExpr(pos, op, x, y))
}
@ -99,9 +99,8 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
// the type.
return typed(typ, n)
}
n1 := transformConvCall(n)
n1.SetTypecheck(1)
return n1
typed(typ, n)
return transformConvCall(n)
}
if fun, ok := fun.(*ir.Name); ok && fun.BuiltinOp != 0 {
@ -133,12 +132,8 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
}
}
switch fun.BuiltinOp {
case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN:
return typecheck.Stmt(n)
default:
return typecheck.Expr(n)
}
typed(typ, n)
return transformBuiltin(n)
}
// Add information, now that we know that fun is actually being called.
@ -176,8 +171,8 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
if fun.Op() != ir.OFUNCINST {
// If no type params, do the normal call transformations. This
// will convert OCALL to OCALLFUNC.
transformCall(n)
typed(typ, n)
transformCall(n)
return n
}
@ -195,8 +190,9 @@ func Compare(pos src.XPos, typ *types.Type, op ir.Op, x, y ir.Node) ir.Node {
n.SetTypecheck(3)
return n
}
typed(typ, n)
transformCompare(n)
return typed(typ, n)
return n
}
func Deref(pos src.XPos, x ir.Node) *ir.StarExpr {
@ -291,8 +287,9 @@ func Slice(pos src.XPos, typ *types.Type, x, low, high, max ir.Node) ir.Node {
n.SetTypecheck(3)
return n
}
typed(typ, n)
transformSlice(n)
return typed(typ, n)
return n
}
func Unary(pos src.XPos, op ir.Op, x ir.Node) ir.Node {