mirror of
https://github.com/golang/go
synced 2024-11-19 02:14:43 -07:00
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/21250 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
0a85be573c
commit
268c31870a
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user