Commit 268c3187 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: move substAny to type.go

substAny needs access to many internal details
of gc.Type. substArgTypes comes along for the ride.

Change-Id: I430a4edfd54a1266522f7a9818e5e7b5da72479c
Reviewed-on: https://go-review.googlesource.com/21250Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent 0a85be57
......@@ -1076,100 +1076,6 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node {
return r
}
// substArgTypes substitutes the given list of types for
// successive occurrences of the "any" placeholder in the
// type syntax expression n.Type.
// The result of substArgTypes MUST be assigned back to old, e.g.
// n.Left = substArgTypes(n.Left, t1, t2)
func substArgTypes(old *Node, types ...*Type) *Node {
n := *old // make shallow copy
for _, t := range types {
dowidth(t)
}
n.Type = substAny(n.Type, &types)
if len(types) > 0 {
Fatalf("substArgTypes: too many argument types")
}
return &n
}
// substAny walks t, replacing instances of "any" with successive
// elements removed from types. It returns the substituted type.
func substAny(t *Type, types *[]*Type) *Type {
if t == nil {
return nil
}
switch t.Etype {
default:
// Leave the type unchanged.
case TANY:
if len(*types) == 0 {
Fatalf("substArgTypes: not enough argument types")
}
t = (*types)[0]
*types = (*types)[1:]
case TPTR32, TPTR64, TCHAN, TARRAY:
elem := substAny(t.Type, types)
if elem != t.Type {
t = t.Copy()
t.Type = elem
}
case TMAP:
key := substAny(t.Down, types)
val := substAny(t.Type, types)
if key != t.Down || val != t.Type {
t = t.Copy()
t.Down = key
t.Type = val
}
case TFUNC:
recvs := substAny(t.Recvs(), types)
params := substAny(t.Params(), types)
results := substAny(t.Results(), types)
if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
// Note that this code has to be aware of the
// representation underlying Recvs/Results/Params.
if recvs == t.Recvs() {
recvs = recvs.Copy()
}
if results == t.Results() {
results = results.Copy()
}
t = t.Copy()
*t.RecvsP() = recvs
*t.ResultsP() = results
*t.ParamsP() = params
}
case TSTRUCT:
fields := t.FieldSlice()
var nfs []*Field
for i, f := range fields {
nft := substAny(f.Type, types)
if nft == f.Type {
continue
}
if nfs == nil {
nfs = append([]*Field(nil), fields...)
}
nfs[i] = f.Copy()
nfs[i].Type = nft
}
if nfs != nil {
t = t.Copy()
t.SetFields(nfs)
}
}
return t
}
// Is this a 64-bit type?
func Is64(t *Type) bool {
if t == nil {
......
......@@ -265,6 +265,100 @@ func newField() *Field {
}
}
// substArgTypes substitutes the given list of types for
// successive occurrences of the "any" placeholder in the
// type syntax expression n.Type.
// The result of substArgTypes MUST be assigned back to old, e.g.
// n.Left = substArgTypes(n.Left, t1, t2)
func substArgTypes(old *Node, types ...*Type) *Node {
n := *old // make shallow copy
for _, t := range types {
dowidth(t)
}
n.Type = substAny(n.Type, &types)
if len(types) > 0 {
Fatalf("substArgTypes: too many argument types")
}
return &n
}
// substAny walks t, replacing instances of "any" with successive
// elements removed from types. It returns the substituted type.
func substAny(t *Type, types *[]*Type) *Type {
if t == nil {
return nil
}
switch t.Etype {
default:
// Leave the type unchanged.
case TANY:
if len(*types) == 0 {
Fatalf("substArgTypes: not enough argument types")
}
t = (*types)[0]
*types = (*types)[1:]
case TPTR32, TPTR64, TCHAN, TARRAY:
elem := substAny(t.Type, types)
if elem != t.Type {
t = t.Copy()
t.Type = elem
}
case TMAP:
key := substAny(t.Down, types)
val := substAny(t.Type, types)
if key != t.Down || val != t.Type {
t = t.Copy()
t.Down = key
t.Type = val
}
case TFUNC:
recvs := substAny(t.Recvs(), types)
params := substAny(t.Params(), types)
results := substAny(t.Results(), types)
if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
// Note that this code has to be aware of the
// representation underlying Recvs/Results/Params.
if recvs == t.Recvs() {
recvs = recvs.Copy()
}
if results == t.Results() {
results = results.Copy()
}
t = t.Copy()
*t.RecvsP() = recvs
*t.ResultsP() = results
*t.ParamsP() = params
}
case TSTRUCT:
fields := t.FieldSlice()
var nfs []*Field
for i, f := range fields {
nft := substAny(f.Type, types)
if nft == f.Type {
continue
}
if nfs == nil {
nfs = append([]*Field(nil), fields...)
}
nfs[i] = f.Copy()
nfs[i].Type = nft
}
if nfs != nil {
t = t.Copy()
t.SetFields(nfs)
}
}
return t
}
// Copy returns a shallow copy of the Type.
func (t *Type) Copy() *Type {
if t == nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment