mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: refactor how declarations are imported
This CL moves all of the logic for wiring up imported declarations into export.go, so that it can be reused by the indexed importer code. While here, increase symmetry across routines. Passes toolstash-check. Change-Id: I1ccec5c3999522b010e4d04ed56b632fd4d712d9 Reviewed-on: https://go-review.googlesource.com/107621 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
514018c0aa
commit
dd71e3fef4
3 changed files with 84 additions and 87 deletions
|
|
@ -197,6 +197,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
|
||||||
Cost: int32(inlCost),
|
Cost: int32(inlCost),
|
||||||
Body: body,
|
Body: body,
|
||||||
}
|
}
|
||||||
|
importlist = append(importlist, f)
|
||||||
if Debug['E'] > 0 && Debug['m'] > 2 {
|
if Debug['E'] > 0 && Debug['m'] > 2 {
|
||||||
if Debug['m'] > 3 {
|
if Debug['m'] > 3 {
|
||||||
fmt.Printf("inl body for %v: %+v\n", f, asNodes(body))
|
fmt.Printf("inl body for %v: %+v\n", f, asNodes(body))
|
||||||
|
|
@ -351,13 +352,13 @@ func (p *importer) obj(tag int) {
|
||||||
sym := p.qualifiedName()
|
sym := p.qualifiedName()
|
||||||
typ := p.typ()
|
typ := p.typ()
|
||||||
val := p.value(typ)
|
val := p.value(typ)
|
||||||
importconst(pos, p.imp, sym, idealType(typ), val)
|
importconst(p.imp, pos, sym, idealType(typ), val)
|
||||||
|
|
||||||
case aliasTag:
|
case aliasTag:
|
||||||
pos := p.pos()
|
pos := p.pos()
|
||||||
sym := p.qualifiedName()
|
sym := p.qualifiedName()
|
||||||
typ := p.typ()
|
typ := p.typ()
|
||||||
importalias(pos, p.imp, sym, typ)
|
importalias(p.imp, pos, sym, typ)
|
||||||
|
|
||||||
case typeTag:
|
case typeTag:
|
||||||
p.typ()
|
p.typ()
|
||||||
|
|
@ -366,7 +367,7 @@ func (p *importer) obj(tag int) {
|
||||||
pos := p.pos()
|
pos := p.pos()
|
||||||
sym := p.qualifiedName()
|
sym := p.qualifiedName()
|
||||||
typ := p.typ()
|
typ := p.typ()
|
||||||
importvar(pos, p.imp, sym, typ)
|
importvar(p.imp, pos, sym, typ)
|
||||||
|
|
||||||
case funcTag:
|
case funcTag:
|
||||||
pos := p.pos()
|
pos := p.pos()
|
||||||
|
|
@ -375,28 +376,8 @@ func (p *importer) obj(tag int) {
|
||||||
result := p.paramList()
|
result := p.paramList()
|
||||||
|
|
||||||
sig := functypefield(nil, params, result)
|
sig := functypefield(nil, params, result)
|
||||||
importsym(p.imp, sym, ONAME)
|
importfunc(p.imp, pos, sym, sig)
|
||||||
if old := asNode(sym.Def); old != nil && old.Op == ONAME {
|
p.funcList = append(p.funcList, asNode(sym.Def))
|
||||||
// function was imported before (via another import)
|
|
||||||
if !eqtype(sig, old.Type) {
|
|
||||||
p.formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, old.Type, sig)
|
|
||||||
}
|
|
||||||
n := asNode(old.Type.Nname())
|
|
||||||
p.funcList = append(p.funcList, n)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
n := newfuncnamel(pos, sym)
|
|
||||||
n.Type = sig
|
|
||||||
declare(n, PFUNC)
|
|
||||||
p.funcList = append(p.funcList, n)
|
|
||||||
importlist = append(importlist, n)
|
|
||||||
|
|
||||||
sig.SetNname(asTypesNode(n))
|
|
||||||
|
|
||||||
if Debug['E'] > 0 {
|
|
||||||
fmt.Printf("import [%q] func %v \n", p.imp.Path, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
p.formatErrorf("unexpected object (tag = %d)", tag)
|
p.formatErrorf("unexpected object (tag = %d)", tag)
|
||||||
|
|
@ -468,10 +449,7 @@ func (p *importer) newtyp(etype types.EType) *types.Type {
|
||||||
// importtype declares that pt, an imported named type, has underlying type t.
|
// importtype declares that pt, an imported named type, has underlying type t.
|
||||||
func (p *importer) importtype(pt, t *types.Type) {
|
func (p *importer) importtype(pt, t *types.Type) {
|
||||||
if pt.Etype == TFORW {
|
if pt.Etype == TFORW {
|
||||||
copytype(asNode(pt.Nod), t)
|
copytype(typenod(pt), t)
|
||||||
pt.Sym.Importdef = p.imp
|
|
||||||
pt.Sym.Lastlineno = lineno
|
|
||||||
declare(asNode(pt.Nod), PEXTERN)
|
|
||||||
checkwidth(pt)
|
checkwidth(pt)
|
||||||
} else {
|
} else {
|
||||||
// pt.Orig and t must be identical.
|
// pt.Orig and t must be identical.
|
||||||
|
|
@ -503,7 +481,7 @@ func (p *importer) typ() *types.Type {
|
||||||
pos := p.pos()
|
pos := p.pos()
|
||||||
tsym := p.qualifiedName()
|
tsym := p.qualifiedName()
|
||||||
|
|
||||||
t = pkgtype(pos, p.imp, tsym)
|
t = importtype(p.imp, pos, tsym)
|
||||||
p.typList = append(p.typList, t)
|
p.typList = append(p.typList, t)
|
||||||
dup := !t.IsKind(types.TFORW) // type already imported
|
dup := !t.IsKind(types.TFORW) // type already imported
|
||||||
|
|
||||||
|
|
@ -552,7 +530,6 @@ func (p *importer) typ() *types.Type {
|
||||||
n.SetClass(PFUNC)
|
n.SetClass(PFUNC)
|
||||||
checkwidth(n.Type)
|
checkwidth(n.Type)
|
||||||
p.funcList = append(p.funcList, n)
|
p.funcList = append(p.funcList, n)
|
||||||
importlist = append(importlist, n)
|
|
||||||
|
|
||||||
// (comment from parser.go)
|
// (comment from parser.go)
|
||||||
// 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
|
||||||
|
|
|
||||||
|
|
@ -105,89 +105,112 @@ func dumpexport(bout *bio.Writer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// importsym declares symbol s as an imported object representable by op.
|
func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
|
||||||
// pkg is the package being imported
|
n := asNode(s.Def)
|
||||||
func importsym(pkg *types.Pkg, s *types.Sym, op Op) {
|
if n == nil {
|
||||||
if asNode(s.Def) != nil && asNode(s.Def).Op != op {
|
n = dclname(s)
|
||||||
pkgstr := fmt.Sprintf("during import %q", pkg.Path)
|
s.Def = asTypesNode(n)
|
||||||
redeclare(lineno, s, pkgstr)
|
s.Importdef = ipkg
|
||||||
}
|
}
|
||||||
|
if n.Op != ONONAME && n.Op != op {
|
||||||
|
redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
|
||||||
|
}
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// pkgtype returns the named type declared by symbol s.
|
// pkgtype returns the named type declared by symbol s.
|
||||||
// If no such type has been declared yet, a forward declaration is returned.
|
// If no such type has been declared yet, a forward declaration is returned.
|
||||||
// pkg is the package being imported
|
// ipkg is the package being imported
|
||||||
func pkgtype(pos src.XPos, pkg *types.Pkg, s *types.Sym) *types.Type {
|
func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
|
||||||
importsym(pkg, s, OTYPE)
|
n := importsym(ipkg, pos, s, OTYPE)
|
||||||
if asNode(s.Def) == nil || asNode(s.Def).Op != OTYPE {
|
if n.Op != OTYPE {
|
||||||
t := types.New(TFORW)
|
t := types.New(TFORW)
|
||||||
t.Sym = s
|
t.Sym = s
|
||||||
s.Def = asTypesNode(typenodl(pos, t))
|
t.Nod = asTypesNode(n)
|
||||||
asNode(s.Def).Name = new(Name)
|
|
||||||
|
n.Op = OTYPE
|
||||||
|
n.Pos = pos
|
||||||
|
n.Type = t
|
||||||
|
n.SetClass(PEXTERN)
|
||||||
}
|
}
|
||||||
|
|
||||||
if asNode(s.Def).Type == nil {
|
t := n.Type
|
||||||
Fatalf("pkgtype %v", s)
|
if t == nil {
|
||||||
|
Fatalf("importtype %v", s)
|
||||||
}
|
}
|
||||||
return asNode(s.Def).Type
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// importobj declares symbol s as an imported object representable by op.
|
||||||
|
// ipkg is the package being imported
|
||||||
|
func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node {
|
||||||
|
n := importsym(ipkg, pos, s, op)
|
||||||
|
if n.Op != ONONAME {
|
||||||
|
if n.Op == op && (n.Class() != ctxt || !eqtype(n.Type, t)) {
|
||||||
|
redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
n.Op = op
|
||||||
|
n.Pos = pos
|
||||||
|
n.SetClass(ctxt)
|
||||||
|
n.Type = t
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// importconst declares symbol s as an imported constant with type t and value val.
|
// importconst declares symbol s as an imported constant with type t and value val.
|
||||||
// pkg is the package being imported
|
// ipkg is the package being imported
|
||||||
func importconst(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type, val Val) {
|
func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val Val) {
|
||||||
importsym(pkg, s, OLITERAL)
|
n := importobj(ipkg, pos, s, OLITERAL, PEXTERN, t)
|
||||||
if asNode(s.Def) != nil { // TODO: check if already the same.
|
if n == nil { // TODO: Check that value matches.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n := npos(pos, nodlit(val))
|
n.SetVal(val)
|
||||||
n.Type = t
|
|
||||||
n.Sym = s
|
|
||||||
declare(n, PEXTERN)
|
|
||||||
|
|
||||||
if Debug['E'] != 0 {
|
if Debug['E'] != 0 {
|
||||||
fmt.Printf("import const %v\n", s)
|
fmt.Printf("import const %v %L = %v\n", s, t, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// importfunc declares symbol s as an imported function with type t.
|
||||||
|
// ipkg is the package being imported
|
||||||
|
func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
|
n := importobj(ipkg, pos, s, ONAME, PFUNC, t)
|
||||||
|
if n == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
n.Func = new(Func)
|
||||||
|
t.SetNname(asTypesNode(n))
|
||||||
|
|
||||||
|
if Debug['E'] != 0 {
|
||||||
|
fmt.Printf("import func %v%S\n", s, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// importvar declares symbol s as an imported variable with type t.
|
// importvar declares symbol s as an imported variable with type t.
|
||||||
// pkg is the package being imported
|
// ipkg is the package being imported
|
||||||
func importvar(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
|
func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
importsym(pkg, s, ONAME)
|
n := importobj(ipkg, pos, s, ONAME, PEXTERN, t)
|
||||||
if asNode(s.Def) != nil && asNode(s.Def).Op == ONAME {
|
if n == nil {
|
||||||
if eqtype(t, asNode(s.Def).Type) {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, asNode(s.Def).Type, s.Importdef.Path, t, pkg.Path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n := newnamel(pos, s)
|
|
||||||
s.Importdef = pkg
|
|
||||||
n.Type = t
|
|
||||||
declare(n, PEXTERN)
|
|
||||||
|
|
||||||
if Debug['E'] != 0 {
|
if Debug['E'] != 0 {
|
||||||
fmt.Printf("import var %v %L\n", s, t)
|
fmt.Printf("import var %v %L\n", s, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// importalias declares symbol s as an imported type alias with type t.
|
// importalias declares symbol s as an imported type alias with type t.
|
||||||
// pkg is the package being imported
|
// ipkg is the package being imported
|
||||||
func importalias(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
|
func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
|
||||||
importsym(pkg, s, OTYPE)
|
n := importobj(ipkg, pos, s, OTYPE, PEXTERN, t)
|
||||||
if asNode(s.Def) != nil && asNode(s.Def).Op == OTYPE {
|
if n == nil {
|
||||||
if eqtype(t, asNode(s.Def).Type) {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
yyerror("inconsistent definition for type alias %v during import\n\t%v (in %q)\n\t%v (in %q)", s, asNode(s.Def).Type, s.Importdef.Path, t, pkg.Path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n := newnamel(pos, s)
|
|
||||||
n.Op = OTYPE
|
|
||||||
s.Importdef = pkg
|
|
||||||
n.Type = t
|
|
||||||
declare(n, PEXTERN)
|
|
||||||
|
|
||||||
if Debug['E'] != 0 {
|
if Debug['E'] != 0 {
|
||||||
fmt.Printf("import type %v = %L\n", s, t)
|
fmt.Printf("import type %v = %L\n", s, t)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -915,12 +915,9 @@ func loadsys() {
|
||||||
typ := typs[d.typ]
|
typ := typs[d.typ]
|
||||||
switch d.tag {
|
switch d.tag {
|
||||||
case funcTag:
|
case funcTag:
|
||||||
importsym(Runtimepkg, sym, ONAME)
|
importfunc(Runtimepkg, src.NoXPos, sym, typ)
|
||||||
n := newfuncname(sym)
|
|
||||||
n.Type = typ
|
|
||||||
declare(n, PFUNC)
|
|
||||||
case varTag:
|
case varTag:
|
||||||
importvar(lineno, Runtimepkg, sym, typ)
|
importvar(Runtimepkg, src.NoXPos, sym, typ)
|
||||||
default:
|
default:
|
||||||
Fatalf("unhandled declaration tag %v", d.tag)
|
Fatalf("unhandled declaration tag %v", d.tag)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue