// Copyright 2015 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.

// Binary package import.
// See bexport.go for the export data format and how
// to make a format change.

package gc

import (
	"bufio"
	"cmd/compile/internal/types"
	"cmd/internal/src"
	"encoding/binary"
	"fmt"
	"math/big"
	"strconv"
	"strings"
)

// The overall structure of Import is symmetric to Export: For each
// export method in bexport.go there is a matching and symmetric method
// in bimport.go. Changing the export format requires making symmetric
// changes to bimport.go and bexport.go.

type importer struct {
	in      *bufio.Reader
	imp     *types.Pkg // imported package
	buf     []byte     // reused for reading strings
	version int        // export format version

	// object lists, in order of deserialization
	strList       []string
	pathList      []string
	pkgList       []*types.Pkg
	typList       []*types.Type
	funcList      []*Node // nil entry means already declared
	trackAllTypes bool

	// for delayed type verification
	cmpList []struct{ pt, t *types.Type }

	// position encoding
	posInfoFormat bool
	prevFile      string
	prevLine      int
	posBase       *src.PosBase

	// debugging support
	debugFormat bool
	read        int // bytes read
}

// Import populates imp from the serialized package data read from in.
func Import(imp *types.Pkg, in *bufio.Reader) {
	inimport = true
	defer func() { inimport = false }()

	p := importer{
		in:       in,
		imp:      imp,
		version:  -1,           // unknown version
		strList:  []string{""}, // empty string is mapped to 0
		pathList: []string{""}, // empty path is mapped to 0
	}

	// read version info
	var versionstr string
	if b := p.rawByte(); b == 'c' || b == 'd' {
		// Go1.7 encoding; first byte encodes low-level
		// encoding format (compact vs debug).
		// For backward-compatibility only (avoid problems with
		// old installed packages). Newly compiled packages use
		// the extensible format string.
		// TODO(gri) Remove this support eventually; after Go1.8.
		if b == 'd' {
			p.debugFormat = true
		}
		p.trackAllTypes = p.rawByte() == 'a'
		p.posInfoFormat = p.bool()
		versionstr = p.string()
		if versionstr == "v1" {
			p.version = 0
		}
	} else {
		// Go1.8 extensible encoding
		// read version string and extract version number (ignore anything after the version number)
		versionstr = p.rawStringln(b)
		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
				p.version = v
			}
		}
	}

	// read version specific flags - extend as necessary
	switch p.version {
	// case 6:
	// 	...
	//	fallthrough
	case 5, 4, 3, 2, 1:
		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
		p.trackAllTypes = p.bool()
		p.posInfoFormat = p.bool()
	case 0:
		// Go1.7 encoding format - nothing to do here
	default:
		p.formatErrorf("unknown export format version %d (%q)", p.version, versionstr)
	}

	// --- generic export data ---

	// populate typList with predeclared "known" types
	p.typList = append(p.typList, predeclared()...)

	// read package data
	p.pkg()

	// defer some type-checking until all types are read in completely
	tcok := typecheckok
	typecheckok = true
	defercheckwidth()

	// read objects

	// phase 1
	objcount := 0
	for {
		tag := p.tagOrIndex()
		if tag == endTag {
			break
		}
		p.obj(tag)
		objcount++
	}

	// self-verification
	if count := p.int(); count != objcount {
		p.formatErrorf("got %d objects; want %d", objcount, count)
	}

	// --- compiler-specific export data ---

	// read compiler-specific flags

	// phase 2
	objcount = 0
	for {
		tag := p.tagOrIndex()
		if tag == endTag {
			break
		}
		p.obj(tag)
		objcount++
	}

	// self-verification
	if count := p.int(); count != objcount {
		p.formatErrorf("got %d objects; want %d", objcount, count)
	}

	// read inlineable functions bodies
	if dclcontext != PEXTERN {
		p.formatErrorf("unexpected context %d", dclcontext)
	}

	objcount = 0
	for i0 := -1; ; {
		i := p.int() // index of function with inlineable body
		if i < 0 {
			break
		}

		// don't process the same function twice
		if i <= i0 {
			p.formatErrorf("index not increasing: %d <= %d", i, i0)
		}
		i0 = i

		if funcdepth != 0 {
			p.formatErrorf("unexpected Funcdepth %d", funcdepth)
		}

		// Note: In the original code, funchdr and funcbody are called for
		// all functions (that were not yet imported). Now, we are calling
		// them only for functions with inlineable bodies. funchdr does
		// parameter renaming which doesn't matter if we don't have a body.

		inlCost := p.int()
		if f := p.funcList[i]; f != nil && f.Func.Inl.Len() == 0 {
			// function not yet imported - read body and set it
			funchdr(f)
			body := p.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 = []*Node{nod(OEMPTY, nil, nil)}
			}
			f.Func.Inl.Set(body)
			f.Func.InlCost = int32(inlCost)
			if Debug['E'] > 0 && Debug['m'] > 2 && f.Func.Inl.Len() != 0 {
				if Debug['m'] > 3 {
					fmt.Printf("inl body for %v: %+v\n", f, f.Func.Inl)
				} else {
					fmt.Printf("inl body for %v: %v\n", f, f.Func.Inl)
				}
			}
			funcbody()
		} else {
			// function already imported - read body but discard declarations
			dclcontext = PDISCARD // throw away any declarations
			p.stmtList()
			dclcontext = PEXTERN
		}

		objcount++
	}

	// self-verification
	if count := p.int(); count != objcount {
		p.formatErrorf("got %d functions; want %d", objcount, count)
	}

	if dclcontext != PEXTERN {
		p.formatErrorf("unexpected context %d", dclcontext)
	}

	p.verifyTypes()

	// --- end of export data ---

	typecheckok = tcok
	resumecheckwidth()

	if debug_dclstack != 0 {
		testdclstack()
	}
}

func (p *importer) formatErrorf(format string, args ...interface{}) {
	if debugFormat {
		Fatalf(format, args...)
	}

	yyerror("cannot import %q due to version skew - reinstall package (%s)",
		p.imp.Path, fmt.Sprintf(format, args...))
	errorexit()
}

func (p *importer) verifyTypes() {
	for _, pair := range p.cmpList {
		pt := pair.pt
		t := pair.t
		if !eqtype(pt.Orig, t) {
			p.formatErrorf("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, p.imp.Path)
		}
	}
}

// numImport tracks how often a package with a given name is imported.
// It is used to provide a better error message (by using the package
// path to disambiguate) if a package that appears multiple times with
// the same name appears in an error message.
var numImport = make(map[string]int)

func (p *importer) pkg() *types.Pkg {
	// if the package was seen before, i is its index (>= 0)
	i := p.tagOrIndex()
	if i >= 0 {
		return p.pkgList[i]
	}

	// otherwise, i is the package tag (< 0)
	if i != packageTag {
		p.formatErrorf("expected package tag, found tag = %d", i)
	}

	// read package data
	name := p.string()
	var path string
	if p.version >= 5 {
		path = p.path()
	} else {
		path = p.string()
	}

	// we should never see an empty package name
	if name == "" {
		p.formatErrorf("empty package name for path %q", path)
	}

	// we should never see a bad import path
	if isbadimport(path, true) {
		p.formatErrorf("bad package path %q for package %s", path, name)
	}

	// an empty path denotes the package we are currently importing;
	// it must be the first package we see
	if (path == "") != (len(p.pkgList) == 0) {
		p.formatErrorf("package path %q for pkg index %d", path, len(p.pkgList))
	}

	// add package to pkgList
	pkg := p.imp
	if path != "" {
		pkg = types.NewPkg(path, "")
	}
	if pkg.Name == "" {
		pkg.Name = name
		numImport[name]++
	} else if pkg.Name != name {
		yyerror("conflicting package names %s and %s for path %q", pkg.Name, name, path)
	}
	if myimportpath != "" && path == myimportpath {
		yyerror("import %q: package depends on %q (import cycle)", p.imp.Path, path)
		errorexit()
	}
	p.pkgList = append(p.pkgList, pkg)

	return pkg
}

func idealType(typ *types.Type) *types.Type {
	if typ.IsUntyped() {
		// canonicalize ideal types
		typ = types.Types[TIDEAL]
	}
	return typ
}

func (p *importer) obj(tag int) {
	switch tag {
	case constTag:
		pos := p.pos()
		sym := p.qualifiedName()
		typ := p.typ()
		val := p.value(typ)
		importconst(p.imp, sym, idealType(typ), npos(pos, nodlit(val)))

	case aliasTag:
		pos := p.pos()
		sym := p.qualifiedName()
		typ := p.typ()
		importalias(pos, p.imp, sym, typ)

	case typeTag:
		p.typ()

	case varTag:
		pos := p.pos()
		sym := p.qualifiedName()
		typ := p.typ()
		importvar(pos, p.imp, sym, typ)

	case funcTag:
		pos := p.pos()
		sym := p.qualifiedName()
		params := p.paramList()
		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
		// TODO(mdempsky): Stop clobbering n.Pos in declare.
		savedlineno := lineno
		lineno = pos
		declare(n, PFUNC)
		lineno = savedlineno
		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:
		p.formatErrorf("unexpected object (tag = %d)", tag)
	}
}

func (p *importer) pos() src.XPos {
	if !p.posInfoFormat {
		return src.NoXPos
	}

	file := p.prevFile
	line := p.prevLine
	delta := p.int()
	line += delta
	if p.version >= 5 {
		if delta == deltaNewFile {
			if n := p.int(); n >= 0 {
				// file changed
				file = p.path()
				line = n
			}
		}
	} else {
		if delta == 0 {
			if n := p.int(); n >= 0 {
				// file changed
				file = p.prevFile[:n] + p.string()
				line = p.int()
			}
		}
	}
	if file != p.prevFile {
		p.prevFile = file
		p.posBase = src.NewFileBase(file, file)
	}
	p.prevLine = line

	pos := src.MakePos(p.posBase, uint(line), 0)
	xpos := Ctxt.PosTable.XPos(pos)
	return xpos
}

func (p *importer) path() string {
	// if the path was seen before, i is its index (>= 0)
	// (the empty string is at index 0)
	i := p.int()
	if i >= 0 {
		return p.pathList[i]
	}
	// otherwise, i is the negative path length (< 0)
	a := make([]string, -i)
	for n := range a {
		a[n] = p.string()
	}
	s := strings.Join(a, "/")
	p.pathList = append(p.pathList, s)
	return s
}

func (p *importer) newtyp(etype types.EType) *types.Type {
	t := types.New(etype)
	if p.trackAllTypes {
		p.typList = append(p.typList, t)
	}
	return t
}

// 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)
		checkwidth(pt)
	} else {
		// pt.Orig and t must be identical.
		if p.trackAllTypes {
			// If we track all types, t may not be fully set up yet.
			// Collect the types and verify identity later.
			p.cmpList = append(p.cmpList, struct{ pt, t *types.Type }{pt, t})
		} else if !eqtype(pt.Orig, t) {
			yyerror("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, p.imp.Path)
		}
	}

	if Debug['E'] != 0 {
		fmt.Printf("import type %v %L\n", pt, t)
	}
}

func (p *importer) typ() *types.Type {
	// if the type was seen before, i is its index (>= 0)
	i := p.tagOrIndex()
	if i >= 0 {
		return p.typList[i]
	}

	// otherwise, i is the type tag (< 0)
	var t *types.Type
	switch i {
	case namedTag:
		pos := p.pos()
		tsym := p.qualifiedName()

		t = pkgtype(pos, p.imp, tsym)
		p.typList = append(p.typList, t)
		dup := !t.IsKind(types.TFORW) // type already imported

		// read underlying type
		t0 := p.typ()
		// TODO(mdempsky): Stop clobbering n.Pos in declare.
		savedlineno := lineno
		lineno = pos
		p.importtype(t, t0)
		lineno = savedlineno

		// interfaces don't have associated methods
		if t0.IsInterface() {
			break
		}

		// set correct import context (since p.typ() may be called
		// while importing the body of an inlined function)
		savedContext := dclcontext
		dclcontext = PEXTERN

		// read associated methods
		for i := p.int(); i > 0; i-- {
			mpos := p.pos()
			sym := p.fieldSym()

			// during import unexported method names should be in the type's package
			if !exportname(sym.Name) && sym.Pkg != tsym.Pkg {
				Fatalf("imported method name %+v in wrong package %s\n", sym, tsym.Pkg.Name)
			}

			recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
			params := p.paramList()
			result := p.paramList()
			nointerface := p.bool()

			mt := functypefield(recv[0], params, result)
			oldm := addmethod(sym, mt, false, nointerface)

			if dup {
				// An earlier import already declared this type and its methods.
				// Discard the duplicate method declaration.
				n := asNode(oldm.Type.Nname())
				p.funcList = append(p.funcList, n)
				continue
			}

			n := newfuncnamel(mpos, methodname(sym, recv[0].Type))
			n.Type = mt
			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
			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
			// out by typecheck's lookdot as this $$.ttype. So by providing
			// this back link here we avoid special casing there.
			mt.SetNname(asTypesNode(n))

			if Debug['E'] > 0 {
				fmt.Printf("import [%q] meth %v \n", p.imp.Path, n)
			}
		}

		dclcontext = savedContext

	case arrayTag:
		t = p.newtyp(TARRAY)
		bound := p.int64()
		elem := p.typ()
		t.Extra = &types.Array{Elem: elem, Bound: bound}

	case sliceTag:
		t = p.newtyp(TSLICE)
		elem := p.typ()
		t.Extra = types.Slice{Elem: elem}

	case dddTag:
		t = p.newtyp(TDDDFIELD)
		t.Extra = types.DDDField{T: p.typ()}

	case structTag:
		t = p.newtyp(TSTRUCT)
		t.SetFields(p.fieldList())
		checkwidth(t)

	case pointerTag:
		t = p.newtyp(types.Tptr)
		t.Extra = types.Ptr{Elem: p.typ()}

	case signatureTag:
		t = p.newtyp(TFUNC)
		params := p.paramList()
		result := p.paramList()
		functypefield0(t, nil, params, result)

	case interfaceTag:
		if ml := p.methodList(); len(ml) == 0 {
			t = types.Types[TINTER]
		} else {
			t = p.newtyp(TINTER)
			t.SetInterface(ml)
		}

	case mapTag:
		t = p.newtyp(TMAP)
		mt := t.MapType()
		mt.Key = p.typ()
		mt.Val = p.typ()

	case chanTag:
		t = p.newtyp(TCHAN)
		ct := t.ChanType()
		ct.Dir = types.ChanDir(p.int())
		ct.Elem = p.typ()

	default:
		p.formatErrorf("unexpected type (tag = %d)", i)
	}

	if t == nil {
		p.formatErrorf("nil type (type tag = %d)", i)
	}

	return t
}

func (p *importer) qualifiedName() *types.Sym {
	name := p.string()
	pkg := p.pkg()
	return pkg.Lookup(name)
}

func (p *importer) fieldList() (fields []*types.Field) {
	if n := p.int(); n > 0 {
		fields = make([]*types.Field, n)
		for i := range fields {
			fields[i] = p.field()
		}
	}
	return
}

func (p *importer) field() *types.Field {
	pos := p.pos()
	sym, alias := p.fieldName()
	typ := p.typ()
	note := p.string()

	f := types.NewField()
	if sym.Name == "" {
		// anonymous field: typ must be T or *T and T must be a type name
		s := typ.Sym
		if s == nil && typ.IsPtr() {
			s = typ.Elem().Sym // deref
		}
		sym = sym.Pkg.Lookup(s.Name)
		f.Embedded = 1
	} else if alias {
		// anonymous field: we have an explicit name because it's a type alias
		f.Embedded = 1
	}

	f.Sym = sym
	f.Nname = asTypesNode(newnamel(pos, sym))
	f.Type = typ
	f.Note = note

	return f
}

func (p *importer) methodList() (methods []*types.Field) {
	for n := p.int(); n > 0; n-- {
		f := types.NewField()
		f.Nname = asTypesNode(newname(nblank.Sym))
		asNode(f.Nname).Pos = p.pos()
		f.Type = p.typ()
		methods = append(methods, f)
	}

	for n := p.int(); n > 0; n-- {
		methods = append(methods, p.method())
	}

	return
}

func (p *importer) method() *types.Field {
	pos := p.pos()
	sym := p.methodName()
	params := p.paramList()
	result := p.paramList()

	f := types.NewField()
	f.Sym = sym
	f.Nname = asTypesNode(newnamel(pos, sym))
	f.Type = functypefield(fakeRecvField(), params, result)
	return f
}

func (p *importer) fieldName() (*types.Sym, bool) {
	name := p.string()
	if p.version == 0 && name == "_" {
		// version 0 didn't export a package for _ field names
		// but used the builtin package instead
		return builtinpkg.Lookup(name), false
	}
	pkg := localpkg
	alias := false
	switch name {
	case "":
		// 1) field name matches base type name and is exported: nothing to do
	case "?":
		// 2) field name matches base type name and is not exported: need package
		name = ""
		pkg = p.pkg()
	case "@":
		// 3) field name doesn't match base type name (alias name): need name and possibly package
		name = p.string()
		alias = true
		fallthrough
	default:
		if !exportname(name) {
			pkg = p.pkg()
		}
	}
	return pkg.Lookup(name), alias
}

func (p *importer) methodName() *types.Sym {
	name := p.string()
	if p.version == 0 && name == "_" {
		// version 0 didn't export a package for _ method names
		// but used the builtin package instead
		return builtinpkg.Lookup(name)
	}
	pkg := localpkg
	if !exportname(name) {
		pkg = p.pkg()
	}
	return pkg.Lookup(name)
}

func (p *importer) paramList() []*types.Field {
	i := p.int()
	if i == 0 {
		return nil
	}
	// negative length indicates unnamed parameters
	named := true
	if i < 0 {
		i = -i
		named = false
	}
	// i > 0
	fs := make([]*types.Field, i)
	for i := range fs {
		fs[i] = p.param(named)
	}
	return fs
}

func (p *importer) param(named bool) *types.Field {
	f := types.NewField()
	f.Type = p.typ()
	if f.Type.Etype == TDDDFIELD {
		// TDDDFIELD indicates wrapped ... slice type
		f.Type = types.NewSlice(f.Type.DDDField())
		f.SetIsddd(true)
	}

	if named {
		name := p.string()
		if name == "" {
			p.formatErrorf("expected named parameter")
		}
		// TODO(gri) Supply function/method package rather than
		// encoding the package for each parameter repeatedly.
		pkg := localpkg
		if name != "_" {
			pkg = p.pkg()
		}
		f.Sym = pkg.Lookup(name)
		f.Nname = asTypesNode(newname(f.Sym))
	}

	// TODO(gri) This is compiler-specific (escape info).
	// Move into compiler-specific section eventually?
	f.Note = p.string()

	return f
}

func (p *importer) value(typ *types.Type) (x Val) {
	switch tag := p.tagOrIndex(); tag {
	case falseTag:
		x.U = false

	case trueTag:
		x.U = true

	case int64Tag:
		u := new(Mpint)
		u.SetInt64(p.int64())
		u.Rune = typ == types.Idealrune
		x.U = u

	case floatTag:
		f := newMpflt()
		p.float(f)
		if typ == types.Idealint || typ.IsInteger() {
			// uncommon case: large int encoded as float
			u := new(Mpint)
			u.SetFloat(f)
			x.U = u
			break
		}
		x.U = f

	case complexTag:
		u := new(Mpcplx)
		p.float(&u.Real)
		p.float(&u.Imag)
		x.U = u

	case stringTag:
		x.U = p.string()

	case unknownTag:
		p.formatErrorf("unknown constant (importing package with errors)")

	case nilTag:
		x.U = new(NilVal)

	default:
		p.formatErrorf("unexpected value tag %d", tag)
	}

	// verify ideal type
	if typ.IsUntyped() && untype(x.Ctype()) != typ {
		p.formatErrorf("value %v and type %v don't match", x, typ)
	}

	return
}

func (p *importer) float(x *Mpflt) {
	sign := p.int()
	if sign == 0 {
		x.SetFloat64(0)
		return
	}

	exp := p.int()
	mant := new(big.Int).SetBytes([]byte(p.string()))

	m := x.Val.SetInt(mant)
	m.SetMantExp(m, exp-mant.BitLen())
	if sign < 0 {
		m.Neg(m)
	}
}

// ----------------------------------------------------------------------------
// 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 (p *importer) stmtList() []*Node {
	var list []*Node
	for {
		n := p.node()
		if n == nil {
			break
		}
		// OBLOCK nodes may be created when importing ODCL nodes - unpack them
		if n.Op == OBLOCK {
			list = append(list, n.List.Slice()...)
		} else {
			list = append(list, n)
		}
	}
	return list
}

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

func (p *importer) elemList() []*Node {
	c := p.int()
	list := make([]*Node, c)
	for i := range list {
		s := p.fieldSym()
		list[i] = nodSym(OSTRUCTKEY, p.expr(), s)
	}
	return list
}

func (p *importer) expr() *Node {
	n := p.node()
	if n != nil && n.Op == OBLOCK {
		Fatalf("unexpected block node: %v", n)
	}
	return n
}

func npos(pos src.XPos, n *Node) *Node {
	n.Pos = pos
	return n
}

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

	// case ODDDARG:
	//	unimplemented

	case OLITERAL:
		pos := p.pos()
		typ := p.typ()
		n := npos(pos, nodlit(p.value(typ)))
		if !typ.IsUntyped() {
			// Type-checking simplifies unsafe.Pointer(uintptr(c))
			// to unsafe.Pointer(c) which then cannot type-checked
			// again. Re-introduce explicit uintptr(c) conversion.
			// (issue 16317).
			if typ.IsUnsafePtr() {
				n = nodl(pos, OCONV, n, nil)
				n.Type = types.Types[TUINTPTR]
			}
			n = nodl(pos, OCONV, n, nil)
			n.Type = typ
		}
		return n

	case ONAME:
		return npos(p.pos(), mkname(p.sym()))

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

	case OTYPE:
		return npos(p.pos(), typenod(p.typ()))

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

	// case OCLOSURE:
	//	unimplemented

	case OPTRLIT:
		pos := p.pos()
		n := npos(pos, p.expr())
		if !p.bool() /* !implicit, i.e. '&' operator */ {
			if n.Op == OCOMPLIT {
				// Special case for &T{...}: turn into (*T){...}.
				n.Right = nodl(pos, OIND, n.Right, nil)
				n.Right.SetImplicit(true)
			} else {
				n = nodl(pos, OADDR, n, nil)
			}
		}
		return n

	case OSTRUCTLIT:
		// TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
		savedlineno := lineno
		lineno = p.pos()
		n := nodl(lineno, OCOMPLIT, nil, typenod(p.typ()))
		n.List.Set(p.elemList()) // special handling of field names
		lineno = savedlineno
		return n

	// case OARRAYLIT, OSLICELIT, OMAPLIT:
	// 	unreachable - mapped to case OCOMPLIT below by exporter

	case OCOMPLIT:
		n := nodl(p.pos(), OCOMPLIT, nil, typenod(p.typ()))
		n.List.Set(p.exprList())
		return n

	case OKEY:
		pos := p.pos()
		left, right := p.exprsOrNil()
		return nodl(pos, OKEY, left, right)

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

	// case OCALLPART:
	//	unimplemented

	// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
	// 	unreachable - mapped to case OXDOT below by exporter

	case OXDOT:
		// see parser.new_dotname
		return npos(p.pos(), nodSym(OXDOT, p.expr(), p.fieldSym()))

	// case ODOTTYPE, ODOTTYPE2:
	// 	unreachable - mapped to case ODOTTYPE below by exporter

	case ODOTTYPE:
		n := nodl(p.pos(), ODOTTYPE, p.expr(), nil)
		n.Type = p.typ()
		return n

	// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
	// 	unreachable - mapped to cases below by exporter

	case OINDEX:
		return nodl(p.pos(), op, p.expr(), p.expr())

	case OSLICE, OSLICE3:
		n := nodl(p.pos(), op, p.expr(), nil)
		low, high := p.exprsOrNil()
		var max *Node
		if n.Op.IsSlice3() {
			max = p.expr()
		}
		n.SetSliceBounds(low, high, max)
		return n

	// case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
	// 	unreachable - mapped to OCONV case below by exporter

	case OCONV:
		n := nodl(p.pos(), OCONV, p.expr(), nil)
		n.Type = p.typ()
		return n

	case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
		n := npos(p.pos(), builtinCall(op))
		n.List.Set(p.exprList())
		if op == OAPPEND {
			n.SetIsddd(p.bool())
		}
		return n

	// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
	// 	unreachable - mapped to OCALL case below by exporter

	case OCALL:
		n := nodl(p.pos(), OCALL, p.expr(), nil)
		n.List.Set(p.exprList())
		n.SetIsddd(p.bool())
		return n

	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
		n := npos(p.pos(), builtinCall(OMAKE))
		n.List.Append(typenod(p.typ()))
		n.List.Append(p.exprList()...)
		return n

	// unary expressions
	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
		return nodl(p.pos(), op, p.expr(), nil)

	// binary expressions
	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
		return nodl(p.pos(), op, p.expr(), p.expr())

	case OADDSTR:
		pos := p.pos()
		list := p.exprList()
		x := npos(pos, list[0])
		for _, y := range list[1:] {
			x = nodl(pos, OADD, x, y)
		}
		return x

	// case OCMPSTR, OCMPIFACE:
	// 	unreachable - mapped to std comparison operators by exporter

	case ODCLCONST:
		// TODO(gri) these should not be exported in the first place
		return nodl(p.pos(), OEMPTY, nil, nil)

	// --------------------------------------------------------------------
	// statements
	case ODCL:
		if p.version < 2 {
			// versions 0 and 1 exported a bool here but it
			// was always false - simply ignore in this case
			p.bool()
		}
		pos := p.pos()
		lhs := dclname(p.sym())
		typ := typenod(p.typ())
		return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation

	// case ODCLFIELD:
	//	unimplemented

	// case OAS, OASWB:
	// 	unreachable - mapped to OAS case below by exporter

	case OAS:
		return nodl(p.pos(), OAS, p.expr(), p.expr())

	case OASOP:
		n := nodl(p.pos(), OASOP, nil, nil)
		n.Etype = types.EType(p.int())
		n.Left = p.expr()
		if !p.bool() {
			n.Right = nodintconst(1)
			n.SetImplicit(true)
		} else {
			n.Right = p.expr()
		}
		return n

	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
	// 	unreachable - mapped to OAS2 case below by exporter

	case OAS2:
		n := nodl(p.pos(), OAS2, nil, nil)
		n.List.Set(p.exprList())
		n.Rlist.Set(p.exprList())
		return n

	case ORETURN:
		n := nodl(p.pos(), ORETURN, nil, nil)
		n.List.Set(p.exprList())
		return n

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

	case OPROC, ODEFER:
		return nodl(p.pos(), op, p.expr(), nil)

	case OIF:
		n := nodl(p.pos(), OIF, nil, nil)
		n.Ninit.Set(p.stmtList())
		n.Left = p.expr()
		n.Nbody.Set(p.stmtList())
		n.Rlist.Set(p.stmtList())
		return n

	case OFOR:
		n := nodl(p.pos(), OFOR, nil, nil)
		n.Ninit.Set(p.stmtList())
		n.Left, n.Right = p.exprsOrNil()
		n.Nbody.Set(p.stmtList())
		return n

	case ORANGE:
		n := nodl(p.pos(), ORANGE, nil, nil)
		n.List.Set(p.stmtList())
		n.Right = p.expr()
		n.Nbody.Set(p.stmtList())
		return n

	case OSELECT, OSWITCH:
		n := nodl(p.pos(), op, nil, nil)
		n.Ninit.Set(p.stmtList())
		n.Left, _ = p.exprsOrNil()
		n.List.Set(p.stmtList())
		return n

	// case OCASE, OXCASE:
	// 	unreachable - mapped to OXCASE case below by exporter

	case OXCASE:
		n := nodl(p.pos(), OXCASE, nil, nil)
		n.List.Set(p.exprList())
		// TODO(gri) eventually we must declare variables for type switch
		// statements (type switch statements are not yet exported)
		n.Nbody.Set(p.stmtList())
		return n

	// case OFALL:
	// 	unreachable - mapped to OXFALL case below by exporter

	case OFALL:
		n := nodl(p.pos(), OFALL, nil, nil)
		return n

	case OBREAK, OCONTINUE:
		pos := p.pos()
		left, _ := p.exprsOrNil()
		if left != nil {
			left = newname(left.Sym)
		}
		return nodl(pos, op, left, nil)

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

	case OGOTO, OLABEL:
		return nodl(p.pos(), op, newname(p.expr().Sym), nil)

	case OEND:
		return nil

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

func builtinCall(op Op) *Node {
	return nod(OCALL, mkname(builtinpkg.Lookup(goopnames[op])), nil)
}

func (p *importer) exprsOrNil() (a, b *Node) {
	ab := p.int()
	if ab&1 != 0 {
		a = p.expr()
	}
	if ab&2 != 0 {
		b = p.expr()
	}
	return
}

func (p *importer) fieldSym() *types.Sym {
	name := p.string()
	pkg := localpkg
	if !exportname(name) {
		pkg = p.pkg()
	}
	return pkg.Lookup(name)
}

func (p *importer) sym() *types.Sym {
	name := p.string()
	pkg := localpkg
	if name != "_" {
		pkg = p.pkg()
	}
	linkname := p.string()
	sym := pkg.Lookup(name)
	sym.Linkname = linkname
	return sym
}

func (p *importer) bool() bool {
	return p.int() != 0
}

func (p *importer) op() Op {
	return Op(p.int())
}

// ----------------------------------------------------------------------------
// Low-level decoders

func (p *importer) tagOrIndex() int {
	if p.debugFormat {
		p.marker('t')
	}

	return int(p.rawInt64())
}

func (p *importer) int() int {
	x := p.int64()
	if int64(int(x)) != x {
		p.formatErrorf("exported integer too large")
	}
	return int(x)
}

func (p *importer) int64() int64 {
	if p.debugFormat {
		p.marker('i')
	}

	return p.rawInt64()
}

func (p *importer) string() string {
	if p.debugFormat {
		p.marker('s')
	}
	// if the string was seen before, i is its index (>= 0)
	// (the empty string is at index 0)
	i := p.rawInt64()
	if i >= 0 {
		return p.strList[i]
	}
	// otherwise, i is the negative string length (< 0)
	if n := int(-i); n <= cap(p.buf) {
		p.buf = p.buf[:n]
	} else {
		p.buf = make([]byte, n)
	}
	for i := range p.buf {
		p.buf[i] = p.rawByte()
	}
	s := string(p.buf)
	p.strList = append(p.strList, s)
	return s
}

func (p *importer) marker(want byte) {
	if got := p.rawByte(); got != want {
		p.formatErrorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
	}

	pos := p.read
	if n := int(p.rawInt64()); n != pos {
		p.formatErrorf("incorrect position: got %d; want %d", n, pos)
	}
}

// rawInt64 should only be used by low-level decoders.
func (p *importer) rawInt64() int64 {
	i, err := binary.ReadVarint(p)
	if err != nil {
		p.formatErrorf("read error: %v", err)
	}
	return i
}

// rawStringln should only be used to read the initial version string.
func (p *importer) rawStringln(b byte) string {
	p.buf = p.buf[:0]
	for b != '\n' {
		p.buf = append(p.buf, b)
		b = p.rawByte()
	}
	return string(p.buf)
}

// needed for binary.ReadVarint in rawInt64
func (p *importer) ReadByte() (byte, error) {
	return p.rawByte(), nil
}

// rawByte is the bottleneck interface for reading from p.in.
// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
// rawByte should only be used by low-level decoders.
func (p *importer) rawByte() byte {
	c, err := p.in.ReadByte()
	p.read++
	if err != nil {
		p.formatErrorf("read error: %v", err)
	}
	if c == '|' {
		c, err = p.in.ReadByte()
		p.read++
		if err != nil {
			p.formatErrorf("read error: %v", err)
		}
		switch c {
		case 'S':
			c = '$'
		case '|':
			// nothing to do
		default:
			p.formatErrorf("unexpected escape sequence in export data")
		}
	}
	return c
}
