cmd/compile: remove skipping of implicit operations during export

We'll need to attach types to these operations, so we need to
represent them in the import/export data.

Some of the operations use a selector indicating a different package,
so we need to provide an option to encode the package of a selector.
The default selector() function can't encode that extra information,
as selector's exact encoding is used by go/types.

Change-Id: I4c110fe347b3d915f88a722834bc4058baea7854
Reviewed-on: https://go-review.googlesource.com/c/go/+/299771
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
Keith Randall 2021-03-07 23:48:02 -08:00
parent b6df58bd1f
commit 48895d021b
2 changed files with 43 additions and 18 deletions

View File

@ -617,6 +617,11 @@ func (w *exportWriter) selector(s *types.Sym) {
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
@ -628,6 +633,26 @@ func (w *exportWriter) selector(s *types.Sym) {
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))
}
@ -1299,21 +1324,6 @@ func simplifyForExport(n ir.Node) ir.Node {
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
}
@ -1437,7 +1447,7 @@ func (w *exportWriter) expr(n ir.Node) {
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)

View File

@ -466,6 +466,21 @@ func (r *importReader) ident(selector bool) *types.Sym {
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()
@ -753,7 +768,7 @@ func (r *importReader) doInline(fn *ir.Func) {
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)
@ -1038,7 +1053,7 @@ func (r *importReader) node() ir.Node {
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