Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/compile/internal/typecheck/iimport.go

Documentation: cmd/compile/internal/typecheck

     1  // Copyright 2018 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  // Indexed package import.
     6  // See iexport.go for the export data format.
     7  
     8  package typecheck
     9  
    10  import (
    11  	"encoding/binary"
    12  	"fmt"
    13  	"go/constant"
    14  	"io"
    15  	"math/big"
    16  	"os"
    17  	"strings"
    18  
    19  	"cmd/compile/internal/base"
    20  	"cmd/compile/internal/ir"
    21  	"cmd/compile/internal/types"
    22  	"cmd/internal/bio"
    23  	"cmd/internal/goobj"
    24  	"cmd/internal/obj"
    25  	"cmd/internal/src"
    26  )
    27  
    28  // An iimporterAndOffset identifies an importer and an offset within
    29  // its data section.
    30  type iimporterAndOffset struct {
    31  	p   *iimporter
    32  	off uint64
    33  }
    34  
    35  var (
    36  	// DeclImporter maps from imported identifiers to an importer
    37  	// and offset where that identifier's declaration can be read.
    38  	DeclImporter = map[*types.Sym]iimporterAndOffset{}
    39  
    40  	// inlineImporter is like DeclImporter, but for inline bodies
    41  	// for function and method symbols.
    42  	inlineImporter = map[*types.Sym]iimporterAndOffset{}
    43  )
    44  
    45  // expandDecl returns immediately if n is already a Name node. Otherwise, n should
    46  // be an Ident node, and expandDecl reads in the definition of the specified
    47  // identifier from the appropriate package.
    48  func expandDecl(n ir.Node) ir.Node {
    49  	if n, ok := n.(*ir.Name); ok {
    50  		return n
    51  	}
    52  
    53  	id := n.(*ir.Ident)
    54  	if n := id.Sym().PkgDef(); n != nil {
    55  		return n.(*ir.Name)
    56  	}
    57  
    58  	r := importReaderFor(id.Sym(), DeclImporter)
    59  	if r == nil {
    60  		// Can happen if user tries to reference an undeclared name.
    61  		return n
    62  	}
    63  
    64  	return r.doDecl(n.Sym())
    65  }
    66  
    67  // ImportBody reads in the dcls and body of an imported function (which should not
    68  // yet have been read in).
    69  func ImportBody(fn *ir.Func) {
    70  	if fn.Inl.Body != nil {
    71  		base.Fatalf("%v already has inline body", fn)
    72  	}
    73  
    74  	r := importReaderFor(fn.Nname.Sym(), inlineImporter)
    75  	if r == nil {
    76  		base.Fatalf("missing import reader for %v", fn)
    77  	}
    78  
    79  	if inimport {
    80  		base.Fatalf("recursive inimport")
    81  	}
    82  	inimport = true
    83  	r.doInline(fn)
    84  	inimport = false
    85  }
    86  
    87  func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader {
    88  	x, ok := importers[sym]
    89  	if !ok {
    90  		return nil
    91  	}
    92  
    93  	return x.p.newReader(x.off, sym.Pkg)
    94  }
    95  
    96  type intReader struct {
    97  	*bio.Reader
    98  	pkg *types.Pkg
    99  }
   100  
   101  func (r *intReader) int64() int64 {
   102  	i, err := binary.ReadVarint(r.Reader)
   103  	if err != nil {
   104  		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
   105  		base.ErrorExit()
   106  	}
   107  	return i
   108  }
   109  
   110  func (r *intReader) uint64() uint64 {
   111  	i, err := binary.ReadUvarint(r.Reader)
   112  	if err != nil {
   113  		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
   114  		base.ErrorExit()
   115  	}
   116  	return i
   117  }
   118  
   119  func ReadImports(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType) {
   120  	ird := &intReader{in, pkg}
   121  
   122  	version := ird.uint64()
   123  	if version != iexportVersion {
   124  		base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
   125  		base.ErrorExit()
   126  	}
   127  
   128  	sLen := ird.uint64()
   129  	dLen := ird.uint64()
   130  
   131  	// Map string (and data) section into memory as a single large
   132  	// string. This reduces heap fragmentation and allows
   133  	// returning individual substrings very efficiently.
   134  	data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
   135  	if err != nil {
   136  		base.Errorf("import %q: mapping input: %v", pkg.Path, err)
   137  		base.ErrorExit()
   138  	}
   139  	stringData := data[:sLen]
   140  	declData := data[sLen:]
   141  
   142  	in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
   143  
   144  	p := &iimporter{
   145  		ipkg: pkg,
   146  
   147  		pkgCache:     map[uint64]*types.Pkg{},
   148  		posBaseCache: map[uint64]*src.PosBase{},
   149  		typCache:     map[uint64]*types.Type{},
   150  
   151  		stringData: stringData,
   152  		declData:   declData,
   153  	}
   154  
   155  	for i, pt := range predeclared() {
   156  		p.typCache[uint64(i)] = pt
   157  	}
   158  
   159  	// Declaration index.
   160  	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
   161  		pkg := p.pkgAt(ird.uint64())
   162  		pkgName := p.stringAt(ird.uint64())
   163  		pkgHeight := int(ird.uint64())
   164  		if pkg.Name == "" {
   165  			pkg.Name = pkgName
   166  			pkg.Height = pkgHeight
   167  			types.NumImport[pkgName]++
   168  
   169  			// TODO(mdempsky): This belongs somewhere else.
   170  			pkg.Lookup("_").Def = ir.BlankNode
   171  		} else {
   172  			if pkg.Name != pkgName {
   173  				base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
   174  			}
   175  			if pkg.Height != pkgHeight {
   176  				base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
   177  			}
   178  		}
   179  
   180  		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
   181  			s := pkg.Lookup(p.stringAt(ird.uint64()))
   182  			off := ird.uint64()
   183  
   184  			if _, ok := DeclImporter[s]; !ok {
   185  				DeclImporter[s] = iimporterAndOffset{p, off}
   186  			}
   187  		}
   188  	}
   189  
   190  	// Inline body index.
   191  	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
   192  		pkg := p.pkgAt(ird.uint64())
   193  
   194  		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
   195  			s := pkg.Lookup(p.stringAt(ird.uint64()))
   196  			off := ird.uint64()
   197  
   198  			if _, ok := inlineImporter[s]; !ok {
   199  				inlineImporter[s] = iimporterAndOffset{p, off}
   200  			}
   201  		}
   202  	}
   203  
   204  	// Fingerprint.
   205  	_, err = io.ReadFull(in, fingerprint[:])
   206  	if err != nil {
   207  		base.Errorf("import %s: error reading fingerprint", pkg.Path)
   208  		base.ErrorExit()
   209  	}
   210  	return fingerprint
   211  }
   212  
   213  type iimporter struct {
   214  	ipkg *types.Pkg
   215  
   216  	pkgCache     map[uint64]*types.Pkg
   217  	posBaseCache map[uint64]*src.PosBase
   218  	typCache     map[uint64]*types.Type
   219  
   220  	stringData string
   221  	declData   string
   222  }
   223  
   224  func (p *iimporter) stringAt(off uint64) string {
   225  	var x [binary.MaxVarintLen64]byte
   226  	n := copy(x[:], p.stringData[off:])
   227  
   228  	slen, n := binary.Uvarint(x[:n])
   229  	if n <= 0 {
   230  		base.Fatalf("varint failed")
   231  	}
   232  	spos := off + uint64(n)
   233  	return p.stringData[spos : spos+slen]
   234  }
   235  
   236  func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
   237  	if posBase, ok := p.posBaseCache[off]; ok {
   238  		return posBase
   239  	}
   240  
   241  	file := p.stringAt(off)
   242  	posBase := src.NewFileBase(file, file)
   243  	p.posBaseCache[off] = posBase
   244  	return posBase
   245  }
   246  
   247  func (p *iimporter) pkgAt(off uint64) *types.Pkg {
   248  	if pkg, ok := p.pkgCache[off]; ok {
   249  		return pkg
   250  	}
   251  
   252  	pkg := p.ipkg
   253  	if pkgPath := p.stringAt(off); pkgPath != "" {
   254  		pkg = types.NewPkg(pkgPath, "")
   255  	}
   256  	p.pkgCache[off] = pkg
   257  	return pkg
   258  }
   259  
   260  // An importReader keeps state for reading an individual imported
   261  // object (declaration or inline body).
   262  type importReader struct {
   263  	strings.Reader
   264  	p *iimporter
   265  
   266  	currPkg    *types.Pkg
   267  	prevBase   *src.PosBase
   268  	prevLine   int64
   269  	prevColumn int64
   270  
   271  	// curfn is the current function we're importing into.
   272  	curfn *ir.Func
   273  	// Slice of all dcls for function, including any interior closures
   274  	allDcls        []*ir.Name
   275  	allClosureVars []*ir.Name
   276  }
   277  
   278  func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
   279  	r := &importReader{
   280  		p:       p,
   281  		currPkg: pkg,
   282  	}
   283  	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
   284  	// need to build with Go 1.4.
   285  	r.Reader = *strings.NewReader(p.declData[off:])
   286  	return r
   287  }
   288  
   289  func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
   290  func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
   291  func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }
   292  
   293  func (r *importReader) setPkg() {
   294  	r.currPkg = r.pkg()
   295  }
   296  
   297  func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
   298  	tag := r.byte()
   299  	pos := r.pos()
   300  
   301  	switch tag {
   302  	case 'A':
   303  		typ := r.typ()
   304  
   305  		return importalias(r.p.ipkg, pos, sym, typ)
   306  
   307  	case 'C':
   308  		typ := r.typ()
   309  		val := r.value(typ)
   310  
   311  		n := importconst(r.p.ipkg, pos, sym, typ, val)
   312  		r.constExt(n)
   313  		return n
   314  
   315  	case 'F':
   316  		typ := r.signature(nil)
   317  
   318  		n := importfunc(r.p.ipkg, pos, sym, typ)
   319  		r.funcExt(n)
   320  		return n
   321  
   322  	case 'T':
   323  		// Types can be recursive. We need to setup a stub
   324  		// declaration before recursing.
   325  		n := importtype(r.p.ipkg, pos, sym)
   326  		t := n.Type()
   327  
   328  		// We also need to defer width calculations until
   329  		// after the underlying type has been assigned.
   330  		types.DeferCheckSize()
   331  		underlying := r.typ()
   332  		t.SetUnderlying(underlying)
   333  		types.ResumeCheckSize()
   334  
   335  		if underlying.IsInterface() {
   336  			r.typeExt(t)
   337  			return n
   338  		}
   339  
   340  		ms := make([]*types.Field, r.uint64())
   341  		for i := range ms {
   342  			mpos := r.pos()
   343  			msym := r.selector()
   344  			recv := r.param()
   345  			mtyp := r.signature(recv)
   346  
   347  			// MethodSym already marked m.Sym as a function.
   348  			m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym))
   349  			m.Class = ir.PFUNC
   350  			m.SetType(mtyp)
   351  
   352  			m.Func = ir.NewFunc(mpos)
   353  			m.Func.Nname = m
   354  
   355  			f := types.NewField(mpos, msym, mtyp)
   356  			f.Nname = m
   357  			ms[i] = f
   358  		}
   359  		t.Methods().Set(ms)
   360  
   361  		r.typeExt(t)
   362  		for _, m := range ms {
   363  			r.methExt(m)
   364  		}
   365  		return n
   366  
   367  	case 'V':
   368  		typ := r.typ()
   369  
   370  		n := importvar(r.p.ipkg, pos, sym, typ)
   371  		r.varExt(n)
   372  		return n
   373  
   374  	default:
   375  		base.Fatalf("unexpected tag: %v", tag)
   376  		panic("unreachable")
   377  	}
   378  }
   379  
   380  func (p *importReader) value(typ *types.Type) constant.Value {
   381  	switch constTypeOf(typ) {
   382  	case constant.Bool:
   383  		return constant.MakeBool(p.bool())
   384  	case constant.String:
   385  		return constant.MakeString(p.string())
   386  	case constant.Int:
   387  		var i big.Int
   388  		p.mpint(&i, typ)
   389  		return constant.Make(&i)
   390  	case constant.Float:
   391  		return p.float(typ)
   392  	case constant.Complex:
   393  		return makeComplex(p.float(typ), p.float(typ))
   394  	}
   395  
   396  	base.Fatalf("unexpected value type: %v", typ)
   397  	panic("unreachable")
   398  }
   399  
   400  func (p *importReader) mpint(x *big.Int, typ *types.Type) {
   401  	signed, maxBytes := intSize(typ)
   402  
   403  	maxSmall := 256 - maxBytes
   404  	if signed {
   405  		maxSmall = 256 - 2*maxBytes
   406  	}
   407  	if maxBytes == 1 {
   408  		maxSmall = 256
   409  	}
   410  
   411  	n, _ := p.ReadByte()
   412  	if uint(n) < maxSmall {
   413  		v := int64(n)
   414  		if signed {
   415  			v >>= 1
   416  			if n&1 != 0 {
   417  				v = ^v
   418  			}
   419  		}
   420  		x.SetInt64(v)
   421  		return
   422  	}
   423  
   424  	v := -n
   425  	if signed {
   426  		v = -(n &^ 1) >> 1
   427  	}
   428  	if v < 1 || uint(v) > maxBytes {
   429  		base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
   430  	}
   431  	b := make([]byte, v)
   432  	p.Read(b)
   433  	x.SetBytes(b)
   434  	if signed && n&1 != 0 {
   435  		x.Neg(x)
   436  	}
   437  }
   438  
   439  func (p *importReader) float(typ *types.Type) constant.Value {
   440  	var mant big.Int
   441  	p.mpint(&mant, typ)
   442  	var f big.Float
   443  	f.SetInt(&mant)
   444  	if f.Sign() != 0 {
   445  		f.SetMantExp(&f, int(p.int64()))
   446  	}
   447  	return constant.Make(&f)
   448  }
   449  
   450  func (p *importReader) mprat(orig constant.Value) constant.Value {
   451  	if !p.bool() {
   452  		return orig
   453  	}
   454  	var rat big.Rat
   455  	rat.SetString(p.string())
   456  	return constant.Make(&rat)
   457  }
   458  
   459  func (r *importReader) ident(selector bool) *types.Sym {
   460  	name := r.string()
   461  	if name == "" {
   462  		return nil
   463  	}
   464  	pkg := r.currPkg
   465  	if selector && types.IsExported(name) {
   466  		pkg = types.LocalPkg
   467  	}
   468  	return pkg.Lookup(name)
   469  }
   470  
   471  func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
   472  func (r *importReader) selector() *types.Sym   { return r.ident(true) }
   473  
   474  func (r *importReader) qualifiedIdent() *ir.Ident {
   475  	name := r.string()
   476  	pkg := r.pkg()
   477  	sym := pkg.Lookup(name)
   478  	return ir.NewIdent(src.NoXPos, sym)
   479  }
   480  
   481  func (r *importReader) pos() src.XPos {
   482  	delta := r.int64()
   483  	r.prevColumn += delta >> 1
   484  	if delta&1 != 0 {
   485  		delta = r.int64()
   486  		r.prevLine += delta >> 1
   487  		if delta&1 != 0 {
   488  			r.prevBase = r.posBase()
   489  		}
   490  	}
   491  
   492  	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
   493  		// TODO(mdempsky): Remove once we reliably write
   494  		// position information for all nodes.
   495  		return src.NoXPos
   496  	}
   497  
   498  	if r.prevBase == nil {
   499  		base.Fatalf("missing posbase")
   500  	}
   501  	pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
   502  	return base.Ctxt.PosTable.XPos(pos)
   503  }
   504  
   505  func (r *importReader) typ() *types.Type {
   506  	return r.p.typAt(r.uint64())
   507  }
   508  
   509  func (r *importReader) exoticType() *types.Type {
   510  	switch r.uint64() {
   511  	case exoticTypeNil:
   512  		return nil
   513  	case exoticTypeTuple:
   514  		funarg := types.Funarg(r.uint64())
   515  		n := r.uint64()
   516  		fs := make([]*types.Field, n)
   517  		for i := range fs {
   518  			pos := r.pos()
   519  			var sym *types.Sym
   520  			switch r.uint64() {
   521  			case exoticTypeSymNil:
   522  				sym = nil
   523  			case exoticTypeSymNoPkg:
   524  				sym = types.NoPkg.Lookup(r.string())
   525  			case exoticTypeSymWithPkg:
   526  				pkg := r.pkg()
   527  				sym = pkg.Lookup(r.string())
   528  			default:
   529  				base.Fatalf("unknown symbol kind")
   530  			}
   531  			typ := r.typ()
   532  			f := types.NewField(pos, sym, typ)
   533  			fs[i] = f
   534  		}
   535  		t := types.NewStruct(types.NoPkg, fs)
   536  		t.StructType().Funarg = funarg
   537  		return t
   538  	case exoticTypeRecv:
   539  		var rcvr *types.Field
   540  		if r.bool() { // isFakeRecv
   541  			rcvr = fakeRecvField()
   542  		} else {
   543  			rcvr = r.exoticParam()
   544  		}
   545  		return r.exoticSignature(rcvr)
   546  	case exoticTypeRegular:
   547  		return r.typ()
   548  	default:
   549  		base.Fatalf("bad kind of call type")
   550  		return nil
   551  	}
   552  }
   553  
   554  func (r *importReader) exoticSelector() *types.Sym {
   555  	name := r.string()
   556  	if name == "" {
   557  		return nil
   558  	}
   559  	pkg := r.currPkg
   560  	if types.IsExported(name) {
   561  		pkg = types.LocalPkg
   562  	}
   563  	if r.uint64() != 0 {
   564  		pkg = r.pkg()
   565  	}
   566  	return pkg.Lookup(name)
   567  }
   568  
   569  func (r *importReader) exoticSignature(recv *types.Field) *types.Type {
   570  	var pkg *types.Pkg
   571  	if r.bool() { // hasPkg
   572  		pkg = r.pkg()
   573  	}
   574  	params := r.exoticParamList()
   575  	results := r.exoticParamList()
   576  	return types.NewSignature(pkg, recv, nil, params, results)
   577  }
   578  
   579  func (r *importReader) exoticParamList() []*types.Field {
   580  	n := r.uint64()
   581  	fs := make([]*types.Field, n)
   582  	for i := range fs {
   583  		fs[i] = r.exoticParam()
   584  	}
   585  	return fs
   586  }
   587  
   588  func (r *importReader) exoticParam() *types.Field {
   589  	pos := r.pos()
   590  	sym := r.exoticSym()
   591  	off := r.uint64()
   592  	typ := r.exoticType()
   593  	ddd := r.bool()
   594  	f := types.NewField(pos, sym, typ)
   595  	f.Offset = int64(off)
   596  	if sym != nil {
   597  		f.Nname = ir.NewNameAt(pos, sym)
   598  	}
   599  	f.SetIsDDD(ddd)
   600  	return f
   601  }
   602  
   603  func (r *importReader) exoticField() *types.Field {
   604  	pos := r.pos()
   605  	sym := r.exoticSym()
   606  	off := r.uint64()
   607  	typ := r.exoticType()
   608  	note := r.string()
   609  	f := types.NewField(pos, sym, typ)
   610  	f.Offset = int64(off)
   611  	if sym != nil {
   612  		f.Nname = ir.NewNameAt(pos, sym)
   613  	}
   614  	f.Note = note
   615  	return f
   616  }
   617  
   618  func (r *importReader) exoticSym() *types.Sym {
   619  	name := r.string()
   620  	if name == "" {
   621  		return nil
   622  	}
   623  	var pkg *types.Pkg
   624  	if types.IsExported(name) {
   625  		pkg = types.LocalPkg
   626  	} else {
   627  		pkg = r.pkg()
   628  	}
   629  	return pkg.Lookup(name)
   630  }
   631  
   632  func (p *iimporter) typAt(off uint64) *types.Type {
   633  	t, ok := p.typCache[off]
   634  	if !ok {
   635  		if off < predeclReserved {
   636  			base.Fatalf("predeclared type missing from cache: %d", off)
   637  		}
   638  		t = p.newReader(off-predeclReserved, nil).typ1()
   639  		// Ensure size is calculated for imported types. Since CL 283313, the compiler
   640  		// does not compile the function immediately when it sees them. Instead, funtions
   641  		// are pushed to compile queue, then draining from the queue for compiling.
   642  		// During this process, the size calculation is disabled, so it is not safe for
   643  		// calculating size during SSA generation anymore. See issue #44732.
   644  		types.CheckSize(t)
   645  		p.typCache[off] = t
   646  	}
   647  	return t
   648  }
   649  
   650  func (r *importReader) typ1() *types.Type {
   651  	switch k := r.kind(); k {
   652  	default:
   653  		base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
   654  		return nil
   655  
   656  	case definedType:
   657  		// We might be called from within doInline, in which
   658  		// case Sym.Def can point to declared parameters
   659  		// instead of the top-level types. Also, we don't
   660  		// support inlining functions with local defined
   661  		// types. Therefore, this must be a package-scope
   662  		// type.
   663  		n := expandDecl(r.qualifiedIdent())
   664  		if n.Op() != ir.OTYPE {
   665  			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
   666  		}
   667  		return n.Type()
   668  	case pointerType:
   669  		return types.NewPtr(r.typ())
   670  	case sliceType:
   671  		return types.NewSlice(r.typ())
   672  	case arrayType:
   673  		n := r.uint64()
   674  		return types.NewArray(r.typ(), int64(n))
   675  	case chanType:
   676  		dir := types.ChanDir(r.uint64())
   677  		return types.NewChan(r.typ(), dir)
   678  	case mapType:
   679  		return types.NewMap(r.typ(), r.typ())
   680  
   681  	case signatureType:
   682  		r.setPkg()
   683  		return r.signature(nil)
   684  
   685  	case structType:
   686  		r.setPkg()
   687  
   688  		fs := make([]*types.Field, r.uint64())
   689  		for i := range fs {
   690  			pos := r.pos()
   691  			sym := r.selector()
   692  			typ := r.typ()
   693  			emb := r.bool()
   694  			note := r.string()
   695  
   696  			f := types.NewField(pos, sym, typ)
   697  			if emb {
   698  				f.Embedded = 1
   699  			}
   700  			f.Note = note
   701  			fs[i] = f
   702  		}
   703  
   704  		return types.NewStruct(r.currPkg, fs)
   705  
   706  	case interfaceType:
   707  		r.setPkg()
   708  
   709  		embeddeds := make([]*types.Field, r.uint64())
   710  		for i := range embeddeds {
   711  			pos := r.pos()
   712  			typ := r.typ()
   713  
   714  			embeddeds[i] = types.NewField(pos, nil, typ)
   715  		}
   716  
   717  		methods := make([]*types.Field, r.uint64())
   718  		for i := range methods {
   719  			pos := r.pos()
   720  			sym := r.selector()
   721  			typ := r.signature(fakeRecvField())
   722  
   723  			methods[i] = types.NewField(pos, sym, typ)
   724  		}
   725  
   726  		t := types.NewInterface(r.currPkg, append(embeddeds, methods...))
   727  
   728  		// Ensure we expand the interface in the frontend (#25055).
   729  		types.CheckSize(t)
   730  		return t
   731  	}
   732  }
   733  
   734  func (r *importReader) kind() itag {
   735  	return itag(r.uint64())
   736  }
   737  
   738  func (r *importReader) signature(recv *types.Field) *types.Type {
   739  	params := r.paramList()
   740  	results := r.paramList()
   741  	if n := len(params); n > 0 {
   742  		params[n-1].SetIsDDD(r.bool())
   743  	}
   744  	return types.NewSignature(r.currPkg, recv, nil, params, results)
   745  }
   746  
   747  func (r *importReader) paramList() []*types.Field {
   748  	fs := make([]*types.Field, r.uint64())
   749  	for i := range fs {
   750  		fs[i] = r.param()
   751  	}
   752  	return fs
   753  }
   754  
   755  func (r *importReader) param() *types.Field {
   756  	return types.NewField(r.pos(), r.localIdent(), r.typ())
   757  }
   758  
   759  func (r *importReader) bool() bool {
   760  	return r.uint64() != 0
   761  }
   762  
   763  func (r *importReader) int64() int64 {
   764  	n, err := binary.ReadVarint(r)
   765  	if err != nil {
   766  		base.Fatalf("readVarint: %v", err)
   767  	}
   768  	return n
   769  }
   770  
   771  func (r *importReader) uint64() uint64 {
   772  	n, err := binary.ReadUvarint(r)
   773  	if err != nil {
   774  		base.Fatalf("readVarint: %v", err)
   775  	}
   776  	return n
   777  }
   778  
   779  func (r *importReader) byte() byte {
   780  	x, err := r.ReadByte()
   781  	if err != nil {
   782  		base.Fatalf("declReader.ReadByte: %v", err)
   783  	}
   784  	return x
   785  }
   786  
   787  // Compiler-specific extensions.
   788  
   789  func (r *importReader) constExt(n *ir.Name) {
   790  	switch n.Type() {
   791  	case types.UntypedFloat:
   792  		n.SetVal(r.mprat(n.Val()))
   793  	case types.UntypedComplex:
   794  		v := n.Val()
   795  		re := r.mprat(constant.Real(v))
   796  		im := r.mprat(constant.Imag(v))
   797  		n.SetVal(makeComplex(re, im))
   798  	}
   799  }
   800  
   801  func (r *importReader) varExt(n *ir.Name) {
   802  	r.linkname(n.Sym())
   803  	r.symIdx(n.Sym())
   804  }
   805  
   806  func (r *importReader) funcExt(n *ir.Name) {
   807  	r.linkname(n.Sym())
   808  	r.symIdx(n.Sym())
   809  
   810  	n.Func.ABI = obj.ABI(r.uint64())
   811  
   812  	n.SetPragma(ir.PragmaFlag(r.uint64()))
   813  
   814  	// Escape analysis.
   815  	for _, fs := range &types.RecvsParams {
   816  		for _, f := range fs(n.Type()).FieldSlice() {
   817  			f.Note = r.string()
   818  		}
   819  	}
   820  
   821  	// Inline body.
   822  	if u := r.uint64(); u > 0 {
   823  		n.Func.Inl = &ir.Inline{
   824  			Cost: int32(u - 1),
   825  		}
   826  		n.Func.Endlineno = r.pos()
   827  	}
   828  }
   829  
   830  func (r *importReader) methExt(m *types.Field) {
   831  	if r.bool() {
   832  		m.SetNointerface(true)
   833  	}
   834  	r.funcExt(m.Nname.(*ir.Name))
   835  }
   836  
   837  func (r *importReader) linkname(s *types.Sym) {
   838  	s.Linkname = r.string()
   839  }
   840  
   841  func (r *importReader) symIdx(s *types.Sym) {
   842  	lsym := s.Linksym()
   843  	idx := int32(r.int64())
   844  	if idx != -1 {
   845  		if s.Linkname != "" {
   846  			base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
   847  		}
   848  		lsym.SymIdx = idx
   849  		lsym.Set(obj.AttrIndexed, true)
   850  	}
   851  }
   852  
   853  func (r *importReader) typeExt(t *types.Type) {
   854  	t.SetNotInHeap(r.bool())
   855  	i, pi := r.int64(), r.int64()
   856  	if i != -1 && pi != -1 {
   857  		typeSymIdx[t] = [2]int64{i, pi}
   858  	}
   859  }
   860  
   861  // Map imported type T to the index of type descriptor symbols of T and *T,
   862  // so we can use index to reference the symbol.
   863  var typeSymIdx = make(map[*types.Type][2]int64)
   864  
   865  func BaseTypeIndex(t *types.Type) int64 {
   866  	tbase := t
   867  	if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
   868  		tbase = t.Elem()
   869  	}
   870  	i, ok := typeSymIdx[tbase]
   871  	if !ok {
   872  		return -1
   873  	}
   874  	if t != tbase {
   875  		return i[1]
   876  	}
   877  	return i[0]
   878  }
   879  
   880  func (r *importReader) doInline(fn *ir.Func) {
   881  	if len(fn.Inl.Body) != 0 {
   882  		base.Fatalf("%v already has inline body", fn)
   883  	}
   884  
   885  	//fmt.Printf("Importing %s\n", fn.Nname.Sym().Name)
   886  	r.funcBody(fn)
   887  
   888  	importlist = append(importlist, fn)
   889  
   890  	if base.Flag.E > 0 && base.Flag.LowerM > 2 {
   891  		if base.Flag.LowerM > 3 {
   892  			fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
   893  		} else {
   894  			fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
   895  		}
   896  	}
   897  }
   898  
   899  // ----------------------------------------------------------------------------
   900  // Inlined function bodies
   901  
   902  // Approach: Read nodes and use them to create/declare the same data structures
   903  // as done originally by the (hidden) parser by closely following the parser's
   904  // original code. In other words, "parsing" the import data (which happens to
   905  // be encoded in binary rather textual form) is the best way at the moment to
   906  // re-establish the syntax tree's invariants. At some future point we might be
   907  // able to avoid this round-about way and create the rewritten nodes directly,
   908  // possibly avoiding a lot of duplicate work (name resolution, type checking).
   909  //
   910  // Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
   911  // unrefined nodes (since this is what the importer uses). The respective case
   912  // entries are unreachable in the importer.
   913  
   914  func (r *importReader) funcBody(fn *ir.Func) {
   915  	outerfn := r.curfn
   916  	r.curfn = fn
   917  
   918  	// Import local declarations.
   919  	fn.Inl.Dcl = r.readFuncDcls(fn)
   920  
   921  	// Import function body.
   922  	body := r.stmtList()
   923  	if body == nil {
   924  		// Make sure empty body is not interpreted as
   925  		// no inlineable body (see also parser.fnbody)
   926  		// (not doing so can cause significant performance
   927  		// degradation due to unnecessary calls to empty
   928  		// functions).
   929  		body = []ir.Node{}
   930  	}
   931  	if go117ExportTypes {
   932  		ir.VisitList(body, func(n ir.Node) {
   933  			n.SetTypecheck(1)
   934  		})
   935  	}
   936  	fn.Inl.Body = body
   937  
   938  	r.curfn = outerfn
   939  }
   940  
   941  func (r *importReader) readNames(fn *ir.Func) []*ir.Name {
   942  	dcls := make([]*ir.Name, r.int64())
   943  	for i := range dcls {
   944  		n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent())
   945  		n.Class = ir.PAUTO // overwritten below for parameters/results
   946  		n.Curfn = fn
   947  		n.SetType(r.typ())
   948  		dcls[i] = n
   949  	}
   950  	r.allDcls = append(r.allDcls, dcls...)
   951  	return dcls
   952  }
   953  
   954  func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name {
   955  	dcls := r.readNames(fn)
   956  
   957  	// Fixup parameter classes and associate with their
   958  	// signature's type fields.
   959  	i := 0
   960  	fix := func(f *types.Field, class ir.Class) {
   961  		if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") {
   962  			return
   963  		}
   964  		n := dcls[i]
   965  		n.Class = class
   966  		f.Nname = n
   967  		i++
   968  	}
   969  
   970  	typ := fn.Type()
   971  	if recv := typ.Recv(); recv != nil {
   972  		fix(recv, ir.PPARAM)
   973  	}
   974  	for _, f := range typ.Params().FieldSlice() {
   975  		fix(f, ir.PPARAM)
   976  	}
   977  	for _, f := range typ.Results().FieldSlice() {
   978  		fix(f, ir.PPARAMOUT)
   979  	}
   980  	return dcls
   981  }
   982  
   983  func (r *importReader) localName() *ir.Name {
   984  	i := r.int64()
   985  	if i == -1 {
   986  		return ir.BlankNode.(*ir.Name)
   987  	}
   988  	if i < 0 {
   989  		return r.allClosureVars[-i-2]
   990  	}
   991  	return r.allDcls[i]
   992  }
   993  
   994  func (r *importReader) stmtList() []ir.Node {
   995  	var list []ir.Node
   996  	for {
   997  		n := r.node()
   998  		if n == nil {
   999  			break
  1000  		}
  1001  		// OBLOCK nodes are not written to the import data directly,
  1002  		// but the handling of ODCL calls liststmt, which creates one.
  1003  		// Inline them into the statement list.
  1004  		if n.Op() == ir.OBLOCK {
  1005  			n := n.(*ir.BlockStmt)
  1006  			list = append(list, n.List...)
  1007  		} else {
  1008  			list = append(list, n)
  1009  		}
  1010  
  1011  	}
  1012  	return list
  1013  }
  1014  
  1015  func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
  1016  	namedTypeSwitch := isNamedTypeSwitch(switchExpr)
  1017  
  1018  	cases := make([]*ir.CaseClause, r.uint64())
  1019  	for i := range cases {
  1020  		cas := ir.NewCaseStmt(r.pos(), nil, nil)
  1021  		cas.List = r.stmtList()
  1022  		if namedTypeSwitch {
  1023  			cas.Var = r.localName()
  1024  			cas.Var.Defn = switchExpr
  1025  		}
  1026  		cas.Body = r.stmtList()
  1027  		cases[i] = cas
  1028  	}
  1029  	return cases
  1030  }
  1031  
  1032  func (r *importReader) commList() []*ir.CommClause {
  1033  	cases := make([]*ir.CommClause, r.uint64())
  1034  	for i := range cases {
  1035  		cases[i] = ir.NewCommStmt(r.pos(), r.node(), r.stmtList())
  1036  	}
  1037  	return cases
  1038  }
  1039  
  1040  func (r *importReader) exprList() []ir.Node {
  1041  	var list []ir.Node
  1042  	for {
  1043  		n := r.expr()
  1044  		if n == nil {
  1045  			break
  1046  		}
  1047  		list = append(list, n)
  1048  	}
  1049  	return list
  1050  }
  1051  
  1052  func (r *importReader) expr() ir.Node {
  1053  	n := r.node()
  1054  	if n != nil && n.Op() == ir.OBLOCK {
  1055  		n := n.(*ir.BlockStmt)
  1056  		base.Fatalf("unexpected block node: %v", n)
  1057  	}
  1058  	return n
  1059  }
  1060  
  1061  // TODO(gri) split into expr and stmt
  1062  func (r *importReader) node() ir.Node {
  1063  	op := r.op()
  1064  	switch op {
  1065  	// expressions
  1066  	// case OPAREN:
  1067  	// 	unreachable - unpacked by exporter
  1068  
  1069  	case ir.ONIL:
  1070  		pos := r.pos()
  1071  		typ := r.typ()
  1072  
  1073  		n := ir.NewNilExpr(pos)
  1074  		n.SetType(typ)
  1075  		return n
  1076  
  1077  	case ir.OLITERAL:
  1078  		pos := r.pos()
  1079  		typ := r.typ()
  1080  
  1081  		n := ir.NewBasicLit(pos, r.value(typ))
  1082  		n.SetType(typ)
  1083  		return n
  1084  
  1085  	case ir.ONONAME:
  1086  		n := r.qualifiedIdent()
  1087  		if go117ExportTypes {
  1088  			n2 := Resolve(n)
  1089  			typ := r.typ()
  1090  			if n2.Type() == nil {
  1091  				n2.SetType(typ)
  1092  			}
  1093  			return n2
  1094  		}
  1095  		return n
  1096  
  1097  	case ir.ONAME:
  1098  		return r.localName()
  1099  
  1100  	// case OPACK, ONONAME:
  1101  	// 	unreachable - should have been resolved by typechecking
  1102  
  1103  	case ir.OTYPE:
  1104  		return ir.TypeNode(r.typ())
  1105  
  1106  	case ir.OTYPESW:
  1107  		pos := r.pos()
  1108  		var tag *ir.Ident
  1109  		if s := r.localIdent(); s != nil {
  1110  			tag = ir.NewIdent(pos, s)
  1111  		}
  1112  		return ir.NewTypeSwitchGuard(pos, tag, r.expr())
  1113  
  1114  	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
  1115  	//      unreachable - should have been resolved by typechecking
  1116  
  1117  	case ir.OCLOSURE:
  1118  		//println("Importing CLOSURE")
  1119  		pos := r.pos()
  1120  		typ := r.signature(nil)
  1121  
  1122  		// All the remaining code below is similar to (*noder).funcLit(), but
  1123  		// with Dcls and ClosureVars lists already set up
  1124  		fn := ir.NewFunc(pos)
  1125  		fn.SetIsHiddenClosure(true)
  1126  		fn.Nname = ir.NewNameAt(pos, ir.BlankNode.Sym())
  1127  		fn.Nname.Func = fn
  1128  		fn.Nname.Ntype = ir.TypeNode(typ)
  1129  		fn.Nname.Defn = fn
  1130  		fn.Nname.SetType(typ)
  1131  
  1132  		cvars := make([]*ir.Name, r.int64())
  1133  		for i := range cvars {
  1134  			cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
  1135  			if go117ExportTypes {
  1136  				if cvars[i].Type() != nil || cvars[i].Defn == nil {
  1137  					base.Fatalf("bad import of closure variable")
  1138  				}
  1139  				// Closure variable should have Defn set, which is its captured
  1140  				// variable, and it gets the same type as the captured variable.
  1141  				cvars[i].SetType(cvars[i].Defn.Type())
  1142  			}
  1143  		}
  1144  		fn.ClosureVars = cvars
  1145  		r.allClosureVars = append(r.allClosureVars, cvars...)
  1146  
  1147  		fn.Inl = &ir.Inline{}
  1148  		// Read in the Dcls and Body of the closure after temporarily
  1149  		// setting r.curfn to fn.
  1150  		r.funcBody(fn)
  1151  		fn.Dcl = fn.Inl.Dcl
  1152  		fn.Body = fn.Inl.Body
  1153  		if len(fn.Body) == 0 {
  1154  			// An empty closure must be represented as a single empty
  1155  			// block statement, else it will be dropped.
  1156  			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
  1157  		}
  1158  		fn.Inl = nil
  1159  
  1160  		ir.FinishCaptureNames(pos, r.curfn, fn)
  1161  
  1162  		clo := ir.NewClosureExpr(pos, fn)
  1163  		fn.OClosure = clo
  1164  		if go117ExportTypes {
  1165  			clo.SetType(typ)
  1166  		}
  1167  
  1168  		return clo
  1169  
  1170  	case ir.OSTRUCTLIT:
  1171  		if go117ExportTypes {
  1172  			pos := r.pos()
  1173  			typ := r.typ()
  1174  			list := r.fieldList()
  1175  			n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list)
  1176  			n.SetType(typ)
  1177  			return n
  1178  		}
  1179  		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())
  1180  
  1181  	case ir.OCOMPLIT:
  1182  		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.exprList())
  1183  
  1184  	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
  1185  		if !go117ExportTypes {
  1186  			// unreachable - mapped to OCOMPLIT by exporter
  1187  			goto error
  1188  		}
  1189  		pos := r.pos()
  1190  		typ := r.typ()
  1191  		list := r.exprList()
  1192  		n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list)
  1193  		n.SetType(typ)
  1194  		if op == ir.OSLICELIT {
  1195  			n.Len = int64(r.uint64())
  1196  		}
  1197  		return n
  1198  
  1199  	case ir.OKEY:
  1200  		return ir.NewKeyExpr(r.pos(), r.expr(), r.expr())
  1201  
  1202  	// case OSTRUCTKEY:
  1203  	//	unreachable - handled in case OSTRUCTLIT by elemList
  1204  
  1205  	case ir.OXDOT:
  1206  		// see parser.new_dotname
  1207  		if go117ExportTypes {
  1208  			base.Fatalf("shouldn't encounter XDOT in new importer")
  1209  		}
  1210  		return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.exoticSelector())
  1211  
  1212  	case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
  1213  		if !go117ExportTypes {
  1214  			// unreachable - mapped to case OXDOT by exporter
  1215  			goto error
  1216  		}
  1217  		pos := r.pos()
  1218  		expr := r.expr()
  1219  		sel := r.exoticSelector()
  1220  		n := ir.NewSelectorExpr(pos, op, expr, sel)
  1221  		n.SetType(r.exoticType())
  1222  		switch op {
  1223  		case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
  1224  			n.Selection = r.exoticField()
  1225  		case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
  1226  			// These require a Lookup to link to the correct declaration.
  1227  			rcvrType := expr.Type()
  1228  			typ := n.Type()
  1229  			n.Selection = Lookdot(n, rcvrType, 1)
  1230  			if op == ir.OCALLPART || op == ir.OMETHEXPR {
  1231  				// Lookdot clobbers the opcode and type, undo that.
  1232  				n.SetOp(op)
  1233  				n.SetType(typ)
  1234  			}
  1235  		}
  1236  		return n
  1237  
  1238  	case ir.ODOTTYPE, ir.ODOTTYPE2:
  1239  		n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil)
  1240  		n.SetType(r.typ())
  1241  		if go117ExportTypes {
  1242  			n.SetOp(op)
  1243  		}
  1244  		return n
  1245  
  1246  	case ir.OINDEX, ir.OINDEXMAP:
  1247  		n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr())
  1248  		if go117ExportTypes {
  1249  			n.SetOp(op)
  1250  			n.SetType(r.typ())
  1251  			if op == ir.OINDEXMAP {
  1252  				n.Assigned = r.bool()
  1253  			}
  1254  		}
  1255  		return n
  1256  
  1257  	case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
  1258  		pos, x := r.pos(), r.expr()
  1259  		low, high := r.exprsOrNil()
  1260  		var max ir.Node
  1261  		if op.IsSlice3() {
  1262  			max = r.expr()
  1263  		}
  1264  		n := ir.NewSliceExpr(pos, op, x, low, high, max)
  1265  		if go117ExportTypes {
  1266  			n.SetType(r.typ())
  1267  		}
  1268  		return n
  1269  
  1270  	case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
  1271  		if !go117ExportTypes && op != ir.OCONV {
  1272  			// 	unreachable - mapped to OCONV case by exporter
  1273  			goto error
  1274  		}
  1275  		return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
  1276  
  1277  	case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN, ir.OUNSAFEADD, ir.OUNSAFESLICE:
  1278  		if go117ExportTypes {
  1279  			switch op {
  1280  			case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
  1281  				n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
  1282  				n.SetType(r.typ())
  1283  				return n
  1284  			case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
  1285  				n := ir.NewUnaryExpr(r.pos(), op, r.expr())
  1286  				if op != ir.OPANIC {
  1287  					n.SetType(r.typ())
  1288  				}
  1289  				return n
  1290  			case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
  1291  				n := ir.NewCallExpr(r.pos(), op, nil, r.exprList())
  1292  				if op == ir.OAPPEND {
  1293  					n.IsDDD = r.bool()
  1294  				}
  1295  				if op == ir.OAPPEND || op == ir.ORECOVER {
  1296  					n.SetType(r.typ())
  1297  				}
  1298  				return n
  1299  			}
  1300  			// ir.OMAKE
  1301  			goto error
  1302  		}
  1303  		n := builtinCall(r.pos(), op)
  1304  		n.Args = r.exprList()
  1305  		if op == ir.OAPPEND {
  1306  			n.IsDDD = r.bool()
  1307  		}
  1308  		return n
  1309  
  1310  	case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
  1311  		pos := r.pos()
  1312  		init := r.stmtList()
  1313  		n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList())
  1314  		if go117ExportTypes {
  1315  			n.SetOp(op)
  1316  		}
  1317  		*n.PtrInit() = init
  1318  		n.IsDDD = r.bool()
  1319  		if go117ExportTypes {
  1320  			n.SetType(r.exoticType())
  1321  			n.Use = ir.CallUse(r.uint64())
  1322  		}
  1323  		return n
  1324  
  1325  	case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
  1326  		if go117ExportTypes {
  1327  			pos := r.pos()
  1328  			typ := r.typ()
  1329  			list := r.exprList()
  1330  			var len_, cap_ ir.Node
  1331  			if len(list) > 0 {
  1332  				len_ = list[0]
  1333  			}
  1334  			if len(list) > 1 {
  1335  				cap_ = list[1]
  1336  			}
  1337  			n := ir.NewMakeExpr(pos, op, len_, cap_)
  1338  			n.SetType(typ)
  1339  			return n
  1340  		}
  1341  		n := builtinCall(r.pos(), ir.OMAKE)
  1342  		n.Args.Append(ir.TypeNode(r.typ()))
  1343  		n.Args.Append(r.exprList()...)
  1344  		return n
  1345  
  1346  	// unary expressions
  1347  	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
  1348  		n := ir.NewUnaryExpr(r.pos(), op, r.expr())
  1349  		if go117ExportTypes {
  1350  			n.SetType(r.typ())
  1351  		}
  1352  		return n
  1353  
  1354  	case ir.OADDR, ir.OPTRLIT:
  1355  		n := NodAddrAt(r.pos(), r.expr())
  1356  		if go117ExportTypes {
  1357  			n.SetOp(op)
  1358  			n.SetType(r.typ())
  1359  		}
  1360  		return n
  1361  
  1362  	case ir.ODEREF:
  1363  		n := ir.NewStarExpr(r.pos(), r.expr())
  1364  		if go117ExportTypes {
  1365  			n.SetType(r.typ())
  1366  		}
  1367  		return n
  1368  
  1369  	// binary expressions
  1370  	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
  1371  		ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
  1372  		n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
  1373  		if go117ExportTypes {
  1374  			n.SetType(r.typ())
  1375  		}
  1376  		return n
  1377  
  1378  	case ir.OANDAND, ir.OOROR:
  1379  		n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
  1380  		if go117ExportTypes {
  1381  			n.SetType(r.typ())
  1382  		}
  1383  		return n
  1384  
  1385  	case ir.OSEND:
  1386  		return ir.NewSendStmt(r.pos(), r.expr(), r.expr())
  1387  
  1388  	case ir.OADDSTR:
  1389  		pos := r.pos()
  1390  		list := r.exprList()
  1391  		if go117ExportTypes {
  1392  			n := ir.NewAddStringExpr(pos, list)
  1393  			n.SetType(r.typ())
  1394  			return n
  1395  		}
  1396  		x := list[0]
  1397  		for _, y := range list[1:] {
  1398  			x = ir.NewBinaryExpr(pos, ir.OADD, x, y)
  1399  		}
  1400  		return x
  1401  
  1402  	// --------------------------------------------------------------------
  1403  	// statements
  1404  	case ir.ODCL:
  1405  		var stmts ir.Nodes
  1406  		n := r.localName()
  1407  		stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n))
  1408  		stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil))
  1409  		return ir.NewBlockStmt(n.Pos(), stmts)
  1410  
  1411  	// case OASWB:
  1412  	// 	unreachable - never exported
  1413  
  1414  	case ir.OAS:
  1415  		return ir.NewAssignStmt(r.pos(), r.expr(), r.expr())
  1416  
  1417  	case ir.OASOP:
  1418  		n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
  1419  		if !r.bool() {
  1420  			n.Y = ir.NewInt(1)
  1421  			n.IncDec = true
  1422  		} else {
  1423  			n.Y = r.expr()
  1424  		}
  1425  		return n
  1426  
  1427  	case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
  1428  		if !go117ExportTypes && op != ir.OAS2 {
  1429  			// unreachable - mapped to case OAS2 by exporter
  1430  			goto error
  1431  		}
  1432  		return ir.NewAssignListStmt(r.pos(), op, r.exprList(), r.exprList())
  1433  
  1434  	case ir.ORETURN:
  1435  		return ir.NewReturnStmt(r.pos(), r.exprList())
  1436  
  1437  	// case ORETJMP:
  1438  	// 	unreachable - generated by compiler for trampolin routines (not exported)
  1439  
  1440  	case ir.OGO, ir.ODEFER:
  1441  		return ir.NewGoDeferStmt(r.pos(), op, r.expr())
  1442  
  1443  	case ir.OIF:
  1444  		pos, init := r.pos(), r.stmtList()
  1445  		n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList())
  1446  		*n.PtrInit() = init
  1447  		return n
  1448  
  1449  	case ir.OFOR:
  1450  		pos, init := r.pos(), r.stmtList()
  1451  		cond, post := r.exprsOrNil()
  1452  		n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
  1453  		*n.PtrInit() = init
  1454  		return n
  1455  
  1456  	case ir.ORANGE:
  1457  		pos := r.pos()
  1458  		k, v := r.exprsOrNil()
  1459  		return ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList())
  1460  
  1461  	case ir.OSELECT:
  1462  		pos := r.pos()
  1463  		init := r.stmtList()
  1464  		n := ir.NewSelectStmt(pos, r.commList())
  1465  		*n.PtrInit() = init
  1466  		return n
  1467  
  1468  	case ir.OSWITCH:
  1469  		pos := r.pos()
  1470  		init := r.stmtList()
  1471  		x, _ := r.exprsOrNil()
  1472  		n := ir.NewSwitchStmt(pos, x, r.caseList(x))
  1473  		*n.PtrInit() = init
  1474  		return n
  1475  
  1476  	// case OCASE:
  1477  	//	handled by caseList
  1478  
  1479  	case ir.OFALL:
  1480  		return ir.NewBranchStmt(r.pos(), ir.OFALL, nil)
  1481  
  1482  	// case OEMPTY:
  1483  	// 	unreachable - not emitted by exporter
  1484  
  1485  	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
  1486  		pos := r.pos()
  1487  		var sym *types.Sym
  1488  		if label := r.string(); label != "" {
  1489  			sym = Lookup(label)
  1490  		}
  1491  		return ir.NewBranchStmt(pos, op, sym)
  1492  
  1493  	case ir.OLABEL:
  1494  		return ir.NewLabelStmt(r.pos(), Lookup(r.string()))
  1495  
  1496  	case ir.OEND:
  1497  		return nil
  1498  
  1499  	default:
  1500  		base.Fatalf("cannot import %v (%d) node\n"+
  1501  			"\t==> please file an issue and assign to gri@", op, int(op))
  1502  		panic("unreachable") // satisfy compiler
  1503  	}
  1504  error:
  1505  	base.Fatalf("cannot import %v (%d) node\n"+
  1506  		"\t==> please file an issue and assign to khr@", op, int(op))
  1507  	panic("unreachable") // satisfy compiler
  1508  }
  1509  
  1510  func (r *importReader) op() ir.Op {
  1511  	if debug && r.uint64() != magic {
  1512  		base.Fatalf("import stream has desynchronized")
  1513  	}
  1514  	return ir.Op(r.uint64())
  1515  }
  1516  
  1517  func (r *importReader) fieldList() []ir.Node {
  1518  	list := make([]ir.Node, r.uint64())
  1519  	for i := range list {
  1520  		x := ir.NewStructKeyExpr(r.pos(), r.selector(), r.expr())
  1521  		if go117ExportTypes {
  1522  			x.Offset = int64(r.uint64())
  1523  		}
  1524  		list[i] = x
  1525  	}
  1526  	return list
  1527  }
  1528  
  1529  func (r *importReader) exprsOrNil() (a, b ir.Node) {
  1530  	ab := r.uint64()
  1531  	if ab&1 != 0 {
  1532  		a = r.expr()
  1533  	}
  1534  	if ab&2 != 0 {
  1535  		b = r.node()
  1536  	}
  1537  	return
  1538  }
  1539  
  1540  func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
  1541  	if go117ExportTypes {
  1542  		// These should all be encoded as direct ops, not OCALL.
  1543  		base.Fatalf("builtinCall should not be invoked when types are included in import/export")
  1544  	}
  1545  	return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
  1546  }
  1547  

View as plain text