]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor how declarations are imported
authorMatthew Dempsky <mdempsky@google.com>
Tue, 17 Apr 2018 21:40:56 +0000 (14:40 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 20 Apr 2018 21:19:17 +0000 (21:19 +0000)
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>
src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/export.go
src/cmd/compile/internal/gc/main.go

index 41a9ce41bde5994c5f06f9780973c08b427cd9e4..9ccc549e6934389ca38beb4beff1237998e40c42 100644 (file)
@@ -197,6 +197,7 @@ func Import(imp *types.Pkg, in *bufio.Reader) {
                                Cost: int32(inlCost),
                                Body: body,
                        }
+                       importlist = append(importlist, f)
                        if Debug['E'] > 0 && Debug['m'] > 2 {
                                if Debug['m'] > 3 {
                                        fmt.Printf("inl body for %v: %+v\n", f, asNodes(body))
@@ -351,13 +352,13 @@ func (p *importer) obj(tag int) {
                sym := p.qualifiedName()
                typ := p.typ()
                val := p.value(typ)
-               importconst(pos, p.imp, sym, idealType(typ), val)
+               importconst(p.imp, pos, sym, idealType(typ), val)
 
        case aliasTag:
                pos := p.pos()
                sym := p.qualifiedName()
                typ := p.typ()
-               importalias(pos, p.imp, sym, typ)
+               importalias(p.imp, pos, sym, typ)
 
        case typeTag:
                p.typ()
@@ -366,7 +367,7 @@ func (p *importer) obj(tag int) {
                pos := p.pos()
                sym := p.qualifiedName()
                typ := p.typ()
-               importvar(pos, p.imp, sym, typ)
+               importvar(p.imp, pos, sym, typ)
 
        case funcTag:
                pos := p.pos()
@@ -375,28 +376,8 @@ func (p *importer) obj(tag int) {
                result := p.paramList()
 
                sig := functypefield(nil, params, result)
-               importsym(p.imp, sym, ONAME)
-               if old := asNode(sym.Def); old != nil && old.Op == ONAME {
-                       // 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)
-               }
+               importfunc(p.imp, pos, sym, sig)
+               p.funcList = append(p.funcList, asNode(sym.Def))
 
        default:
                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.
 func (p *importer) importtype(pt, t *types.Type) {
        if pt.Etype == TFORW {
-               copytype(asNode(pt.Nod), t)
-               pt.Sym.Importdef = p.imp
-               pt.Sym.Lastlineno = lineno
-               declare(asNode(pt.Nod), PEXTERN)
+               copytype(typenod(pt), t)
                checkwidth(pt)
        } else {
                // pt.Orig and t must be identical.
@@ -503,7 +481,7 @@ func (p *importer) typ() *types.Type {
                pos := p.pos()
                tsym := p.qualifiedName()
 
-               t = pkgtype(pos, p.imp, tsym)
+               t = importtype(p.imp, pos, tsym)
                p.typList = append(p.typList, t)
                dup := !t.IsKind(types.TFORW) // type already imported
 
@@ -552,7 +530,6 @@ func (p *importer) typ() *types.Type {
                        n.SetClass(PFUNC)
                        checkwidth(n.Type)
                        p.funcList = append(p.funcList, n)
-                       importlist = append(importlist, n)
 
                        // (comment from parser.go)
                        // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
index a72747fa5bb20bdaa88c0b6cab7b7c627b9e42a4..1747ccc29e3005070f549ca5767a974da80e7f1f 100644 (file)
@@ -105,66 +105,98 @@ func dumpexport(bout *bio.Writer) {
        }
 }
 
-// importsym declares symbol s as an imported object representable by op.
-// pkg is the package being imported
-func importsym(pkg *types.Pkg, s *types.Sym, op Op) {
-       if asNode(s.Def) != nil && asNode(s.Def).Op != op {
-               pkgstr := fmt.Sprintf("during import %q", pkg.Path)
-               redeclare(lineno, s, pkgstr)
+func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op) *Node {
+       n := asNode(s.Def)
+       if n == nil {
+               n = dclname(s)
+               s.Def = asTypesNode(n)
+               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.
 // If no such type has been declared yet, a forward declaration is returned.
-// pkg is the package being imported
-func pkgtype(pos src.XPos, pkg *types.Pkg, s *types.Sym) *types.Type {
-       importsym(pkg, s, OTYPE)
-       if asNode(s.Def) == nil || asNode(s.Def).Op != OTYPE {
+// ipkg is the package being imported
+func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
+       n := importsym(ipkg, pos, s, OTYPE)
+       if n.Op != OTYPE {
                t := types.New(TFORW)
                t.Sym = s
-               s.Def = asTypesNode(typenodl(pos, t))
-               asNode(s.Def).Name = new(Name)
+               t.Nod = asTypesNode(n)
+
+               n.Op = OTYPE
+               n.Pos = pos
+               n.Type = t
+               n.SetClass(PEXTERN)
        }
 
-       if asNode(s.Def).Type == nil {
-               Fatalf("pkgtype %v", s)
+       t := n.Type
+       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.
-// pkg is the package being imported
-func importconst(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type, val Val) {
-       importsym(pkg, s, OLITERAL)
-       if asNode(s.Def) != nil { // TODO: check if already the same.
+// ipkg is the package being imported
+func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val Val) {
+       n := importobj(ipkg, pos, s, OLITERAL, PEXTERN, t)
+       if n == nil { // TODO: Check that value matches.
                return
        }
 
-       n := npos(pos, nodlit(val))
-       n.Type = t
-       n.Sym = s
-       declare(n, PEXTERN)
+       n.SetVal(val)
 
        if Debug['E'] != 0 {
-               fmt.Printf("import const %v\n", s)
+               fmt.Printf("import const %v %L = %v\n", s, t, val)
        }
 }
 
-// importvar declares symbol s as an imported variable with type t.
-// pkg is the package being imported
-func importvar(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
-       importsym(pkg, s, ONAME)
-       if asNode(s.Def) != nil && asNode(s.Def).Op == ONAME {
-               if eqtype(t, asNode(s.Def).Type) {
-                       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)
+// 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 := newnamel(pos, s)
-       s.Importdef = pkg
-       n.Type = t
-       declare(n, PEXTERN)
+       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.
+// ipkg is the package being imported
+func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
+       n := importobj(ipkg, pos, s, ONAME, PEXTERN, t)
+       if n == nil {
+               return
+       }
 
        if Debug['E'] != 0 {
                fmt.Printf("import var %v %L\n", s, t)
@@ -172,22 +204,13 @@ func importvar(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
 }
 
 // importalias declares symbol s as an imported type alias with type t.
-// pkg is the package being imported
-func importalias(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type) {
-       importsym(pkg, s, OTYPE)
-       if asNode(s.Def) != nil && asNode(s.Def).Op == OTYPE {
-               if eqtype(t, asNode(s.Def).Type) {
-                       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)
+// ipkg is the package being imported
+func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
+       n := importobj(ipkg, pos, s, OTYPE, PEXTERN, t)
+       if n == nil {
+               return
        }
 
-       n := newnamel(pos, s)
-       n.Op = OTYPE
-       s.Importdef = pkg
-       n.Type = t
-       declare(n, PEXTERN)
-
        if Debug['E'] != 0 {
                fmt.Printf("import type %v = %L\n", s, t)
        }
index 89904286052469607cb6d6e34df292484cc21c7b..80c7db5357a1bf0a087caeec46a21bc60676c1dd 100644 (file)
@@ -915,12 +915,9 @@ func loadsys() {
                typ := typs[d.typ]
                switch d.tag {
                case funcTag:
-                       importsym(Runtimepkg, sym, ONAME)
-                       n := newfuncname(sym)
-                       n.Type = typ
-                       declare(n, PFUNC)
+                       importfunc(Runtimepkg, src.NoXPos, sym, typ)
                case varTag:
-                       importvar(lineno, Runtimepkg, sym, typ)
+                       importvar(Runtimepkg, src.NoXPos, sym, typ)
                default:
                        Fatalf("unhandled declaration tag %v", d.tag)
                }