1// Copyright 2015 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// Binary package import.
6// See bexport.go for the export data format and how
7// to make a format change.
8
9package gc
10
11import (
12	"bufio"
13	"cmd/compile/internal/types"
14	"cmd/internal/src"
15	"encoding/binary"
16	"fmt"
17	"math/big"
18	"strconv"
19	"strings"
20)
21
22// The overall structure of Import is symmetric to Export: For each
23// export method in bexport.go there is a matching and symmetric method
24// in bimport.go. Changing the export format requires making symmetric
25// changes to bimport.go and bexport.go.
26
27type importer struct {
28	in      *bufio.Reader
29	imp     *types.Pkg // imported package
30	buf     []byte     // reused for reading strings
31	version int        // export format version
32
33	// object lists, in order of deserialization
34	strList       []string
35	pathList      []string
36	pkgList       []*types.Pkg
37	typList       []*types.Type
38	funcList      []*Node // nil entry means already declared
39	trackAllTypes bool
40
41	// for delayed type verification
42	cmpList []struct{ pt, t *types.Type }
43
44	// position encoding
45	posInfoFormat bool
46	prevFile      string
47	prevLine      int
48	posBase       *src.PosBase
49
50	// debugging support
51	debugFormat bool
52	read        int // bytes read
53}
54
55// Import populates imp from the serialized package data read from in.
56func Import(imp *types.Pkg, in *bufio.Reader) {
57	inimport = true
58	defer func() { inimport = false }()
59
60	p := importer{
61		in:       in,
62		imp:      imp,
63		version:  -1,           // unknown version
64		strList:  []string{""}, // empty string is mapped to 0
65		pathList: []string{""}, // empty path is mapped to 0
66	}
67
68	// read version info
69	var versionstr string
70	if b := p.rawByte(); b == 'c' || b == 'd' {
71		// Go1.7 encoding; first byte encodes low-level
72		// encoding format (compact vs debug).
73		// For backward-compatibility only (avoid problems with
74		// old installed packages). Newly compiled packages use
75		// the extensible format string.
76		// TODO(gri) Remove this support eventually; after Go1.8.
77		if b == 'd' {
78			p.debugFormat = true
79		}
80		p.trackAllTypes = p.rawByte() == 'a'
81		p.posInfoFormat = p.bool()
82		versionstr = p.string()
83		if versionstr == "v1" {
84			p.version = 0
85		}
86	} else {
87		// Go1.8 extensible encoding
88		// read version string and extract version number (ignore anything after the version number)
89		versionstr = p.rawStringln(b)
90		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
91			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
92				p.version = v
93			}
94		}
95	}
96
97	// read version specific flags - extend as necessary
98	switch p.version {
99	// case 6:
100	// 	...
101	//	fallthrough
102	case 5, 4, 3, 2, 1:
103		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
104		p.trackAllTypes = p.bool()
105		p.posInfoFormat = p.bool()
106	case 0:
107		// Go1.7 encoding format - nothing to do here
108	default:
109		p.formatErrorf("unknown export format version %d (%q)", p.version, versionstr)
110	}
111
112	// --- generic export data ---
113
114	// populate typList with predeclared "known" types
115	p.typList = append(p.typList, predeclared()...)
116
117	// read package data
118	p.pkg()
119
120	// defer some type-checking until all types are read in completely
121	tcok := typecheckok
122	typecheckok = true
123	defercheckwidth()
124
125	// read objects
126
127	// phase 1
128	objcount := 0
129	for {
130		tag := p.tagOrIndex()
131		if tag == endTag {
132			break
133		}
134		p.obj(tag)
135		objcount++
136	}
137
138	// self-verification
139	if count := p.int(); count != objcount {
140		p.formatErrorf("got %d objects; want %d", objcount, count)
141	}
142
143	// --- compiler-specific export data ---
144
145	// read compiler-specific flags
146
147	// phase 2
148	objcount = 0
149	for {
150		tag := p.tagOrIndex()
151		if tag == endTag {
152			break
153		}
154		p.obj(tag)
155		objcount++
156	}
157
158	// self-verification
159	if count := p.int(); count != objcount {
160		p.formatErrorf("got %d objects; want %d", objcount, count)
161	}
162
163	// read inlineable functions bodies
164	if dclcontext != PEXTERN {
165		p.formatErrorf("unexpected context %d", dclcontext)
166	}
167
168	objcount = 0
169	for i0 := -1; ; {
170		i := p.int() // index of function with inlineable body
171		if i < 0 {
172			break
173		}
174
175		// don't process the same function twice
176		if i <= i0 {
177			p.formatErrorf("index not increasing: %d <= %d", i, i0)
178		}
179		i0 = i
180
181		if funcdepth != 0 {
182			p.formatErrorf("unexpected Funcdepth %d", funcdepth)
183		}
184
185		// Note: In the original code, funchdr and funcbody are called for
186		// all functions (that were not yet imported). Now, we are calling
187		// them only for functions with inlineable bodies. funchdr does
188		// parameter renaming which doesn't matter if we don't have a body.
189
190		if f := p.funcList[i]; f != nil {
191			// function not yet imported - read body and set it
192			funchdr(f)
193			body := p.stmtList()
194			if body == nil {
195				// Make sure empty body is not interpreted as
196				// no inlineable body (see also parser.fnbody)
197				// (not doing so can cause significant performance
198				// degradation due to unnecessary calls to empty
199				// functions).
200				body = []*Node{nod(OEMPTY, nil, nil)}
201			}
202			f.Func.Inl.Set(body)
203			funcbody(f)
204		} else {
205			// function already imported - read body but discard declarations
206			dclcontext = PDISCARD // throw away any declarations
207			p.stmtList()
208			dclcontext = PEXTERN
209		}
210
211		objcount++
212	}
213
214	// self-verification
215	if count := p.int(); count != objcount {
216		p.formatErrorf("got %d functions; want %d", objcount, count)
217	}
218
219	if dclcontext != PEXTERN {
220		p.formatErrorf("unexpected context %d", dclcontext)
221	}
222
223	p.verifyTypes()
224
225	// --- end of export data ---
226
227	typecheckok = tcok
228	resumecheckwidth()
229
230	if debug_dclstack != 0 {
231		testdclstack()
232	}
233}
234
235func (p *importer) formatErrorf(format string, args ...interface{}) {
236	if debugFormat {
237		Fatalf(format, args...)
238	}
239
240	yyerror("cannot import %q due to version skew - reinstall package (%s)",
241		p.imp.Path, fmt.Sprintf(format, args...))
242	errorexit()
243}
244
245func (p *importer) verifyTypes() {
246	for _, pair := range p.cmpList {
247		pt := pair.pt
248		t := pair.t
249		if !eqtype(pt.Orig, t) {
250			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)
251		}
252	}
253}
254
255// numImport tracks how often a package with a given name is imported.
256// It is used to provide a better error message (by using the package
257// path to disambiguate) if a package that appears multiple times with
258// the same name appears in an error message.
259var numImport = make(map[string]int)
260
261func (p *importer) pkg() *types.Pkg {
262	// if the package was seen before, i is its index (>= 0)
263	i := p.tagOrIndex()
264	if i >= 0 {
265		return p.pkgList[i]
266	}
267
268	// otherwise, i is the package tag (< 0)
269	if i != packageTag {
270		p.formatErrorf("expected package tag, found tag = %d", i)
271	}
272
273	// read package data
274	name := p.string()
275	var path string
276	if p.version >= 5 {
277		path = p.path()
278	} else {
279		path = p.string()
280	}
281
282	// we should never see an empty package name
283	if name == "" {
284		p.formatErrorf("empty package name for path %q", path)
285	}
286
287	// we should never see a bad import path
288	if isbadimport(path, true) {
289		p.formatErrorf("bad package path %q for package %s", path, name)
290	}
291
292	// an empty path denotes the package we are currently importing;
293	// it must be the first package we see
294	if (path == "") != (len(p.pkgList) == 0) {
295		p.formatErrorf("package path %q for pkg index %d", path, len(p.pkgList))
296	}
297
298	// add package to pkgList
299	pkg := p.imp
300	if path != "" {
301		pkg = types.NewPkg(path, "")
302	}
303	if pkg.Name == "" {
304		pkg.Name = name
305		numImport[name]++
306	} else if pkg.Name != name {
307		yyerror("conflicting package names %s and %s for path %q", pkg.Name, name, path)
308	}
309	if myimportpath != "" && path == myimportpath {
310		yyerror("import %q: package depends on %q (import cycle)", p.imp.Path, path)
311		errorexit()
312	}
313	p.pkgList = append(p.pkgList, pkg)
314
315	return pkg
316}
317
318func idealType(typ *types.Type) *types.Type {
319	if typ.IsUntyped() {
320		// canonicalize ideal types
321		typ = types.Types[TIDEAL]
322	}
323	return typ
324}
325
326func (p *importer) obj(tag int) {
327	switch tag {
328	case constTag:
329		p.pos()
330		sym := p.qualifiedName()
331		typ := p.typ()
332		val := p.value(typ)
333		importconst(p.imp, sym, idealType(typ), nodlit(val))
334
335	case aliasTag:
336		p.pos()
337		sym := p.qualifiedName()
338		typ := p.typ()
339		importalias(p.imp, sym, typ)
340
341	case typeTag:
342		p.typ()
343
344	case varTag:
345		p.pos()
346		sym := p.qualifiedName()
347		typ := p.typ()
348		importvar(p.imp, sym, typ)
349
350	case funcTag:
351		p.pos()
352		sym := p.qualifiedName()
353		params := p.paramList()
354		result := p.paramList()
355
356		sig := functypefield(nil, params, result)
357		importsym(p.imp, sym, ONAME)
358		if asNode(sym.Def) != nil && asNode(sym.Def).Op == ONAME {
359			// function was imported before (via another import)
360			if !eqtype(sig, asNode(sym.Def).Type) {
361				p.formatErrorf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, asNode(sym.Def).Type, sig)
362			}
363			p.funcList = append(p.funcList, nil)
364			break
365		}
366
367		n := newfuncname(sym)
368		n.Type = sig
369		declare(n, PFUNC)
370		p.funcList = append(p.funcList, n)
371		importlist = append(importlist, n)
372
373		if Debug['E'] > 0 {
374			fmt.Printf("import [%q] func %v \n", p.imp.Path, n)
375			if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
376				fmt.Printf("inl body: %v\n", n.Func.Inl)
377			}
378		}
379
380	default:
381		p.formatErrorf("unexpected object (tag = %d)", tag)
382	}
383}
384
385func (p *importer) pos() src.XPos {
386	if !p.posInfoFormat {
387		return src.NoXPos
388	}
389
390	file := p.prevFile
391	line := p.prevLine
392	delta := p.int()
393	line += delta
394	if p.version >= 5 {
395		if delta == deltaNewFile {
396			if n := p.int(); n >= 0 {
397				// file changed
398				file = p.path()
399				line = n
400			}
401		}
402	} else {
403		if delta == 0 {
404			if n := p.int(); n >= 0 {
405				// file changed
406				file = p.prevFile[:n] + p.string()
407				line = p.int()
408			}
409		}
410	}
411	if file != p.prevFile {
412		p.prevFile = file
413		p.posBase = src.NewFileBase(file, file)
414	}
415	p.prevLine = line
416
417	pos := src.MakePos(p.posBase, uint(line), 0)
418	xpos := Ctxt.PosTable.XPos(pos)
419	return xpos
420}
421
422func (p *importer) path() string {
423	// if the path was seen before, i is its index (>= 0)
424	// (the empty string is at index 0)
425	i := p.int()
426	if i >= 0 {
427		return p.pathList[i]
428	}
429	// otherwise, i is the negative path length (< 0)
430	a := make([]string, -i)
431	for n := range a {
432		a[n] = p.string()
433	}
434	s := strings.Join(a, "/")
435	p.pathList = append(p.pathList, s)
436	return s
437}
438
439func (p *importer) newtyp(etype types.EType) *types.Type {
440	t := types.New(etype)
441	if p.trackAllTypes {
442		p.typList = append(p.typList, t)
443	}
444	return t
445}
446
447// importtype declares that pt, an imported named type, has underlying type t.
448func (p *importer) importtype(pt, t *types.Type) {
449	if pt.Etype == TFORW {
450		copytype(asNode(pt.Nod), t)
451		pt.Sym.Importdef = p.imp
452		pt.Sym.Lastlineno = lineno
453		declare(asNode(pt.Nod), PEXTERN)
454		checkwidth(pt)
455	} else {
456		// pt.Orig and t must be identical.
457		if p.trackAllTypes {
458			// If we track all types, t may not be fully set up yet.
459			// Collect the types and verify identity later.
460			p.cmpList = append(p.cmpList, struct{ pt, t *types.Type }{pt, t})
461		} else if !eqtype(pt.Orig, t) {
462			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)
463		}
464	}
465
466	if Debug['E'] != 0 {
467		fmt.Printf("import type %v %L\n", pt, t)
468	}
469}
470
471func (p *importer) typ() *types.Type {
472	// if the type was seen before, i is its index (>= 0)
473	i := p.tagOrIndex()
474	if i >= 0 {
475		return p.typList[i]
476	}
477
478	// otherwise, i is the type tag (< 0)
479	var t *types.Type
480	switch i {
481	case namedTag:
482		p.pos()
483		tsym := p.qualifiedName()
484
485		t = pkgtype(p.imp, tsym)
486		p.typList = append(p.typList, t)
487
488		// read underlying type
489		t0 := p.typ()
490		p.importtype(t, t0)
491
492		// interfaces don't have associated methods
493		if t0.IsInterface() {
494			break
495		}
496
497		// set correct import context (since p.typ() may be called
498		// while importing the body of an inlined function)
499		savedContext := dclcontext
500		dclcontext = PEXTERN
501
502		// read associated methods
503		for i := p.int(); i > 0; i-- {
504			p.pos()
505			sym := p.fieldSym()
506
507			// during import unexported method names should be in the type's package
508			if !exportname(sym.Name) && sym.Pkg != tsym.Pkg {
509				Fatalf("imported method name %+v in wrong package %s\n", sym, tsym.Pkg.Name)
510			}
511
512			recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
513			params := p.paramList()
514			result := p.paramList()
515			nointerface := p.bool()
516
517			n := newfuncname(methodname(sym, recv[0].Type))
518			n.Type = functypefield(recv[0], params, result)
519			checkwidth(n.Type)
520			addmethod(sym, n.Type, false, nointerface)
521			p.funcList = append(p.funcList, n)
522			importlist = append(importlist, n)
523
524			// (comment from parser.go)
525			// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
526			// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
527			// out by typecheck's lookdot as this $$.ttype. So by providing
528			// this back link here we avoid special casing there.
529			n.Type.FuncType().Nname = asTypesNode(n)
530
531			if Debug['E'] > 0 {
532				fmt.Printf("import [%q] meth %v \n", p.imp.Path, n)
533				if Debug['m'] > 2 && n.Func.Inl.Len() != 0 {
534					fmt.Printf("inl body: %v\n", n.Func.Inl)
535				}
536			}
537		}
538
539		dclcontext = savedContext
540
541	case arrayTag:
542		t = p.newtyp(TARRAY)
543		bound := p.int64()
544		elem := p.typ()
545		t.Extra = &types.Array{Elem: elem, Bound: bound}
546
547	case sliceTag:
548		t = p.newtyp(TSLICE)
549		elem := p.typ()
550		t.Extra = types.Slice{Elem: elem}
551
552	case dddTag:
553		t = p.newtyp(TDDDFIELD)
554		t.Extra = types.DDDField{T: p.typ()}
555
556	case structTag:
557		t = p.newtyp(TSTRUCT)
558		t.SetFields(p.fieldList())
559		checkwidth(t)
560
561	case pointerTag:
562		t = p.newtyp(types.Tptr)
563		t.Extra = types.Ptr{Elem: p.typ()}
564
565	case signatureTag:
566		t = p.newtyp(TFUNC)
567		params := p.paramList()
568		result := p.paramList()
569		functypefield0(t, nil, params, result)
570
571	case interfaceTag:
572		if ml := p.methodList(); len(ml) == 0 {
573			t = types.Types[TINTER]
574		} else {
575			t = p.newtyp(TINTER)
576			t.SetInterface(ml)
577		}
578
579	case mapTag:
580		t = p.newtyp(TMAP)
581		mt := t.MapType()
582		mt.Key = p.typ()
583		mt.Val = p.typ()
584
585	case chanTag:
586		t = p.newtyp(TCHAN)
587		ct := t.ChanType()
588		ct.Dir = types.ChanDir(p.int())
589		ct.Elem = p.typ()
590
591	default:
592		p.formatErrorf("unexpected type (tag = %d)", i)
593	}
594
595	if t == nil {
596		p.formatErrorf("nil type (type tag = %d)", i)
597	}
598
599	return t
600}
601
602func (p *importer) qualifiedName() *types.Sym {
603	name := p.string()
604	pkg := p.pkg()
605	return pkg.Lookup(name)
606}
607
608func (p *importer) fieldList() (fields []*types.Field) {
609	if n := p.int(); n > 0 {
610		fields = make([]*types.Field, n)
611		for i := range fields {
612			fields[i] = p.field()
613		}
614	}
615	return
616}
617
618func (p *importer) field() *types.Field {
619	p.pos()
620	sym, alias := p.fieldName()
621	typ := p.typ()
622	note := p.string()
623
624	f := types.NewField()
625	if sym.Name == "" {
626		// anonymous field: typ must be T or *T and T must be a type name
627		s := typ.Sym
628		if s == nil && typ.IsPtr() {
629			s = typ.Elem().Sym // deref
630		}
631		sym = sym.Pkg.Lookup(s.Name)
632		f.Embedded = 1
633	} else if alias {
634		// anonymous field: we have an explicit name because it's a type alias
635		f.Embedded = 1
636	}
637
638	f.Sym = sym
639	f.Nname = asTypesNode(newname(sym))
640	f.Type = typ
641	f.Note = note
642
643	return f
644}
645
646func (p *importer) methodList() (methods []*types.Field) {
647	for n := p.int(); n > 0; n-- {
648		f := types.NewField()
649		f.Nname = asTypesNode(newname(nblank.Sym))
650		asNode(f.Nname).Pos = p.pos()
651		f.Type = p.typ()
652		methods = append(methods, f)
653	}
654
655	for n := p.int(); n > 0; n-- {
656		methods = append(methods, p.method())
657	}
658
659	return
660}
661
662func (p *importer) method() *types.Field {
663	p.pos()
664	sym := p.methodName()
665	params := p.paramList()
666	result := p.paramList()
667
668	f := types.NewField()
669	f.Sym = sym
670	f.Nname = asTypesNode(newname(sym))
671	f.Type = functypefield(fakeRecvField(), params, result)
672	return f
673}
674
675func (p *importer) fieldName() (*types.Sym, bool) {
676	name := p.string()
677	if p.version == 0 && name == "_" {
678		// version 0 didn't export a package for _ field names
679		// but used the builtin package instead
680		return builtinpkg.Lookup(name), false
681	}
682	pkg := localpkg
683	alias := false
684	switch name {
685	case "":
686		// 1) field name matches base type name and is exported: nothing to do
687	case "?":
688		// 2) field name matches base type name and is not exported: need package
689		name = ""
690		pkg = p.pkg()
691	case "@":
692		// 3) field name doesn't match base type name (alias name): need name and possibly package
693		name = p.string()
694		alias = true
695		fallthrough
696	default:
697		if !exportname(name) {
698			pkg = p.pkg()
699		}
700	}
701	return pkg.Lookup(name), alias
702}
703
704func (p *importer) methodName() *types.Sym {
705	name := p.string()
706	if p.version == 0 && name == "_" {
707		// version 0 didn't export a package for _ method names
708		// but used the builtin package instead
709		return builtinpkg.Lookup(name)
710	}
711	pkg := localpkg
712	if !exportname(name) {
713		pkg = p.pkg()
714	}
715	return pkg.Lookup(name)
716}
717
718func (p *importer) paramList() []*types.Field {
719	i := p.int()
720	if i == 0 {
721		return nil
722	}
723	// negative length indicates unnamed parameters
724	named := true
725	if i < 0 {
726		i = -i
727		named = false
728	}
729	// i > 0
730	fs := make([]*types.Field, i)
731	for i := range fs {
732		fs[i] = p.param(named)
733	}
734	return fs
735}
736
737func (p *importer) param(named bool) *types.Field {
738	f := types.NewField()
739	f.Type = p.typ()
740	if f.Type.Etype == TDDDFIELD {
741		// TDDDFIELD indicates wrapped ... slice type
742		f.Type = types.NewSlice(f.Type.DDDField())
743		f.SetIsddd(true)
744	}
745
746	if named {
747		name := p.string()
748		if name == "" {
749			p.formatErrorf("expected named parameter")
750		}
751		// TODO(gri) Supply function/method package rather than
752		// encoding the package for each parameter repeatedly.
753		pkg := localpkg
754		if name != "_" {
755			pkg = p.pkg()
756		}
757		f.Sym = pkg.Lookup(name)
758		f.Nname = asTypesNode(newname(f.Sym))
759	}
760
761	// TODO(gri) This is compiler-specific (escape info).
762	// Move into compiler-specific section eventually?
763	f.Note = p.string()
764
765	return f
766}
767
768func (p *importer) value(typ *types.Type) (x Val) {
769	switch tag := p.tagOrIndex(); tag {
770	case falseTag:
771		x.U = false
772
773	case trueTag:
774		x.U = true
775
776	case int64Tag:
777		u := new(Mpint)
778		u.SetInt64(p.int64())
779		u.Rune = typ == types.Idealrune
780		x.U = u
781
782	case floatTag:
783		f := newMpflt()
784		p.float(f)
785		if typ == types.Idealint || typ.IsInteger() {
786			// uncommon case: large int encoded as float
787			u := new(Mpint)
788			u.SetFloat(f)
789			x.U = u
790			break
791		}
792		x.U = f
793
794	case complexTag:
795		u := new(Mpcplx)
796		p.float(&u.Real)
797		p.float(&u.Imag)
798		x.U = u
799
800	case stringTag:
801		x.U = p.string()
802
803	case unknownTag:
804		p.formatErrorf("unknown constant (importing package with errors)")
805
806	case nilTag:
807		x.U = new(NilVal)
808
809	default:
810		p.formatErrorf("unexpected value tag %d", tag)
811	}
812
813	// verify ideal type
814	if typ.IsUntyped() && untype(x.Ctype()) != typ {
815		p.formatErrorf("value %v and type %v don't match", x, typ)
816	}
817
818	return
819}
820
821func (p *importer) float(x *Mpflt) {
822	sign := p.int()
823	if sign == 0 {
824		x.SetFloat64(0)
825		return
826	}
827
828	exp := p.int()
829	mant := new(big.Int).SetBytes([]byte(p.string()))
830
831	m := x.Val.SetInt(mant)
832	m.SetMantExp(m, exp-mant.BitLen())
833	if sign < 0 {
834		m.Neg(m)
835	}
836}
837
838// ----------------------------------------------------------------------------
839// Inlined function bodies
840
841// Approach: Read nodes and use them to create/declare the same data structures
842// as done originally by the (hidden) parser by closely following the parser's
843// original code. In other words, "parsing" the import data (which happens to
844// be encoded in binary rather textual form) is the best way at the moment to
845// re-establish the syntax tree's invariants. At some future point we might be
846// able to avoid this round-about way and create the rewritten nodes directly,
847// possibly avoiding a lot of duplicate work (name resolution, type checking).
848//
849// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
850// unrefined nodes (since this is what the importer uses). The respective case
851// entries are unreachable in the importer.
852
853func (p *importer) stmtList() []*Node {
854	var list []*Node
855	for {
856		n := p.node()
857		if n == nil {
858			break
859		}
860		// OBLOCK nodes may be created when importing ODCL nodes - unpack them
861		if n.Op == OBLOCK {
862			list = append(list, n.List.Slice()...)
863		} else {
864			list = append(list, n)
865		}
866	}
867	return list
868}
869
870func (p *importer) exprList() []*Node {
871	var list []*Node
872	for {
873		n := p.expr()
874		if n == nil {
875			break
876		}
877		list = append(list, n)
878	}
879	return list
880}
881
882func (p *importer) elemList() []*Node {
883	c := p.int()
884	list := make([]*Node, c)
885	for i := range list {
886		s := p.fieldSym()
887		list[i] = nodSym(OSTRUCTKEY, p.expr(), s)
888	}
889	return list
890}
891
892func (p *importer) expr() *Node {
893	n := p.node()
894	if n != nil && n.Op == OBLOCK {
895		Fatalf("unexpected block node: %v", n)
896	}
897	return n
898}
899
900func npos(pos src.XPos, n *Node) *Node {
901	n.Pos = pos
902	return n
903}
904
905// TODO(gri) split into expr and stmt
906func (p *importer) node() *Node {
907	switch op := p.op(); op {
908	// expressions
909	// case OPAREN:
910	// 	unreachable - unpacked by exporter
911
912	// case ODDDARG:
913	//	unimplemented
914
915	case OLITERAL:
916		pos := p.pos()
917		typ := p.typ()
918		n := npos(pos, nodlit(p.value(typ)))
919		if !typ.IsUntyped() {
920			// Type-checking simplifies unsafe.Pointer(uintptr(c))
921			// to unsafe.Pointer(c) which then cannot type-checked
922			// again. Re-introduce explicit uintptr(c) conversion.
923			// (issue 16317).
924			if typ.IsUnsafePtr() {
925				n = nod(OCONV, n, nil)
926				n.Type = types.Types[TUINTPTR]
927			}
928			n = nod(OCONV, n, nil)
929			n.Type = typ
930		}
931		return n
932
933	case ONAME:
934		return npos(p.pos(), mkname(p.sym()))
935
936	// case OPACK, ONONAME:
937	// 	unreachable - should have been resolved by typechecking
938
939	case OTYPE:
940		pos := p.pos()
941		if p.bool() {
942			return npos(pos, mkname(p.sym()))
943		}
944		return npos(pos, typenod(p.typ()))
945
946	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
947	//      unreachable - should have been resolved by typechecking
948
949	// case OCLOSURE:
950	//	unimplemented
951
952	case OPTRLIT:
953		n := npos(p.pos(), p.expr())
954		if !p.bool() /* !implicit, i.e. '&' operator */ {
955			if n.Op == OCOMPLIT {
956				// Special case for &T{...}: turn into (*T){...}.
957				n.Right = nod(OIND, n.Right, nil)
958				n.Right.SetImplicit(true)
959			} else {
960				n = nod(OADDR, n, nil)
961			}
962		}
963		return n
964
965	case OSTRUCTLIT:
966		n := nodl(p.pos(), OCOMPLIT, nil, typenod(p.typ()))
967		n.List.Set(p.elemList()) // special handling of field names
968		return n
969
970	// case OARRAYLIT, OSLICELIT, OMAPLIT:
971	// 	unreachable - mapped to case OCOMPLIT below by exporter
972
973	case OCOMPLIT:
974		n := nodl(p.pos(), OCOMPLIT, nil, typenod(p.typ()))
975		n.List.Set(p.exprList())
976		return n
977
978	case OKEY:
979		pos := p.pos()
980		left, right := p.exprsOrNil()
981		return nodl(pos, OKEY, left, right)
982
983	// case OSTRUCTKEY:
984	//	unreachable - handled in case OSTRUCTLIT by elemList
985
986	// case OCALLPART:
987	//	unimplemented
988
989	// case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
990	// 	unreachable - mapped to case OXDOT below by exporter
991
992	case OXDOT:
993		// see parser.new_dotname
994		return npos(p.pos(), nodSym(OXDOT, p.expr(), p.fieldSym()))
995
996	// case ODOTTYPE, ODOTTYPE2:
997	// 	unreachable - mapped to case ODOTTYPE below by exporter
998
999	case ODOTTYPE:
1000		n := nodl(p.pos(), ODOTTYPE, p.expr(), nil)
1001		n.Type = p.typ()
1002		return n
1003
1004	// case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
1005	// 	unreachable - mapped to cases below by exporter
1006
1007	case OINDEX:
1008		return nodl(p.pos(), op, p.expr(), p.expr())
1009
1010	case OSLICE, OSLICE3:
1011		n := nodl(p.pos(), op, p.expr(), nil)
1012		low, high := p.exprsOrNil()
1013		var max *Node
1014		if n.Op.IsSlice3() {
1015			max = p.expr()
1016		}
1017		n.SetSliceBounds(low, high, max)
1018		return n
1019
1020	// case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
1021	// 	unreachable - mapped to OCONV case below by exporter
1022
1023	case OCONV:
1024		n := nodl(p.pos(), OCONV, p.expr(), nil)
1025		n.Type = p.typ()
1026		return n
1027
1028	case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
1029		n := npos(p.pos(), builtinCall(op))
1030		n.List.Set(p.exprList())
1031		if op == OAPPEND {
1032			n.SetIsddd(p.bool())
1033		}
1034		return n
1035
1036	// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
1037	// 	unreachable - mapped to OCALL case below by exporter
1038
1039	case OCALL:
1040		n := nodl(p.pos(), OCALL, p.expr(), nil)
1041		n.List.Set(p.exprList())
1042		n.SetIsddd(p.bool())
1043		return n
1044
1045	case OMAKEMAP, OMAKECHAN, OMAKESLICE:
1046		n := npos(p.pos(), builtinCall(OMAKE))
1047		n.List.Append(typenod(p.typ()))
1048		n.List.Append(p.exprList()...)
1049		return n
1050
1051	// unary expressions
1052	case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
1053		return nodl(p.pos(), op, p.expr(), nil)
1054
1055	// binary expressions
1056	case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
1057		OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
1058		return nodl(p.pos(), op, p.expr(), p.expr())
1059
1060	case OADDSTR:
1061		pos := p.pos()
1062		list := p.exprList()
1063		x := npos(pos, list[0])
1064		for _, y := range list[1:] {
1065			x = nodl(pos, OADD, x, y)
1066		}
1067		return x
1068
1069	// case OCMPSTR, OCMPIFACE:
1070	// 	unreachable - mapped to std comparison operators by exporter
1071
1072	case ODCLCONST:
1073		// TODO(gri) these should not be exported in the first place
1074		return nodl(p.pos(), OEMPTY, nil, nil)
1075
1076	// --------------------------------------------------------------------
1077	// statements
1078	case ODCL:
1079		if p.version < 2 {
1080			// versions 0 and 1 exported a bool here but it
1081			// was always false - simply ignore in this case
1082			p.bool()
1083		}
1084		pos := p.pos()
1085		lhs := dclname(p.sym())
1086		typ := typenod(p.typ())
1087		return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
1088
1089	// case ODCLFIELD:
1090	//	unimplemented
1091
1092	// case OAS, OASWB:
1093	// 	unreachable - mapped to OAS case below by exporter
1094
1095	case OAS:
1096		return nodl(p.pos(), OAS, p.expr(), p.expr())
1097
1098	case OASOP:
1099		n := nodl(p.pos(), OASOP, nil, nil)
1100		n.Etype = types.EType(p.int())
1101		n.Left = p.expr()
1102		if !p.bool() {
1103			n.Right = nodintconst(1)
1104			n.SetImplicit(true)
1105		} else {
1106			n.Right = p.expr()
1107		}
1108		return n
1109
1110	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
1111	// 	unreachable - mapped to OAS2 case below by exporter
1112
1113	case OAS2:
1114		n := nodl(p.pos(), OAS2, nil, nil)
1115		n.List.Set(p.exprList())
1116		n.Rlist.Set(p.exprList())
1117		return n
1118
1119	case ORETURN:
1120		n := nodl(p.pos(), ORETURN, nil, nil)
1121		n.List.Set(p.exprList())
1122		return n
1123
1124	// case ORETJMP:
1125	// 	unreachable - generated by compiler for trampolin routines (not exported)
1126
1127	case OPROC, ODEFER:
1128		return nodl(p.pos(), op, p.expr(), nil)
1129
1130	case OIF:
1131		types.Markdcl()
1132		n := nodl(p.pos(), OIF, nil, nil)
1133		n.Ninit.Set(p.stmtList())
1134		n.Left = p.expr()
1135		n.Nbody.Set(p.stmtList())
1136		n.Rlist.Set(p.stmtList())
1137		types.Popdcl()
1138		return n
1139
1140	case OFOR:
1141		types.Markdcl()
1142		n := nodl(p.pos(), OFOR, nil, nil)
1143		n.Ninit.Set(p.stmtList())
1144		n.Left, n.Right = p.exprsOrNil()
1145		n.Nbody.Set(p.stmtList())
1146		types.Popdcl()
1147		return n
1148
1149	case ORANGE:
1150		types.Markdcl()
1151		n := nodl(p.pos(), ORANGE, nil, nil)
1152		n.List.Set(p.stmtList())
1153		n.Right = p.expr()
1154		n.Nbody.Set(p.stmtList())
1155		types.Popdcl()
1156		return n
1157
1158	case OSELECT, OSWITCH:
1159		types.Markdcl()
1160		n := nodl(p.pos(), op, nil, nil)
1161		n.Ninit.Set(p.stmtList())
1162		n.Left, _ = p.exprsOrNil()
1163		n.List.Set(p.stmtList())
1164		types.Popdcl()
1165		return n
1166
1167	// case OCASE, OXCASE:
1168	// 	unreachable - mapped to OXCASE case below by exporter
1169
1170	case OXCASE:
1171		types.Markdcl()
1172		n := nodl(p.pos(), OXCASE, nil, nil)
1173		n.Xoffset = int64(types.Block)
1174		n.List.Set(p.exprList())
1175		// TODO(gri) eventually we must declare variables for type switch
1176		// statements (type switch statements are not yet exported)
1177		n.Nbody.Set(p.stmtList())
1178		types.Popdcl()
1179		return n
1180
1181	// case OFALL:
1182	// 	unreachable - mapped to OXFALL case below by exporter
1183
1184	case OXFALL:
1185		n := nodl(p.pos(), OXFALL, nil, nil)
1186		n.Xoffset = int64(types.Block)
1187		return n
1188
1189	case OBREAK, OCONTINUE:
1190		pos := p.pos()
1191		left, _ := p.exprsOrNil()
1192		if left != nil {
1193			left = newname(left.Sym)
1194		}
1195		return nodl(pos, op, left, nil)
1196
1197	// case OEMPTY:
1198	// 	unreachable - not emitted by exporter
1199
1200	case OGOTO, OLABEL:
1201		return nodl(p.pos(), op, newname(p.expr().Sym), nil)
1202
1203	case OEND:
1204		return nil
1205
1206	default:
1207		Fatalf("cannot import %v (%d) node\n"+
1208			"==> please file an issue and assign to gri@\n", op, int(op))
1209		panic("unreachable") // satisfy compiler
1210	}
1211}
1212
1213func builtinCall(op Op) *Node {
1214	return nod(OCALL, mkname(builtinpkg.Lookup(goopnames[op])), nil)
1215}
1216
1217func (p *importer) exprsOrNil() (a, b *Node) {
1218	ab := p.int()
1219	if ab&1 != 0 {
1220		a = p.expr()
1221	}
1222	if ab&2 != 0 {
1223		b = p.expr()
1224	}
1225	return
1226}
1227
1228func (p *importer) fieldSym() *types.Sym {
1229	name := p.string()
1230	pkg := localpkg
1231	if !exportname(name) {
1232		pkg = p.pkg()
1233	}
1234	return pkg.Lookup(name)
1235}
1236
1237func (p *importer) sym() *types.Sym {
1238	name := p.string()
1239	pkg := localpkg
1240	if name != "_" {
1241		pkg = p.pkg()
1242	}
1243	linkname := p.string()
1244	sym := pkg.Lookup(name)
1245	sym.Linkname = linkname
1246	return sym
1247}
1248
1249func (p *importer) bool() bool {
1250	return p.int() != 0
1251}
1252
1253func (p *importer) op() Op {
1254	return Op(p.int())
1255}
1256
1257// ----------------------------------------------------------------------------
1258// Low-level decoders
1259
1260func (p *importer) tagOrIndex() int {
1261	if p.debugFormat {
1262		p.marker('t')
1263	}
1264
1265	return int(p.rawInt64())
1266}
1267
1268func (p *importer) int() int {
1269	x := p.int64()
1270	if int64(int(x)) != x {
1271		p.formatErrorf("exported integer too large")
1272	}
1273	return int(x)
1274}
1275
1276func (p *importer) int64() int64 {
1277	if p.debugFormat {
1278		p.marker('i')
1279	}
1280
1281	return p.rawInt64()
1282}
1283
1284func (p *importer) string() string {
1285	if p.debugFormat {
1286		p.marker('s')
1287	}
1288	// if the string was seen before, i is its index (>= 0)
1289	// (the empty string is at index 0)
1290	i := p.rawInt64()
1291	if i >= 0 {
1292		return p.strList[i]
1293	}
1294	// otherwise, i is the negative string length (< 0)
1295	if n := int(-i); n <= cap(p.buf) {
1296		p.buf = p.buf[:n]
1297	} else {
1298		p.buf = make([]byte, n)
1299	}
1300	for i := range p.buf {
1301		p.buf[i] = p.rawByte()
1302	}
1303	s := string(p.buf)
1304	p.strList = append(p.strList, s)
1305	return s
1306}
1307
1308func (p *importer) marker(want byte) {
1309	if got := p.rawByte(); got != want {
1310		p.formatErrorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
1311	}
1312
1313	pos := p.read
1314	if n := int(p.rawInt64()); n != pos {
1315		p.formatErrorf("incorrect position: got %d; want %d", n, pos)
1316	}
1317}
1318
1319// rawInt64 should only be used by low-level decoders.
1320func (p *importer) rawInt64() int64 {
1321	i, err := binary.ReadVarint(p)
1322	if err != nil {
1323		p.formatErrorf("read error: %v", err)
1324	}
1325	return i
1326}
1327
1328// rawStringln should only be used to read the initial version string.
1329func (p *importer) rawStringln(b byte) string {
1330	p.buf = p.buf[:0]
1331	for b != '\n' {
1332		p.buf = append(p.buf, b)
1333		b = p.rawByte()
1334	}
1335	return string(p.buf)
1336}
1337
1338// needed for binary.ReadVarint in rawInt64
1339func (p *importer) ReadByte() (byte, error) {
1340	return p.rawByte(), nil
1341}
1342
1343// rawByte is the bottleneck interface for reading from p.in.
1344// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
1345// rawByte should only be used by low-level decoders.
1346func (p *importer) rawByte() byte {
1347	c, err := p.in.ReadByte()
1348	p.read++
1349	if err != nil {
1350		p.formatErrorf("read error: %v", err)
1351	}
1352	if c == '|' {
1353		c, err = p.in.ReadByte()
1354		p.read++
1355		if err != nil {
1356			p.formatErrorf("read error: %v", err)
1357		}
1358		switch c {
1359		case 'S':
1360			c = '$'
1361		case '|':
1362			// nothing to do
1363		default:
1364			p.formatErrorf("unexpected escape sequence in export data")
1365		}
1366	}
1367	return c
1368}
1369