marked map[*types.Type]bool // types already seen by markType
}
+// markObject visits a reachable object.
+func (p *exporter) markObject(n *Node) {
+ if n.Op == ONAME && n.Class() == PFUNC {
+ inlFlood(n)
+ }
+
+ p.markType(n.Type)
+}
+
// markType recursively visits types reachable from t to identify
// functions whose inline bodies may be needed.
func (p *exporter) markType(t *types.Type) {
if t.Sym != nil && t.Etype != TINTER {
for _, m := range t.Methods().Slice() {
if types.IsExported(m.Sym.Name) {
- p.markType(m.Type)
+ p.markObject(asNode(m.Type.Nname()))
}
}
}
}
case TFUNC:
- // If t is the type of a function or method, then
- // t.Nname() is its ONAME. Mark its inline body and
- // any recursively called functions for export.
- inlFlood(asNode(t.Nname()))
-
for _, f := range t.Results().FieldSlice() {
p.markType(f.Type)
}
// - msym is the method symbol
// - t is function type (with receiver)
// Returns a pointer to the existing or added Field; or nil if there's an error.
-func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
+func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
if msym == nil {
Fatalf("no method symbol")
}
}
f := types.NewField(lineno, msym, t)
+ f.Type.SetNname(asTypesNode(n.Func.Nname))
f.SetNointerface(nointerface)
mt.Methods().Append(f)
)
func iexport(out *bufio.Writer) {
- // Mark inline bodies that are reachable through exported types.
+ // Mark inline bodies that are reachable through exported objects.
// (Phase 0 of bexport.go.)
{
// TODO(mdempsky): Separate from bexport logic.
p := &exporter{marked: make(map[*types.Type]bool)}
for _, n := range exportlist {
- sym := n.Sym
- p.markType(asNode(sym.Def).Type)
+ p.markObject(n)
}
}
recv := r.param()
mtyp := r.signature(recv)
- ms[i] = types.NewField(mpos, msym, mtyp)
-
m := newfuncnamel(mpos, methodSym(recv.Type, msym))
m.Type = mtyp
m.SetClass(PFUNC)
// methodSym already marked m.Sym as a function.
- // (comment from parser.go)
- // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
- // (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
- // out by typecheck's lookdot as this $$.ttype. So by providing
- // this back link here we avoid special casing there.
- mtyp.SetNname(asTypesNode(m))
+ f := types.NewField(mpos, msym, mtyp)
+ f.Type.SetNname(asTypesNode(m))
+ ms[i] = f
}
t.Methods().Set(ms)
t.FuncType().Nname = asTypesNode(n.Func.Nname)
rcvr := t.Recv()
if rcvr != nil && n.Func.Shortname != nil {
- m := addmethod(n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
+ m := addmethod(n, n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
if m == nil {
return
}