mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: create/use noder2 transform functions for more node types
Pull out the transformation part of the typechecking functions for:
- assignment statements
- return statements
- send statements
- select statements
- type conversions
- normal function/method calls
- index operations
The transform functions are like the original typechecking functions,
but with all code removed related to:
- Detecting compile-time errors (already done by types2)
- Setting the actual type of existing nodes (already done based on
info from types2)
- Dealing with untyped constants
Moved all the transformation functions to a separate file, transform.go.
Continuing with the same pattern, we delay transforming a node if it has
any type params in its args, marking it with a typecheck flag of 3, and
do the actual transformation during stenciling.
Assignment statements are tricky, since their transformation must be
delayed if any of the left or right-hands-sides are delayed.
Still to do are:
- selector expressions (OXDOT)
- composite literal expressions (OCOMPLIT)
- builtin function calls
Change-Id: Ie608cadbbc69b40db0067a5536cf707dd974aacc
Reviewed-on: https://go-review.googlesource.com/c/go/+/304049
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
29ed12d4c7
commit
e7e0995cba
7 changed files with 650 additions and 157 deletions
|
|
@ -95,10 +95,9 @@ func (g *irgen) stencil() {
|
|||
copy(withRecv[1:], call.Args)
|
||||
call.Args = withRecv
|
||||
}
|
||||
// Do the typechecking of the Call now, which changes OCALL
|
||||
// Transform the Call now, which changes OCALL
|
||||
// to OCALLFUNC and does typecheckaste/assignconvfn.
|
||||
call.SetTypecheck(0)
|
||||
typecheck.Call(call)
|
||||
transformCall(call)
|
||||
modified = true
|
||||
})
|
||||
|
||||
|
|
@ -372,16 +371,36 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
// their instantiated type was known.
|
||||
if typecheck.IsCmp(x.Op()) {
|
||||
transformCompare(m.(*ir.BinaryExpr))
|
||||
m.SetTypecheck(1)
|
||||
} else if x.Op() == ir.OSLICE || x.Op() == ir.OSLICE3 {
|
||||
transformSlice(m.(*ir.SliceExpr))
|
||||
m.SetTypecheck(1)
|
||||
} else if x.Op() == ir.OADD {
|
||||
m = transformAdd(m.(*ir.BinaryExpr))
|
||||
m.SetTypecheck(1)
|
||||
} else {
|
||||
base.Fatalf("Unexpected node with Typecheck() == 3")
|
||||
switch x.Op() {
|
||||
case ir.OSLICE:
|
||||
case ir.OSLICE3:
|
||||
transformSlice(m.(*ir.SliceExpr))
|
||||
|
||||
case ir.OADD:
|
||||
m = transformAdd(m.(*ir.BinaryExpr))
|
||||
|
||||
case ir.OINDEX:
|
||||
transformIndex(m.(*ir.IndexExpr))
|
||||
|
||||
case ir.OAS2:
|
||||
as2 := m.(*ir.AssignListStmt)
|
||||
transformAssign(as2, as2.Lhs, as2.Rhs)
|
||||
|
||||
case ir.OAS:
|
||||
as := m.(*ir.AssignStmt)
|
||||
lhs, rhs := []ir.Node{as.X}, []ir.Node{as.Y}
|
||||
transformAssign(as, lhs, rhs)
|
||||
|
||||
case ir.OASOP:
|
||||
as := m.(*ir.AssignOpStmt)
|
||||
transformCheckAssign(as, as.X)
|
||||
|
||||
default:
|
||||
base.Fatalf("Unexpected node with Typecheck() == 3")
|
||||
}
|
||||
}
|
||||
m.SetTypecheck(1)
|
||||
}
|
||||
|
||||
switch x.Op() {
|
||||
|
|
@ -415,26 +434,25 @@ func (subst *subster) node(n ir.Node) ir.Node {
|
|||
case ir.OCALL:
|
||||
call := m.(*ir.CallExpr)
|
||||
if call.X.Op() == ir.OTYPE {
|
||||
// Do typechecking on a conversion, now that we
|
||||
// know the type argument.
|
||||
m.SetTypecheck(0)
|
||||
m = typecheck.Expr(m)
|
||||
// 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, now that we know the method
|
||||
// value is being called.
|
||||
// Redo the typechecking 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)
|
||||
call.SetTypecheck(0)
|
||||
typecheck.Call(call)
|
||||
transformCall(call)
|
||||
} else if call.X.Op() == ir.ODOT || call.X.Op() == ir.ODOTPTR {
|
||||
// An OXDOT for a generic receiver was resolved to
|
||||
// an access to a field which has a function
|
||||
// value. Typecheck the call to that function, now
|
||||
// value. Transform the call to that function, now
|
||||
// that the OXDOT was resolved.
|
||||
call.SetTypecheck(0)
|
||||
typecheck.Call(call)
|
||||
transformCall(call)
|
||||
} else if name := call.X.Name(); name != nil {
|
||||
switch name.BuiltinOp {
|
||||
case ir.OMAKE, ir.OREAL, ir.OIMAG, ir.OLEN, ir.OCAP, ir.OAPPEND:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue