gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/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  // This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
     6  
     7  package gcimporter
     8  
     9  import (
    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  
    23  type 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.
    54  func 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  
   163  func errorf(format string, args ...interface{}) {
   164  	panic(fmt.Sprintf(format, args...))
   165  }
   166  
   167  func (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.
   216  func 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  
   232  func 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  
   239  func (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  
   257  func (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  
   295  const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
   296  
   297  func (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  
   355  var (
   356  	fakeLines     []int
   357  	fakeLinesOnce sync.Once
   358  )
   359  
   360  func (p *importer) qualifiedName() (pkg *types.Package, name string) {
   361  	name = p.string()
   362  	pkg = p.pkg()
   363  	return
   364  }
   365  
   366  func (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.
   373  type dddSlice struct {
   374  	elem types.Type
   375  }
   376  
   377  func (t *dddSlice) Underlying() types.Type { return t }
   378  func (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.
   384  func (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  
   564  func (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  
   575  func (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  
   602  func (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  
   612  func (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  
   621  func (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  
   652  func (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  
   672  func (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  
   700  func exported(name string) bool {
   701  	ch, _ := utf8.DecodeRuneInString(name)
   702  	return unicode.IsUpper(ch)
   703  }
   704  
   705  func (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  
   729  func (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  
   777  func (p *importer) tagOrIndex() int {
   778  	if p.debugFormat {
   779  		p.marker('t')
   780  	}
   781  
   782  	return int(p.rawInt64())
   783  }
   784  
   785  func (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  
   793  func (p *importer) int64() int64 {
   794  	if p.debugFormat {
   795  		p.marker('i')
   796  	}
   797  
   798  	return p.rawInt64()
   799  }
   800  
   801  func (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  
   821  func (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  
   845  func (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.
   857  func (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.
   866  func (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
   876  func (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.
   883  func (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.
   908  const (
   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  
   944  var 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  
   990  type anyType struct{}
   991  
   992  func (t anyType) Underlying() types.Type { return t }
   993  func (t anyType) String() string         { return "any" }