base.Fatalf("missing currPkg")
}
+ // If the selector being written is unexported, it comes with a package qualifier.
+ // If the selector being written is exported, it is not package-qualified.
+ // See the spec: https://golang.org/ref/spec#Uniqueness_of_identifiers
+ // As an optimization, we don't actually write the package every time - instead we
+ // call setPkg before a group of selectors (all of which must have the same package qualifier).
pkg := w.currPkg
if types.IsExported(s.Name) {
pkg = types.LocalPkg
w.string(s.Name)
}
+// Export a selector, but one whose package may not match
+// the package being compiled. This is a separate function
+// because the standard selector() serialization format is fixed
+// by the go/types reader. This one can only be used during
+// inline/generic body exporting.
+func (w *exportWriter) exoticSelector(s *types.Sym) {
+ pkg := w.currPkg
+ if types.IsExported(s.Name) {
+ pkg = types.LocalPkg
+ }
+
+ w.string(s.Name)
+ if s.Pkg == pkg {
+ w.uint64(0)
+ } else {
+ w.uint64(1)
+ w.pkg(s.Pkg)
+ }
+}
+
func (w *exportWriter) typ(t *types.Type) {
w.data.uint64(w.p.typOff(t))
}
case ir.OPAREN:
n := n.(*ir.ParenExpr)
return simplifyForExport(n.X)
- case ir.ODEREF:
- n := n.(*ir.StarExpr)
- if n.Implicit() {
- return simplifyForExport(n.X)
- }
- case ir.OADDR:
- n := n.(*ir.AddrExpr)
- if n.Implicit() {
- return simplifyForExport(n.X)
- }
- case ir.ODOT, ir.ODOTPTR:
- n := n.(*ir.SelectorExpr)
- if n.Implicit() {
- return simplifyForExport(n.X)
- }
}
return n
}
w.op(ir.OXDOT)
w.pos(n.Pos())
w.expr(n.X)
- w.selector(n.Sel)
+ w.exoticSelector(n.Sel)
case ir.ODOTTYPE, ir.ODOTTYPE2:
n := n.(*ir.TypeAssertExpr)
func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
func (r *importReader) selector() *types.Sym { return r.ident(true) }
+func (r *importReader) exoticSelector() *types.Sym {
+ name := r.string()
+ if name == "" {
+ return nil
+ }
+ pkg := r.currPkg
+ if types.IsExported(name) {
+ pkg = types.LocalPkg
+ }
+ if r.uint64() != 0 {
+ pkg = r.pkg()
+ }
+ return pkg.Lookup(name)
+}
+
func (r *importReader) qualifiedIdent() *ir.Ident {
name := r.string()
pkg := r.pkg()
base.Fatalf("%v already has inline body", fn)
}
- //fmt.Printf("Importing %v\n", n)
+ //fmt.Printf("Importing %s\n", fn.Nname.Sym().Name)
r.funcBody(fn)
importlist = append(importlist, fn)
case ir.OXDOT:
// see parser.new_dotname
- return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.selector())
+ return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.exoticSelector())
// case ODOTTYPE, ODOTTYPE2:
// unreachable - mapped to case ODOTTYPE below by exporter