mirror of
https://github.com/golang/go
synced 2024-11-11 20:20:23 -07:00
[dev.regabi] cmd/compile: adjustments to Copy and DeepCopy
DeepCopy is not called DeepSepCopy, so it should use Copy, not SepCopy. Also, the old gc.treecopy, which became ir.DeepCopy, only copied the Left, Right, and List fields - not Init, Rlist, Body - and I didn't notice when I moved it over. A general utility function should of course copy the whole node, so do that. Finally, the semantics of Copy should not depend on whether a particular child node is held directly in a field or in a slice, so make Copy duplicate the slice backing arrays as well. (Logically, those backing arrays are part of the node storage.) Passes buildall w/ toolstash -cmp. Change-Id: I18fbe3f2b40078f566ed6370684d5585052b36a1 Reviewed-on: https://go-review.googlesource.com/c/go/+/275309 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
99ecfcae31
commit
989a3f5041
@ -61,9 +61,33 @@ func Copy(n Node) Node {
|
||||
if n, ok := n.(OrigNode); ok && n.Orig() == n {
|
||||
copy.(OrigNode).SetOrig(copy)
|
||||
}
|
||||
|
||||
// Copy lists so that updates to n.List[0]
|
||||
// don't affect copy.List[0] and vice versa,
|
||||
// same as updates to Left and Right.
|
||||
// TODO(rsc): Eventually the Node implementations will need to do this.
|
||||
if l := copy.List(); l.Len() > 0 {
|
||||
copy.SetList(copyList(l))
|
||||
}
|
||||
if l := copy.Rlist(); l.Len() > 0 {
|
||||
copy.SetRlist(copyList(l))
|
||||
}
|
||||
if l := copy.Init(); l.Len() > 0 {
|
||||
copy.SetInit(copyList(l))
|
||||
}
|
||||
if l := copy.Body(); l.Len() > 0 {
|
||||
copy.SetBody(copyList(l))
|
||||
}
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
func copyList(x Nodes) Nodes {
|
||||
out := make([]Node, x.Len())
|
||||
copy(out, x.Slice())
|
||||
return AsNodes(out)
|
||||
}
|
||||
|
||||
// A Node can implement DeepCopyNode to provide a custom implementation
|
||||
// of DeepCopy. If the compiler only needs access to a Node's structure during
|
||||
// DeepCopy, then a Node can implement DeepCopyNode instead of providing
|
||||
@ -94,10 +118,15 @@ func DeepCopy(pos src.XPos, n Node) Node {
|
||||
|
||||
switch n.Op() {
|
||||
default:
|
||||
m := SepCopy(n)
|
||||
m := Copy(n)
|
||||
m.SetLeft(DeepCopy(pos, n.Left()))
|
||||
m.SetRight(DeepCopy(pos, n.Right()))
|
||||
m.PtrList().Set(deepCopyList(pos, n.List().Slice()))
|
||||
// deepCopyList instead of DeepCopyList
|
||||
// because Copy already copied all these slices.
|
||||
deepCopyList(pos, m.PtrList().Slice())
|
||||
deepCopyList(pos, m.PtrRlist().Slice())
|
||||
deepCopyList(pos, m.PtrInit().Slice())
|
||||
deepCopyList(pos, m.PtrBody().Slice())
|
||||
if pos.IsKnown() {
|
||||
m.SetPos(pos)
|
||||
}
|
||||
@ -118,10 +147,18 @@ func DeepCopy(pos src.XPos, n Node) Node {
|
||||
}
|
||||
}
|
||||
|
||||
func deepCopyList(pos src.XPos, list []Node) []Node {
|
||||
// DeepCopyList returns a list of deep copies (using DeepCopy) of the nodes in list.
|
||||
func DeepCopyList(pos src.XPos, list []Node) []Node {
|
||||
var out []Node
|
||||
for _, n := range list {
|
||||
out = append(out, DeepCopy(pos, n))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// deepCopyList edits list to point to deep copies of its elements.
|
||||
func deepCopyList(pos src.XPos, list []Node) {
|
||||
for i, n := range list {
|
||||
list[i] = DeepCopy(pos, n)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user