// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Indexed package import.
// See iexport.go for the export data format.

package typecheck

import (
	"encoding/binary"
	"fmt"
	"go/constant"
	"math/big"
	"os"
	"strings"

	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"cmd/internal/src"
)

// An iimporterAndOffset identifies an importer and an offset within
// its data section.
type iimporterAndOffset struct {
	p   *iimporter
	off uint64
}

var (
	// DeclImporter maps from imported identifiers to an importer
	// and offset where that identifier's declaration can be read.
	DeclImporter = map[*types.Sym]iimporterAndOffset{}

	// inlineImporter is like DeclImporter, but for inline bodies
	// for function and method symbols.
	inlineImporter = map[*types.Sym]iimporterAndOffset{}
)

// expandDecl returns immediately if n is already a Name node. Otherwise, n should
// be an Ident node, and expandDecl reads in the definition of the specified
// identifier from the appropriate package.
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(id.Sym(), DeclImporter)
	if r == nil {
		// Can happen if user tries to reference an undeclared name.
		return n
	}

	return r.doDecl(n.Sym())
}

// ImportBody reads in the dcls and body of an imported function (which should not
// yet have been read in).
func ImportBody(fn *ir.Func) {
	if fn.Inl.Body != nil {
		base.Fatalf("%v already has inline body", fn)
	}

	r := importReaderFor(fn.Nname.Sym(), inlineImporter)
	if r == nil {
		base.Fatalf("missing import reader for %v", fn)
	}

	if inimport {
		base.Fatalf("recursive inimport")
	}
	inimport = true
	r.doInline(fn)
	inimport = false
}

// HaveInlineBody reports whether we have fn's inline body available
// for inlining.
func HaveInlineBody(fn *ir.Func) bool {
	if fn.Inl == nil {
		return false
	}

	// Unified IR is much more conservative about pruning unreachable
	// methods (at the cost of increased build artifact size).
	if base.Debug.Unified != 0 {
		return true
	}

	if fn.Inl.Body != nil {
		return true
	}

	_, ok := inlineImporter[fn.Nname.Sym()]
	return ok
}

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, sym.Pkg)
}

type intReader struct {
	*strings.Reader
	pkg *types.Pkg
}

func (r *intReader) int64() int64 {
	i, err := binary.ReadVarint(r.Reader)
	if err != nil {
		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
		base.ErrorExit()
	}
	return i
}

func (r *intReader) uint64() uint64 {
	i, err := binary.ReadUvarint(r.Reader)
	if err != nil {
		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
		base.ErrorExit()
	}
	return i
}

func ReadImports(pkg *types.Pkg, data string) {
	ird := &intReader{strings.NewReader(data), pkg}

	version := ird.uint64()
	switch version {
	case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
	default:
		base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
		base.ErrorExit()
	}

	sLen := int64(ird.uint64())
	dLen := int64(ird.uint64())

	// TODO(mdempsky): Replace os.SEEK_CUR with io.SeekCurrent after
	// #44505 is fixed.
	whence, _ := ird.Seek(0, os.SEEK_CUR)
	stringData := data[whence : whence+sLen]
	declData := data[whence+sLen : whence+sLen+dLen]
	ird.Seek(sLen+dLen, os.SEEK_CUR)

	p := &iimporter{
		exportVersion: version,
		ipkg:          pkg,

		pkgCache:     map[uint64]*types.Pkg{},
		posBaseCache: map[uint64]*src.PosBase{},
		typCache:     map[uint64]*types.Type{},

		stringData: stringData,
		declData:   declData,
	}

	for i, pt := range predeclared() {
		p.typCache[uint64(i)] = pt
	}

	// Declaration index.
	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
		pkg := p.pkgAt(ird.uint64())
		pkgName := p.stringAt(ird.uint64())
		pkgHeight := int(ird.uint64())
		if pkg.Name == "" {
			pkg.Name = pkgName
			pkg.Height = pkgHeight
			types.NumImport[pkgName]++

			// TODO(mdempsky): This belongs somewhere else.
			pkg.Lookup("_").Def = ir.BlankNode
		} else {
			if pkg.Name != pkgName {
				base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
			}
			if pkg.Height != pkgHeight {
				base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
			}
		}

		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
			s := pkg.Lookup(p.nameAt(ird.uint64()))
			off := ird.uint64()

			if _, ok := DeclImporter[s]; !ok {
				DeclImporter[s] = iimporterAndOffset{p, off}
			}
		}
	}

	// Inline body index.
	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
		pkg := p.pkgAt(ird.uint64())

		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
			s := pkg.Lookup(p.nameAt(ird.uint64()))
			off := ird.uint64()

			if _, ok := inlineImporter[s]; !ok {
				inlineImporter[s] = iimporterAndOffset{p, off}
			}
		}
	}
}

type iimporter struct {
	exportVersion uint64
	ipkg          *types.Pkg

	pkgCache     map[uint64]*types.Pkg
	posBaseCache map[uint64]*src.PosBase
	typCache     map[uint64]*types.Type

	stringData string
	declData   string
}

func (p *iimporter) stringAt(off uint64) string {
	var x [binary.MaxVarintLen64]byte
	n := copy(x[:], p.stringData[off:])

	slen, n := binary.Uvarint(x[:n])
	if n <= 0 {
		base.Fatalf("varint failed")
	}
	spos := off + uint64(n)
	return p.stringData[spos : spos+slen]
}

// nameAt is the same as stringAt, except it replaces instances
// of "" with the path of the package being imported.
func (p *iimporter) nameAt(off uint64) string {
	s := p.stringAt(off)
	// Names of objects (functions, methods, globals) may include ""
	// to represent the path name of the imported package.
	// Replace "" with the imported package prefix. This occurs
	// specifically for generics where the names of instantiations
	// and dictionaries contain package-qualified type names.
	// Include the dot to avoid matching with struct tags ending in '"'.
	if strings.Contains(s, "\"\".") {
		s = strings.Replace(s, "\"\".", p.ipkg.Prefix+".", -1)
	}
	return s
}

func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
	if posBase, ok := p.posBaseCache[off]; ok {
		return posBase
	}

	file := p.stringAt(off)
	posBase := src.NewFileBase(file, file)
	p.posBaseCache[off] = posBase
	return posBase
}

func (p *iimporter) pkgAt(off uint64) *types.Pkg {
	if pkg, ok := p.pkgCache[off]; ok {
		return pkg
	}

	pkg := p.ipkg
	if pkgPath := p.stringAt(off); pkgPath != "" {
		pkg = types.NewPkg(pkgPath, "")
	}
	p.pkgCache[off] = pkg
	return pkg
}

// An importReader keeps state for reading an individual imported
// object (declaration or inline body).
type importReader struct {
	strings.Reader
	p *iimporter

	currPkg    *types.Pkg
	prevBase   *src.PosBase
	prevLine   int64
	prevColumn int64

	// curfn is the current function we're importing into.
	curfn *ir.Func
	// Slice of all dcls for function, including any interior closures
	allDcls        []*ir.Name
	allClosureVars []*ir.Name
	autotmpgen     int
}

func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
	r := &importReader{
		p:       p,
		currPkg: pkg,
	}
	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
	// need to build with Go 1.4.
	r.Reader = *strings.NewReader(p.declData[off:])
	return r
}

func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
func (r *importReader) name() string          { return r.p.nameAt(r.uint64()) }
func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }

func (r *importReader) setPkg() {
	r.currPkg = r.pkg()
}

func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
	tag := r.byte()
	pos := r.pos()

	switch tag {
	case 'A':
		typ := r.typ()

		return importalias(pos, sym, typ)

	case 'C':
		typ := r.typ()
		val := r.value(typ)

		n := importconst(pos, sym, typ, val)
		r.constExt(n)
		return n

	case 'F', 'G':
		var tparams []*types.Field
		if tag == 'G' {
			tparams = r.tparamList()
		}
		typ := r.signature(nil, tparams)

		n := importfunc(pos, sym, typ)
		r.funcExt(n)
		return n

	case 'T', 'U':
		// Types can be recursive. We need to setup a stub
		// declaration before recursing.
		n := importtype(pos, sym)
		t := n.Type()

		// Because of recursion, we need to defer width calculations and
		// instantiations on intermediate types until the top-level type is
		// fully constructed. Note that we can have recursion via type
		// constraints.
		types.DeferCheckSize()
		deferDoInst()
		if tag == 'U' {
			rparams := r.typeList()
			t.SetRParams(rparams)
		}

		underlying := r.typ()
		t.SetUnderlying(underlying)

		if underlying.IsInterface() {
			// Finish up all type instantiations and CheckSize calls
			// now that a top-level type is fully constructed.
			resumeDoInst()
			types.ResumeCheckSize()
			r.typeExt(t)
			return n
		}

		ms := make([]*types.Field, r.uint64())
		for i := range ms {
			mpos := r.pos()
			msym := r.selector()
			recv := r.param()
			mtyp := r.signature(recv, nil)

			// MethodSym already marked m.Sym as a function.
			m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym))
			m.Class = ir.PFUNC
			m.SetType(mtyp)

			m.Func = ir.NewFunc(mpos)
			m.Func.Nname = m

			f := types.NewField(mpos, msym, mtyp)
			f.Nname = m
			ms[i] = f
		}
		t.Methods().Set(ms)

		// Finish up all instantiations and CheckSize calls now
		// that a top-level type is fully constructed.
		resumeDoInst()
		types.ResumeCheckSize()

		r.typeExt(t)
		for _, m := range ms {
			r.methExt(m)
		}
		return n

	case 'P':
		if r.p.exportVersion < iexportVersionGenerics {
			base.Fatalf("unexpected type param type")
		}
		if sym.Def != nil {
			// Make sure we use the same type param type for the same
			// name, whether it is created during types1-import or
			// this types2-to-types1 translation.
			return sym.Def.(*ir.Name)
		}
		// The typeparam index is set at the point where the containing type
		// param list is imported.
		t := types.NewTypeParam(sym, 0)
		// Nname needed to save the pos.
		nname := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
		sym.Def = nname
		nname.SetType(t)
		t.SetNod(nname)
		implicit := false
		if r.p.exportVersion >= iexportVersionGo1_18 {
			implicit = r.bool()
		}
		bound := r.typ()
		if implicit {
			bound.MarkImplicit()
		}
		t.SetBound(bound)
		return nname

	case 'V':
		typ := r.typ()

		n := importvar(pos, sym, typ)
		r.varExt(n)
		return n

	default:
		base.Fatalf("unexpected tag: %v", tag)
		panic("unreachable")
	}
}

func (r *importReader) value(typ *types.Type) constant.Value {
	var kind constant.Kind
	var valType *types.Type

	if r.p.exportVersion >= iexportVersionGo1_18 {
		// TODO: add support for using the kind in the non-typeparam case.
		kind = constant.Kind(r.int64())
	}

	if typ.IsTypeParam() {
		if r.p.exportVersion < iexportVersionGo1_18 {
			// If a constant had a typeparam type, then we wrote out its
			// actual constant kind as well.
			kind = constant.Kind(r.int64())
		}
		switch kind {
		case constant.Int:
			valType = types.Types[types.TINT64]
		case constant.Float:
			valType = types.Types[types.TFLOAT64]
		case constant.Complex:
			valType = types.Types[types.TCOMPLEX128]
		}
	} else {
		kind = constTypeOf(typ)
		valType = typ
	}

	switch kind {
	case constant.Bool:
		return constant.MakeBool(r.bool())
	case constant.String:
		return constant.MakeString(r.string())
	case constant.Int:
		var i big.Int
		r.mpint(&i, valType)
		return constant.Make(&i)
	case constant.Float:
		return r.float(valType)
	case constant.Complex:
		return makeComplex(r.float(valType), r.float(valType))
	}

	base.Fatalf("unexpected value type: %v", typ)
	panic("unreachable")
}

func (r *importReader) mpint(x *big.Int, typ *types.Type) {
	signed, maxBytes := intSize(typ)

	maxSmall := 256 - maxBytes
	if signed {
		maxSmall = 256 - 2*maxBytes
	}
	if maxBytes == 1 {
		maxSmall = 256
	}

	n, _ := r.ReadByte()
	if uint(n) < maxSmall {
		v := int64(n)
		if signed {
			v >>= 1
			if n&1 != 0 {
				v = ^v
			}
		}
		x.SetInt64(v)
		return
	}

	v := -n
	if signed {
		v = -(n &^ 1) >> 1
	}
	if v < 1 || uint(v) > maxBytes {
		base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
	}
	b := make([]byte, v)
	r.Read(b)
	x.SetBytes(b)
	if signed && n&1 != 0 {
		x.Neg(x)
	}
}

func (r *importReader) float(typ *types.Type) constant.Value {
	var mant big.Int
	r.mpint(&mant, typ)
	var f big.Float
	f.SetInt(&mant)
	if f.Sign() != 0 {
		f.SetMantExp(&f, int(r.int64()))
	}
	return constant.Make(&f)
}

func (r *importReader) mprat(orig constant.Value) constant.Value {
	if !r.bool() {
		return orig
	}
	var rat big.Rat
	rat.SetString(r.string())
	return constant.Make(&rat)
}

func (r *importReader) ident(selector bool) *types.Sym {
	name := r.string()
	if name == "" {
		return nil
	}
	pkg := r.currPkg
	if selector {
		if types.IsExported(name) {
			pkg = types.LocalPkg
		}
	} else {
		if name == "$autotmp" {
			name = autotmpname(r.autotmpgen)
			r.autotmpgen++
		}
	}
	return pkg.Lookup(name)
}

func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
func (r *importReader) selector() *types.Sym   { return r.ident(true) }

func (r *importReader) qualifiedIdent() *ir.Ident {
	name := r.name()
	pkg := r.pkg()
	sym := pkg.Lookup(name)
	return ir.NewIdent(src.NoXPos, sym)
}

func (r *importReader) pos() src.XPos {
	delta := r.int64()
	r.prevColumn += delta >> 1
	if delta&1 != 0 {
		delta = r.int64()
		r.prevLine += delta >> 1
		if delta&1 != 0 {
			r.prevBase = r.posBase()
		}
	}

	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
		// TODO(mdempsky): Remove once we reliably write
		// position information for all nodes.
		return src.NoXPos
	}

	if r.prevBase == nil {
		base.Fatalf("missing posbase")
	}
	pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
	return base.Ctxt.PosTable.XPos(pos)
}

func (r *importReader) typ() *types.Type {
	// If this is a top-level type call, defer type instantiations until the
	// type is fully constructed.
	types.DeferCheckSize()
	deferDoInst()
	t := r.p.typAt(r.uint64())
	resumeDoInst()
	types.ResumeCheckSize()
	return t
}

func (r *importReader) exoticType() *types.Type {
	switch r.uint64() {
	case exoticTypeNil:
		return nil
	case exoticTypeTuple:
		funarg := types.Funarg(r.uint64())
		n := r.uint64()
		fs := make([]*types.Field, n)
		for i := range fs {
			pos := r.pos()
			var sym *types.Sym
			switch r.uint64() {
			case exoticTypeSymNil:
				sym = nil
			case exoticTypeSymNoPkg:
				sym = types.NoPkg.Lookup(r.string())
			case exoticTypeSymWithPkg:
				pkg := r.pkg()
				sym = pkg.Lookup(r.string())
			default:
				base.Fatalf("unknown symbol kind")
			}
			typ := r.typ()
			f := types.NewField(pos, sym, typ)
			fs[i] = f
		}
		t := types.NewStruct(types.NoPkg, fs)
		t.StructType().Funarg = funarg
		return t
	case exoticTypeRecv:
		var rcvr *types.Field
		if r.bool() { // isFakeRecv
			rcvr = types.FakeRecv()
		} else {
			rcvr = r.exoticParam()
		}
		return r.exoticSignature(rcvr)
	case exoticTypeRegular:
		return r.typ()
	default:
		base.Fatalf("bad kind of call type")
		return nil
	}
}

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) exoticSignature(recv *types.Field) *types.Type {
	var pkg *types.Pkg
	if r.bool() { // hasPkg
		pkg = r.pkg()
	}
	params := r.exoticParamList()
	results := r.exoticParamList()
	return types.NewSignature(pkg, recv, nil, params, results)
}

func (r *importReader) exoticParamList() []*types.Field {
	n := r.uint64()
	fs := make([]*types.Field, n)
	for i := range fs {
		fs[i] = r.exoticParam()
	}
	return fs
}

func (r *importReader) exoticParam() *types.Field {
	pos := r.pos()
	sym := r.exoticSym()
	off := r.uint64()
	typ := r.exoticType()
	ddd := r.bool()
	f := types.NewField(pos, sym, typ)
	f.Offset = int64(off)
	if sym != nil {
		f.Nname = ir.NewNameAt(pos, sym)
	}
	f.SetIsDDD(ddd)
	return f
}

func (r *importReader) exoticField() *types.Field {
	pos := r.pos()
	sym := r.exoticSym()
	off := r.uint64()
	typ := r.exoticType()
	note := r.string()
	f := types.NewField(pos, sym, typ)
	f.Offset = int64(off)
	if sym != nil {
		f.Nname = ir.NewNameAt(pos, sym)
	}
	f.Note = note
	return f
}

func (r *importReader) exoticSym() *types.Sym {
	name := r.string()
	if name == "" {
		return nil
	}
	var pkg *types.Pkg
	if types.IsExported(name) {
		pkg = types.LocalPkg
	} else {
		pkg = r.pkg()
	}
	return pkg.Lookup(name)
}

func (p *iimporter) typAt(off uint64) *types.Type {
	t, ok := p.typCache[off]
	if !ok {
		if off < predeclReserved {
			base.Fatalf("predeclared type missing from cache: %d", off)
		}
		t = p.newReader(off-predeclReserved, nil).typ1()
		// Ensure size is calculated for imported types. Since CL 283313, the compiler
		// does not compile the function immediately when it sees them. Instead, funtions
		// are pushed to compile queue, then draining from the queue for compiling.
		// During this process, the size calculation is disabled, so it is not safe for
		// calculating size during SSA generation anymore. See issue #44732.
		//
		// No need to calc sizes for re-instantiated generic types, and
		// they are not necessarily resolved until the top-level type is
		// defined (because of recursive types).
		if t.OrigType() == nil || !t.HasTParam() {
			types.CheckSize(t)
		}
		p.typCache[off] = t
	}
	return t
}

func (r *importReader) typ1() *types.Type {
	switch k := r.kind(); k {
	default:
		base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
		return nil

	case definedType:
		// We might be called from within doInline, in which
		// case Sym.Def can point to declared parameters
		// instead of the top-level types. Also, we don't
		// support inlining functions with local defined
		// types. Therefore, this must be a package-scope
		// type.
		n := expandDecl(r.qualifiedIdent())
		if n.Op() != ir.OTYPE {
			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
		}
		return n.Type()
	case pointerType:
		return types.NewPtr(r.typ())
	case sliceType:
		return types.NewSlice(r.typ())
	case arrayType:
		n := r.uint64()
		return types.NewArray(r.typ(), int64(n))
	case chanType:
		dir := types.ChanDir(r.uint64())
		return types.NewChan(r.typ(), dir)
	case mapType:
		return types.NewMap(r.typ(), r.typ())

	case signatureType:
		r.setPkg()
		return r.signature(nil, nil)

	case structType:
		r.setPkg()

		fs := make([]*types.Field, r.uint64())
		for i := range fs {
			pos := r.pos()
			sym := r.selector()
			typ := r.typ()
			emb := r.bool()
			note := r.string()

			f := types.NewField(pos, sym, typ)
			if emb {
				f.Embedded = 1
			}
			f.Note = note
			fs[i] = f
		}

		return types.NewStruct(r.currPkg, fs)

	case interfaceType:
		r.setPkg()

		embeddeds := make([]*types.Field, r.uint64())
		for i := range embeddeds {
			pos := r.pos()
			typ := r.typ()

			embeddeds[i] = types.NewField(pos, nil, typ)
		}

		methods := make([]*types.Field, r.uint64())
		for i := range methods {
			pos := r.pos()
			sym := r.selector()
			typ := r.signature(types.FakeRecv(), nil)

			methods[i] = types.NewField(pos, sym, typ)
		}

		if len(embeddeds)+len(methods) == 0 {
			return types.Types[types.TINTER]
		}

		t := types.NewInterface(r.currPkg, append(embeddeds, methods...), false)

		// Ensure we expand the interface in the frontend (#25055).
		types.CheckSize(t)
		return t

	case typeParamType:
		if r.p.exportVersion < iexportVersionGenerics {
			base.Fatalf("unexpected type param type")
		}
		// Similar to code for defined types, since we "declared"
		// typeparams to deal with recursion (typeparam is used within its
		// own type bound).
		ident := r.qualifiedIdent()
		if ident.Sym().Def != nil {
			return ident.Sym().Def.(*ir.Name).Type()
		}
		n := expandDecl(ident)
		if n.Op() != ir.OTYPE {
			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
		}
		return n.Type()

	case instanceType:
		if r.p.exportVersion < iexportVersionGenerics {
			base.Fatalf("unexpected instantiation type")
		}
		pos := r.pos()
		len := r.uint64()
		targs := make([]*types.Type, len)
		for i := range targs {
			targs[i] = r.typ()
		}
		baseType := r.typ()
		t := Instantiate(pos, baseType, targs)
		return t

	case unionType:
		if r.p.exportVersion < iexportVersionGenerics {
			base.Fatalf("unexpected instantiation type")
		}
		nt := int(r.uint64())
		terms := make([]*types.Type, nt)
		tildes := make([]bool, nt)
		for i := range terms {
			tildes[i] = r.bool()
			terms[i] = r.typ()
		}
		return types.NewUnion(terms, tildes)
	}
}

func (r *importReader) kind() itag {
	return itag(r.uint64())
}

func (r *importReader) signature(recv *types.Field, tparams []*types.Field) *types.Type {
	params := r.paramList()
	results := r.paramList()
	if n := len(params); n > 0 {
		params[n-1].SetIsDDD(r.bool())
	}
	return types.NewSignature(r.currPkg, recv, tparams, params, results)
}

func (r *importReader) typeList() []*types.Type {
	n := r.uint64()
	if n == 0 {
		return nil
	}
	ts := make([]*types.Type, n)
	for i := range ts {
		ts[i] = r.typ()
		if ts[i].IsTypeParam() {
			ts[i].SetIndex(i)
		}
	}
	return ts
}

func (r *importReader) tparamList() []*types.Field {
	n := r.uint64()
	if n == 0 {
		return nil
	}
	fs := make([]*types.Field, n)
	for i := range fs {
		typ := r.typ()
		typ.SetIndex(i)
		fs[i] = types.NewField(typ.Pos(), typ.Sym(), typ)
	}
	return fs
}

func (r *importReader) paramList() []*types.Field {
	fs := make([]*types.Field, r.uint64())
	for i := range fs {
		fs[i] = r.param()
	}
	return fs
}

func (r *importReader) param() *types.Field {
	return types.NewField(r.pos(), r.localIdent(), r.typ())
}

func (r *importReader) bool() bool {
	return r.uint64() != 0
}

func (r *importReader) int64() int64 {
	n, err := binary.ReadVarint(r)
	if err != nil {
		base.Fatalf("readVarint: %v", err)
	}
	return n
}

func (r *importReader) uint64() uint64 {
	n, err := binary.ReadUvarint(r)
	if err != nil {
		base.Fatalf("readVarint: %v", err)
	}
	return n
}

func (r *importReader) byte() byte {
	x, err := r.ReadByte()
	if err != nil {
		base.Fatalf("declReader.ReadByte: %v", err)
	}
	return x
}

// Compiler-specific extensions.

func (r *importReader) constExt(n *ir.Name) {
	switch n.Type() {
	case types.UntypedFloat:
		n.SetVal(r.mprat(n.Val()))
	case types.UntypedComplex:
		v := n.Val()
		re := r.mprat(constant.Real(v))
		im := r.mprat(constant.Imag(v))
		n.SetVal(makeComplex(re, im))
	}
}

func (r *importReader) varExt(n *ir.Name) {
	r.linkname(n.Sym())
	r.symIdx(n.Sym())
}

func (r *importReader) funcExt(n *ir.Name) {
	r.linkname(n.Sym())
	r.symIdx(n.Sym())

	n.Func.ABI = obj.ABI(r.uint64())

	// Make sure //go:noinline pragma is imported (so stenciled functions have
	// same noinline status as the corresponding generic function.)
	n.Func.Pragma = ir.PragmaFlag(r.uint64())

	// Escape analysis.
	for _, fs := range &types.RecvsParams {
		for _, f := range fs(n.Type()).FieldSlice() {
			f.Note = r.string()
		}
	}

	// Inline body.
	if u := r.uint64(); u > 0 {
		n.Func.Inl = &ir.Inline{
			Cost:            int32(u - 1),
			CanDelayResults: r.bool(),
		}
		n.Func.Endlineno = r.pos()
	}
}

func (r *importReader) methExt(m *types.Field) {
	if r.bool() {
		m.SetNointerface(true)
	}
	r.funcExt(m.Nname.(*ir.Name))
}

func (r *importReader) linkname(s *types.Sym) {
	s.Linkname = r.string()
}

func (r *importReader) symIdx(s *types.Sym) {
	lsym := s.Linksym()
	idx := int32(r.int64())
	if idx != -1 {
		if s.Linkname != "" {
			base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
		}
		lsym.SymIdx = idx
		lsym.Set(obj.AttrIndexed, true)
	}
}

func (r *importReader) typeExt(t *types.Type) {
	t.SetNotInHeap(r.bool())
	SetBaseTypeIndex(t, r.int64(), r.int64())
}

func SetBaseTypeIndex(t *types.Type, i, pi int64) {
	if t.Obj() == nil {
		base.Fatalf("SetBaseTypeIndex on non-defined type %v", t)
	}
	if i != -1 && pi != -1 {
		typeSymIdx[t] = [2]int64{i, pi}
	}
}

// Map imported type T to the index of type descriptor symbols of T and *T,
// so we can use index to reference the symbol.
// TODO(mdempsky): Store this information directly in the Type's Name.
var typeSymIdx = make(map[*types.Type][2]int64)

func BaseTypeIndex(t *types.Type) int64 {
	tbase := t
	if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
		tbase = t.Elem()
	}
	i, ok := typeSymIdx[tbase]
	if !ok {
		return -1
	}
	if t != tbase {
		return i[1]
	}
	return i[0]
}

func (r *importReader) doInline(fn *ir.Func) {
	if len(fn.Inl.Body) != 0 {
		base.Fatalf("%v already has inline body", fn)
	}

	//fmt.Printf("Importing %s\n", fn.Nname.Sym().Name)
	r.funcBody(fn)

	importlist = append(importlist, fn)

	if base.Flag.E > 0 && base.Flag.LowerM > 2 {
		if base.Flag.LowerM > 3 {
			fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
		} else {
			fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
		}
	}
}

// ----------------------------------------------------------------------------
// Inlined function bodies

// Approach: Read nodes and use them to create/declare the same data structures
// as done originally by the (hidden) parser by closely following the parser's
// original code. In other words, "parsing" the import data (which happens to
// be encoded in binary rather textual form) is the best way at the moment to
// re-establish the syntax tree's invariants. At some future point we might be
// able to avoid this round-about way and create the rewritten nodes directly,
// possibly avoiding a lot of duplicate work (name resolution, type checking).
//
// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
// unrefined nodes (since this is what the importer uses). The respective case
// entries are unreachable in the importer.

func (r *importReader) funcBody(fn *ir.Func) {
	outerfn := r.curfn
	r.curfn = fn

	// Import local declarations.
	fn.Inl.Dcl = r.readFuncDcls(fn)

	// Import function body.
	body := r.stmtList()
	if body == nil {
		// Make sure empty body is not interpreted as
		// no inlineable body (see also parser.fnbody)
		// (not doing so can cause significant performance
		// degradation due to unnecessary calls to empty
		// functions).
		body = []ir.Node{}
	}
	if go117ExportTypes {
		ir.VisitList(body, func(n ir.Node) {
			n.SetTypecheck(1)
		})
	}
	fn.Inl.Body = body

	r.curfn = outerfn
	if base.Flag.W >= 3 {
		fmt.Printf("Imported for %v", fn)
		ir.DumpList("", fn.Inl.Body)
	}
}

func (r *importReader) readNames(fn *ir.Func) []*ir.Name {
	dcls := make([]*ir.Name, r.int64())
	for i := range dcls {
		n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent())
		n.Class = ir.PAUTO // overwritten below for parameters/results
		n.Curfn = fn
		n.SetType(r.typ())
		dcls[i] = n
	}
	r.allDcls = append(r.allDcls, dcls...)
	return dcls
}

func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name {
	dcls := r.readNames(fn)

	// Fixup parameter classes and associate with their
	// signature's type fields.
	i := 0
	fix := func(f *types.Field, class ir.Class) {
		if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") {
			return
		}
		n := dcls[i]
		n.Class = class
		f.Nname = n
		i++
	}

	typ := fn.Type()
	if recv := typ.Recv(); recv != nil {
		fix(recv, ir.PPARAM)
	}
	for _, f := range typ.Params().FieldSlice() {
		fix(f, ir.PPARAM)
	}
	for _, f := range typ.Results().FieldSlice() {
		fix(f, ir.PPARAMOUT)
	}
	return dcls
}

func (r *importReader) localName() *ir.Name {
	i := r.int64()
	if i == -1 {
		return ir.BlankNode.(*ir.Name)
	}
	if i < 0 {
		return r.allClosureVars[-i-2]
	}
	return r.allDcls[i]
}

func (r *importReader) stmtList() []ir.Node {
	var list []ir.Node
	for {
		n := r.node()
		if n == nil {
			break
		}
		// OBLOCK nodes are not written to the import data directly,
		// but the handling of ODCL calls liststmt, which creates one.
		// Inline them into the statement list.
		if n.Op() == ir.OBLOCK {
			n := n.(*ir.BlockStmt)
			list = append(list, n.List...)
			continue
		}
		if len(list) > 0 {
			// check for an optional label that can only immediately
			// precede a for/range/select/switch statement.
			if last := list[len(list)-1]; last.Op() == ir.OLABEL {
				label := last.(*ir.LabelStmt).Label
				switch n.Op() {
				case ir.OFOR:
					n.(*ir.ForStmt).Label = label
				case ir.ORANGE:
					n.(*ir.RangeStmt).Label = label
				case ir.OSELECT:
					n.(*ir.SelectStmt).Label = label
				case ir.OSWITCH:
					n.(*ir.SwitchStmt).Label = label
				}
			}
		}
		list = append(list, n)
	}
	return list
}

func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
	namedTypeSwitch := isNamedTypeSwitch(switchExpr)

	cases := make([]*ir.CaseClause, r.uint64())
	for i := range cases {
		cas := ir.NewCaseStmt(r.pos(), nil, nil)
		cas.List = r.stmtList()
		if namedTypeSwitch {
			cas.Var = r.localName()
			cas.Var.Defn = switchExpr
		}
		cas.Body = r.stmtList()
		cases[i] = cas
	}
	return cases
}

func (r *importReader) commList() []*ir.CommClause {
	cases := make([]*ir.CommClause, r.uint64())
	for i := range cases {
		pos := r.pos()
		defaultCase := r.bool()
		var comm ir.Node
		if !defaultCase {
			comm = r.node()
		}
		cases[i] = ir.NewCommStmt(pos, comm, r.stmtList())
	}
	return cases
}

func (r *importReader) exprList() []ir.Node {
	var list []ir.Node
	for {
		n := r.expr()
		if n == nil {
			break
		}
		list = append(list, n)
	}
	return list
}

func (r *importReader) expr() ir.Node {
	n := r.node()
	if n != nil && n.Op() == ir.OBLOCK {
		n := n.(*ir.BlockStmt)
		base.Fatalf("unexpected block node: %v", n)
	}
	return n
}

// TODO(gri) split into expr and stmt
func (r *importReader) node() ir.Node {
	op := r.op()
	switch op {
	// expressions
	// case OPAREN:
	// 	unreachable - unpacked by exporter

	case ir.ONIL:
		pos := r.pos()
		typ := r.typ()

		n := ir.NewNilExpr(pos)
		n.SetType(typ)
		return n

	case ir.OLITERAL:
		pos := r.pos()
		typ := r.typ()

		n := ir.NewBasicLit(pos, r.value(typ))
		n.SetType(typ)
		return n

	case ir.ONONAME:
		isKey := r.bool()
		n := r.qualifiedIdent()
		if go117ExportTypes {
			var n2 ir.Node = n
			// Key ONONAME entries should not be resolved - they should
			// stay as identifiers.
			if !isKey {
				n2 = Resolve(n)
			}
			typ := r.typ()
			if n2.Type() == nil {
				n2.SetType(typ)
			}
			return n2
		}
		return n

	case ir.ONAME:
		isBuiltin := r.bool()
		if isBuiltin {
			pkg := types.BuiltinPkg
			if r.bool() {
				pkg = types.UnsafePkg
			}
			return pkg.Lookup(r.string()).Def.(*ir.Name)
		}
		return r.localName()

	// case OPACK, ONONAME:
	// 	unreachable - should have been resolved by typechecking

	case ir.OTYPE:
		return ir.TypeNode(r.typ())

	case ir.ODYNAMICTYPE:
		n := ir.NewDynamicType(r.pos(), r.expr())
		if r.bool() {
			n.ITab = r.expr()
		}
		n.SetType(r.typ())
		return n

	case ir.OTYPESW:
		pos := r.pos()
		var tag *ir.Ident
		if s := r.localIdent(); s != nil {
			tag = ir.NewIdent(pos, s)
		}
		return ir.NewTypeSwitchGuard(pos, tag, r.expr())

	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
	//      unreachable - should have been resolved by typechecking

	case ir.OCLOSURE:
		//println("Importing CLOSURE")
		pos := r.pos()
		r.setPkg()
		typ := r.signature(nil, nil)
		r.setPkg()

		// All the remaining code below is similar to (*noder).funcLit(), but
		// with Dcls and ClosureVars lists already set up
		fn := ir.NewClosureFunc(pos, true)
		fn.Nname.SetType(typ)

		cvars := make([]*ir.Name, r.int64())
		for i := range cvars {
			cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
			if go117ExportTypes && cvars[i].Defn == nil {
				base.Fatalf("bad import of closure variable")
			}
		}
		fn.ClosureVars = cvars
		r.allClosureVars = append(r.allClosureVars, cvars...)

		fn.Inl = &ir.Inline{}
		// Read in the Dcls and Body of the closure after temporarily
		// setting r.curfn to fn.
		r.funcBody(fn)
		fn.Dcl = fn.Inl.Dcl
		fn.Body = fn.Inl.Body
		if len(fn.Body) == 0 {
			// An empty closure must be represented as a single empty
			// block statement, else it will be dropped.
			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
		}
		fn.Inl = nil

		ir.FinishCaptureNames(pos, r.curfn, fn)

		clo := fn.OClosure
		if go117ExportTypes {
			clo.SetType(typ)
		}
		return clo

	case ir.OSTRUCTLIT:
		if go117ExportTypes {
			pos := r.pos()
			typ := r.typ()
			list := r.fieldList()
			n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list)
			n.SetType(typ)
			return n
		}
		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())

	case ir.OCOMPLIT:
		pos := r.pos()
		t := r.typ()
		n := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ir.TypeNode(t), r.exprList())
		n.SetType(t)
		return n

	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
		if !go117ExportTypes {
			// unreachable - mapped to OCOMPLIT by exporter
			goto error
		}
		pos := r.pos()
		typ := r.typ()
		list := r.exprList()
		n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list)
		n.SetType(typ)
		if op == ir.OSLICELIT {
			n.Len = int64(r.uint64())
		}
		return n

	case ir.OKEY:
		return ir.NewKeyExpr(r.pos(), r.expr(), r.expr())

	// case OSTRUCTKEY:
	//	unreachable - handled in case OSTRUCTLIT by elemList

	case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OMETHVALUE, ir.OMETHEXPR:
		// For !go117ExportTypes,  we should only see OXDOT.
		// For go117ExportTypes, we usually see all the other ops, but can see
		// OXDOT for generic functions.
		if op != ir.OXDOT && !go117ExportTypes {
			goto error
		}
		pos := r.pos()
		expr := r.expr()
		sel := r.exoticSelector()
		n := ir.NewSelectorExpr(pos, op, expr, sel)
		if go117ExportTypes {
			n.SetType(r.exoticType())
			switch op {
			case ir.OXDOT:
				hasSelection := r.bool()
				// We reconstruct n.Selection for method calls on
				// generic types and method calls due to type param
				// bounds.  Otherwise, n.Selection is nil.
				if hasSelection {
					n1 := ir.NewSelectorExpr(pos, op, expr, sel)
					AddImplicitDots(n1)
					var m *types.Field
					if n1.X.Type().IsTypeParam() {
						genType := n1.X.Type().Bound()
						m = Lookdot1(n1, sel, genType, genType.AllMethods(), 1)
					} else {
						genType := types.ReceiverBaseType(n1.X.Type())
						if genType.IsInstantiatedGeneric() {
							genType = genType.OrigType()
						}
						m = Lookdot1(n1, sel, genType, genType.Methods(), 1)
					}
					assert(m != nil)
					n.Selection = m
				}
			case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
				n.Selection = r.exoticField()
			case ir.OMETHEXPR:
				n = typecheckMethodExpr(n).(*ir.SelectorExpr)
			case ir.ODOTMETH, ir.OMETHVALUE:
				// These require a Lookup to link to the correct declaration.
				rcvrType := expr.Type()
				typ := n.Type()
				n.Selection = Lookdot(n, rcvrType, 1)
				if op == ir.OMETHVALUE {
					// Lookdot clobbers the opcode and type, undo that.
					n.SetOp(op)
					n.SetType(typ)
				}
			}
		}
		return n

	case ir.ODOTTYPE, ir.ODOTTYPE2:
		n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil)
		n.SetType(r.typ())
		if go117ExportTypes {
			n.SetOp(op)
		}
		return n

	case ir.ODYNAMICDOTTYPE, ir.ODYNAMICDOTTYPE2:
		n := ir.NewDynamicTypeAssertExpr(r.pos(), op, r.expr(), r.expr())
		n.SetType(r.typ())
		return n

	case ir.OINDEX, ir.OINDEXMAP:
		n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr())
		if go117ExportTypes {
			n.SetOp(op)
			n.SetType(r.exoticType())
			if op == ir.OINDEXMAP {
				n.Assigned = r.bool()
			}
		}
		return n

	case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
		pos, x := r.pos(), r.expr()
		low, high := r.exprsOrNil()
		var max ir.Node
		if op.IsSlice3() {
			max = r.expr()
		}
		n := ir.NewSliceExpr(pos, op, x, low, high, max)
		if go117ExportTypes {
			n.SetType(r.typ())
		}
		return n

	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
		if !go117ExportTypes && op != ir.OCONV {
			// 	unreachable - mapped to OCONV case by exporter
			goto error
		}
		return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())

	case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN, ir.OUNSAFEADD, ir.OUNSAFESLICE:
		if go117ExportTypes {
			switch op {
			case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
				n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
				n.SetType(r.typ())
				return n
			case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
				n := ir.NewUnaryExpr(r.pos(), op, r.expr())
				if op != ir.OPANIC {
					n.SetType(r.typ())
				}
				return n
			case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
				n := ir.NewCallExpr(r.pos(), op, nil, r.exprList())
				if op == ir.OAPPEND {
					n.IsDDD = r.bool()
				}
				if op == ir.OAPPEND || op == ir.ORECOVER {
					n.SetType(r.typ())
				}
				return n
			}
			// ir.OMAKE
			goto error
		}
		n := builtinCall(r.pos(), op)
		n.Args = r.exprList()
		if op == ir.OAPPEND {
			n.IsDDD = r.bool()
		}
		return n

	case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
		pos := r.pos()
		init := r.stmtList()
		n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList())
		if go117ExportTypes {
			n.SetOp(op)
		}
		n.SetInit(init)
		n.IsDDD = r.bool()
		if go117ExportTypes {
			n.SetType(r.exoticType())
		}
		return n

	case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
		if go117ExportTypes {
			pos := r.pos()
			typ := r.typ()
			list := r.exprList()
			var len_, cap_ ir.Node
			if len(list) > 0 {
				len_ = list[0]
			}
			if len(list) > 1 {
				cap_ = list[1]
			}
			n := ir.NewMakeExpr(pos, op, len_, cap_)
			n.SetType(typ)
			return n
		}
		n := builtinCall(r.pos(), ir.OMAKE)
		n.Args.Append(ir.TypeNode(r.typ()))
		n.Args.Append(r.exprList()...)
		return n

	case ir.OLINKSYMOFFSET:
		pos := r.pos()
		name := r.string()
		off := r.uint64()
		typ := r.typ()
		return ir.NewLinksymOffsetExpr(pos, Lookup(name).Linksym(), int64(off), typ)

	// unary expressions
	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV, ir.OIDATA:
		n := ir.NewUnaryExpr(r.pos(), op, r.expr())
		if go117ExportTypes {
			n.SetType(r.typ())
		}
		return n

	case ir.OADDR, ir.OPTRLIT:
		if go117ExportTypes {
			pos := r.pos()
			expr := r.expr()
			expr.SetTypecheck(1) // we do this for all nodes after importing, but do it now so markAddrOf can see it.
			n := NodAddrAt(pos, expr)
			n.SetOp(op)
			n.SetType(r.typ())
			return n
		}
		n := NodAddrAt(r.pos(), r.expr())
		return n

	case ir.ODEREF:
		n := ir.NewStarExpr(r.pos(), r.expr())
		if go117ExportTypes {
			n.SetType(r.typ())
		}
		return n

	// binary expressions
	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
		ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR, ir.OEFACE:
		n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
		if go117ExportTypes {
			n.SetType(r.typ())
		}
		return n

	case ir.OANDAND, ir.OOROR:
		n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
		if go117ExportTypes {
			n.SetType(r.typ())
		}
		return n

	case ir.OSEND:
		return ir.NewSendStmt(r.pos(), r.expr(), r.expr())

	case ir.OADDSTR:
		pos := r.pos()
		list := r.exprList()
		if go117ExportTypes {
			n := ir.NewAddStringExpr(pos, list)
			n.SetType(r.typ())
			return n
		}
		x := list[0]
		for _, y := range list[1:] {
			x = ir.NewBinaryExpr(pos, ir.OADD, x, y)
		}
		return x

	// --------------------------------------------------------------------
	// statements
	case ir.ODCL:
		var stmts ir.Nodes
		n := r.localName()
		stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n))
		stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil))
		return ir.NewBlockStmt(n.Pos(), stmts)

	// case OASWB:
	// 	unreachable - never exported

	case ir.OAS:
		pos := r.pos()
		init := r.stmtList()
		n := ir.NewAssignStmt(pos, r.expr(), r.expr())
		n.SetInit(init)
		n.Def = r.bool()
		return n

	case ir.OASOP:
		n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
		if !r.bool() {
			n.Y = ir.NewInt(1)
			n.IncDec = true
		} else {
			n.Y = r.expr()
		}
		return n

	case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
		if !go117ExportTypes && op != ir.OAS2 {
			// unreachable - mapped to case OAS2 by exporter
			goto error
		}
		pos := r.pos()
		init := r.stmtList()
		n := ir.NewAssignListStmt(pos, op, r.exprList(), r.exprList())
		n.SetInit(init)
		n.Def = r.bool()
		return n

	case ir.ORETURN:
		return ir.NewReturnStmt(r.pos(), r.exprList())

	// case ORETJMP:
	// 	unreachable - generated by compiler for trampolin routines (not exported)

	case ir.OGO, ir.ODEFER:
		return ir.NewGoDeferStmt(r.pos(), op, r.expr())

	case ir.OIF:
		pos, init := r.pos(), r.stmtList()
		n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList())
		n.SetInit(init)
		return n

	case ir.OFOR:
		pos, init := r.pos(), r.stmtList()
		cond, post := r.exprsOrNil()
		n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
		n.SetInit(init)
		return n

	case ir.ORANGE:
		pos, init := r.pos(), r.stmtList()
		k, v := r.exprsOrNil()
		n := ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList())
		n.SetInit(init)
		return n

	case ir.OSELECT:
		pos := r.pos()
		init := r.stmtList()
		n := ir.NewSelectStmt(pos, r.commList())
		n.SetInit(init)
		return n

	case ir.OSWITCH:
		pos := r.pos()
		init := r.stmtList()
		x, _ := r.exprsOrNil()
		n := ir.NewSwitchStmt(pos, x, r.caseList(x))
		n.SetInit(init)
		return n

	// case OCASE:
	//	handled by caseList

	case ir.OFALL:
		return ir.NewBranchStmt(r.pos(), ir.OFALL, nil)

	// case OEMPTY:
	// 	unreachable - not emitted by exporter

	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
		pos := r.pos()
		var sym *types.Sym
		if label := r.string(); label != "" {
			sym = Lookup(label)
		}
		return ir.NewBranchStmt(pos, op, sym)

	case ir.OLABEL:
		return ir.NewLabelStmt(r.pos(), Lookup(r.string()))

	case ir.OEND:
		return nil

	case ir.OFUNCINST:
		pos := r.pos()
		x := r.expr()
		ntargs := r.uint64()
		var targs []ir.Node
		if ntargs > 0 {
			targs = make([]ir.Node, ntargs)
			for i := range targs {
				targs[i] = ir.TypeNode(r.typ())
			}
		}
		n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs)
		if go117ExportTypes {
			n.SetType(r.typ())
		}
		return n

	case ir.OSELRECV2:
		pos := r.pos()
		init := r.stmtList()
		n := ir.NewAssignListStmt(pos, ir.OSELRECV2, r.exprList(), r.exprList())
		n.SetInit(init)
		n.Def = r.bool()
		return n

	default:
		base.Fatalf("cannot import %v (%d) node\n"+
			"\t==> please file an issue and assign to gri@", op, int(op))
		panic("unreachable") // satisfy compiler
	}
error:
	base.Fatalf("cannot import %v (%d) node\n"+
		"\t==> please file an issue and assign to khr@", op, int(op))
	panic("unreachable") // satisfy compiler
}

func (r *importReader) op() ir.Op {
	if debug && r.uint64() != magic {
		base.Fatalf("import stream has desynchronized")
	}
	return ir.Op(r.uint64())
}

func (r *importReader) fieldList() []ir.Node {
	list := make([]ir.Node, r.uint64())
	for i := range list {
		list[i] = ir.NewStructKeyExpr(r.pos(), r.exoticField(), r.expr())
	}
	return list
}

func (r *importReader) exprsOrNil() (a, b ir.Node) {
	ab := r.uint64()
	if ab&1 != 0 {
		a = r.expr()
	}
	if ab&2 != 0 {
		b = r.node()
	}
	return
}

func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
	if go117ExportTypes {
		// These should all be encoded as direct ops, not OCALL.
		base.Fatalf("builtinCall should not be invoked when types are included in import/export")
	}
	return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
}

// NewIncompleteNamedType returns a TFORW type t with name specified by sym, such
// that t.nod and sym.Def are set correctly. If there are any RParams for the type,
// they should be set soon after creating the TFORW type, before creating the
// underlying type. That ensures that the HasTParam and HasShape flags will be set
// properly, in case this type is part of some mutually recursive type.
func NewIncompleteNamedType(pos src.XPos, sym *types.Sym) *types.Type {
	name := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
	forw := types.NewNamed(name)
	name.SetType(forw)
	sym.Def = name
	return forw
}

// Instantiate creates a new named type which is the instantiation of the base
// named generic type, with the specified type args.
func Instantiate(pos src.XPos, baseType *types.Type, targs []*types.Type) *types.Type {
	baseSym := baseType.Sym()
	if strings.Index(baseSym.Name, "[") >= 0 {
		base.Fatalf("arg to Instantiate is not a base generic type")
	}
	name := InstTypeName(baseSym.Name, targs)
	instSym := baseSym.Pkg.Lookup(name)
	if instSym.Def != nil {
		// May match existing type from previous import or
		// types2-to-types1 conversion.
		t := instSym.Def.Type()
		if t.Kind() != types.TFORW {
			return t
		}
		// Or, we have started creating this type in (*TSubster).Typ, but its
		// underlying type was not completed yet, so we need to add this type
		// to deferredInstStack, if not already there.
		found := false
		for _, t2 := range deferredInstStack {
			if t2 == t {
				found = true
				break
			}
		}
		if !found {
			deferredInstStack = append(deferredInstStack, t)
		}
		return t
	}

	t := NewIncompleteNamedType(baseType.Pos(), instSym)
	t.SetRParams(targs)
	t.SetOrigType(baseType)

	// baseType may still be TFORW or its methods may not be fully filled in
	// (since we are in the middle of importing it). So, delay call to
	// substInstType until we get back up to the top of the current top-most
	// type import.
	deferredInstStack = append(deferredInstStack, t)

	return t
}

var deferredInstStack []*types.Type
var deferInst int

// deferDoInst defers substitution on instantiated types until we are at the
// top-most defined type, so the base types are fully defined.
func deferDoInst() {
	deferInst++
}

func resumeDoInst() {
	if deferInst == 1 {
		for len(deferredInstStack) > 0 {
			t := deferredInstStack[0]
			deferredInstStack = deferredInstStack[1:]
			substInstType(t, t.OrigType(), t.RParams())
		}
	}
	deferInst--
}

// doInst creates a new instantiation type (which will be added to
// deferredInstStack for completion later) for an incomplete type encountered
// during a type substitution for an instantiation. This is needed for
// instantiations of mutually recursive types.
func doInst(t *types.Type) *types.Type {
	assert(t.Kind() == types.TFORW)
	return Instantiate(t.Pos(), t.OrigType(), t.RParams())
}

// substInstType completes the instantiation of a generic type by doing a
// substitution on the underlying type itself and any methods. t is the
// instantiation being created, baseType is the base generic type, and targs are
// the type arguments that baseType is being instantiated with.
func substInstType(t *types.Type, baseType *types.Type, targs []*types.Type) {
	assert(t.Kind() == types.TFORW)
	subst := Tsubster{
		Tparams:       baseType.RParams(),
		Targs:         targs,
		SubstForwFunc: doInst,
	}
	t.SetUnderlying(subst.Typ(baseType.Underlying()))

	newfields := make([]*types.Field, baseType.Methods().Len())
	for i, f := range baseType.Methods().Slice() {
		if !f.IsMethod() || types.IsInterfaceMethod(f.Type) {
			// Do a normal substitution if this is a non-method (which
			// means this must be an interface used as a constraint) or
			// an interface method.
			t2 := subst.Typ(f.Type)
			newfields[i] = types.NewField(f.Pos, f.Sym, t2)
			continue
		}
		recvType := f.Type.Recv().Type
		if recvType.IsPtr() {
			recvType = recvType.Elem()
		}
		// Substitute in the method using the type params used in the
		// method (not the type params in the definition of the generic type).
		msubst := Tsubster{
			Tparams:       recvType.RParams(),
			Targs:         targs,
			SubstForwFunc: doInst,
		}
		t2 := msubst.Typ(f.Type)
		oldsym := f.Nname.Sym()
		newsym := MakeFuncInstSym(oldsym, targs, true, true)
		var nname *ir.Name
		if newsym.Def != nil {
			nname = newsym.Def.(*ir.Name)
		} else {
			nname = ir.NewNameAt(f.Pos, newsym)
			nname.SetType(t2)
			ir.MarkFunc(nname)
			newsym.Def = nname
		}
		newfields[i] = types.NewField(f.Pos, f.Sym, t2)
		newfields[i].Nname = nname
	}
	t.Methods().Set(newfields)
	if !t.HasTParam() && !t.HasShape() && t.Kind() != types.TINTER && t.Methods().Len() > 0 {
		// Generate all the methods for a new fully-instantiated,
		// non-interface, non-shape type.
		NeedInstType(t)
	}
}
