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