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