github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/x/tools/go/gcimporter15/bimport.go (about)

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