"*math/big.Int %s": "",
"[16]byte %x": "",
"[]*cmd/compile/internal/gc.Node %v": "",
- "[]*cmd/compile/internal/gc.Sig %#v": "",
"[]*cmd/compile/internal/ssa.Block %v": "",
"[]*cmd/compile/internal/ssa.Value %v": "",
"[]byte %s": "",
)
type Sig struct {
- name string
- pkg *types.Pkg
+ name *types.Sym
isym *types.Sym
tsym *types.Sym
type_ *types.Type
mtype *types.Type
}
-// siglt sorts method signatures by name with exported methods first,
-// and then non-exported methods by their package path.
-func siglt(a, b *Sig) bool {
- if (a.pkg == nil) != (b.pkg == nil) {
- return a.pkg == nil
- }
- if a.name != b.name {
- return a.name < b.name
- }
- if a.pkg != nil && a.pkg != b.pkg {
- return a.pkg.Path < b.pkg.Path
- }
- return false
-}
-
// Builds a type representing a Bucket structure for
// the given map type. This type is not visible to users -
// we include only enough information to generate a correct GC
continue
}
- var sig Sig
- ms = append(ms, &sig)
-
- sig.name = method.Name
- if !types.IsExported(method.Name) {
- if method.Pkg == nil {
- Fatalf("methods: missing package")
- }
- sig.pkg = method.Pkg
+ sig := &Sig{
+ name: method,
+ isym: methodSym(it, method),
+ tsym: methodSym(t, method),
+ type_: methodfunc(f.Type, t),
+ mtype: methodfunc(f.Type, nil),
}
-
- sig.isym = methodSym(it, method)
- sig.tsym = methodSym(t, method)
- sig.type_ = methodfunc(f.Type, t)
- sig.mtype = methodfunc(f.Type, nil)
+ ms = append(ms, sig)
this := f.Type.Recv().Type
if f.Type.Etype != TFUNC || f.Sym == nil {
continue
}
- method := f.Sym
- var sig = Sig{
- name: method.Name,
- }
- if !types.IsExported(method.Name) {
- if method.Pkg == nil {
- Fatalf("imethods: missing package")
- }
- sig.pkg = method.Pkg
+ if f.Sym.IsBlank() {
+ Fatalf("unexpected blank symbol in interface method set")
}
-
- sig.mtype = f.Type
- sig.type_ = methodfunc(f.Type, nil)
-
if n := len(methods); n > 0 {
last := methods[n-1]
- if !(siglt(last, &sig)) {
- Fatalf("sigcmp vs sortinter %s %s", last.name, sig.name)
+ if !last.name.Less(f.Sym) {
+ Fatalf("sigcmp vs sortinter %v %v", last.name, f.Sym)
}
}
- methods = append(methods, &sig)
- // Compiler can only refer to wrappers for non-blank methods.
- if method.IsBlank() {
- continue
+ sig := &Sig{
+ name: f.Sym,
+ mtype: f.Type,
+ type_: methodfunc(f.Type, nil),
}
+ methods = append(methods, sig)
// NOTE(rsc): Perhaps an oversight that
// IfaceType.Method is not in the reflect data.
// Generate the method body, so that compiled
// code can refer to it.
- isym := methodSym(t, method)
+ isym := methodSym(t, f.Sym)
if !isym.Siggen() {
isym.SetSiggen(true)
genwrapper(t, f, isym)
if mcount != int(uint16(mcount)) {
Fatalf("too many methods on %v: %d", t, mcount)
}
- xcount := sort.Search(mcount, func(i int) bool { return m[i].pkg != nil })
+ xcount := sort.Search(mcount, func(i int) bool { return !types.IsExported(m[i].name.Name) })
if dataAdd != int(uint32(dataAdd)) {
Fatalf("methods are too far away on %v: %d", t, dataAdd)
}
func dextratypeData(lsym *obj.LSym, ot int, t *types.Type) int {
for _, a := range methods(t) {
// ../../../../runtime/type.go:/method
- exported := types.IsExported(a.name)
+ exported := types.IsExported(a.name.Name)
var pkg *types.Pkg
- if !exported && a.pkg != typePkg(t) {
- pkg = a.pkg
+ if !exported && a.name.Pkg != typePkg(t) {
+ pkg = a.name.Pkg
}
- nsym := dname(a.name, "", pkg, exported)
+ nsym := dname(a.name.Name, "", pkg, exported)
ot = dsymptrOff(lsym, ot, nsym)
ot = dmethodptrOff(lsym, ot, dtypesym(a.mtype))
for _, a := range m {
// ../../../../runtime/type.go:/imethod
- exported := types.IsExported(a.name)
+ exported := types.IsExported(a.name.Name)
var pkg *types.Pkg
- if !exported && a.pkg != tpkg {
- pkg = a.pkg
+ if !exported && a.name.Pkg != tpkg {
+ pkg = a.name.Pkg
}
- nsym := dname(a.name, "", pkg, exported)
+ nsym := dname(a.name.Name, "", pkg, exported)
ot = dsymptrOff(lsym, ot, nsym)
ot = dsymptrOff(lsym, ot, dtypesym(a.type_))
// both sigs and methods are sorted by name,
// so we can find the intersect in a single pass
for _, m := range methods {
- if m.name == sigs[0].name {
+ if m.name.Name == sigs[0].name.Name {
out = append(out, m.isym.Linksym())
sigs = sigs[1:]
if len(sigs) == 0 {
+++ /dev/null
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gc
-
-import (
- "cmd/compile/internal/types"
- "cmd/internal/obj"
- "reflect"
- "testing"
-)
-
-func TestSortingBySigLT(t *testing.T) {
- data := []*Sig{
- &Sig{name: "b", pkg: &types.Pkg{Path: "abc"}},
- &Sig{name: "B", pkg: nil},
- &Sig{name: "C", pkg: nil},
- &Sig{name: "c", pkg: &types.Pkg{Path: "uvw"}},
- &Sig{name: "C", pkg: nil},
- &Sig{name: "φ", pkg: &types.Pkg{Path: "gr"}},
- &Sig{name: "Φ", pkg: nil},
- &Sig{name: "b", pkg: &types.Pkg{Path: "xyz"}},
- &Sig{name: "a", pkg: &types.Pkg{Path: "abc"}},
- &Sig{name: "B", pkg: nil},
- }
- want := []*Sig{
- &Sig{name: "B", pkg: nil},
- &Sig{name: "B", pkg: nil},
- &Sig{name: "C", pkg: nil},
- &Sig{name: "C", pkg: nil},
- &Sig{name: "Φ", pkg: nil},
- &Sig{name: "a", pkg: &types.Pkg{Path: "abc"}},
- &Sig{name: "b", pkg: &types.Pkg{Path: "abc"}},
- &Sig{name: "b", pkg: &types.Pkg{Path: "xyz"}},
- &Sig{name: "c", pkg: &types.Pkg{Path: "uvw"}},
- &Sig{name: "φ", pkg: &types.Pkg{Path: "gr"}},
- }
- if len(data) != len(want) {
- t.Fatal("want and data must match")
- }
- if reflect.DeepEqual(data, want) {
- t.Fatal("data must be shuffled")
- }
- obj.SortSlice(data, func(i, j int) bool { return siglt(data[i], data[j]) })
- if !reflect.DeepEqual(data, want) {
- t.Logf("want: %#v", want)
- t.Logf("data: %#v", data)
- t.Errorf("sorting failed")
- }
-}
return &n2
}
-// methcmp sorts methods by name with exported methods first,
-// and then non-exported methods by their package path.
+// methcmp sorts methods by symbol.
type methcmp []*types.Field
-func (x methcmp) Len() int { return len(x) }
-func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x methcmp) Less(i, j int) bool {
- a := x[i]
- b := x[j]
- if a.Sym == b.Sym {
- return false
- }
-
- // Blank methods to the end.
- if a.Sym == nil {
- return false
- }
- if b.Sym == nil {
- return true
- }
-
- // Exported methods to the front.
- ea := types.IsExported(a.Sym.Name)
- eb := types.IsExported(b.Sym.Name)
- if ea != eb {
- return ea
- }
-
- // Sort by name and then package.
- if a.Sym.Name != b.Sym.Name {
- return a.Sym.Name < b.Sym.Name
- }
- if !ea && a.Sym.Pkg.Path != b.Sym.Pkg.Path {
- return a.Sym.Pkg.Path < b.Sym.Pkg.Path
- }
-
- return false
-}
+func (x methcmp) Len() int { return len(x) }
+func (x methcmp) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x methcmp) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) }
func nodintconst(v int64) *Node {
u := new(Mpint)
return Ctxt.Lookup(sym.LinksymName())
}
+// Less reports whether symbol a is ordered before symbol b.
+//
+// Symbols are ordered exported before non-exported, then by name, and
+// finally (for non-exported symbols) by package path.
+func (a *Sym) Less(b *Sym) bool {
+ if a == b {
+ return false
+ }
+
+ // Exported symbols before non-exported.
+ ea := IsExported(a.Name)
+ eb := IsExported(b.Name)
+ if ea != eb {
+ return ea
+ }
+
+ // Order by name and then (for non-exported names) by package.
+ if a.Name != b.Name {
+ return a.Name < b.Name
+ }
+ if !ea {
+ return a.Pkg.Path < b.Pkg.Path
+ }
+ return false
+}
+
// IsExported reports whether name is an exported Go symbol (that is,
// whether it begins with an upper-case letter).
func IsExported(name string) bool {
--- /dev/null
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types_test
+
+import (
+ "cmd/compile/internal/types"
+ "cmd/internal/obj"
+ "reflect"
+ "testing"
+)
+
+func TestSymLess(t *testing.T) {
+ var (
+ local = types.NewPkg("", "")
+ abc = types.NewPkg("abc", "")
+ uvw = types.NewPkg("uvw", "")
+ xyz = types.NewPkg("xyz", "")
+ gr = types.NewPkg("gr", "")
+ )
+
+ data := []*types.Sym{
+ abc.Lookup("b"),
+ local.Lookup("B"),
+ local.Lookup("C"),
+ uvw.Lookup("c"),
+ local.Lookup("C"),
+ gr.Lookup("φ"),
+ local.Lookup("Φ"),
+ xyz.Lookup("b"),
+ abc.Lookup("a"),
+ local.Lookup("B"),
+ }
+ want := []*types.Sym{
+ local.Lookup("B"),
+ local.Lookup("B"),
+ local.Lookup("C"),
+ local.Lookup("C"),
+ local.Lookup("Φ"),
+ abc.Lookup("a"),
+ abc.Lookup("b"),
+ xyz.Lookup("b"),
+ uvw.Lookup("c"),
+ gr.Lookup("φ"),
+ }
+ if len(data) != len(want) {
+ t.Fatal("want and data must match")
+ }
+ if reflect.DeepEqual(data, want) {
+ t.Fatal("data must be shuffled")
+ }
+ obj.SortSlice(data, func(i, j int) bool { return data[i].Less(data[j]) })
+ if !reflect.DeepEqual(data, want) {
+ t.Logf("want: %#v", want)
+ t.Logf("data: %#v", data)
+ t.Errorf("sorting failed")
+ }
+}