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// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
6
7package gcimporter
8
9import (
10	"encoding/binary"
11	"fmt"
12	"go/constant"
13	"go/token"
14	"go/types"
15	"sort"
16	"strconv"
17	"strings"
18	"sync"
19	"unicode"
20	"unicode/utf8"
21)
22
23type importer struct {
24	imports    map[string]*types.Package
25	data       []byte
26	importpath string
27	buf        []byte // for reading strings
28	version    int    // export format version
29
30	// object lists
31	strList       []string           // in order of appearance
32	pathList      []string           // in order of appearance
33	pkgList       []*types.Package   // in order of appearance
34	typList       []types.Type       // in order of appearance
35	interfaceList []*types.Interface // for delayed completion only
36	trackAllTypes bool
37
38	// position encoding
39	posInfoFormat bool
40	prevFile      string
41	prevLine      int
42	fset          *token.FileSet
43	files         map[string]*token.File
44
45	// debugging support
46	debugFormat bool
47	read        int // bytes read
48}
49
50// BImportData imports a package from the serialized package data
51// and returns the number of bytes consumed and a reference to the package.
52// If the export data version is not recognized or the format is otherwise
53// compromised, an error is returned.
54func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
55	// catch panics and return them as errors
56	defer func() {
57		if e := recover(); e != nil {
58			// The package (filename) causing the problem is added to this
59			// error by a wrapper in the caller (Import in gcimporter.go).
60			// Return a (possibly nil or incomplete) package unchanged (see #16088).
61			err = fmt.Errorf("cannot import, possibly version skew (%v) - reinstall package", e)
62		}
63	}()
64
65	p := importer{
66		imports:    imports,
67		data:       data,
68		importpath: path,
69		version:    -1,           // unknown version
70		strList:    []string{""}, // empty string is mapped to 0
71		pathList:   []string{""}, // empty string is mapped to 0
72		fset:       fset,
73		files:      make(map[string]*token.File),
74	}
75
76	// read version info
77	var versionstr string
78	if b := p.rawByte(); b == 'c' || b == 'd' {
79		// Go1.7 encoding; first byte encodes low-level
80		// encoding format (compact vs debug).
81		// For backward-compatibility only (avoid problems with
82		// old installed packages). Newly compiled packages use
83		// the extensible format string.
84		// TODO(gri) Remove this support eventually; after Go1.8.
85		if b == 'd' {
86			p.debugFormat = true
87		}
88		p.trackAllTypes = p.rawByte() == 'a'
89		p.posInfoFormat = p.int() != 0
90		versionstr = p.string()
91		if versionstr == "v1" {
92			p.version = 0
93		}
94	} else {
95		// Go1.8 extensible encoding
96		// read version string and extract version number (ignore anything after the version number)
97		versionstr = p.rawStringln(b)
98		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
99			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
100				p.version = v
101			}
102		}
103	}
104
105	// read version specific flags - extend as necessary
106	switch p.version {
107	// case 6:
108	// 	...
109	//	fallthrough
110	case 5, 4, 3, 2, 1:
111		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
112		p.trackAllTypes = p.int() != 0
113		p.posInfoFormat = p.int() != 0
114	case 0:
115		// Go1.7 encoding format - nothing to do here
116	default:
117		errorf("unknown export format version %d (%q)", p.version, versionstr)
118	}
119
120	// --- generic export data ---
121
122	// populate typList with predeclared "known" types
123	p.typList = append(p.typList, predeclared...)
124
125	// read package data
126	pkg = p.pkg()
127
128	// read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
129	objcount := 0
130	for {
131		tag := p.tagOrIndex()
132		if tag == endTag {
133			break
134		}
135		p.obj(tag)
136		objcount++
137	}
138
139	// self-verification
140	if count := p.int(); count != objcount {
141		errorf("got %d objects; want %d", objcount, count)
142	}
143
144	// ignore compiler-specific import data
145
146	// complete interfaces
147	// TODO(gri) re-investigate if we still need to do this in a delayed fashion
148	for _, typ := range p.interfaceList {
149		typ.Complete()
150	}
151
152	// record all referenced packages as imports
153	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
154	sort.Sort(byPath(list))
155	pkg.SetImports(list)
156
157	// package was imported completely and without errors
158	pkg.MarkComplete()
159
160	return p.read, pkg, nil
161}
162
163func errorf(format string, args ...interface{}) {
164	panic(fmt.Sprintf(format, args...))
165}
166
167func (p *importer) pkg() *types.Package {
168	// if the package was seen before, i is its index (>= 0)
169	i := p.tagOrIndex()
170	if i >= 0 {
171		return p.pkgList[i]
172	}
173
174	// otherwise, i is the package tag (< 0)
175	if i != packageTag {
176		errorf("unexpected package tag %d version %d", i, p.version)
177	}
178
179	// read package data
180	name := p.string()
181	var path string
182	if p.version >= 5 {
183		path = p.path()
184	} else {
185		path = p.string()
186	}
187
188	// we should never see an empty package name
189	if name == "" {
190		errorf("empty package name in import")
191	}
192
193	// an empty path denotes the package we are currently importing;
194	// it must be the first package we see
195	if (path == "") != (len(p.pkgList) == 0) {
196		errorf("package path %q for pkg index %d", path, len(p.pkgList))
197	}
198
199	// if the package was imported before, use that one; otherwise create a new one
200	if path == "" {
201		path = p.importpath
202	}
203	pkg := p.imports[path]
204	if pkg == nil {
205		pkg = types.NewPackage(path, name)
206		p.imports[path] = pkg
207	} else if pkg.Name() != name {
208		errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
209	}
210	p.pkgList = append(p.pkgList, pkg)
211
212	return pkg
213}
214
215// objTag returns the tag value for each object kind.
216func objTag(obj types.Object) int {
217	switch obj.(type) {
218	case *types.Const:
219		return constTag
220	case *types.TypeName:
221		return typeTag
222	case *types.Var:
223		return varTag
224	case *types.Func:
225		return funcTag
226	default:
227		errorf("unexpected object: %v (%T)", obj, obj) // panics
228		panic("unreachable")
229	}
230}
231
232func sameObj(a, b types.Object) bool {
233	// Because unnamed types are not canonicalized, we cannot simply compare types for
234	// (pointer) identity.
235	// Ideally we'd check equality of constant values as well, but this is good enough.
236	return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
237}
238
239func (p *importer) declare(obj types.Object) {
240	pkg := obj.Pkg()
241	if alt := pkg.Scope().Insert(obj); alt != nil {
242		// This can only trigger if we import a (non-type) object a second time.
243		// Excluding type aliases, this cannot happen because 1) we only import a package
244		// once; and b) we ignore compiler-specific export data which may contain
245		// functions whose inlined function bodies refer to other functions that
246		// were already imported.
247		// However, type aliases require reexporting the original type, so we need
248		// to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
249		// method importer.obj, switch case importing functions).
250		// TODO(gri) review/update this comment once the gc compiler handles type aliases.
251		if !sameObj(obj, alt) {
252			errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
253		}
254	}
255}
256
257func (p *importer) obj(tag int) {
258	switch tag {
259	case constTag:
260		pos := p.pos()
261		pkg, name := p.qualifiedName()
262		typ := p.typ(nil)
263		val := p.value()
264		p.declare(types.NewConst(pos, pkg, name, typ, val))
265
266	case aliasTag:
267		// TODO(gri) verify type alias hookup is correct
268		pos := p.pos()
269		pkg, name := p.qualifiedName()
270		typ := p.typ(nil)
271		p.declare(types.NewTypeName(pos, pkg, name, typ))
272
273	case typeTag:
274		p.typ(nil)
275
276	case varTag:
277		pos := p.pos()
278		pkg, name := p.qualifiedName()
279		typ := p.typ(nil)
280		p.declare(types.NewVar(pos, pkg, name, typ))
281
282	case funcTag:
283		pos := p.pos()
284		pkg, name := p.qualifiedName()
285		params, isddd := p.paramList()
286		result, _ := p.paramList()
287		sig := types.NewSignature(nil, params, result, isddd)
288		p.declare(types.NewFunc(pos, pkg, name, sig))
289
290	default:
291		errorf("unexpected object tag %d", tag)
292	}
293}
294
295const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
296
297func (p *importer) pos() token.Pos {
298	if !p.posInfoFormat {
299		return token.NoPos
300	}
301
302	file := p.prevFile
303	line := p.prevLine
304	delta := p.int()
305	line += delta
306	if p.version >= 5 {
307		if delta == deltaNewFile {
308			if n := p.int(); n >= 0 {
309				// file changed
310				file = p.path()
311				line = n
312			}
313		}
314	} else {
315		if delta == 0 {
316			if n := p.int(); n >= 0 {
317				// file changed
318				file = p.prevFile[:n] + p.string()
319				line = p.int()
320			}
321		}
322	}
323	p.prevFile = file
324	p.prevLine = line
325
326	// Synthesize a token.Pos
327
328	// Since we don't know the set of needed file positions, we
329	// reserve maxlines positions per file.
330	const maxlines = 64 * 1024
331	f := p.files[file]
332	if f == nil {
333		f = p.fset.AddFile(file, -1, maxlines)
334		p.files[file] = f
335		// Allocate the fake linebreak indices on first use.
336		// TODO(adonovan): opt: save ~512KB using a more complex scheme?
337		fakeLinesOnce.Do(func() {
338			fakeLines = make([]int, maxlines)
339			for i := range fakeLines {
340				fakeLines[i] = i
341			}
342		})
343		f.SetLines(fakeLines)
344	}
345
346	if line > maxlines {
347		line = 1
348	}
349
350	// Treat the file as if it contained only newlines
351	// and column=1: use the line number as the offset.
352	return f.Pos(line - 1)
353}
354
355var (
356	fakeLines     []int
357	fakeLinesOnce sync.Once
358)
359
360func (p *importer) qualifiedName() (pkg *types.Package, name string) {
361	name = p.string()
362	pkg = p.pkg()
363	return
364}
365
366func (p *importer) record(t types.Type) {
367	p.typList = append(p.typList, t)
368}
369
370// A dddSlice is a types.Type representing ...T parameters.
371// It only appears for parameter types and does not escape
372// the importer.
373type dddSlice struct {
374	elem types.Type
375}
376
377func (t *dddSlice) Underlying() types.Type { return t }
378func (t *dddSlice) String() string         { return "..." + t.elem.String() }
379
380// parent is the package which declared the type; parent == nil means
381// the package currently imported. The parent package is needed for
382// exported struct fields and interface methods which don't contain
383// explicit package information in the export data.
384func (p *importer) typ(parent *types.Package) types.Type {
385	// if the type was seen before, i is its index (>= 0)
386	i := p.tagOrIndex()
387	if i >= 0 {
388		return p.typList[i]
389	}
390
391	// otherwise, i is the type tag (< 0)
392	switch i {
393	case namedTag:
394		// read type object
395		pos := p.pos()
396		parent, name := p.qualifiedName()
397		scope := parent.Scope()
398		obj := scope.Lookup(name)
399
400		// if the object doesn't exist yet, create and insert it
401		if obj == nil {
402			obj = types.NewTypeName(pos, parent, name, nil)
403			scope.Insert(obj)
404		}
405
406		if _, ok := obj.(*types.TypeName); !ok {
407			errorf("pkg = %s, name = %s => %s", parent, name, obj)
408		}
409
410		// associate new named type with obj if it doesn't exist yet
411		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
412
413		// but record the existing type, if any
414		t := obj.Type().(*types.Named)
415		p.record(t)
416
417		// read underlying type
418		t0.SetUnderlying(p.typ(parent))
419
420		// interfaces don't have associated methods
421		if types.IsInterface(t0) {
422			return t
423		}
424
425		// read associated methods
426		for i := p.int(); i > 0; i-- {
427			// TODO(gri) replace this with something closer to fieldName
428			pos := p.pos()
429			name := p.string()
430			if !exported(name) {
431				p.pkg()
432			}
433
434			recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
435			params, isddd := p.paramList()
436			result, _ := p.paramList()
437			p.int() // go:nointerface pragma - discarded
438
439			sig := types.NewSignature(recv.At(0), params, result, isddd)
440			t0.AddMethod(types.NewFunc(pos, parent, name, sig))
441		}
442
443		return t
444
445	case arrayTag:
446		t := new(types.Array)
447		if p.trackAllTypes {
448			p.record(t)
449		}
450
451		n := p.int64()
452		*t = *types.NewArray(p.typ(parent), n)
453		return t
454
455	case sliceTag:
456		t := new(types.Slice)
457		if p.trackAllTypes {
458			p.record(t)
459		}
460
461		*t = *types.NewSlice(p.typ(parent))
462		return t
463
464	case dddTag:
465		t := new(dddSlice)
466		if p.trackAllTypes {
467			p.record(t)
468		}
469
470		t.elem = p.typ(parent)
471		return t
472
473	case structTag:
474		t := new(types.Struct)
475		if p.trackAllTypes {
476			p.record(t)
477		}
478
479		*t = *types.NewStruct(p.fieldList(parent))
480		return t
481
482	case pointerTag:
483		t := new(types.Pointer)
484		if p.trackAllTypes {
485			p.record(t)
486		}
487
488		*t = *types.NewPointer(p.typ(parent))
489		return t
490
491	case signatureTag:
492		t := new(types.Signature)
493		if p.trackAllTypes {
494			p.record(t)
495		}
496
497		params, isddd := p.paramList()
498		result, _ := p.paramList()
499		*t = *types.NewSignature(nil, params, result, isddd)
500		return t
501
502	case interfaceTag:
503		// Create a dummy entry in the type list. This is safe because we
504		// cannot expect the interface type to appear in a cycle, as any
505		// such cycle must contain a named type which would have been
506		// first defined earlier.
507		n := len(p.typList)
508		if p.trackAllTypes {
509			p.record(nil)
510		}
511
512		var embeddeds []*types.Named
513		for n := p.int(); n > 0; n-- {
514			p.pos()
515			embeddeds = append(embeddeds, p.typ(parent).(*types.Named))
516		}
517
518		t := types.NewInterface(p.methodList(parent), embeddeds)
519		p.interfaceList = append(p.interfaceList, t)
520		if p.trackAllTypes {
521			p.typList[n] = t
522		}
523		return t
524
525	case mapTag:
526		t := new(types.Map)
527		if p.trackAllTypes {
528			p.record(t)
529		}
530
531		key := p.typ(parent)
532		val := p.typ(parent)
533		*t = *types.NewMap(key, val)
534		return t
535
536	case chanTag:
537		t := new(types.Chan)
538		if p.trackAllTypes {
539			p.record(t)
540		}
541
542		var dir types.ChanDir
543		// tag values must match the constants in cmd/compile/internal/gc/go.go
544		switch d := p.int(); d {
545		case 1 /* Crecv */ :
546			dir = types.RecvOnly
547		case 2 /* Csend */ :
548			dir = types.SendOnly
549		case 3 /* Cboth */ :
550			dir = types.SendRecv
551		default:
552			errorf("unexpected channel dir %d", d)
553		}
554		val := p.typ(parent)
555		*t = *types.NewChan(dir, val)
556		return t
557
558	default:
559		errorf("unexpected type tag %d", i) // panics
560		panic("unreachable")
561	}
562}
563
564func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
565	if n := p.int(); n > 0 {
566		fields = make([]*types.Var, n)
567		tags = make([]string, n)
568		for i := range fields {
569			fields[i], tags[i] = p.field(parent)
570		}
571	}
572	return
573}
574
575func (p *importer) field(parent *types.Package) (*types.Var, string) {
576	pos := p.pos()
577	pkg, name, alias := p.fieldName(parent)
578	typ := p.typ(parent)
579	tag := p.string()
580
581	anonymous := false
582	if name == "" {
583		// anonymous field - typ must be T or *T and T must be a type name
584		switch typ := deref(typ).(type) {
585		case *types.Basic: // basic types are named types
586			pkg = nil // // objects defined in Universe scope have no package
587			name = typ.Name()
588		case *types.Named:
589			name = typ.Obj().Name()
590		default:
591			errorf("named base type expected")
592		}
593		anonymous = true
594	} else if alias {
595		// anonymous field: we have an explicit name because it's an alias
596		anonymous = true
597	}
598
599	return types.NewField(pos, pkg, name, typ, anonymous), tag
600}
601
602func (p *importer) methodList(parent *types.Package) (methods []*types.Func) {
603	if n := p.int(); n > 0 {
604		methods = make([]*types.Func, n)
605		for i := range methods {
606			methods[i] = p.method(parent)
607		}
608	}
609	return
610}
611
612func (p *importer) method(parent *types.Package) *types.Func {
613	pos := p.pos()
614	pkg, name, _ := p.fieldName(parent)
615	params, isddd := p.paramList()
616	result, _ := p.paramList()
617	sig := types.NewSignature(nil, params, result, isddd)
618	return types.NewFunc(pos, pkg, name, sig)
619}
620
621func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) {
622	name = p.string()
623	pkg = parent
624	if pkg == nil {
625		// use the imported package instead
626		pkg = p.pkgList[0]
627	}
628	if p.version == 0 && name == "_" {
629		// version 0 didn't export a package for _ fields
630		return
631	}
632	switch name {
633	case "":
634		// 1) field name matches base type name and is exported: nothing to do
635	case "?":
636		// 2) field name matches base type name and is not exported: need package
637		name = ""
638		pkg = p.pkg()
639	case "@":
640		// 3) field name doesn't match type name (alias)
641		name = p.string()
642		alias = true
643		fallthrough
644	default:
645		if !exported(name) {
646			pkg = p.pkg()
647		}
648	}
649	return
650}
651
652func (p *importer) paramList() (*types.Tuple, bool) {
653	n := p.int()
654	if n == 0 {
655		return nil, false
656	}
657	// negative length indicates unnamed parameters
658	named := true
659	if n < 0 {
660		n = -n
661		named = false
662	}
663	// n > 0
664	params := make([]*types.Var, n)
665	isddd := false
666	for i := range params {
667		params[i], isddd = p.param(named)
668	}
669	return types.NewTuple(params...), isddd
670}
671
672func (p *importer) param(named bool) (*types.Var, bool) {
673	t := p.typ(nil)
674	td, isddd := t.(*dddSlice)
675	if isddd {
676		t = types.NewSlice(td.elem)
677	}
678
679	var pkg *types.Package
680	var name string
681	if named {
682		name = p.string()
683		if name == "" {
684			errorf("expected named parameter")
685		}
686		if name != "_" {
687			pkg = p.pkg()
688		}
689		if i := strings.Index(name, "·"); i > 0 {
690			name = name[:i] // cut off gc-specific parameter numbering
691		}
692	}
693
694	// read and discard compiler-specific info
695	p.string()
696
697	return types.NewVar(token.NoPos, pkg, name, t), isddd
698}
699
700func exported(name string) bool {
701	ch, _ := utf8.DecodeRuneInString(name)
702	return unicode.IsUpper(ch)
703}
704
705func (p *importer) value() constant.Value {
706	switch tag := p.tagOrIndex(); tag {
707	case falseTag:
708		return constant.MakeBool(false)
709	case trueTag:
710		return constant.MakeBool(true)
711	case int64Tag:
712		return constant.MakeInt64(p.int64())
713	case floatTag:
714		return p.float()
715	case complexTag:
716		re := p.float()
717		im := p.float()
718		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
719	case stringTag:
720		return constant.MakeString(p.string())
721	case unknownTag:
722		return constant.MakeUnknown()
723	default:
724		errorf("unexpected value tag %d", tag) // panics
725		panic("unreachable")
726	}
727}
728
729func (p *importer) float() constant.Value {
730	sign := p.int()
731	if sign == 0 {
732		return constant.MakeInt64(0)
733	}
734
735	exp := p.int()
736	mant := []byte(p.string()) // big endian
737
738	// remove leading 0's if any
739	for len(mant) > 0 && mant[0] == 0 {
740		mant = mant[1:]
741	}
742
743	// convert to little endian
744	// TODO(gri) go/constant should have a more direct conversion function
745	//           (e.g., once it supports a big.Float based implementation)
746	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
747		mant[i], mant[j] = mant[j], mant[i]
748	}
749
750	// adjust exponent (constant.MakeFromBytes creates an integer value,
751	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
752	exp -= len(mant) << 3
753	if len(mant) > 0 {
754		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
755			exp++
756		}
757	}
758
759	x := constant.MakeFromBytes(mant)
760	switch {
761	case exp < 0:
762		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
763		x = constant.BinaryOp(x, token.QUO, d)
764	case exp > 0:
765		x = constant.Shift(x, token.SHL, uint(exp))
766	}
767
768	if sign < 0 {
769		x = constant.UnaryOp(token.SUB, x, 0)
770	}
771	return x
772}
773
774// ----------------------------------------------------------------------------
775// Low-level decoders
776
777func (p *importer) tagOrIndex() int {
778	if p.debugFormat {
779		p.marker('t')
780	}
781
782	return int(p.rawInt64())
783}
784
785func (p *importer) int() int {
786	x := p.int64()
787	if int64(int(x)) != x {
788		errorf("exported integer too large")
789	}
790	return int(x)
791}
792
793func (p *importer) int64() int64 {
794	if p.debugFormat {
795		p.marker('i')
796	}
797
798	return p.rawInt64()
799}
800
801func (p *importer) path() string {
802	if p.debugFormat {
803		p.marker('p')
804	}
805	// if the path was seen before, i is its index (>= 0)
806	// (the empty string is at index 0)
807	i := p.rawInt64()
808	if i >= 0 {
809		return p.pathList[i]
810	}
811	// otherwise, i is the negative path length (< 0)
812	a := make([]string, -i)
813	for n := range a {
814		a[n] = p.string()
815	}
816	s := strings.Join(a, "/")
817	p.pathList = append(p.pathList, s)
818	return s
819}
820
821func (p *importer) string() string {
822	if p.debugFormat {
823		p.marker('s')
824	}
825	// if the string was seen before, i is its index (>= 0)
826	// (the empty string is at index 0)
827	i := p.rawInt64()
828	if i >= 0 {
829		return p.strList[i]
830	}
831	// otherwise, i is the negative string length (< 0)
832	if n := int(-i); n <= cap(p.buf) {
833		p.buf = p.buf[:n]
834	} else {
835		p.buf = make([]byte, n)
836	}
837	for i := range p.buf {
838		p.buf[i] = p.rawByte()
839	}
840	s := string(p.buf)
841	p.strList = append(p.strList, s)
842	return s
843}
844
845func (p *importer) marker(want byte) {
846	if got := p.rawByte(); got != want {
847		errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
848	}
849
850	pos := p.read
851	if n := int(p.rawInt64()); n != pos {
852		errorf("incorrect position: got %d; want %d", n, pos)
853	}
854}
855
856// rawInt64 should only be used by low-level decoders.
857func (p *importer) rawInt64() int64 {
858	i, err := binary.ReadVarint(p)
859	if err != nil {
860		errorf("read error: %v", err)
861	}
862	return i
863}
864
865// rawStringln should only be used to read the initial version string.
866func (p *importer) rawStringln(b byte) string {
867	p.buf = p.buf[:0]
868	for b != '\n' {
869		p.buf = append(p.buf, b)
870		b = p.rawByte()
871	}
872	return string(p.buf)
873}
874
875// needed for binary.ReadVarint in rawInt64
876func (p *importer) ReadByte() (byte, error) {
877	return p.rawByte(), nil
878}
879
880// byte is the bottleneck interface for reading p.data.
881// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
882// rawByte should only be used by low-level decoders.
883func (p *importer) rawByte() byte {
884	b := p.data[0]
885	r := 1
886	if b == '|' {
887		b = p.data[1]
888		r = 2
889		switch b {
890		case 'S':
891			b = '$'
892		case '|':
893			// nothing to do
894		default:
895			errorf("unexpected escape sequence in export data")
896		}
897	}
898	p.data = p.data[r:]
899	p.read += r
900	return b
901
902}
903
904// ----------------------------------------------------------------------------
905// Export format
906
907// Tags. Must be < 0.
908const (
909	// Objects
910	packageTag = -(iota + 1)
911	constTag
912	typeTag
913	varTag
914	funcTag
915	endTag
916
917	// Types
918	namedTag
919	arrayTag
920	sliceTag
921	dddTag
922	structTag
923	pointerTag
924	signatureTag
925	interfaceTag
926	mapTag
927	chanTag
928
929	// Values
930	falseTag
931	trueTag
932	int64Tag
933	floatTag
934	fractionTag // not used by gc
935	complexTag
936	stringTag
937	nilTag     // only used by gc (appears in exported inlined function bodies)
938	unknownTag // not used by gc (only appears in packages with errors)
939
940	// Type aliases
941	aliasTag
942)
943
944var predeclared = []types.Type{
945	// basic types
946	types.Typ[types.Bool],
947	types.Typ[types.Int],
948	types.Typ[types.Int8],
949	types.Typ[types.Int16],
950	types.Typ[types.Int32],
951	types.Typ[types.Int64],
952	types.Typ[types.Uint],
953	types.Typ[types.Uint8],
954	types.Typ[types.Uint16],
955	types.Typ[types.Uint32],
956	types.Typ[types.Uint64],
957	types.Typ[types.Uintptr],
958	types.Typ[types.Float32],
959	types.Typ[types.Float64],
960	types.Typ[types.Complex64],
961	types.Typ[types.Complex128],
962	types.Typ[types.String],
963
964	// basic type aliases
965	types.Universe.Lookup("byte").Type(),
966	types.Universe.Lookup("rune").Type(),
967
968	// error
969	types.Universe.Lookup("error").Type(),
970
971	// untyped types
972	types.Typ[types.UntypedBool],
973	types.Typ[types.UntypedInt],
974	types.Typ[types.UntypedRune],
975	types.Typ[types.UntypedFloat],
976	types.Typ[types.UntypedComplex],
977	types.Typ[types.UntypedString],
978	types.Typ[types.UntypedNil],
979
980	// package unsafe
981	types.Typ[types.UnsafePointer],
982
983	// invalid type
984	types.Typ[types.Invalid], // only appears in packages with errors
985
986	// used internally by gc; never used by this package or in .a files
987	anyType{},
988}
989
990type anyType struct{}
991
992func (t anyType) Underlying() types.Type { return t }
993func (t anyType) String() string         { return "any" }
994