}
}
-func importsym(ipkg *types.Pkg, s *types.Sym, op ir.Op) *ir.Name {
- n := ir.AsNode(s.PkgDef())
- if n == nil {
- // iimport should have created a stub ONONAME
- // declaration for all imported symbols. The exception
- // is declarations for Runtimepkg, which are populated
- // by loadsys instead.
- if s.Pkg != Runtimepkg {
- base.Fatalf("missing ONONAME for %v\n", s)
- }
-
- n = ir.NewDeclNameAt(src.NoXPos, s)
- s.SetPkgDef(n)
- s.Importdef = ipkg
- }
- if n.Op() != ir.ONONAME && n.Op() != op {
- redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
+func importsym(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class) *ir.Name {
+ if n := s.PkgDef(); n != nil {
+ base.Fatalf("importsym of symbol that already exists: %v", n)
}
- return n.(*ir.Name)
+
+ n := ir.NewDeclNameAt(pos, s)
+ n.SetOp(op) // TODO(mdempsky): Add as argument to NewDeclNameAt.
+ n.SetClass(ctxt)
+ s.SetPkgDef(n)
+ s.Importdef = ipkg
+ return n
}
// importtype returns the named type declared by symbol s.
// If no such type has been declared yet, a forward declaration is returned.
// ipkg is the package being imported
-func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
- n := importsym(ipkg, s, ir.OTYPE)
- if n.Op() != ir.OTYPE {
- t := types.NewNamed(n)
- n.SetOp(ir.OTYPE)
- n.SetPos(pos)
- n.SetType(t)
- n.SetClass(ir.PEXTERN)
- }
-
- t := n.Type()
- if t == nil {
- base.Fatalf("importtype %v", s)
- }
- return t
+func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *ir.Name {
+ n := importsym(ipkg, pos, s, ir.OTYPE, ir.PEXTERN)
+ n.SetType(types.NewNamed(n))
+ return n
}
// 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 ir.Op, ctxt ir.Class, t *types.Type) ir.Node {
- n := importsym(ipkg, s, op)
- if n.Op() != ir.ONONAME {
- if n.Op() == op && (op == ir.ONAME && n.Class() != ctxt || !types.Identical(n.Type(), t)) {
- redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
- }
- return nil
- }
-
- n.SetOp(op)
- n.SetPos(pos)
- n.SetClass(ctxt)
+func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Name {
+ n := importsym(ipkg, pos, s, op, ctxt)
+ n.SetType(t)
if ctxt == ir.PFUNC {
n.Sym().SetFunc(true)
}
- n.SetType(t)
return n
}
// importconst declares symbol s as an imported constant with type t and value val.
// ipkg is the package being imported
-func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val constant.Value) {
+func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val constant.Value) *ir.Name {
n := importobj(ipkg, pos, s, ir.OLITERAL, ir.PEXTERN, t)
- if n == nil { // TODO: Check that value matches.
- return
- }
-
n.SetVal(val)
-
- if base.Flag.E != 0 {
- fmt.Printf("import const %v %L = %v\n", s, t, val)
- }
+ return n
}
// 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) {
+func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
n := importobj(ipkg, pos, s, ir.ONAME, ir.PFUNC, t)
- if n == nil {
- return
- }
- name := n.(*ir.Name)
fn := ir.NewFunc(pos)
fn.SetType(t)
- name.SetFunc(fn)
- fn.Nname = name
+ n.SetFunc(fn)
+ fn.Nname = n
- if base.Flag.E != 0 {
- fmt.Printf("import func %v%S\n", s, t)
- }
+ return n
}
// 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, ir.ONAME, ir.PEXTERN, t)
- if n == nil {
- return
- }
-
- if base.Flag.E != 0 {
- fmt.Printf("import var %v %L\n", s, t)
- }
+func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
+ return importobj(ipkg, pos, s, ir.ONAME, ir.PEXTERN, t)
}
// importalias declares symbol s as an imported type alias with type t.
// 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, ir.OTYPE, ir.PEXTERN, t)
- if n == nil {
- return
- }
-
- if base.Flag.E != 0 {
- fmt.Printf("import type %v = %L\n", s, t)
- }
+func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
+ return importobj(ipkg, pos, s, ir.OTYPE, ir.PEXTERN, t)
}
func dumpasmhdr() {
inlineImporter = map[*types.Sym]iimporterAndOffset{}
)
-func expandDecl(n *ir.Name) {
- if n.Op() != ir.ONONAME {
- return
+func expandDecl(n ir.Node) ir.Node {
+ if n, ok := n.(*ir.Name); ok {
+ return n
+ }
+
+ id := n.(*ir.Ident)
+ if n := id.Sym().PkgDef(); n != nil {
+ return n.(*ir.Name)
}
- r := importReaderFor(n, declImporter)
+ r := importReaderFor(id.Sym(), declImporter)
if r == nil {
// Can happen if user tries to reference an undeclared name.
- return
+ return n
}
- r.doDecl(n)
+ return r.doDecl(n.Sym())
}
func expandInline(fn *ir.Func) {
return
}
- r := importReaderFor(fn.Nname, inlineImporter)
+ r := importReaderFor(fn.Nname.Sym(), inlineImporter)
if r == nil {
base.Fatalf("missing import reader for %v", fn)
}
r.doInline(fn)
}
-func importReaderFor(n *ir.Name, importers map[*types.Sym]iimporterAndOffset) *importReader {
- x, ok := importers[n.Sym()]
+func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader {
+ x, ok := importers[sym]
if !ok {
return nil
}
- return x.p.newReader(x.off, n.Sym().Pkg)
+ return x.p.newReader(x.off, sym.Pkg)
}
type intReader struct {
r.currPkg = r.pkg()
}
-func (r *importReader) doDecl(n ir.Node) {
- if n.Op() != ir.ONONAME {
- base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym(), n.Op())
- }
-
+func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
tag := r.byte()
pos := r.pos()
case 'A':
typ := r.typ()
- importalias(r.p.ipkg, pos, n.Sym(), typ)
+ return importalias(r.p.ipkg, pos, sym, typ)
case 'C':
typ := r.typ()
val := r.value(typ)
- importconst(r.p.ipkg, pos, n.Sym(), typ, val)
+ return importconst(r.p.ipkg, pos, sym, typ, val)
case 'F':
typ := r.signature(nil)
- importfunc(r.p.ipkg, pos, n.Sym(), typ)
+ n := importfunc(r.p.ipkg, pos, sym, typ)
r.funcExt(n)
+ return n
case 'T':
// Types can be recursive. We need to setup a stub
// declaration before recursing.
- t := importtype(r.p.ipkg, pos, n.Sym())
+ n := importtype(r.p.ipkg, pos, sym)
+ t := n.Type()
// We also need to defer width calculations until
// after the underlying type has been assigned.
if underlying.IsInterface() {
r.typeExt(t)
- break
+ return n
}
ms := make([]*types.Field, r.uint64())
for _, m := range ms {
r.methExt(m)
}
+ return n
case 'V':
typ := r.typ()
- importvar(r.p.ipkg, pos, n.Sym(), typ)
+ n := importvar(r.p.ipkg, pos, sym, typ)
r.varExt(n)
+ return n
default:
base.Fatalf("unexpected tag: %v", tag)
+ panic("unreachable")
}
}
return pkg.Lookup(name)
}
-func (r *importReader) qualifiedIdent() *ir.Name {
+func (r *importReader) qualifiedIdent() *ir.Ident {
name := r.string()
pkg := r.pkg()
sym := pkg.Lookup(name)
- n := sym.PkgDef()
- if n == nil {
- n = ir.NewDeclNameAt(src.NoXPos, sym)
- sym.SetPkgDef(n)
- }
- return n.(*ir.Name)
+ return ir.NewIdent(src.NoXPos, sym)
}
func (r *importReader) pos() src.XPos {
// support inlining functions with local defined
// types. Therefore, this must be a package-scope
// type.
- n := r.qualifiedIdent()
- if n.Op() == ir.ONONAME {
- expandDecl(n)
- }
+ n := expandDecl(r.qualifiedIdent())
if n.Op() != ir.OTYPE {
base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
}