package ir
import (
- "cmd/compile/internal/base"
"cmd/internal/src"
)
-// A Node may implement the Orig and SetOrig method to
-// maintain a pointer to the "unrewritten" form of a Node.
-// If a Node does not implement OrigNode, it is its own Orig.
+// Orig returns n.
//
-// Note that both SepCopy and Copy have definitions compatible
-// with a Node that does not implement OrigNode: such a Node
-// is its own Orig, and in that case, that's what both want to return
-// anyway (SepCopy unconditionally, and Copy only when the input
-// is its own Orig as well, but if the output does not implement
-// OrigNode, then neither does the input, making the condition true).
-type OrigNode interface {
- Node
- Orig() Node
- SetOrig(Node)
-}
-
-// origNode may be embedded into a Node to make it implement OrigNode.
-type origNode struct {
- orig Node `mknode:"-"`
-}
-
-func (n *origNode) Orig() Node { return n.orig }
-func (n *origNode) SetOrig(o Node) { n.orig = o }
-
-// Orig returns the “original” node for n.
-// If n implements OrigNode, Orig returns n.Orig().
-// Otherwise Orig returns n itself.
+// TODO(mdempsky): Remove.
func Orig(n Node) Node {
- if n, ok := n.(OrigNode); ok {
- o := n.Orig()
- if o == nil {
- Dump("Orig nil", n)
- base.Fatalf("Orig returned nil")
- }
- return o
- }
return n
}
-// SepCopy returns a separate shallow copy of n,
-// breaking any Orig link to any other nodes.
+// SepCopy returns a shallow copy of n.
+//
+// TODO(mdempsky): Replace with Copy.
func SepCopy(n Node) Node {
- n = n.copy()
- if n, ok := n.(OrigNode); ok {
- n.SetOrig(n)
- }
- return n
+ return n.copy()
}
// Copy returns a shallow copy of n.
-// If Orig(n) == n, then Orig(Copy(n)) == the copy.
-// Otherwise the Orig link is preserved as well.
-//
-// The specific semantics surrounding Orig are subtle but right for most uses.
-// See issues #26855 and #27765 for pitfalls.
func Copy(n Node) Node {
- c := n.copy()
- if n, ok := n.(OrigNode); ok && n.Orig() == n {
- c.(OrigNode).SetOrig(c)
- }
- return c
+ return n.copy()
}
// DeepCopy returns a “deep” copy of n, with its entire structure copied
// A CallExpr is a function call X(Args).
type CallExpr struct {
miniExpr
- origNode
X Node
Args Nodes
RType Node `mknode:"-"` // see reflectdata/helpers.go
func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
n := &CallExpr{X: fun}
n.pos = pos
- n.orig = n
n.SetOp(op)
n.Args = args
return n
// Before type-checking, the type is Ntype.
type CompLitExpr struct {
miniExpr
- origNode
List Nodes // initialized values
RType Node `mknode:"-"` // *runtime._type for OMAPLIT map types
Prealloc *Name
if typ != nil {
n.SetType(typ)
}
- n.orig = n
return n
}