mirror of
https://github.com/golang/go
synced 2024-11-23 22:00:11 -07:00
cmd/compile/internal/gc: simplify ascompatte
Passes toolstash -cmp. Change-Id: Ibb51ccaf29ee97c3463543175c9ac7b85ea10a7f Reviewed-on: https://go-review.googlesource.com/37339 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
ba6e5776fd
commit
f7f3514bd8
@ -338,7 +338,7 @@ func walkstmt(n *Node) *Node {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
ll := ascompatte(n.Op, nil, false, Curfn.Type.Results(), n.List.Slice(), 1, &n.Ninit)
|
ll := ascompatte(nil, false, Curfn.Type.Results(), n.List.Slice(), 1, &n.Ninit)
|
||||||
n.List.Set(ll)
|
n.List.Set(ll)
|
||||||
|
|
||||||
case ORETJMP:
|
case ORETJMP:
|
||||||
@ -611,7 +611,7 @@ opswitch:
|
|||||||
}
|
}
|
||||||
n.Left = walkexpr(n.Left, init)
|
n.Left = walkexpr(n.Left, init)
|
||||||
walkexprlist(n.List.Slice(), init)
|
walkexprlist(n.List.Slice(), init)
|
||||||
ll := ascompatte(n.Op, n, n.Isddd, t.Params(), n.List.Slice(), 0, init)
|
ll := ascompatte(n, n.Isddd, t.Params(), n.List.Slice(), 0, init)
|
||||||
n.List.Set(reorder1(ll))
|
n.List.Set(reorder1(ll))
|
||||||
|
|
||||||
case OCALLFUNC:
|
case OCALLFUNC:
|
||||||
@ -644,7 +644,7 @@ opswitch:
|
|||||||
n.Left = walkexpr(n.Left, init)
|
n.Left = walkexpr(n.Left, init)
|
||||||
walkexprlist(n.List.Slice(), init)
|
walkexprlist(n.List.Slice(), init)
|
||||||
|
|
||||||
ll := ascompatte(n.Op, n, n.Isddd, t.Params(), n.List.Slice(), 0, init)
|
ll := ascompatte(n, n.Isddd, t.Params(), n.List.Slice(), 0, init)
|
||||||
n.List.Set(reorder1(ll))
|
n.List.Set(reorder1(ll))
|
||||||
|
|
||||||
case OCALLMETH:
|
case OCALLMETH:
|
||||||
@ -654,8 +654,8 @@ opswitch:
|
|||||||
}
|
}
|
||||||
n.Left = walkexpr(n.Left, init)
|
n.Left = walkexpr(n.Left, init)
|
||||||
walkexprlist(n.List.Slice(), init)
|
walkexprlist(n.List.Slice(), init)
|
||||||
ll := ascompatte(n.Op, n, false, t.Recvs(), []*Node{n.Left.Left}, 0, init)
|
ll := ascompatte(n, false, t.Recvs(), []*Node{n.Left.Left}, 0, init)
|
||||||
lr := ascompatte(n.Op, n, n.Isddd, t.Params(), n.List.Slice(), 0, init)
|
lr := ascompatte(n, n.Isddd, t.Params(), n.List.Slice(), 0, init)
|
||||||
ll = append(ll, lr...)
|
ll = append(ll, lr...)
|
||||||
n.Left.Left = nil
|
n.Left.Left = nil
|
||||||
ullmancalc(n.Left)
|
ullmancalc(n.Left)
|
||||||
@ -1737,162 +1737,82 @@ func ascompatet(op Op, nl Nodes, nr *Type) []*Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// package all the arguments that match a ... T parameter into a []T.
|
// package all the arguments that match a ... T parameter into a []T.
|
||||||
func mkdotargslice(lr0, nn []*Node, l *Field, fp int, init *Nodes, ddd *Node) []*Node {
|
func mkdotargslice(typ *Type, args []*Node, init *Nodes, ddd *Node) *Node {
|
||||||
esc := uint16(EscUnknown)
|
esc := uint16(EscUnknown)
|
||||||
if ddd != nil {
|
if ddd != nil {
|
||||||
esc = ddd.Esc
|
esc = ddd.Esc
|
||||||
}
|
}
|
||||||
|
|
||||||
tslice := typSlice(l.Type.Elem())
|
if len(args) == 0 {
|
||||||
|
n := nodnil()
|
||||||
var n *Node
|
n.Type = typ
|
||||||
if len(lr0) == 0 {
|
return n
|
||||||
n = nodnil()
|
|
||||||
n.Type = tslice
|
|
||||||
} else {
|
|
||||||
n = nod(OCOMPLIT, nil, typenod(tslice))
|
|
||||||
if ddd != nil && prealloc[ddd] != nil {
|
|
||||||
prealloc[n] = prealloc[ddd] // temporary to use
|
|
||||||
}
|
|
||||||
n.List.Set(lr0)
|
|
||||||
n.Esc = esc
|
|
||||||
n = typecheck(n, Erv)
|
|
||||||
if n.Type == nil {
|
|
||||||
Fatalf("mkdotargslice: typecheck failed")
|
|
||||||
}
|
|
||||||
n = walkexpr(n, init)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a := nod(OAS, nodarg(l, fp), n)
|
n := nod(OCOMPLIT, nil, typenod(typ))
|
||||||
nn = append(nn, convas(a, init))
|
if ddd != nil && prealloc[ddd] != nil {
|
||||||
return nn
|
prealloc[n] = prealloc[ddd] // temporary to use
|
||||||
}
|
|
||||||
|
|
||||||
// helpers for shape errors
|
|
||||||
func dumptypes(nl *Type, what string) string {
|
|
||||||
s := ""
|
|
||||||
for _, l := range nl.Fields().Slice() {
|
|
||||||
if s != "" {
|
|
||||||
s += ", "
|
|
||||||
}
|
|
||||||
s += fldconv(l, 0)
|
|
||||||
}
|
}
|
||||||
if s == "" {
|
n.List.Set(args)
|
||||||
s = fmt.Sprintf("[no arguments %s]", what)
|
n.Esc = esc
|
||||||
|
n = typecheck(n, Erv)
|
||||||
|
if n.Type == nil {
|
||||||
|
Fatalf("mkdotargslice: typecheck failed")
|
||||||
}
|
}
|
||||||
return s
|
n = walkexpr(n, init)
|
||||||
}
|
return n
|
||||||
|
|
||||||
func dumpnodetypes(l []*Node, what string) string {
|
|
||||||
s := ""
|
|
||||||
for _, r := range l {
|
|
||||||
if s != "" {
|
|
||||||
s += ", "
|
|
||||||
}
|
|
||||||
s += r.Type.String()
|
|
||||||
}
|
|
||||||
if s == "" {
|
|
||||||
s = fmt.Sprintf("[no arguments %s]", what)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check assign expression list to
|
// check assign expression list to
|
||||||
// a type list. called in
|
// a type list. called in
|
||||||
// return expr-list
|
// return expr-list
|
||||||
// func(expr-list)
|
// func(expr-list)
|
||||||
func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, init *Nodes) []*Node {
|
func ascompatte(call *Node, isddd bool, lhs *Type, rhs []*Node, fp int, init *Nodes) []*Node {
|
||||||
lr0 := lr
|
|
||||||
l, savel := iterFields(nl)
|
|
||||||
var r *Node
|
|
||||||
if len(lr) > 0 {
|
|
||||||
r = lr[0]
|
|
||||||
}
|
|
||||||
var nn []*Node
|
var nn []*Node
|
||||||
|
|
||||||
// f(g()) where g has multiple return values
|
// f(g()) where g has multiple return values
|
||||||
if r != nil && len(lr) <= 1 && r.Type.IsFuncArgStruct() {
|
if len(rhs) == 1 && rhs[0].Type.IsFuncArgStruct() {
|
||||||
// optimization - can do block copy
|
// optimization - can do block copy
|
||||||
if eqtypenoname(r.Type, nl) {
|
if eqtypenoname(rhs[0].Type, lhs) {
|
||||||
arg := nodarg(nl, fp)
|
nl := nodarg(lhs, fp)
|
||||||
r = nod(OCONVNOP, r, nil)
|
nr := nod(OCONVNOP, rhs[0], nil)
|
||||||
r.Type = arg.Type
|
nr.Type = nl.Type
|
||||||
nn = []*Node{convas(nod(OAS, arg, r), init)}
|
nn = []*Node{convas(nod(OAS, nl, nr), init)}
|
||||||
goto ret
|
goto ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// conversions involved.
|
// conversions involved.
|
||||||
// copy into temporaries.
|
// copy into temporaries.
|
||||||
var alist []*Node
|
var tmps []*Node
|
||||||
|
for _, nr := range rhs[0].Type.FieldSlice() {
|
||||||
for _, l := range r.Type.Fields().Slice() {
|
tmps = append(tmps, temp(nr.Type))
|
||||||
tmp := temp(l.Type)
|
|
||||||
alist = append(alist, tmp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a := nod(OAS2, nil, nil)
|
a := nod(OAS2, nil, nil)
|
||||||
a.List.Set(alist)
|
a.List.Set(tmps)
|
||||||
a.Rlist.Set(lr)
|
a.Rlist.Set(rhs)
|
||||||
a = typecheck(a, Etop)
|
a = typecheck(a, Etop)
|
||||||
a = walkstmt(a)
|
a = walkstmt(a)
|
||||||
init.Append(a)
|
init.Append(a)
|
||||||
lr = alist
|
|
||||||
r = lr[0]
|
rhs = tmps
|
||||||
l, savel = iterFields(nl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
// For each parameter (LHS), assign its corresponding argument (RHS).
|
||||||
if l != nil && l.Isddd {
|
// If there's a ... parameter (which is only valid as the final
|
||||||
// the ddd parameter must be last
|
// parameter) and this is not a ... call expression,
|
||||||
ll := savel.Next()
|
// then assign the remaining arguments as a slice.
|
||||||
|
for i, nl := range lhs.FieldSlice() {
|
||||||
if ll != nil {
|
var nr *Node
|
||||||
yyerror("... must be last argument")
|
if nl.Isddd && !isddd {
|
||||||
}
|
nr = mkdotargslice(nl.Type, rhs[i:], init, call.Right)
|
||||||
|
} else {
|
||||||
// special case --
|
nr = rhs[i]
|
||||||
// only if we are assigning a single ddd
|
|
||||||
// argument to a ddd parameter then it is
|
|
||||||
// passed through unencapsulated
|
|
||||||
if r != nil && len(lr) <= 1 && isddd && eqtype(l.Type, r.Type) {
|
|
||||||
a := nod(OAS, nodarg(l, fp), r)
|
|
||||||
a = convas(a, init)
|
|
||||||
nn = append(nn, a)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// normal case -- make a slice of all
|
|
||||||
// remaining arguments and pass it to
|
|
||||||
// the ddd parameter.
|
|
||||||
nn = mkdotargslice(lr, nn, l, fp, init, call.Right)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if l == nil || r == nil {
|
a := nod(OAS, nodarg(nl, fp), nr)
|
||||||
if l != nil || r != nil {
|
|
||||||
l1 := dumptypes(nl, "expected")
|
|
||||||
l2 := dumpnodetypes(lr0, "given")
|
|
||||||
if l != nil {
|
|
||||||
yyerror("not enough arguments to %v\n\t%s\n\t%s", op, l1, l2)
|
|
||||||
} else {
|
|
||||||
yyerror("too many arguments to %v\n\t%s\n\t%s", op, l1, l2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
a := nod(OAS, nodarg(l, fp), r)
|
|
||||||
a = convas(a, init)
|
a = convas(a, init)
|
||||||
nn = append(nn, a)
|
nn = append(nn, a)
|
||||||
|
|
||||||
l = savel.Next()
|
|
||||||
r = nil
|
|
||||||
lr = lr[1:]
|
|
||||||
if len(lr) > 0 {
|
|
||||||
r = lr[0]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
|
Loading…
Reference in New Issue
Block a user