if name == "" {
Fatalf("importer: unexpected anonymous name")
}
- structpkg = importpkg // parser.go:hidden_pkg_importsym
return importpkg.Lookup(name)
}
n := methodname1(newname(sym), recv[0].Right)
n.Type = functype(recv[0], params, result)
checkwidth(n.Type)
- // addmethod uses the global variable structpkg to verify consistency
- {
- saved := structpkg
- structpkg = tsym.Pkg
- addmethod(sym, n.Type, false, false)
- structpkg = saved
- }
+ addmethod(sym, n.Type, tsym.Pkg, false, false)
funchdr(n)
// (comment from parser.go)
return n
}
-// add a method, declared as a function,
-// n is fieldname, pa is base type, t is function type
-func addmethod(sf *Sym, t *Type, local bool, nointerface bool) {
+// Add a method, declared as a function.
+// - msym is the method symbol
+// - 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
- if sf == nil {
+ if msym == nil {
Fatalf("no method symbol")
}
return
}
- pa = pa.Type
+ pa = pa.Type // base type
f := methtype(pa, 1)
if f == nil {
t = pa
return
}
- if isblanksym(sf) {
+ if isblanksym(msym) {
return
}
if pa.Etype == TSTRUCT {
for f, it := IterFields(pa); f != nil; f = it.Next() {
- if f.Sym == sf {
- Yyerror("type %v has both field and method named %v", pa, sf)
+ if f.Sym == msym {
+ Yyerror("type %v has both field and method named %v", pa, msym)
return
}
}
}
- n := Nod(ODCLFIELD, newname(sf), nil)
+ n := Nod(ODCLFIELD, newname(msym), nil)
n.Type = t
var d *Type // last found
if f.Etype != TFIELD {
Fatalf("addmethod: not TFIELD: %v", Tconv(f, obj.FmtLong))
}
- if sf.Name != f.Sym.Name {
+ if msym.Name != f.Sym.Name {
continue
}
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
}
f.Nointerface = nointerface
// 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 {
- Fatalf("imported method name %v in wrong package %s\n", Sconv(f.Sym, obj.FmtSign), structpkg.Name)
+ 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), tpkg.Name)
}
if d == nil {
} else {
d.Down = f
}
- return
}
func funccompile(n *Node) {
fnest int // function nesting level (for error handling)
xnest int // expression nesting level (for complit ambiguity resolution)
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.
ss.Type = functype(s2[0], s6, s8)
checkwidth(ss.Type)
- addmethod(s4, ss.Type, false, false)
+ addmethod(s4, ss.Type, p.structpkg, false, false)
funchdr(ss)
// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
defer p.trace("hidden_pkg_importsym")()
}
- s1 := p.hidden_importsym()
-
- ss := s1
- structpkg = ss.Pkg
-
- return ss
+ s := p.hidden_importsym()
+ p.structpkg = s.Pkg
+ return s
}
func (p *parser) hidden_pkgtype() *Type {