1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Indexed package import.
6// See iexport.go for the export data format.
7
8package typecheck
9
10import (
11	"encoding/binary"
12	"fmt"
13	"go/constant"
14	"math/big"
15	"os"
16	"strings"
17
18	"cmd/compile/internal/base"
19	"cmd/compile/internal/ir"
20	"cmd/compile/internal/types"
21	"cmd/internal/obj"
22	"cmd/internal/src"
23)
24
25// An iimporterAndOffset identifies an importer and an offset within
26// its data section.
27type iimporterAndOffset struct {
28	p   *iimporter
29	off uint64
30}
31
32var (
33	// DeclImporter maps from imported identifiers to an importer
34	// and offset where that identifier's declaration can be read.
35	DeclImporter = map[*types.Sym]iimporterAndOffset{}
36
37	// inlineImporter is like DeclImporter, but for inline bodies
38	// for function and method symbols.
39	inlineImporter = map[*types.Sym]iimporterAndOffset{}
40)
41
42// expandDecl returns immediately if n is already a Name node. Otherwise, n should
43// be an Ident node, and expandDecl reads in the definition of the specified
44// identifier from the appropriate package.
45func expandDecl(n ir.Node) ir.Node {
46	if n, ok := n.(*ir.Name); ok {
47		return n
48	}
49
50	id := n.(*ir.Ident)
51	if n := id.Sym().PkgDef(); n != nil {
52		return n.(*ir.Name)
53	}
54
55	r := importReaderFor(id.Sym(), DeclImporter)
56	if r == nil {
57		// Can happen if user tries to reference an undeclared name.
58		return n
59	}
60
61	return r.doDecl(n.Sym())
62}
63
64// ImportBody reads in the dcls and body of an imported function (which should not
65// yet have been read in).
66func ImportBody(fn *ir.Func) {
67	if fn.Inl.Body != nil {
68		base.Fatalf("%v already has inline body", fn)
69	}
70
71	r := importReaderFor(fn.Nname.Sym(), inlineImporter)
72	if r == nil {
73		base.Fatalf("missing import reader for %v", fn)
74	}
75
76	if inimport {
77		base.Fatalf("recursive inimport")
78	}
79	inimport = true
80	r.doInline(fn)
81	inimport = false
82}
83
84// HaveInlineBody reports whether we have fn's inline body available
85// for inlining.
86func HaveInlineBody(fn *ir.Func) bool {
87	if fn.Inl == nil {
88		return false
89	}
90
91	// Unified IR is much more conservative about pruning unreachable
92	// methods (at the cost of increased build artifact size).
93	if base.Debug.Unified != 0 {
94		return true
95	}
96
97	if fn.Inl.Body != nil {
98		return true
99	}
100
101	_, ok := inlineImporter[fn.Nname.Sym()]
102	return ok
103}
104
105func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader {
106	x, ok := importers[sym]
107	if !ok {
108		return nil
109	}
110
111	return x.p.newReader(x.off, sym.Pkg)
112}
113
114type intReader struct {
115	*strings.Reader
116	pkg *types.Pkg
117}
118
119func (r *intReader) int64() int64 {
120	i, err := binary.ReadVarint(r.Reader)
121	if err != nil {
122		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
123		base.ErrorExit()
124	}
125	return i
126}
127
128func (r *intReader) uint64() uint64 {
129	i, err := binary.ReadUvarint(r.Reader)
130	if err != nil {
131		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
132		base.ErrorExit()
133	}
134	return i
135}
136
137func ReadImports(pkg *types.Pkg, data string) {
138	ird := &intReader{strings.NewReader(data), pkg}
139
140	version := ird.uint64()
141	switch version {
142	case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
143	default:
144		base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
145		base.ErrorExit()
146	}
147
148	sLen := int64(ird.uint64())
149	dLen := int64(ird.uint64())
150
151	// TODO(mdempsky): Replace os.SEEK_CUR with io.SeekCurrent after
152	// #44505 is fixed.
153	whence, _ := ird.Seek(0, os.SEEK_CUR)
154	stringData := data[whence : whence+sLen]
155	declData := data[whence+sLen : whence+sLen+dLen]
156	ird.Seek(sLen+dLen, os.SEEK_CUR)
157
158	p := &iimporter{
159		exportVersion: version,
160		ipkg:          pkg,
161
162		pkgCache:     map[uint64]*types.Pkg{},
163		posBaseCache: map[uint64]*src.PosBase{},
164		typCache:     map[uint64]*types.Type{},
165
166		stringData: stringData,
167		declData:   declData,
168	}
169
170	for i, pt := range predeclared() {
171		p.typCache[uint64(i)] = pt
172	}
173
174	// Declaration index.
175	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
176		pkg := p.pkgAt(ird.uint64())
177		pkgName := p.stringAt(ird.uint64())
178		pkgHeight := int(ird.uint64())
179		if pkg.Name == "" {
180			pkg.Name = pkgName
181			pkg.Height = pkgHeight
182			types.NumImport[pkgName]++
183
184			// TODO(mdempsky): This belongs somewhere else.
185			pkg.Lookup("_").Def = ir.BlankNode
186		} else {
187			if pkg.Name != pkgName {
188				base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
189			}
190			if pkg.Height != pkgHeight {
191				base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
192			}
193		}
194
195		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
196			s := pkg.Lookup(p.nameAt(ird.uint64()))
197			off := ird.uint64()
198
199			if _, ok := DeclImporter[s]; !ok {
200				DeclImporter[s] = iimporterAndOffset{p, off}
201			}
202		}
203	}
204
205	// Inline body index.
206	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
207		pkg := p.pkgAt(ird.uint64())
208
209		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
210			s := pkg.Lookup(p.nameAt(ird.uint64()))
211			off := ird.uint64()
212
213			if _, ok := inlineImporter[s]; !ok {
214				inlineImporter[s] = iimporterAndOffset{p, off}
215			}
216		}
217	}
218}
219
220type iimporter struct {
221	exportVersion uint64
222	ipkg          *types.Pkg
223
224	pkgCache     map[uint64]*types.Pkg
225	posBaseCache map[uint64]*src.PosBase
226	typCache     map[uint64]*types.Type
227
228	stringData string
229	declData   string
230}
231
232func (p *iimporter) stringAt(off uint64) string {
233	var x [binary.MaxVarintLen64]byte
234	n := copy(x[:], p.stringData[off:])
235
236	slen, n := binary.Uvarint(x[:n])
237	if n <= 0 {
238		base.Fatalf("varint failed")
239	}
240	spos := off + uint64(n)
241	return p.stringData[spos : spos+slen]
242}
243
244// nameAt is the same as stringAt, except it replaces instances
245// of "" with the path of the package being imported.
246func (p *iimporter) nameAt(off uint64) string {
247	s := p.stringAt(off)
248	// Names of objects (functions, methods, globals) may include ""
249	// to represent the path name of the imported package.
250	// Replace "" with the imported package prefix. This occurs
251	// specifically for generics where the names of instantiations
252	// and dictionaries contain package-qualified type names.
253	// Include the dot to avoid matching with struct tags ending in '"'.
254	if strings.Contains(s, "\"\".") {
255		s = strings.Replace(s, "\"\".", p.ipkg.Prefix+".", -1)
256	}
257	return s
258}
259
260func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
261	if posBase, ok := p.posBaseCache[off]; ok {
262		return posBase
263	}
264
265	file := p.stringAt(off)
266	posBase := src.NewFileBase(file, file)
267	p.posBaseCache[off] = posBase
268	return posBase
269}
270
271func (p *iimporter) pkgAt(off uint64) *types.Pkg {
272	if pkg, ok := p.pkgCache[off]; ok {
273		return pkg
274	}
275
276	pkg := p.ipkg
277	if pkgPath := p.stringAt(off); pkgPath != "" {
278		pkg = types.NewPkg(pkgPath, "")
279	}
280	p.pkgCache[off] = pkg
281	return pkg
282}
283
284// An importReader keeps state for reading an individual imported
285// object (declaration or inline body).
286type importReader struct {
287	strings.Reader
288	p *iimporter
289
290	currPkg    *types.Pkg
291	prevBase   *src.PosBase
292	prevLine   int64
293	prevColumn int64
294
295	// curfn is the current function we're importing into.
296	curfn *ir.Func
297	// Slice of all dcls for function, including any interior closures
298	allDcls        []*ir.Name
299	allClosureVars []*ir.Name
300	autotmpgen     int
301}
302
303func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
304	r := &importReader{
305		p:       p,
306		currPkg: pkg,
307	}
308	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
309	// need to build with Go 1.4.
310	r.Reader = *strings.NewReader(p.declData[off:])
311	return r
312}
313
314func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
315func (r *importReader) name() string          { return r.p.nameAt(r.uint64()) }
316func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
317func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }
318
319func (r *importReader) setPkg() {
320	r.currPkg = r.pkg()
321}
322
323func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
324	tag := r.byte()
325	pos := r.pos()
326
327	switch tag {
328	case 'A':
329		typ := r.typ()
330
331		return importalias(pos, sym, typ)
332
333	case 'C':
334		typ := r.typ()
335		val := r.value(typ)
336
337		n := importconst(pos, sym, typ, val)
338		r.constExt(n)
339		return n
340
341	case 'F', 'G':
342		var tparams []*types.Field
343		if tag == 'G' {
344			tparams = r.tparamList()
345		}
346		typ := r.signature(nil, tparams)
347
348		n := importfunc(pos, sym, typ)
349		r.funcExt(n)
350		return n
351
352	case 'T', 'U':
353		// Types can be recursive. We need to setup a stub
354		// declaration before recursing.
355		n := importtype(pos, sym)
356		t := n.Type()
357		if tag == 'U' {
358			rparams := r.typeList()
359			t.SetRParams(rparams)
360		}
361
362		// We also need to defer width calculations until
363		// after the underlying type has been assigned.
364		types.DeferCheckSize()
365		deferDoInst()
366		underlying := r.typ()
367		t.SetUnderlying(underlying)
368
369		if underlying.IsInterface() {
370			// Finish up all type instantiations and CheckSize calls
371			// now that a top-level type is fully constructed.
372			resumeDoInst()
373			types.ResumeCheckSize()
374			r.typeExt(t)
375			return n
376		}
377
378		ms := make([]*types.Field, r.uint64())
379		for i := range ms {
380			mpos := r.pos()
381			msym := r.selector()
382			recv := r.param()
383			mtyp := r.signature(recv, nil)
384
385			// MethodSym already marked m.Sym as a function.
386			m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym))
387			m.Class = ir.PFUNC
388			m.SetType(mtyp)
389
390			m.Func = ir.NewFunc(mpos)
391			m.Func.Nname = m
392
393			f := types.NewField(mpos, msym, mtyp)
394			f.Nname = m
395			ms[i] = f
396		}
397		t.Methods().Set(ms)
398
399		// Finish up all instantiations and CheckSize calls now
400		// that a top-level type is fully constructed.
401		resumeDoInst()
402		types.ResumeCheckSize()
403
404		r.typeExt(t)
405		for _, m := range ms {
406			r.methExt(m)
407		}
408		return n
409
410	case 'P':
411		if r.p.exportVersion < iexportVersionGenerics {
412			base.Fatalf("unexpected type param type")
413		}
414		if sym.Def != nil {
415			// Make sure we use the same type param type for the same
416			// name, whether it is created during types1-import or
417			// this types2-to-types1 translation.
418			return sym.Def.(*ir.Name)
419		}
420		// The typeparam index is set at the point where the containing type
421		// param list is imported.
422		t := types.NewTypeParam(sym, 0)
423		// Nname needed to save the pos.
424		nname := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
425		sym.Def = nname
426		nname.SetType(t)
427		t.SetNod(nname)
428		implicit := false
429		if r.p.exportVersion >= iexportVersionGo1_18 {
430			implicit = r.bool()
431		}
432		bound := r.typ()
433		if implicit {
434			bound.MarkImplicit()
435		}
436		t.SetBound(bound)
437		return nname
438
439	case 'V':
440		typ := r.typ()
441
442		n := importvar(pos, sym, typ)
443		r.varExt(n)
444		return n
445
446	default:
447		base.Fatalf("unexpected tag: %v", tag)
448		panic("unreachable")
449	}
450}
451
452func (r *importReader) value(typ *types.Type) constant.Value {
453	var kind constant.Kind
454	var valType *types.Type
455
456	if r.p.exportVersion >= iexportVersionGo1_18 {
457		// TODO: add support for using the kind in the non-typeparam case.
458		kind = constant.Kind(r.int64())
459	}
460
461	if typ.IsTypeParam() {
462		if r.p.exportVersion < iexportVersionGo1_18 {
463			// If a constant had a typeparam type, then we wrote out its
464			// actual constant kind as well.
465			kind = constant.Kind(r.int64())
466		}
467		switch kind {
468		case constant.Int:
469			valType = types.Types[types.TINT64]
470		case constant.Float:
471			valType = types.Types[types.TFLOAT64]
472		case constant.Complex:
473			valType = types.Types[types.TCOMPLEX128]
474		}
475	} else {
476		kind = constTypeOf(typ)
477		valType = typ
478	}
479
480	switch kind {
481	case constant.Bool:
482		return constant.MakeBool(r.bool())
483	case constant.String:
484		return constant.MakeString(r.string())
485	case constant.Int:
486		var i big.Int
487		r.mpint(&i, valType)
488		return constant.Make(&i)
489	case constant.Float:
490		return r.float(valType)
491	case constant.Complex:
492		return makeComplex(r.float(valType), r.float(valType))
493	}
494
495	base.Fatalf("unexpected value type: %v", typ)
496	panic("unreachable")
497}
498
499func (r *importReader) mpint(x *big.Int, typ *types.Type) {
500	signed, maxBytes := intSize(typ)
501
502	maxSmall := 256 - maxBytes
503	if signed {
504		maxSmall = 256 - 2*maxBytes
505	}
506	if maxBytes == 1 {
507		maxSmall = 256
508	}
509
510	n, _ := r.ReadByte()
511	if uint(n) < maxSmall {
512		v := int64(n)
513		if signed {
514			v >>= 1
515			if n&1 != 0 {
516				v = ^v
517			}
518		}
519		x.SetInt64(v)
520		return
521	}
522
523	v := -n
524	if signed {
525		v = -(n &^ 1) >> 1
526	}
527	if v < 1 || uint(v) > maxBytes {
528		base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
529	}
530	b := make([]byte, v)
531	r.Read(b)
532	x.SetBytes(b)
533	if signed && n&1 != 0 {
534		x.Neg(x)
535	}
536}
537
538func (r *importReader) float(typ *types.Type) constant.Value {
539	var mant big.Int
540	r.mpint(&mant, typ)
541	var f big.Float
542	f.SetInt(&mant)
543	if f.Sign() != 0 {
544		f.SetMantExp(&f, int(r.int64()))
545	}
546	return constant.Make(&f)
547}
548
549func (r *importReader) mprat(orig constant.Value) constant.Value {
550	if !r.bool() {
551		return orig
552	}
553	var rat big.Rat
554	rat.SetString(r.string())
555	return constant.Make(&rat)
556}
557
558func (r *importReader) ident(selector bool) *types.Sym {
559	name := r.string()
560	if name == "" {
561		return nil
562	}
563	pkg := r.currPkg
564	if selector {
565		if types.IsExported(name) {
566			pkg = types.LocalPkg
567		}
568	} else {
569		if name == "$autotmp" {
570			name = autotmpname(r.autotmpgen)
571			r.autotmpgen++
572		}
573	}
574	return pkg.Lookup(name)
575}
576
577func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
578func (r *importReader) selector() *types.Sym   { return r.ident(true) }
579
580func (r *importReader) qualifiedIdent() *ir.Ident {
581	name := r.name()
582	pkg := r.pkg()
583	sym := pkg.Lookup(name)
584	return ir.NewIdent(src.NoXPos, sym)
585}
586
587func (r *importReader) pos() src.XPos {
588	delta := r.int64()
589	r.prevColumn += delta >> 1
590	if delta&1 != 0 {
591		delta = r.int64()
592		r.prevLine += delta >> 1
593		if delta&1 != 0 {
594			r.prevBase = r.posBase()
595		}
596	}
597
598	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
599		// TODO(mdempsky): Remove once we reliably write
600		// position information for all nodes.
601		return src.NoXPos
602	}
603
604	if r.prevBase == nil {
605		base.Fatalf("missing posbase")
606	}
607	pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
608	return base.Ctxt.PosTable.XPos(pos)
609}
610
611func (r *importReader) typ() *types.Type {
612	// If this is a top-level type call, defer type instantiations until the
613	// type is fully constructed.
614	types.DeferCheckSize()
615	deferDoInst()
616	t := r.p.typAt(r.uint64())
617	resumeDoInst()
618	types.ResumeCheckSize()
619	return t
620}
621
622func (r *importReader) exoticType() *types.Type {
623	switch r.uint64() {
624	case exoticTypeNil:
625		return nil
626	case exoticTypeTuple:
627		funarg := types.Funarg(r.uint64())
628		n := r.uint64()
629		fs := make([]*types.Field, n)
630		for i := range fs {
631			pos := r.pos()
632			var sym *types.Sym
633			switch r.uint64() {
634			case exoticTypeSymNil:
635				sym = nil
636			case exoticTypeSymNoPkg:
637				sym = types.NoPkg.Lookup(r.string())
638			case exoticTypeSymWithPkg:
639				pkg := r.pkg()
640				sym = pkg.Lookup(r.string())
641			default:
642				base.Fatalf("unknown symbol kind")
643			}
644			typ := r.typ()
645			f := types.NewField(pos, sym, typ)
646			fs[i] = f
647		}
648		t := types.NewStruct(types.NoPkg, fs)
649		t.StructType().Funarg = funarg
650		return t
651	case exoticTypeRecv:
652		var rcvr *types.Field
653		if r.bool() { // isFakeRecv
654			rcvr = types.FakeRecv()
655		} else {
656			rcvr = r.exoticParam()
657		}
658		return r.exoticSignature(rcvr)
659	case exoticTypeRegular:
660		return r.typ()
661	default:
662		base.Fatalf("bad kind of call type")
663		return nil
664	}
665}
666
667func (r *importReader) exoticSelector() *types.Sym {
668	name := r.string()
669	if name == "" {
670		return nil
671	}
672	pkg := r.currPkg
673	if types.IsExported(name) {
674		pkg = types.LocalPkg
675	}
676	if r.uint64() != 0 {
677		pkg = r.pkg()
678	}
679	return pkg.Lookup(name)
680}
681
682func (r *importReader) exoticSignature(recv *types.Field) *types.Type {
683	var pkg *types.Pkg
684	if r.bool() { // hasPkg
685		pkg = r.pkg()
686	}
687	params := r.exoticParamList()
688	results := r.exoticParamList()
689	return types.NewSignature(pkg, recv, nil, params, results)
690}
691
692func (r *importReader) exoticParamList() []*types.Field {
693	n := r.uint64()
694	fs := make([]*types.Field, n)
695	for i := range fs {
696		fs[i] = r.exoticParam()
697	}
698	return fs
699}
700
701func (r *importReader) exoticParam() *types.Field {
702	pos := r.pos()
703	sym := r.exoticSym()
704	off := r.uint64()
705	typ := r.exoticType()
706	ddd := r.bool()
707	f := types.NewField(pos, sym, typ)
708	f.Offset = int64(off)
709	if sym != nil {
710		f.Nname = ir.NewNameAt(pos, sym)
711	}
712	f.SetIsDDD(ddd)
713	return f
714}
715
716func (r *importReader) exoticField() *types.Field {
717	pos := r.pos()
718	sym := r.exoticSym()
719	off := r.uint64()
720	typ := r.exoticType()
721	note := r.string()
722	f := types.NewField(pos, sym, typ)
723	f.Offset = int64(off)
724	if sym != nil {
725		f.Nname = ir.NewNameAt(pos, sym)
726	}
727	f.Note = note
728	return f
729}
730
731func (r *importReader) exoticSym() *types.Sym {
732	name := r.string()
733	if name == "" {
734		return nil
735	}
736	var pkg *types.Pkg
737	if types.IsExported(name) {
738		pkg = types.LocalPkg
739	} else {
740		pkg = r.pkg()
741	}
742	return pkg.Lookup(name)
743}
744
745func (p *iimporter) typAt(off uint64) *types.Type {
746	t, ok := p.typCache[off]
747	if !ok {
748		if off < predeclReserved {
749			base.Fatalf("predeclared type missing from cache: %d", off)
750		}
751		t = p.newReader(off-predeclReserved, nil).typ1()
752		// Ensure size is calculated for imported types. Since CL 283313, the compiler
753		// does not compile the function immediately when it sees them. Instead, funtions
754		// are pushed to compile queue, then draining from the queue for compiling.
755		// During this process, the size calculation is disabled, so it is not safe for
756		// calculating size during SSA generation anymore. See issue #44732.
757		//
758		// No need to calc sizes for re-instantiated generic types, and
759		// they are not necessarily resolved until the top-level type is
760		// defined (because of recursive types).
761		if t.OrigSym() == nil || !t.HasTParam() {
762			types.CheckSize(t)
763		}
764		p.typCache[off] = t
765	}
766	return t
767}
768
769func (r *importReader) typ1() *types.Type {
770	switch k := r.kind(); k {
771	default:
772		base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
773		return nil
774
775	case definedType:
776		// We might be called from within doInline, in which
777		// case Sym.Def can point to declared parameters
778		// instead of the top-level types. Also, we don't
779		// support inlining functions with local defined
780		// types. Therefore, this must be a package-scope
781		// type.
782		n := expandDecl(r.qualifiedIdent())
783		if n.Op() != ir.OTYPE {
784			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
785		}
786		return n.Type()
787	case pointerType:
788		return types.NewPtr(r.typ())
789	case sliceType:
790		return types.NewSlice(r.typ())
791	case arrayType:
792		n := r.uint64()
793		return types.NewArray(r.typ(), int64(n))
794	case chanType:
795		dir := types.ChanDir(r.uint64())
796		return types.NewChan(r.typ(), dir)
797	case mapType:
798		return types.NewMap(r.typ(), r.typ())
799
800	case signatureType:
801		r.setPkg()
802		return r.signature(nil, nil)
803
804	case structType:
805		r.setPkg()
806
807		fs := make([]*types.Field, r.uint64())
808		for i := range fs {
809			pos := r.pos()
810			sym := r.selector()
811			typ := r.typ()
812			emb := r.bool()
813			note := r.string()
814
815			f := types.NewField(pos, sym, typ)
816			if emb {
817				f.Embedded = 1
818			}
819			f.Note = note
820			fs[i] = f
821		}
822
823		return types.NewStruct(r.currPkg, fs)
824
825	case interfaceType:
826		r.setPkg()
827
828		embeddeds := make([]*types.Field, r.uint64())
829		for i := range embeddeds {
830			pos := r.pos()
831			typ := r.typ()
832
833			embeddeds[i] = types.NewField(pos, nil, typ)
834		}
835
836		methods := make([]*types.Field, r.uint64())
837		for i := range methods {
838			pos := r.pos()
839			sym := r.selector()
840			typ := r.signature(types.FakeRecv(), nil)
841
842			methods[i] = types.NewField(pos, sym, typ)
843		}
844
845		if len(embeddeds)+len(methods) == 0 {
846			return types.Types[types.TINTER]
847		}
848
849		t := types.NewInterface(r.currPkg, append(embeddeds, methods...), false)
850
851		// Ensure we expand the interface in the frontend (#25055).
852		types.CheckSize(t)
853		return t
854
855	case typeParamType:
856		if r.p.exportVersion < iexportVersionGenerics {
857			base.Fatalf("unexpected type param type")
858		}
859		// Similar to code for defined types, since we "declared"
860		// typeparams to deal with recursion (typeparam is used within its
861		// own type bound).
862		ident := r.qualifiedIdent()
863		if ident.Sym().Def != nil {
864			return ident.Sym().Def.(*ir.Name).Type()
865		}
866		n := expandDecl(ident)
867		if n.Op() != ir.OTYPE {
868			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
869		}
870		return n.Type()
871
872	case instanceType:
873		if r.p.exportVersion < iexportVersionGenerics {
874			base.Fatalf("unexpected instantiation type")
875		}
876		pos := r.pos()
877		len := r.uint64()
878		targs := make([]*types.Type, len)
879		for i := range targs {
880			targs[i] = r.typ()
881		}
882		baseType := r.typ()
883		t := Instantiate(pos, baseType, targs)
884		return t
885
886	case unionType:
887		if r.p.exportVersion < iexportVersionGenerics {
888			base.Fatalf("unexpected instantiation type")
889		}
890		nt := int(r.uint64())
891		terms := make([]*types.Type, nt)
892		tildes := make([]bool, nt)
893		for i := range terms {
894			tildes[i] = r.bool()
895			terms[i] = r.typ()
896		}
897		return types.NewUnion(terms, tildes)
898	}
899}
900
901func (r *importReader) kind() itag {
902	return itag(r.uint64())
903}
904
905func (r *importReader) signature(recv *types.Field, tparams []*types.Field) *types.Type {
906	params := r.paramList()
907	results := r.paramList()
908	if n := len(params); n > 0 {
909		params[n-1].SetIsDDD(r.bool())
910	}
911	return types.NewSignature(r.currPkg, recv, tparams, params, results)
912}
913
914func (r *importReader) typeList() []*types.Type {
915	n := r.uint64()
916	if n == 0 {
917		return nil
918	}
919	ts := make([]*types.Type, n)
920	for i := range ts {
921		ts[i] = r.typ()
922		if ts[i].IsTypeParam() {
923			ts[i].SetIndex(i)
924		}
925	}
926	return ts
927}
928
929func (r *importReader) tparamList() []*types.Field {
930	n := r.uint64()
931	if n == 0 {
932		return nil
933	}
934	fs := make([]*types.Field, n)
935	for i := range fs {
936		typ := r.typ()
937		typ.SetIndex(i)
938		fs[i] = types.NewField(typ.Pos(), typ.Sym(), typ)
939	}
940	return fs
941}
942
943func (r *importReader) paramList() []*types.Field {
944	fs := make([]*types.Field, r.uint64())
945	for i := range fs {
946		fs[i] = r.param()
947	}
948	return fs
949}
950
951func (r *importReader) param() *types.Field {
952	return types.NewField(r.pos(), r.localIdent(), r.typ())
953}
954
955func (r *importReader) bool() bool {
956	return r.uint64() != 0
957}
958
959func (r *importReader) int64() int64 {
960	n, err := binary.ReadVarint(r)
961	if err != nil {
962		base.Fatalf("readVarint: %v", err)
963	}
964	return n
965}
966
967func (r *importReader) uint64() uint64 {
968	n, err := binary.ReadUvarint(r)
969	if err != nil {
970		base.Fatalf("readVarint: %v", err)
971	}
972	return n
973}
974
975func (r *importReader) byte() byte {
976	x, err := r.ReadByte()
977	if err != nil {
978		base.Fatalf("declReader.ReadByte: %v", err)
979	}
980	return x
981}
982
983// Compiler-specific extensions.
984
985func (r *importReader) constExt(n *ir.Name) {
986	switch n.Type() {
987	case types.UntypedFloat:
988		n.SetVal(r.mprat(n.Val()))
989	case types.UntypedComplex:
990		v := n.Val()
991		re := r.mprat(constant.Real(v))
992		im := r.mprat(constant.Imag(v))
993		n.SetVal(makeComplex(re, im))
994	}
995}
996
997func (r *importReader) varExt(n *ir.Name) {
998	r.linkname(n.Sym())
999	r.symIdx(n.Sym())
1000}
1001
1002func (r *importReader) funcExt(n *ir.Name) {
1003	r.linkname(n.Sym())
1004	r.symIdx(n.Sym())
1005
1006	n.Func.ABI = obj.ABI(r.uint64())
1007
1008	// Make sure //go:noinline pragma is imported (so stenciled functions have
1009	// same noinline status as the corresponding generic function.)
1010	n.Func.Pragma = ir.PragmaFlag(r.uint64())
1011
1012	// Escape analysis.
1013	for _, fs := range &types.RecvsParams {
1014		for _, f := range fs(n.Type()).FieldSlice() {
1015			f.Note = r.string()
1016		}
1017	}
1018
1019	// Inline body.
1020	if u := r.uint64(); u > 0 {
1021		n.Func.Inl = &ir.Inline{
1022			Cost:            int32(u - 1),
1023			CanDelayResults: r.bool(),
1024		}
1025		n.Func.Endlineno = r.pos()
1026	}
1027}
1028
1029func (r *importReader) methExt(m *types.Field) {
1030	if r.bool() {
1031		m.SetNointerface(true)
1032	}
1033	r.funcExt(m.Nname.(*ir.Name))
1034}
1035
1036func (r *importReader) linkname(s *types.Sym) {
1037	s.Linkname = r.string()
1038}
1039
1040func (r *importReader) symIdx(s *types.Sym) {
1041	lsym := s.Linksym()
1042	idx := int32(r.int64())
1043	if idx != -1 {
1044		if s.Linkname != "" {
1045			base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
1046		}
1047		lsym.SymIdx = idx
1048		lsym.Set(obj.AttrIndexed, true)
1049	}
1050}
1051
1052func (r *importReader) typeExt(t *types.Type) {
1053	t.SetNotInHeap(r.bool())
1054	SetBaseTypeIndex(t, r.int64(), r.int64())
1055}
1056
1057func SetBaseTypeIndex(t *types.Type, i, pi int64) {
1058	if t.Obj() == nil {
1059		base.Fatalf("SetBaseTypeIndex on non-defined type %v", t)
1060	}
1061	if i != -1 && pi != -1 {
1062		typeSymIdx[t] = [2]int64{i, pi}
1063	}
1064}
1065
1066// Map imported type T to the index of type descriptor symbols of T and *T,
1067// so we can use index to reference the symbol.
1068// TODO(mdempsky): Store this information directly in the Type's Name.
1069var typeSymIdx = make(map[*types.Type][2]int64)
1070
1071func BaseTypeIndex(t *types.Type) int64 {
1072	tbase := t
1073	if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
1074		tbase = t.Elem()
1075	}
1076	i, ok := typeSymIdx[tbase]
1077	if !ok {
1078		return -1
1079	}
1080	if t != tbase {
1081		return i[1]
1082	}
1083	return i[0]
1084}
1085
1086func (r *importReader) doInline(fn *ir.Func) {
1087	if len(fn.Inl.Body) != 0 {
1088		base.Fatalf("%v already has inline body", fn)
1089	}
1090
1091	//fmt.Printf("Importing %s\n", fn.Nname.Sym().Name)
1092	r.funcBody(fn)
1093
1094	importlist = append(importlist, fn)
1095
1096	if base.Flag.E > 0 && base.Flag.LowerM > 2 {
1097		if base.Flag.LowerM > 3 {
1098			fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
1099		} else {
1100			fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
1101		}
1102	}
1103}
1104
1105// ----------------------------------------------------------------------------
1106// Inlined function bodies
1107
1108// Approach: Read nodes and use them to create/declare the same data structures
1109// as done originally by the (hidden) parser by closely following the parser's
1110// original code. In other words, "parsing" the import data (which happens to
1111// be encoded in binary rather textual form) is the best way at the moment to
1112// re-establish the syntax tree's invariants. At some future point we might be
1113// able to avoid this round-about way and create the rewritten nodes directly,
1114// possibly avoiding a lot of duplicate work (name resolution, type checking).
1115//
1116// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
1117// unrefined nodes (since this is what the importer uses). The respective case
1118// entries are unreachable in the importer.
1119
1120func (r *importReader) funcBody(fn *ir.Func) {
1121	outerfn := r.curfn
1122	r.curfn = fn
1123
1124	// Import local declarations.
1125	fn.Inl.Dcl = r.readFuncDcls(fn)
1126
1127	// Import function body.
1128	body := r.stmtList()
1129	if body == nil {
1130		// Make sure empty body is not interpreted as
1131		// no inlineable body (see also parser.fnbody)
1132		// (not doing so can cause significant performance
1133		// degradation due to unnecessary calls to empty
1134		// functions).
1135		body = []ir.Node{}
1136	}
1137	if go117ExportTypes {
1138		ir.VisitList(body, func(n ir.Node) {
1139			n.SetTypecheck(1)
1140		})
1141	}
1142	fn.Inl.Body = body
1143
1144	r.curfn = outerfn
1145	if base.Flag.W >= 3 {
1146		fmt.Printf("Imported for %v", fn)
1147		ir.DumpList("", fn.Inl.Body)
1148	}
1149}
1150
1151func (r *importReader) readNames(fn *ir.Func) []*ir.Name {
1152	dcls := make([]*ir.Name, r.int64())
1153	for i := range dcls {
1154		n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent())
1155		n.Class = ir.PAUTO // overwritten below for parameters/results
1156		n.Curfn = fn
1157		n.SetType(r.typ())
1158		dcls[i] = n
1159	}
1160	r.allDcls = append(r.allDcls, dcls...)
1161	return dcls
1162}
1163
1164func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name {
1165	dcls := r.readNames(fn)
1166
1167	// Fixup parameter classes and associate with their
1168	// signature's type fields.
1169	i := 0
1170	fix := func(f *types.Field, class ir.Class) {
1171		if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") {
1172			return
1173		}
1174		n := dcls[i]
1175		n.Class = class
1176		f.Nname = n
1177		i++
1178	}
1179
1180	typ := fn.Type()
1181	if recv := typ.Recv(); recv != nil {
1182		fix(recv, ir.PPARAM)
1183	}
1184	for _, f := range typ.Params().FieldSlice() {
1185		fix(f, ir.PPARAM)
1186	}
1187	for _, f := range typ.Results().FieldSlice() {
1188		fix(f, ir.PPARAMOUT)
1189	}
1190	return dcls
1191}
1192
1193func (r *importReader) localName() *ir.Name {
1194	i := r.int64()
1195	if i == -1 {
1196		return ir.BlankNode.(*ir.Name)
1197	}
1198	if i < 0 {
1199		return r.allClosureVars[-i-2]
1200	}
1201	return r.allDcls[i]
1202}
1203
1204func (r *importReader) stmtList() []ir.Node {
1205	var list []ir.Node
1206	for {
1207		n := r.node()
1208		if n == nil {
1209			break
1210		}
1211		// OBLOCK nodes are not written to the import data directly,
1212		// but the handling of ODCL calls liststmt, which creates one.
1213		// Inline them into the statement list.
1214		if n.Op() == ir.OBLOCK {
1215			n := n.(*ir.BlockStmt)
1216			list = append(list, n.List...)
1217			continue
1218		}
1219		if len(list) > 0 {
1220			// check for an optional label that can only immediately
1221			// precede a for/range/select/switch statement.
1222			if last := list[len(list)-1]; last.Op() == ir.OLABEL {
1223				label := last.(*ir.LabelStmt).Label
1224				switch n.Op() {
1225				case ir.OFOR:
1226					n.(*ir.ForStmt).Label = label
1227				case ir.ORANGE:
1228					n.(*ir.RangeStmt).Label = label
1229				case ir.OSELECT:
1230					n.(*ir.SelectStmt).Label = label
1231				case ir.OSWITCH:
1232					n.(*ir.SwitchStmt).Label = label
1233				}
1234			}
1235		}
1236		list = append(list, n)
1237	}
1238	return list
1239}
1240
1241func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
1242	namedTypeSwitch := isNamedTypeSwitch(switchExpr)
1243
1244	cases := make([]*ir.CaseClause, r.uint64())
1245	for i := range cases {
1246		cas := ir.NewCaseStmt(r.pos(), nil, nil)
1247		cas.List = r.stmtList()
1248		if namedTypeSwitch {
1249			cas.Var = r.localName()
1250			cas.Var.Defn = switchExpr
1251		}
1252		cas.Body = r.stmtList()
1253		cases[i] = cas
1254	}
1255	return cases
1256}
1257
1258func (r *importReader) commList() []*ir.CommClause {
1259	cases := make([]*ir.CommClause, r.uint64())
1260	for i := range cases {
1261		pos := r.pos()
1262		defaultCase := r.bool()
1263		var comm ir.Node
1264		if !defaultCase {
1265			comm = r.node()
1266		}
1267		cases[i] = ir.NewCommStmt(pos, comm, r.stmtList())
1268	}
1269	return cases
1270}
1271
1272func (r *importReader) exprList() []ir.Node {
1273	var list []ir.Node
1274	for {
1275		n := r.expr()
1276		if n == nil {
1277			break
1278		}
1279		list = append(list, n)
1280	}
1281	return list
1282}
1283
1284func (r *importReader) expr() ir.Node {
1285	n := r.node()
1286	if n != nil && n.Op() == ir.OBLOCK {
1287		n := n.(*ir.BlockStmt)
1288		base.Fatalf("unexpected block node: %v", n)
1289	}
1290	return n
1291}
1292
1293// TODO(gri) split into expr and stmt
1294func (r *importReader) node() ir.Node {
1295	op := r.op()
1296	switch op {
1297	// expressions
1298	// case OPAREN:
1299	// 	unreachable - unpacked by exporter
1300
1301	case ir.ONIL:
1302		pos := r.pos()
1303		typ := r.typ()
1304
1305		n := ir.NewNilExpr(pos)
1306		n.SetType(typ)
1307		return n
1308
1309	case ir.OLITERAL:
1310		pos := r.pos()
1311		typ := r.typ()
1312
1313		n := ir.NewBasicLit(pos, r.value(typ))
1314		n.SetType(typ)
1315		return n
1316
1317	case ir.ONONAME:
1318		isKey := r.bool()
1319		n := r.qualifiedIdent()
1320		if go117ExportTypes {
1321			var n2 ir.Node = n
1322			// Key ONONAME entries should not be resolved - they should
1323			// stay as identifiers.
1324			if !isKey {
1325				n2 = Resolve(n)
1326			}
1327			typ := r.typ()
1328			if n2.Type() == nil {
1329				n2.SetType(typ)
1330			}
1331			return n2
1332		}
1333		return n
1334
1335	case ir.ONAME:
1336		isBuiltin := r.bool()
1337		if isBuiltin {
1338			pkg := types.BuiltinPkg
1339			if r.bool() {
1340				pkg = types.UnsafePkg
1341			}
1342			return pkg.Lookup(r.string()).Def.(*ir.Name)
1343		}
1344		return r.localName()
1345
1346	// case OPACK, ONONAME:
1347	// 	unreachable - should have been resolved by typechecking
1348
1349	case ir.OTYPE:
1350		return ir.TypeNode(r.typ())
1351
1352	case ir.ODYNAMICTYPE:
1353		n := ir.NewDynamicType(r.pos(), r.expr())
1354		if r.bool() {
1355			n.ITab = r.expr()
1356		}
1357		n.SetType(r.typ())
1358		return n
1359
1360	case ir.OTYPESW:
1361		pos := r.pos()
1362		var tag *ir.Ident
1363		if s := r.localIdent(); s != nil {
1364			tag = ir.NewIdent(pos, s)
1365		}
1366		return ir.NewTypeSwitchGuard(pos, tag, r.expr())
1367
1368	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
1369	//      unreachable - should have been resolved by typechecking
1370
1371	case ir.OCLOSURE:
1372		//println("Importing CLOSURE")
1373		pos := r.pos()
1374		typ := r.signature(nil, nil)
1375
1376		// All the remaining code below is similar to (*noder).funcLit(), but
1377		// with Dcls and ClosureVars lists already set up
1378		fn := ir.NewClosureFunc(pos, true)
1379		fn.Nname.SetType(typ)
1380
1381		cvars := make([]*ir.Name, r.int64())
1382		for i := range cvars {
1383			cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
1384			if go117ExportTypes && cvars[i].Defn == nil {
1385				base.Fatalf("bad import of closure variable")
1386			}
1387		}
1388		fn.ClosureVars = cvars
1389		r.allClosureVars = append(r.allClosureVars, cvars...)
1390
1391		fn.Inl = &ir.Inline{}
1392		// Read in the Dcls and Body of the closure after temporarily
1393		// setting r.curfn to fn.
1394		r.funcBody(fn)
1395		fn.Dcl = fn.Inl.Dcl
1396		fn.Body = fn.Inl.Body
1397		if len(fn.Body) == 0 {
1398			// An empty closure must be represented as a single empty
1399			// block statement, else it will be dropped.
1400			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
1401		}
1402		fn.Inl = nil
1403
1404		ir.FinishCaptureNames(pos, r.curfn, fn)
1405
1406		clo := fn.OClosure
1407		if go117ExportTypes {
1408			clo.SetType(typ)
1409		}
1410		return clo
1411
1412	case ir.OSTRUCTLIT:
1413		if go117ExportTypes {
1414			pos := r.pos()
1415			typ := r.typ()
1416			list := r.fieldList()
1417			n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list)
1418			n.SetType(typ)
1419			return n
1420		}
1421		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())
1422
1423	case ir.OCOMPLIT:
1424		pos := r.pos()
1425		t := r.typ()
1426		n := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ir.TypeNode(t), r.exprList())
1427		n.SetType(t)
1428		return n
1429
1430	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
1431		if !go117ExportTypes {
1432			// unreachable - mapped to OCOMPLIT by exporter
1433			goto error
1434		}
1435		pos := r.pos()
1436		typ := r.typ()
1437		list := r.exprList()
1438		n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list)
1439		n.SetType(typ)
1440		if op == ir.OSLICELIT {
1441			n.Len = int64(r.uint64())
1442		}
1443		return n
1444
1445	case ir.OKEY:
1446		return ir.NewKeyExpr(r.pos(), r.expr(), r.expr())
1447
1448	// case OSTRUCTKEY:
1449	//	unreachable - handled in case OSTRUCTLIT by elemList
1450
1451	case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OMETHVALUE, ir.OMETHEXPR:
1452		// For !go117ExportTypes,  we should only see OXDOT.
1453		// For go117ExportTypes, we usually see all the other ops, but can see
1454		// OXDOT for generic functions.
1455		if op != ir.OXDOT && !go117ExportTypes {
1456			goto error
1457		}
1458		pos := r.pos()
1459		expr := r.expr()
1460		sel := r.exoticSelector()
1461		n := ir.NewSelectorExpr(pos, op, expr, sel)
1462		if go117ExportTypes {
1463			n.SetType(r.exoticType())
1464			switch op {
1465			case ir.OXDOT:
1466				hasSelection := r.bool()
1467				// We reconstruct n.Selection for method calls on
1468				// generic types and method calls due to type param
1469				// bounds.  Otherwise, n.Selection is nil.
1470				if hasSelection {
1471					n1 := ir.NewSelectorExpr(pos, op, expr, sel)
1472					AddImplicitDots(n1)
1473					var m *types.Field
1474					if n1.X.Type().IsTypeParam() {
1475						genType := n1.X.Type().Bound()
1476						m = Lookdot1(n1, sel, genType, genType.AllMethods(), 1)
1477					} else {
1478						genType := types.ReceiverBaseType(n1.X.Type())
1479						if genType.IsInstantiatedGeneric() {
1480							genType = genType.OrigSym().Def.Type()
1481						}
1482						m = Lookdot1(n1, sel, genType, genType.Methods(), 1)
1483					}
1484					assert(m != nil)
1485					n.Selection = m
1486				}
1487			case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
1488				n.Selection = r.exoticField()
1489			case ir.OMETHEXPR:
1490				n = typecheckMethodExpr(n).(*ir.SelectorExpr)
1491			case ir.ODOTMETH, ir.OMETHVALUE:
1492				// These require a Lookup to link to the correct declaration.
1493				rcvrType := expr.Type()
1494				typ := n.Type()
1495				n.Selection = Lookdot(n, rcvrType, 1)
1496				if op == ir.OMETHVALUE {
1497					// Lookdot clobbers the opcode and type, undo that.
1498					n.SetOp(op)
1499					n.SetType(typ)
1500				}
1501			}
1502		}
1503		return n
1504
1505	case ir.ODOTTYPE, ir.ODOTTYPE2:
1506		n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil)
1507		n.SetType(r.typ())
1508		if go117ExportTypes {
1509			n.SetOp(op)
1510		}
1511		return n
1512
1513	case ir.ODYNAMICDOTTYPE, ir.ODYNAMICDOTTYPE2:
1514		n := ir.NewDynamicTypeAssertExpr(r.pos(), op, r.expr(), r.expr())
1515		n.SetType(r.typ())
1516		return n
1517
1518	case ir.OINDEX, ir.OINDEXMAP:
1519		n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr())
1520		if go117ExportTypes {
1521			n.SetOp(op)
1522			n.SetType(r.exoticType())
1523			if op == ir.OINDEXMAP {
1524				n.Assigned = r.bool()
1525			}
1526		}
1527		return n
1528
1529	case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
1530		pos, x := r.pos(), r.expr()
1531		low, high := r.exprsOrNil()
1532		var max ir.Node
1533		if op.IsSlice3() {
1534			max = r.expr()
1535		}
1536		n := ir.NewSliceExpr(pos, op, x, low, high, max)
1537		if go117ExportTypes {
1538			n.SetType(r.typ())
1539		}
1540		return n
1541
1542	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
1543		if !go117ExportTypes && op != ir.OCONV {
1544			// 	unreachable - mapped to OCONV case by exporter
1545			goto error
1546		}
1547		return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
1548
1549	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:
1550		if go117ExportTypes {
1551			switch op {
1552			case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
1553				n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
1554				n.SetType(r.typ())
1555				return n
1556			case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
1557				n := ir.NewUnaryExpr(r.pos(), op, r.expr())
1558				if op != ir.OPANIC {
1559					n.SetType(r.typ())
1560				}
1561				return n
1562			case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
1563				n := ir.NewCallExpr(r.pos(), op, nil, r.exprList())
1564				if op == ir.OAPPEND {
1565					n.IsDDD = r.bool()
1566				}
1567				if op == ir.OAPPEND || op == ir.ORECOVER {
1568					n.SetType(r.typ())
1569				}
1570				return n
1571			}
1572			// ir.OMAKE
1573			goto error
1574		}
1575		n := builtinCall(r.pos(), op)
1576		n.Args = r.exprList()
1577		if op == ir.OAPPEND {
1578			n.IsDDD = r.bool()
1579		}
1580		return n
1581
1582	case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
1583		pos := r.pos()
1584		init := r.stmtList()
1585		n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList())
1586		if go117ExportTypes {
1587			n.SetOp(op)
1588		}
1589		n.SetInit(init)
1590		n.IsDDD = r.bool()
1591		if go117ExportTypes {
1592			n.SetType(r.exoticType())
1593		}
1594		return n
1595
1596	case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
1597		if go117ExportTypes {
1598			pos := r.pos()
1599			typ := r.typ()
1600			list := r.exprList()
1601			var len_, cap_ ir.Node
1602			if len(list) > 0 {
1603				len_ = list[0]
1604			}
1605			if len(list) > 1 {
1606				cap_ = list[1]
1607			}
1608			n := ir.NewMakeExpr(pos, op, len_, cap_)
1609			n.SetType(typ)
1610			return n
1611		}
1612		n := builtinCall(r.pos(), ir.OMAKE)
1613		n.Args.Append(ir.TypeNode(r.typ()))
1614		n.Args.Append(r.exprList()...)
1615		return n
1616
1617	case ir.OLINKSYMOFFSET:
1618		pos := r.pos()
1619		name := r.string()
1620		off := r.uint64()
1621		typ := r.typ()
1622		return ir.NewLinksymOffsetExpr(pos, Lookup(name).Linksym(), int64(off), typ)
1623
1624	// unary expressions
1625	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV, ir.OIDATA:
1626		n := ir.NewUnaryExpr(r.pos(), op, r.expr())
1627		if go117ExportTypes {
1628			n.SetType(r.typ())
1629		}
1630		return n
1631
1632	case ir.OADDR, ir.OPTRLIT:
1633		n := NodAddrAt(r.pos(), r.expr())
1634		if go117ExportTypes {
1635			n.SetOp(op)
1636			n.SetType(r.typ())
1637		}
1638		return n
1639
1640	case ir.ODEREF:
1641		n := ir.NewStarExpr(r.pos(), r.expr())
1642		if go117ExportTypes {
1643			n.SetType(r.typ())
1644		}
1645		return n
1646
1647	// binary expressions
1648	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
1649		ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR, ir.OEFACE:
1650		n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
1651		if go117ExportTypes {
1652			n.SetType(r.typ())
1653		}
1654		return n
1655
1656	case ir.OANDAND, ir.OOROR:
1657		n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
1658		if go117ExportTypes {
1659			n.SetType(r.typ())
1660		}
1661		return n
1662
1663	case ir.OSEND:
1664		return ir.NewSendStmt(r.pos(), r.expr(), r.expr())
1665
1666	case ir.OADDSTR:
1667		pos := r.pos()
1668		list := r.exprList()
1669		if go117ExportTypes {
1670			n := ir.NewAddStringExpr(pos, list)
1671			n.SetType(r.typ())
1672			return n
1673		}
1674		x := list[0]
1675		for _, y := range list[1:] {
1676			x = ir.NewBinaryExpr(pos, ir.OADD, x, y)
1677		}
1678		return x
1679
1680	// --------------------------------------------------------------------
1681	// statements
1682	case ir.ODCL:
1683		var stmts ir.Nodes
1684		n := r.localName()
1685		stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n))
1686		stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil))
1687		return ir.NewBlockStmt(n.Pos(), stmts)
1688
1689	// case OASWB:
1690	// 	unreachable - never exported
1691
1692	case ir.OAS:
1693		pos := r.pos()
1694		init := r.stmtList()
1695		n := ir.NewAssignStmt(pos, r.expr(), r.expr())
1696		n.SetInit(init)
1697		n.Def = r.bool()
1698		return n
1699
1700	case ir.OASOP:
1701		n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
1702		if !r.bool() {
1703			n.Y = ir.NewInt(1)
1704			n.IncDec = true
1705		} else {
1706			n.Y = r.expr()
1707		}
1708		return n
1709
1710	case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
1711		if !go117ExportTypes && op != ir.OAS2 {
1712			// unreachable - mapped to case OAS2 by exporter
1713			goto error
1714		}
1715		pos := r.pos()
1716		init := r.stmtList()
1717		n := ir.NewAssignListStmt(pos, op, r.exprList(), r.exprList())
1718		n.SetInit(init)
1719		n.Def = r.bool()
1720		return n
1721
1722	case ir.ORETURN:
1723		return ir.NewReturnStmt(r.pos(), r.exprList())
1724
1725	// case ORETJMP:
1726	// 	unreachable - generated by compiler for trampolin routines (not exported)
1727
1728	case ir.OGO, ir.ODEFER:
1729		return ir.NewGoDeferStmt(r.pos(), op, r.expr())
1730
1731	case ir.OIF:
1732		pos, init := r.pos(), r.stmtList()
1733		n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList())
1734		n.SetInit(init)
1735		return n
1736
1737	case ir.OFOR:
1738		pos, init := r.pos(), r.stmtList()
1739		cond, post := r.exprsOrNil()
1740		n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
1741		n.SetInit(init)
1742		return n
1743
1744	case ir.ORANGE:
1745		pos, init := r.pos(), r.stmtList()
1746		k, v := r.exprsOrNil()
1747		n := ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList())
1748		n.SetInit(init)
1749		return n
1750
1751	case ir.OSELECT:
1752		pos := r.pos()
1753		init := r.stmtList()
1754		n := ir.NewSelectStmt(pos, r.commList())
1755		n.SetInit(init)
1756		return n
1757
1758	case ir.OSWITCH:
1759		pos := r.pos()
1760		init := r.stmtList()
1761		x, _ := r.exprsOrNil()
1762		n := ir.NewSwitchStmt(pos, x, r.caseList(x))
1763		n.SetInit(init)
1764		return n
1765
1766	// case OCASE:
1767	//	handled by caseList
1768
1769	case ir.OFALL:
1770		return ir.NewBranchStmt(r.pos(), ir.OFALL, nil)
1771
1772	// case OEMPTY:
1773	// 	unreachable - not emitted by exporter
1774
1775	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
1776		pos := r.pos()
1777		var sym *types.Sym
1778		if label := r.string(); label != "" {
1779			sym = Lookup(label)
1780		}
1781		return ir.NewBranchStmt(pos, op, sym)
1782
1783	case ir.OLABEL:
1784		return ir.NewLabelStmt(r.pos(), Lookup(r.string()))
1785
1786	case ir.OEND:
1787		return nil
1788
1789	case ir.OFUNCINST:
1790		pos := r.pos()
1791		x := r.expr()
1792		ntargs := r.uint64()
1793		var targs []ir.Node
1794		if ntargs > 0 {
1795			targs = make([]ir.Node, ntargs)
1796			for i := range targs {
1797				targs[i] = ir.TypeNode(r.typ())
1798			}
1799		}
1800		n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs)
1801		if go117ExportTypes {
1802			n.SetType(r.typ())
1803		}
1804		return n
1805
1806	case ir.OSELRECV2:
1807		pos := r.pos()
1808		init := r.stmtList()
1809		n := ir.NewAssignListStmt(pos, ir.OSELRECV2, r.exprList(), r.exprList())
1810		n.SetInit(init)
1811		n.Def = r.bool()
1812		return n
1813
1814	default:
1815		base.Fatalf("cannot import %v (%d) node\n"+
1816			"\t==> please file an issue and assign to gri@", op, int(op))
1817		panic("unreachable") // satisfy compiler
1818	}
1819error:
1820	base.Fatalf("cannot import %v (%d) node\n"+
1821		"\t==> please file an issue and assign to khr@", op, int(op))
1822	panic("unreachable") // satisfy compiler
1823}
1824
1825func (r *importReader) op() ir.Op {
1826	if debug && r.uint64() != magic {
1827		base.Fatalf("import stream has desynchronized")
1828	}
1829	return ir.Op(r.uint64())
1830}
1831
1832func (r *importReader) fieldList() []ir.Node {
1833	list := make([]ir.Node, r.uint64())
1834	for i := range list {
1835		list[i] = ir.NewStructKeyExpr(r.pos(), r.exoticField(), r.expr())
1836	}
1837	return list
1838}
1839
1840func (r *importReader) exprsOrNil() (a, b ir.Node) {
1841	ab := r.uint64()
1842	if ab&1 != 0 {
1843		a = r.expr()
1844	}
1845	if ab&2 != 0 {
1846		b = r.node()
1847	}
1848	return
1849}
1850
1851func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
1852	if go117ExportTypes {
1853		// These should all be encoded as direct ops, not OCALL.
1854		base.Fatalf("builtinCall should not be invoked when types are included in import/export")
1855	}
1856	return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
1857}
1858
1859// NewIncompleteNamedType returns a TFORW type t with name specified by sym, such
1860// that t.nod and sym.Def are set correctly. If there are any RParams for the type,
1861// they should be set soon after creating the TFORW type, before creating the
1862// underlying type. That ensures that the HasTParam and HasShape flags will be set
1863// properly, in case this type is part of some mutually recursive type.
1864func NewIncompleteNamedType(pos src.XPos, sym *types.Sym) *types.Type {
1865	name := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
1866	forw := types.NewNamed(name)
1867	name.SetType(forw)
1868	sym.Def = name
1869	return forw
1870}
1871
1872// Instantiate creates a new named type which is the instantiation of the base
1873// named generic type, with the specified type args.
1874func Instantiate(pos src.XPos, baseType *types.Type, targs []*types.Type) *types.Type {
1875	baseSym := baseType.Sym()
1876	if strings.Index(baseSym.Name, "[") >= 0 {
1877		base.Fatalf("arg to Instantiate is not a base generic type")
1878	}
1879	name := InstTypeName(baseSym.Name, targs)
1880	instSym := baseSym.Pkg.Lookup(name)
1881	if instSym.Def != nil {
1882		// May match existing type from previous import or
1883		// types2-to-types1 conversion.
1884		t := instSym.Def.Type()
1885		if t.Kind() != types.TFORW {
1886			return t
1887		}
1888		// Or, we have started creating this type in (*TSubster).Typ, but its
1889		// underlying type was not completed yet, so we need to add this type
1890		// to deferredInstStack, if not already there.
1891		found := false
1892		for _, t2 := range deferredInstStack {
1893			if t2 == t {
1894				found = true
1895				break
1896			}
1897		}
1898		if !found {
1899			deferredInstStack = append(deferredInstStack, t)
1900		}
1901		return t
1902	}
1903
1904	t := NewIncompleteNamedType(baseType.Pos(), instSym)
1905	t.SetRParams(targs)
1906	t.SetOrigSym(baseSym)
1907
1908	// baseType may still be TFORW or its methods may not be fully filled in
1909	// (since we are in the middle of importing it). So, delay call to
1910	// substInstType until we get back up to the top of the current top-most
1911	// type import.
1912	deferredInstStack = append(deferredInstStack, t)
1913
1914	return t
1915}
1916
1917var deferredInstStack []*types.Type
1918var deferInst int
1919
1920// deferDoInst defers substitution on instantiated types until we are at the
1921// top-most defined type, so the base types are fully defined.
1922func deferDoInst() {
1923	deferInst++
1924}
1925
1926func resumeDoInst() {
1927	if deferInst == 1 {
1928		for len(deferredInstStack) > 0 {
1929			t := deferredInstStack[0]
1930			deferredInstStack = deferredInstStack[1:]
1931			substInstType(t, t.OrigSym().Def.(*ir.Name).Type(), t.RParams())
1932		}
1933	}
1934	deferInst--
1935}
1936
1937// doInst creates a new instantiation type (which will be added to
1938// deferredInstStack for completion later) for an incomplete type encountered
1939// during a type substitution for an instantiation. This is needed for
1940// instantiations of mutually recursive types.
1941func doInst(t *types.Type) *types.Type {
1942	assert(t.Kind() == types.TFORW)
1943	return Instantiate(t.Pos(), t.OrigSym().Def.(*ir.Name).Type(), t.RParams())
1944}
1945
1946// substInstType completes the instantiation of a generic type by doing a
1947// substitution on the underlying type itself and any methods. t is the
1948// instantiation being created, baseType is the base generic type, and targs are
1949// the type arguments that baseType is being instantiated with.
1950func substInstType(t *types.Type, baseType *types.Type, targs []*types.Type) {
1951	assert(t.Kind() == types.TFORW)
1952	subst := Tsubster{
1953		Tparams:       baseType.RParams(),
1954		Targs:         targs,
1955		SubstForwFunc: doInst,
1956	}
1957	t.SetUnderlying(subst.Typ(baseType.Underlying()))
1958
1959	newfields := make([]*types.Field, baseType.Methods().Len())
1960	for i, f := range baseType.Methods().Slice() {
1961		if !f.IsMethod() || types.IsInterfaceMethod(f.Type) {
1962			// Do a normal substitution if this is a non-method (which
1963			// means this must be an interface used as a constraint) or
1964			// an interface method.
1965			t2 := subst.Typ(f.Type)
1966			newfields[i] = types.NewField(f.Pos, f.Sym, t2)
1967			continue
1968		}
1969		recvType := f.Type.Recv().Type
1970		if recvType.IsPtr() {
1971			recvType = recvType.Elem()
1972		}
1973		// Substitute in the method using the type params used in the
1974		// method (not the type params in the definition of the generic type).
1975		msubst := Tsubster{
1976			Tparams:       recvType.RParams(),
1977			Targs:         targs,
1978			SubstForwFunc: doInst,
1979		}
1980		t2 := msubst.Typ(f.Type)
1981		oldsym := f.Nname.Sym()
1982		newsym := MakeFuncInstSym(oldsym, targs, true, true)
1983		var nname *ir.Name
1984		if newsym.Def != nil {
1985			nname = newsym.Def.(*ir.Name)
1986		} else {
1987			nname = ir.NewNameAt(f.Pos, newsym)
1988			nname.SetType(t2)
1989			ir.MarkFunc(nname)
1990			newsym.Def = nname
1991		}
1992		newfields[i] = types.NewField(f.Pos, f.Sym, t2)
1993		newfields[i].Nname = nname
1994	}
1995	t.Methods().Set(newfields)
1996	if !t.HasTParam() && !t.HasShape() && t.Kind() != types.TINTER && t.Methods().Len() > 0 {
1997		// Generate all the methods for a new fully-instantiated,
1998		// non-interface, non-shape type.
1999		NeedInstType(t)
2000	}
2001}
2002