mirror of
https://github.com/golang/go
synced 2024-11-19 11:44:45 -07:00
cmd/compile: rework checkdupfields
Use a map to detect duplicate symbols. Allows eliminating an otherwise unneeded field from Sym and gets rid of a global variable. Change-Id: Ic004bca7e9130a1261a1cddbc17244529a2a1df4 Reviewed-on: https://go-review.googlesource.com/20552 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
6b3d4a5353
commit
88a21ebb21
@ -795,19 +795,23 @@ func structfield(n *Node) *Type {
|
||||
return f
|
||||
}
|
||||
|
||||
var uniqgen uint32
|
||||
|
||||
func checkdupfields(t *Type, what string) {
|
||||
// checkdupfields emits errors for duplicately named fields or methods in
|
||||
// a list of struct or interface types.
|
||||
func checkdupfields(what string, ts ...*Type) {
|
||||
lno := lineno
|
||||
|
||||
for ; t != nil; t = t.Down {
|
||||
if t.Sym != nil && t.Nname != nil && !isblank(t.Nname) {
|
||||
if t.Sym.Uniqgen == uniqgen {
|
||||
lineno = t.Nname.Lineno
|
||||
Yyerror("duplicate %s %s", what, t.Sym.Name)
|
||||
} else {
|
||||
t.Sym.Uniqgen = uniqgen
|
||||
seen := make(map[*Sym]bool)
|
||||
for _, t := range ts {
|
||||
for f, it := IterFields(t); f != nil; f = it.Next() {
|
||||
if f.Sym == nil || f.Nname == nil || isblank(f.Nname) {
|
||||
continue
|
||||
}
|
||||
if seen[f.Sym] {
|
||||
lineno = f.Nname.Lineno
|
||||
Yyerror("duplicate %s %s", what, f.Sym.Name)
|
||||
continue
|
||||
}
|
||||
seen[f.Sym] = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -839,8 +843,7 @@ func tostruct0(t *Type, l []*Node) {
|
||||
}
|
||||
}
|
||||
|
||||
uniqgen++
|
||||
checkdupfields(t.Type, "field")
|
||||
checkdupfields("field", t)
|
||||
|
||||
if !t.Broke {
|
||||
checkwidth(t)
|
||||
@ -980,8 +983,7 @@ func tointerface0(t *Type, l []*Node) *Type {
|
||||
}
|
||||
}
|
||||
|
||||
uniqgen++
|
||||
checkdupfields(t.Type, "method")
|
||||
checkdupfields("method", t)
|
||||
t = sortinter(t)
|
||||
checkwidth(t)
|
||||
|
||||
@ -1156,10 +1158,7 @@ func functype0(t *Type, this *Node, in, out []*Node) {
|
||||
*t.ResultsP() = tofunargs(out)
|
||||
*t.ParamsP() = tofunargs(in)
|
||||
|
||||
uniqgen++
|
||||
checkdupfields(t.Recvs().Type, "argument")
|
||||
checkdupfields(t.Results().Type, "argument")
|
||||
checkdupfields(t.Params().Type, "argument")
|
||||
checkdupfields("argument", t.Recvs(), t.Results(), t.Params())
|
||||
|
||||
if t.Recvs().Broke || t.Results().Broke || t.Params().Broke {
|
||||
t.Broke = true
|
||||
|
@ -68,7 +68,6 @@ type Pkg struct {
|
||||
|
||||
type Sym struct {
|
||||
Flags SymFlags
|
||||
Uniqgen uint32
|
||||
Link *Sym
|
||||
Importdef *Pkg // where imported definition was found
|
||||
Linkname string // link name
|
||||
|
@ -26,7 +26,7 @@ func TestSizeof(t *testing.T) {
|
||||
{Func{}, 104, 184},
|
||||
{Name{}, 52, 80},
|
||||
{Node{}, 92, 144},
|
||||
{Sym{}, 64, 112},
|
||||
{Sym{}, 60, 112},
|
||||
{Type{}, 144, 240},
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user