1
0
mirror of https://github.com/golang/go synced 2024-11-19 13:54:56 -07:00

cmd/compile: remove structpkg global variable

The structpkg global variable was only used to verify internal
consistency when declaring methods during import. Track the
value in the parser and binary importer directly and pass it
to the relevant function as an argument.

Change-Id: I7e5e006f9046d84f9a3959616f073798fda36c97
Reviewed-on: https://go-review.googlesource.com/20606
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Robert Griesemer 2016-03-11 17:12:31 -08:00
parent 7c546566c3
commit 68c86a0096
5 changed files with 24 additions and 32 deletions

View File

@ -195,7 +195,6 @@ func (p *importer) localname() *Sym {
if name == "" { if name == "" {
Fatalf("importer: unexpected anonymous name") Fatalf("importer: unexpected anonymous name")
} }
structpkg = importpkg // parser.go:hidden_pkg_importsym
return importpkg.Lookup(name) return importpkg.Lookup(name)
} }
@ -252,13 +251,7 @@ func (p *importer) typ() *Type {
n := methodname1(newname(sym), recv[0].Right) n := methodname1(newname(sym), recv[0].Right)
n.Type = functype(recv[0], params, result) n.Type = functype(recv[0], params, result)
checkwidth(n.Type) checkwidth(n.Type)
// addmethod uses the global variable structpkg to verify consistency addmethod(sym, n.Type, tsym.Pkg, false, false)
{
saved := structpkg
structpkg = tsym.Pkg
addmethod(sym, n.Type, false, false)
structpkg = saved
}
funchdr(n) funchdr(n)
// (comment from parser.go) // (comment from parser.go)

View File

@ -1284,11 +1284,13 @@ func methodname1(n *Node, t *Node) *Node {
return n return n
} }
// add a method, declared as a function, // Add a method, declared as a function.
// n is fieldname, pa is base type, t is function type // - msym is the method symbol
func addmethod(sf *Sym, t *Type, local bool, nointerface bool) { // - t is function type (with receiver)
// - tpkg is the package of the type declaring the method during import, or nil (ignored) --- for verification only
func addmethod(msym *Sym, t *Type, tpkg *Pkg, local, nointerface bool) {
// get field sym // get field sym
if sf == nil { if msym == nil {
Fatalf("no method symbol") Fatalf("no method symbol")
} }
@ -1299,7 +1301,7 @@ func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
return return
} }
pa = pa.Type pa = pa.Type // base type
f := methtype(pa, 1) f := methtype(pa, 1)
if f == nil { if f == nil {
t = pa t = pa
@ -1348,20 +1350,20 @@ func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
return return
} }
if isblanksym(sf) { if isblanksym(msym) {
return return
} }
if pa.Etype == TSTRUCT { if pa.Etype == TSTRUCT {
for f, it := IterFields(pa); f != nil; f = it.Next() { for f, it := IterFields(pa); f != nil; f = it.Next() {
if f.Sym == sf { if f.Sym == msym {
Yyerror("type %v has both field and method named %v", pa, sf) Yyerror("type %v has both field and method named %v", pa, msym)
return return
} }
} }
} }
n := Nod(ODCLFIELD, newname(sf), nil) n := Nod(ODCLFIELD, newname(msym), nil)
n.Type = t n.Type = t
var d *Type // last found var d *Type // last found
@ -1370,11 +1372,11 @@ func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
if f.Etype != TFIELD { if f.Etype != TFIELD {
Fatalf("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong)) Fatalf("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong))
} }
if sf.Name != f.Sym.Name { if msym.Name != f.Sym.Name {
continue continue
} }
if !Eqtype(t, f.Type) { if !Eqtype(t, f.Type) {
Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", pa, sf, f.Type, t) Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", pa, msym, f.Type, t)
} }
return return
} }
@ -1383,8 +1385,8 @@ func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
f.Nointerface = nointerface f.Nointerface = nointerface
// during import unexported method names should be in the type's package // during import unexported method names should be in the type's package
if importpkg != nil && f.Sym != nil && !exportname(f.Sym.Name) && f.Sym.Pkg != structpkg { if tpkg != nil && f.Sym != nil && !exportname(f.Sym.Name) && f.Sym.Pkg != tpkg {
Fatalf("imported method name %v in wrong package %s\n", Sconv(f.Sym, obj.FmtSign), structpkg.Name) Fatalf("imported method name %v in wrong package %s\n", Sconv(f.Sym, obj.FmtSign), tpkg.Name)
} }
if d == nil { if d == nil {
@ -1392,7 +1394,6 @@ func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
} else { } else {
d.Down = f d.Down = f
} }
return
} }
func funccompile(n *Node) { func funccompile(n *Node) {

View File

@ -248,8 +248,6 @@ var localpkg *Pkg // package being compiled
var importpkg *Pkg // package being imported var importpkg *Pkg // package being imported
var structpkg *Pkg // package that declared struct, during import
var gostringpkg *Pkg // fake pkg for Go strings var gostringpkg *Pkg // fake pkg for Go strings
var itabpkg *Pkg // fake pkg for itab cache var itabpkg *Pkg // fake pkg for itab cache

View File

@ -36,6 +36,9 @@ type parser struct {
fnest int // function nesting level (for error handling) fnest int // function nesting level (for error handling)
xnest int // expression nesting level (for complit ambiguity resolution) xnest int // expression nesting level (for complit ambiguity resolution)
indent []byte // tracing support indent []byte // tracing support
// TODO(gri) remove this once we switch to binary export format
structpkg *Pkg // for verification in addmethod only
} }
// newparser returns a new parser ready to parse from src. // newparser returns a new parser ready to parse from src.
@ -2008,7 +2011,7 @@ func (p *parser) hidden_fndcl() *Node {
ss.Type = functype(s2[0], s6, s8) ss.Type = functype(s2[0], s6, s8)
checkwidth(ss.Type) checkwidth(ss.Type)
addmethod(s4, ss.Type, false, false) addmethod(s4, ss.Type, p.structpkg, false, false)
funchdr(ss) funchdr(ss)
// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
@ -2863,12 +2866,9 @@ func (p *parser) hidden_pkg_importsym() *Sym {
defer p.trace("hidden_pkg_importsym")() defer p.trace("hidden_pkg_importsym")()
} }
s1 := p.hidden_importsym() s := p.hidden_importsym()
p.structpkg = s.Pkg
ss := s1 return s
structpkg = ss.Pkg
return ss
} }
func (p *parser) hidden_pkgtype() *Type { func (p *parser) hidden_pkgtype() *Type {

View File

@ -3438,7 +3438,7 @@ func typecheckfunc(n *Node) {
t.Nname = n.Func.Nname t.Nname = n.Func.Nname
rcvr := t.Recv() rcvr := t.Recv()
if rcvr != nil && n.Func.Shortname != nil { if rcvr != nil && n.Func.Shortname != nil {
addmethod(n.Func.Shortname.Sym, t, true, n.Func.Nname.Nointerface) addmethod(n.Func.Shortname.Sym, t, nil, true, n.Func.Nname.Nointerface)
} }
for _, ln := range n.Func.Dcl { for _, ln := range n.Func.Dcl {