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

     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  	"math/big"
    15  	"os"
    16  	"strings"
    17  
    18  	"cmd/compile/internal/base"
    19  	"cmd/compile/internal/ir"
    20  	"cmd/compile/internal/types"
    21  	"cmd/internal/obj"
    22  	"cmd/internal/src"
    23  )
    24  
    25  // An iimporterAndOffset identifies an importer and an offset within
    26  // its data section.
    27  type iimporterAndOffset struct {
    28  	p   *iimporter
    29  	off uint64
    30  }
    31  
    32  var (
    33  	// DeclImporter maps from imported identifiers to an importer
    34  	// and offset where that identifier's declaration can be read.
    35  	DeclImporter = map[*types.Sym]iimporterAndOffset{}
    36  
    37  	// inlineImporter is like DeclImporter, but for inline bodies
    38  	// for function and method symbols.
    39  	inlineImporter = map[*types.Sym]iimporterAndOffset{}
    40  )
    41  
    42  // expandDecl returns immediately if n is already a Name node. Otherwise, n should
    43  // be an Ident node, and expandDecl reads in the definition of the specified
    44  // identifier from the appropriate package.
    45  func expandDecl(n ir.Node) ir.Node {
    46  	if n, ok := n.(*ir.Name); ok {
    47  		return n
    48  	}
    49  
    50  	id := n.(*ir.Ident)
    51  	if n := id.Sym().PkgDef(); n != nil {
    52  		return n.(*ir.Name)
    53  	}
    54  
    55  	r := importReaderFor(id.Sym(), DeclImporter)
    56  	if r == nil {
    57  		// Can happen if user tries to reference an undeclared name.
    58  		return n
    59  	}
    60  
    61  	return r.doDecl(n.Sym())
    62  }
    63  
    64  // ImportBody reads in the dcls and body of an imported function (which should not
    65  // yet have been read in).
    66  func ImportBody(fn *ir.Func) {
    67  	if fn.Inl.Body != nil {
    68  		base.Fatalf("%v already has inline body", fn)
    69  	}
    70  
    71  	r := importReaderFor(fn.Nname.Sym(), inlineImporter)
    72  	if r == nil {
    73  		base.Fatalf("missing import reader for %v", fn)
    74  	}
    75  
    76  	if inimport {
    77  		base.Fatalf("recursive inimport")
    78  	}
    79  	inimport = true
    80  	r.doInline(fn)
    81  	inimport = false
    82  }
    83  
    84  // HaveInlineBody reports whether we have fn's inline body available
    85  // for inlining.
    86  func HaveInlineBody(fn *ir.Func) bool {
    87  	if fn.Inl == nil {
    88  		return false
    89  	}
    90  
    91  	// Unified IR is much more conservative about pruning unreachable
    92  	// methods (at the cost of increased build artifact size).
    93  	if base.Debug.Unified != 0 {
    94  		return true
    95  	}
    96  
    97  	if fn.Inl.Body != nil {
    98  		return true
    99  	}
   100  
   101  	_, ok := inlineImporter[fn.Nname.Sym()]
   102  	return ok
   103  }
   104  
   105  func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader {
   106  	x, ok := importers[sym]
   107  	if !ok {
   108  		return nil
   109  	}
   110  
   111  	return x.p.newReader(x.off, sym.Pkg)
   112  }
   113  
   114  type intReader struct {
   115  	*strings.Reader
   116  	pkg *types.Pkg
   117  }
   118  
   119  func (r *intReader) int64() int64 {
   120  	i, err := binary.ReadVarint(r.Reader)
   121  	if err != nil {
   122  		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
   123  		base.ErrorExit()
   124  	}
   125  	return i
   126  }
   127  
   128  func (r *intReader) uint64() uint64 {
   129  	i, err := binary.ReadUvarint(r.Reader)
   130  	if err != nil {
   131  		base.Errorf("import %q: read error: %v", r.pkg.Path, err)
   132  		base.ErrorExit()
   133  	}
   134  	return i
   135  }
   136  
   137  func ReadImports(pkg *types.Pkg, data string) {
   138  	ird := &intReader{strings.NewReader(data), pkg}
   139  
   140  	version := ird.uint64()
   141  	switch version {
   142  	case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
   143  	default:
   144  		base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
   145  		base.ErrorExit()
   146  	}
   147  
   148  	sLen := int64(ird.uint64())
   149  	dLen := int64(ird.uint64())
   150  
   151  	// TODO(mdempsky): Replace os.SEEK_CUR with io.SeekCurrent after
   152  	// #44505 is fixed.
   153  	whence, _ := ird.Seek(0, os.SEEK_CUR)
   154  	stringData := data[whence : whence+sLen]
   155  	declData := data[whence+sLen : whence+sLen+dLen]
   156  	ird.Seek(sLen+dLen, os.SEEK_CUR)
   157  
   158  	p := &iimporter{
   159  		exportVersion: version,
   160  		ipkg:          pkg,
   161  
   162  		pkgCache:     map[uint64]*types.Pkg{},
   163  		posBaseCache: map[uint64]*src.PosBase{},
   164  		typCache:     map[uint64]*types.Type{},
   165  
   166  		stringData: stringData,
   167  		declData:   declData,
   168  	}
   169  
   170  	for i, pt := range predeclared() {
   171  		p.typCache[uint64(i)] = pt
   172  	}
   173  
   174  	// Declaration index.
   175  	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
   176  		pkg := p.pkgAt(ird.uint64())
   177  		pkgName := p.stringAt(ird.uint64())
   178  		pkgHeight := int(ird.uint64())
   179  		if pkg.Name == "" {
   180  			pkg.Name = pkgName
   181  			pkg.Height = pkgHeight
   182  			types.NumImport[pkgName]++
   183  
   184  			// TODO(mdempsky): This belongs somewhere else.
   185  			pkg.Lookup("_").Def = ir.BlankNode
   186  		} else {
   187  			if pkg.Name != pkgName {
   188  				base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
   189  			}
   190  			if pkg.Height != pkgHeight {
   191  				base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
   192  			}
   193  		}
   194  
   195  		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
   196  			s := pkg.Lookup(p.nameAt(ird.uint64()))
   197  			off := ird.uint64()
   198  
   199  			if _, ok := DeclImporter[s]; !ok {
   200  				DeclImporter[s] = iimporterAndOffset{p, off}
   201  			}
   202  		}
   203  	}
   204  
   205  	// Inline body index.
   206  	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
   207  		pkg := p.pkgAt(ird.uint64())
   208  
   209  		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
   210  			s := pkg.Lookup(p.nameAt(ird.uint64()))
   211  			off := ird.uint64()
   212  
   213  			if _, ok := inlineImporter[s]; !ok {
   214  				inlineImporter[s] = iimporterAndOffset{p, off}
   215  			}
   216  		}
   217  	}
   218  }
   219  
   220  type iimporter struct {
   221  	exportVersion uint64
   222  	ipkg          *types.Pkg
   223  
   224  	pkgCache     map[uint64]*types.Pkg
   225  	posBaseCache map[uint64]*src.PosBase
   226  	typCache     map[uint64]*types.Type
   227  
   228  	stringData string
   229  	declData   string
   230  }
   231  
   232  func (p *iimporter) stringAt(off uint64) string {
   233  	var x [binary.MaxVarintLen64]byte
   234  	n := copy(x[:], p.stringData[off:])
   235  
   236  	slen, n := binary.Uvarint(x[:n])
   237  	if n <= 0 {
   238  		base.Fatalf("varint failed")
   239  	}
   240  	spos := off + uint64(n)
   241  	return p.stringData[spos : spos+slen]
   242  }
   243  
   244  // nameAt is the same as stringAt, except it replaces instances
   245  // of "" with the path of the package being imported.
   246  func (p *iimporter) nameAt(off uint64) string {
   247  	s := p.stringAt(off)
   248  	// Names of objects (functions, methods, globals) may include ""
   249  	// to represent the path name of the imported package.
   250  	// Replace "" with the imported package prefix. This occurs
   251  	// specifically for generics where the names of instantiations
   252  	// and dictionaries contain package-qualified type names.
   253  	// Include the dot to avoid matching with struct tags ending in '"'.
   254  	if strings.Contains(s, "\"\".") {
   255  		s = strings.Replace(s, "\"\".", p.ipkg.Prefix+".", -1)
   256  	}
   257  	return s
   258  }
   259  
   260  func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
   261  	if posBase, ok := p.posBaseCache[off]; ok {
   262  		return posBase
   263  	}
   264  
   265  	file := p.stringAt(off)
   266  	posBase := src.NewFileBase(file, file)
   267  	p.posBaseCache[off] = posBase
   268  	return posBase
   269  }
   270  
   271  func (p *iimporter) pkgAt(off uint64) *types.Pkg {
   272  	if pkg, ok := p.pkgCache[off]; ok {
   273  		return pkg
   274  	}
   275  
   276  	pkg := p.ipkg
   277  	if pkgPath := p.stringAt(off); pkgPath != "" {
   278  		pkg = types.NewPkg(pkgPath, "")
   279  	}
   280  	p.pkgCache[off] = pkg
   281  	return pkg
   282  }
   283  
   284  // An importReader keeps state for reading an individual imported
   285  // object (declaration or inline body).
   286  type importReader struct {
   287  	strings.Reader
   288  	p *iimporter
   289  
   290  	currPkg    *types.Pkg
   291  	prevBase   *src.PosBase
   292  	prevLine   int64
   293  	prevColumn int64
   294  
   295  	// curfn is the current function we're importing into.
   296  	curfn *ir.Func
   297  	// Slice of all dcls for function, including any interior closures
   298  	allDcls        []*ir.Name
   299  	allClosureVars []*ir.Name
   300  	autotmpgen     int
   301  }
   302  
   303  func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
   304  	r := &importReader{
   305  		p:       p,
   306  		currPkg: pkg,
   307  	}
   308  	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
   309  	// need to build with Go 1.4.
   310  	r.Reader = *strings.NewReader(p.declData[off:])
   311  	return r
   312  }
   313  
   314  func (r *importReader) string() string        { return r.p.stringAt(r.uint64()) }
   315  func (r *importReader) name() string          { return r.p.nameAt(r.uint64()) }
   316  func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
   317  func (r *importReader) pkg() *types.Pkg       { return r.p.pkgAt(r.uint64()) }
   318  
   319  func (r *importReader) setPkg() {
   320  	r.currPkg = r.pkg()
   321  }
   322  
   323  func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
   324  	tag := r.byte()
   325  	pos := r.pos()
   326  
   327  	switch tag {
   328  	case 'A':
   329  		typ := r.typ()
   330  
   331  		return importalias(pos, sym, typ)
   332  
   333  	case 'C':
   334  		typ := r.typ()
   335  		val := r.value(typ)
   336  
   337  		n := importconst(pos, sym, typ, val)
   338  		r.constExt(n)
   339  		return n
   340  
   341  	case 'F', 'G':
   342  		var tparams []*types.Field
   343  		if tag == 'G' {
   344  			tparams = r.tparamList()
   345  		}
   346  		typ := r.signature(nil, tparams)
   347  
   348  		n := importfunc(pos, sym, typ)
   349  		r.funcExt(n)
   350  		return n
   351  
   352  	case 'T', 'U':
   353  		// Types can be recursive. We need to setup a stub
   354  		// declaration before recursing.
   355  		n := importtype(pos, sym)
   356  		t := n.Type()
   357  
   358  		// Because of recursion, we need to defer width calculations and
   359  		// instantiations on intermediate types until the top-level type is
   360  		// fully constructed. Note that we can have recursion via type
   361  		// constraints.
   362  		types.DeferCheckSize()
   363  		deferDoInst()
   364  		if tag == 'U' {
   365  			rparams := r.typeList()
   366  			t.SetRParams(rparams)
   367  		}
   368  
   369  		underlying := r.typ()
   370  		t.SetUnderlying(underlying)
   371  
   372  		if underlying.IsInterface() {
   373  			// Finish up all type instantiations and CheckSize calls
   374  			// now that a top-level type is fully constructed.
   375  			resumeDoInst()
   376  			types.ResumeCheckSize()
   377  			r.typeExt(t)
   378  			return n
   379  		}
   380  
   381  		ms := make([]*types.Field, r.uint64())
   382  		for i := range ms {
   383  			mpos := r.pos()
   384  			msym := r.selector()
   385  			recv := r.param()
   386  			mtyp := r.signature(recv, nil)
   387  
   388  			// MethodSym already marked m.Sym as a function.
   389  			m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym))
   390  			m.Class = ir.PFUNC
   391  			m.SetType(mtyp)
   392  
   393  			m.Func = ir.NewFunc(mpos)
   394  			m.Func.Nname = m
   395  
   396  			f := types.NewField(mpos, msym, mtyp)
   397  			f.Nname = m
   398  			ms[i] = f
   399  		}
   400  		t.Methods().Set(ms)
   401  
   402  		// Finish up all instantiations and CheckSize calls now
   403  		// that a top-level type is fully constructed.
   404  		resumeDoInst()
   405  		types.ResumeCheckSize()
   406  
   407  		r.typeExt(t)
   408  		for _, m := range ms {
   409  			r.methExt(m)
   410  		}
   411  		return n
   412  
   413  	case 'P':
   414  		if r.p.exportVersion < iexportVersionGenerics {
   415  			base.Fatalf("unexpected type param type")
   416  		}
   417  		if sym.Def != nil {
   418  			// Make sure we use the same type param type for the same
   419  			// name, whether it is created during types1-import or
   420  			// this types2-to-types1 translation.
   421  			return sym.Def.(*ir.Name)
   422  		}
   423  		// The typeparam index is set at the point where the containing type
   424  		// param list is imported.
   425  		t := types.NewTypeParam(sym, 0)
   426  		// Nname needed to save the pos.
   427  		nname := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
   428  		sym.Def = nname
   429  		nname.SetType(t)
   430  		t.SetNod(nname)
   431  		implicit := false
   432  		if r.p.exportVersion >= iexportVersionGo1_18 {
   433  			implicit = r.bool()
   434  		}
   435  		bound := r.typ()
   436  		if implicit {
   437  			bound.MarkImplicit()
   438  		}
   439  		t.SetBound(bound)
   440  		return nname
   441  
   442  	case 'V':
   443  		typ := r.typ()
   444  
   445  		n := importvar(pos, sym, typ)
   446  		r.varExt(n)
   447  		return n
   448  
   449  	default:
   450  		base.Fatalf("unexpected tag: %v", tag)
   451  		panic("unreachable")
   452  	}
   453  }
   454  
   455  func (r *importReader) value(typ *types.Type) constant.Value {
   456  	var kind constant.Kind
   457  	var valType *types.Type
   458  
   459  	if r.p.exportVersion >= iexportVersionGo1_18 {
   460  		// TODO: add support for using the kind in the non-typeparam case.
   461  		kind = constant.Kind(r.int64())
   462  	}
   463  
   464  	if typ.IsTypeParam() {
   465  		if r.p.exportVersion < iexportVersionGo1_18 {
   466  			// If a constant had a typeparam type, then we wrote out its
   467  			// actual constant kind as well.
   468  			kind = constant.Kind(r.int64())
   469  		}
   470  		switch kind {
   471  		case constant.Int:
   472  			valType = types.Types[types.TINT64]
   473  		case constant.Float:
   474  			valType = types.Types[types.TFLOAT64]
   475  		case constant.Complex:
   476  			valType = types.Types[types.TCOMPLEX128]
   477  		}
   478  	} else {
   479  		kind = constTypeOf(typ)
   480  		valType = typ
   481  	}
   482  
   483  	switch kind {
   484  	case constant.Bool:
   485  		return constant.MakeBool(r.bool())
   486  	case constant.String:
   487  		return constant.MakeString(r.string())
   488  	case constant.Int:
   489  		var i big.Int
   490  		r.mpint(&i, valType)
   491  		return constant.Make(&i)
   492  	case constant.Float:
   493  		return r.float(valType)
   494  	case constant.Complex:
   495  		return makeComplex(r.float(valType), r.float(valType))
   496  	}
   497  
   498  	base.Fatalf("unexpected value type: %v", typ)
   499  	panic("unreachable")
   500  }
   501  
   502  func (r *importReader) mpint(x *big.Int, typ *types.Type) {
   503  	signed, maxBytes := intSize(typ)
   504  
   505  	maxSmall := 256 - maxBytes
   506  	if signed {
   507  		maxSmall = 256 - 2*maxBytes
   508  	}
   509  	if maxBytes == 1 {
   510  		maxSmall = 256
   511  	}
   512  
   513  	n, _ := r.ReadByte()
   514  	if uint(n) < maxSmall {
   515  		v := int64(n)
   516  		if signed {
   517  			v >>= 1
   518  			if n&1 != 0 {
   519  				v = ^v
   520  			}
   521  		}
   522  		x.SetInt64(v)
   523  		return
   524  	}
   525  
   526  	v := -n
   527  	if signed {
   528  		v = -(n &^ 1) >> 1
   529  	}
   530  	if v < 1 || uint(v) > maxBytes {
   531  		base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
   532  	}
   533  	b := make([]byte, v)
   534  	r.Read(b)
   535  	x.SetBytes(b)
   536  	if signed && n&1 != 0 {
   537  		x.Neg(x)
   538  	}
   539  }
   540  
   541  func (r *importReader) float(typ *types.Type) constant.Value {
   542  	var mant big.Int
   543  	r.mpint(&mant, typ)
   544  	var f big.Float
   545  	f.SetInt(&mant)
   546  	if f.Sign() != 0 {
   547  		f.SetMantExp(&f, int(r.int64()))
   548  	}
   549  	return constant.Make(&f)
   550  }
   551  
   552  func (r *importReader) mprat(orig constant.Value) constant.Value {
   553  	if !r.bool() {
   554  		return orig
   555  	}
   556  	var rat big.Rat
   557  	rat.SetString(r.string())
   558  	return constant.Make(&rat)
   559  }
   560  
   561  func (r *importReader) ident(selector bool) *types.Sym {
   562  	name := r.string()
   563  	if name == "" {
   564  		return nil
   565  	}
   566  	pkg := r.currPkg
   567  	if selector {
   568  		if types.IsExported(name) {
   569  			pkg = types.LocalPkg
   570  		}
   571  	} else {
   572  		if name == "$autotmp" {
   573  			name = autotmpname(r.autotmpgen)
   574  			r.autotmpgen++
   575  		}
   576  	}
   577  	return pkg.Lookup(name)
   578  }
   579  
   580  func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
   581  func (r *importReader) selector() *types.Sym   { return r.ident(true) }
   582  
   583  func (r *importReader) qualifiedIdent() *ir.Ident {
   584  	name := r.name()
   585  	pkg := r.pkg()
   586  	sym := pkg.Lookup(name)
   587  	return ir.NewIdent(src.NoXPos, sym)
   588  }
   589  
   590  func (r *importReader) pos() src.XPos {
   591  	delta := r.int64()
   592  	r.prevColumn += delta >> 1
   593  	if delta&1 != 0 {
   594  		delta = r.int64()
   595  		r.prevLine += delta >> 1
   596  		if delta&1 != 0 {
   597  			r.prevBase = r.posBase()
   598  		}
   599  	}
   600  
   601  	if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
   602  		// TODO(mdempsky): Remove once we reliably write
   603  		// position information for all nodes.
   604  		return src.NoXPos
   605  	}
   606  
   607  	if r.prevBase == nil {
   608  		base.Fatalf("missing posbase")
   609  	}
   610  	pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
   611  	return base.Ctxt.PosTable.XPos(pos)
   612  }
   613  
   614  func (r *importReader) typ() *types.Type {
   615  	// If this is a top-level type call, defer type instantiations until the
   616  	// type is fully constructed.
   617  	types.DeferCheckSize()
   618  	deferDoInst()
   619  	t := r.p.typAt(r.uint64())
   620  	resumeDoInst()
   621  	types.ResumeCheckSize()
   622  	return t
   623  }
   624  
   625  func (r *importReader) exoticType() *types.Type {
   626  	switch r.uint64() {
   627  	case exoticTypeNil:
   628  		return nil
   629  	case exoticTypeTuple:
   630  		funarg := types.Funarg(r.uint64())
   631  		n := r.uint64()
   632  		fs := make([]*types.Field, n)
   633  		for i := range fs {
   634  			pos := r.pos()
   635  			var sym *types.Sym
   636  			switch r.uint64() {
   637  			case exoticTypeSymNil:
   638  				sym = nil
   639  			case exoticTypeSymNoPkg:
   640  				sym = types.NoPkg.Lookup(r.string())
   641  			case exoticTypeSymWithPkg:
   642  				pkg := r.pkg()
   643  				sym = pkg.Lookup(r.string())
   644  			default:
   645  				base.Fatalf("unknown symbol kind")
   646  			}
   647  			typ := r.typ()
   648  			f := types.NewField(pos, sym, typ)
   649  			fs[i] = f
   650  		}
   651  		t := types.NewStruct(types.NoPkg, fs)
   652  		t.StructType().Funarg = funarg
   653  		return t
   654  	case exoticTypeRecv:
   655  		var rcvr *types.Field
   656  		if r.bool() { // isFakeRecv
   657  			rcvr = types.FakeRecv()
   658  		} else {
   659  			rcvr = r.exoticParam()
   660  		}
   661  		return r.exoticSignature(rcvr)
   662  	case exoticTypeRegular:
   663  		return r.typ()
   664  	default:
   665  		base.Fatalf("bad kind of call type")
   666  		return nil
   667  	}
   668  }
   669  
   670  func (r *importReader) exoticSelector() *types.Sym {
   671  	name := r.string()
   672  	if name == "" {
   673  		return nil
   674  	}
   675  	pkg := r.currPkg
   676  	if types.IsExported(name) {
   677  		pkg = types.LocalPkg
   678  	}
   679  	if r.uint64() != 0 {
   680  		pkg = r.pkg()
   681  	}
   682  	return pkg.Lookup(name)
   683  }
   684  
   685  func (r *importReader) exoticSignature(recv *types.Field) *types.Type {
   686  	var pkg *types.Pkg
   687  	if r.bool() { // hasPkg
   688  		pkg = r.pkg()
   689  	}
   690  	params := r.exoticParamList()
   691  	results := r.exoticParamList()
   692  	return types.NewSignature(pkg, recv, nil, params, results)
   693  }
   694  
   695  func (r *importReader) exoticParamList() []*types.Field {
   696  	n := r.uint64()
   697  	fs := make([]*types.Field, n)
   698  	for i := range fs {
   699  		fs[i] = r.exoticParam()
   700  	}
   701  	return fs
   702  }
   703  
   704  func (r *importReader) exoticParam() *types.Field {
   705  	pos := r.pos()
   706  	sym := r.exoticSym()
   707  	off := r.uint64()
   708  	typ := r.exoticType()
   709  	ddd := r.bool()
   710  	f := types.NewField(pos, sym, typ)
   711  	f.Offset = int64(off)
   712  	if sym != nil {
   713  		f.Nname = ir.NewNameAt(pos, sym)
   714  	}
   715  	f.SetIsDDD(ddd)
   716  	return f
   717  }
   718  
   719  func (r *importReader) exoticField() *types.Field {
   720  	pos := r.pos()
   721  	sym := r.exoticSym()
   722  	off := r.uint64()
   723  	typ := r.exoticType()
   724  	note := r.string()
   725  	f := types.NewField(pos, sym, typ)
   726  	f.Offset = int64(off)
   727  	if sym != nil {
   728  		f.Nname = ir.NewNameAt(pos, sym)
   729  	}
   730  	f.Note = note
   731  	return f
   732  }
   733  
   734  func (r *importReader) exoticSym() *types.Sym {
   735  	name := r.string()
   736  	if name == "" {
   737  		return nil
   738  	}
   739  	var pkg *types.Pkg
   740  	if types.IsExported(name) {
   741  		pkg = types.LocalPkg
   742  	} else {
   743  		pkg = r.pkg()
   744  	}
   745  	return pkg.Lookup(name)
   746  }
   747  
   748  func (p *iimporter) typAt(off uint64) *types.Type {
   749  	t, ok := p.typCache[off]
   750  	if !ok {
   751  		if off < predeclReserved {
   752  			base.Fatalf("predeclared type missing from cache: %d", off)
   753  		}
   754  		t = p.newReader(off-predeclReserved, nil).typ1()
   755  		// Ensure size is calculated for imported types. Since CL 283313, the compiler
   756  		// does not compile the function immediately when it sees them. Instead, funtions
   757  		// are pushed to compile queue, then draining from the queue for compiling.
   758  		// During this process, the size calculation is disabled, so it is not safe for
   759  		// calculating size during SSA generation anymore. See issue #44732.
   760  		//
   761  		// No need to calc sizes for re-instantiated generic types, and
   762  		// they are not necessarily resolved until the top-level type is
   763  		// defined (because of recursive types).
   764  		if t.OrigType() == nil || !t.HasTParam() {
   765  			types.CheckSize(t)
   766  		}
   767  		p.typCache[off] = t
   768  	}
   769  	return t
   770  }
   771  
   772  func (r *importReader) typ1() *types.Type {
   773  	switch k := r.kind(); k {
   774  	default:
   775  		base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
   776  		return nil
   777  
   778  	case definedType:
   779  		// We might be called from within doInline, in which
   780  		// case Sym.Def can point to declared parameters
   781  		// instead of the top-level types. Also, we don't
   782  		// support inlining functions with local defined
   783  		// types. Therefore, this must be a package-scope
   784  		// type.
   785  		n := expandDecl(r.qualifiedIdent())
   786  		if n.Op() != ir.OTYPE {
   787  			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
   788  		}
   789  		return n.Type()
   790  	case pointerType:
   791  		return types.NewPtr(r.typ())
   792  	case sliceType:
   793  		return types.NewSlice(r.typ())
   794  	case arrayType:
   795  		n := r.uint64()
   796  		return types.NewArray(r.typ(), int64(n))
   797  	case chanType:
   798  		dir := types.ChanDir(r.uint64())
   799  		return types.NewChan(r.typ(), dir)
   800  	case mapType:
   801  		return types.NewMap(r.typ(), r.typ())
   802  
   803  	case signatureType:
   804  		r.setPkg()
   805  		return r.signature(nil, nil)
   806  
   807  	case structType:
   808  		r.setPkg()
   809  
   810  		fs := make([]*types.Field, r.uint64())
   811  		for i := range fs {
   812  			pos := r.pos()
   813  			sym := r.selector()
   814  			typ := r.typ()
   815  			emb := r.bool()
   816  			note := r.string()
   817  
   818  			f := types.NewField(pos, sym, typ)
   819  			if emb {
   820  				f.Embedded = 1
   821  			}
   822  			f.Note = note
   823  			fs[i] = f
   824  		}
   825  
   826  		return types.NewStruct(r.currPkg, fs)
   827  
   828  	case interfaceType:
   829  		r.setPkg()
   830  
   831  		embeddeds := make([]*types.Field, r.uint64())
   832  		for i := range embeddeds {
   833  			pos := r.pos()
   834  			typ := r.typ()
   835  
   836  			embeddeds[i] = types.NewField(pos, nil, typ)
   837  		}
   838  
   839  		methods := make([]*types.Field, r.uint64())
   840  		for i := range methods {
   841  			pos := r.pos()
   842  			sym := r.selector()
   843  			typ := r.signature(types.FakeRecv(), nil)
   844  
   845  			methods[i] = types.NewField(pos, sym, typ)
   846  		}
   847  
   848  		if len(embeddeds)+len(methods) == 0 {
   849  			return types.Types[types.TINTER]
   850  		}
   851  
   852  		t := types.NewInterface(r.currPkg, append(embeddeds, methods...), false)
   853  
   854  		// Ensure we expand the interface in the frontend (#25055).
   855  		types.CheckSize(t)
   856  		return t
   857  
   858  	case typeParamType:
   859  		if r.p.exportVersion < iexportVersionGenerics {
   860  			base.Fatalf("unexpected type param type")
   861  		}
   862  		// Similar to code for defined types, since we "declared"
   863  		// typeparams to deal with recursion (typeparam is used within its
   864  		// own type bound).
   865  		ident := r.qualifiedIdent()
   866  		if ident.Sym().Def != nil {
   867  			return ident.Sym().Def.(*ir.Name).Type()
   868  		}
   869  		n := expandDecl(ident)
   870  		if n.Op() != ir.OTYPE {
   871  			base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
   872  		}
   873  		return n.Type()
   874  
   875  	case instanceType:
   876  		if r.p.exportVersion < iexportVersionGenerics {
   877  			base.Fatalf("unexpected instantiation type")
   878  		}
   879  		pos := r.pos()
   880  		len := r.uint64()
   881  		targs := make([]*types.Type, len)
   882  		for i := range targs {
   883  			targs[i] = r.typ()
   884  		}
   885  		baseType := r.typ()
   886  		t := Instantiate(pos, baseType, targs)
   887  		return t
   888  
   889  	case unionType:
   890  		if r.p.exportVersion < iexportVersionGenerics {
   891  			base.Fatalf("unexpected instantiation type")
   892  		}
   893  		nt := int(r.uint64())
   894  		terms := make([]*types.Type, nt)
   895  		tildes := make([]bool, nt)
   896  		for i := range terms {
   897  			tildes[i] = r.bool()
   898  			terms[i] = r.typ()
   899  		}
   900  		return types.NewUnion(terms, tildes)
   901  	}
   902  }
   903  
   904  func (r *importReader) kind() itag {
   905  	return itag(r.uint64())
   906  }
   907  
   908  func (r *importReader) signature(recv *types.Field, tparams []*types.Field) *types.Type {
   909  	params := r.paramList()
   910  	results := r.paramList()
   911  	if n := len(params); n > 0 {
   912  		params[n-1].SetIsDDD(r.bool())
   913  	}
   914  	return types.NewSignature(r.currPkg, recv, tparams, params, results)
   915  }
   916  
   917  func (r *importReader) typeList() []*types.Type {
   918  	n := r.uint64()
   919  	if n == 0 {
   920  		return nil
   921  	}
   922  	ts := make([]*types.Type, n)
   923  	for i := range ts {
   924  		ts[i] = r.typ()
   925  		if ts[i].IsTypeParam() {
   926  			ts[i].SetIndex(i)
   927  		}
   928  	}
   929  	return ts
   930  }
   931  
   932  func (r *importReader) tparamList() []*types.Field {
   933  	n := r.uint64()
   934  	if n == 0 {
   935  		return nil
   936  	}
   937  	fs := make([]*types.Field, n)
   938  	for i := range fs {
   939  		typ := r.typ()
   940  		typ.SetIndex(i)
   941  		fs[i] = types.NewField(typ.Pos(), typ.Sym(), typ)
   942  	}
   943  	return fs
   944  }
   945  
   946  func (r *importReader) paramList() []*types.Field {
   947  	fs := make([]*types.Field, r.uint64())
   948  	for i := range fs {
   949  		fs[i] = r.param()
   950  	}
   951  	return fs
   952  }
   953  
   954  func (r *importReader) param() *types.Field {
   955  	return types.NewField(r.pos(), r.localIdent(), r.typ())
   956  }
   957  
   958  func (r *importReader) bool() bool {
   959  	return r.uint64() != 0
   960  }
   961  
   962  func (r *importReader) int64() int64 {
   963  	n, err := binary.ReadVarint(r)
   964  	if err != nil {
   965  		base.Fatalf("readVarint: %v", err)
   966  	}
   967  	return n
   968  }
   969  
   970  func (r *importReader) uint64() uint64 {
   971  	n, err := binary.ReadUvarint(r)
   972  	if err != nil {
   973  		base.Fatalf("readVarint: %v", err)
   974  	}
   975  	return n
   976  }
   977  
   978  func (r *importReader) byte() byte {
   979  	x, err := r.ReadByte()
   980  	if err != nil {
   981  		base.Fatalf("declReader.ReadByte: %v", err)
   982  	}
   983  	return x
   984  }
   985  
   986  // Compiler-specific extensions.
   987  
   988  func (r *importReader) constExt(n *ir.Name) {
   989  	switch n.Type() {
   990  	case types.UntypedFloat:
   991  		n.SetVal(r.mprat(n.Val()))
   992  	case types.UntypedComplex:
   993  		v := n.Val()
   994  		re := r.mprat(constant.Real(v))
   995  		im := r.mprat(constant.Imag(v))
   996  		n.SetVal(makeComplex(re, im))
   997  	}
   998  }
   999  
  1000  func (r *importReader) varExt(n *ir.Name) {
  1001  	r.linkname(n.Sym())
  1002  	r.symIdx(n.Sym())
  1003  }
  1004  
  1005  func (r *importReader) funcExt(n *ir.Name) {
  1006  	r.linkname(n.Sym())
  1007  	r.symIdx(n.Sym())
  1008  
  1009  	n.Func.ABI = obj.ABI(r.uint64())
  1010  
  1011  	// Make sure //go:noinline pragma is imported (so stenciled functions have
  1012  	// same noinline status as the corresponding generic function.)
  1013  	n.Func.Pragma = ir.PragmaFlag(r.uint64())
  1014  
  1015  	// Escape analysis.
  1016  	for _, fs := range &types.RecvsParams {
  1017  		for _, f := range fs(n.Type()).FieldSlice() {
  1018  			f.Note = r.string()
  1019  		}
  1020  	}
  1021  
  1022  	// Inline body.
  1023  	if u := r.uint64(); u > 0 {
  1024  		n.Func.Inl = &ir.Inline{
  1025  			Cost:            int32(u - 1),
  1026  			CanDelayResults: r.bool(),
  1027  		}
  1028  		n.Func.Endlineno = r.pos()
  1029  	}
  1030  }
  1031  
  1032  func (r *importReader) methExt(m *types.Field) {
  1033  	if r.bool() {
  1034  		m.SetNointerface(true)
  1035  	}
  1036  	r.funcExt(m.Nname.(*ir.Name))
  1037  }
  1038  
  1039  func (r *importReader) linkname(s *types.Sym) {
  1040  	s.Linkname = r.string()
  1041  }
  1042  
  1043  func (r *importReader) symIdx(s *types.Sym) {
  1044  	lsym := s.Linksym()
  1045  	idx := int32(r.int64())
  1046  	if idx != -1 {
  1047  		if s.Linkname != "" {
  1048  			base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
  1049  		}
  1050  		lsym.SymIdx = idx
  1051  		lsym.Set(obj.AttrIndexed, true)
  1052  	}
  1053  }
  1054  
  1055  func (r *importReader) typeExt(t *types.Type) {
  1056  	t.SetNotInHeap(r.bool())
  1057  	SetBaseTypeIndex(t, r.int64(), r.int64())
  1058  }
  1059  
  1060  func SetBaseTypeIndex(t *types.Type, i, pi int64) {
  1061  	if t.Obj() == nil {
  1062  		base.Fatalf("SetBaseTypeIndex on non-defined type %v", t)
  1063  	}
  1064  	if i != -1 && pi != -1 {
  1065  		typeSymIdx[t] = [2]int64{i, pi}
  1066  	}
  1067  }
  1068  
  1069  // Map imported type T to the index of type descriptor symbols of T and *T,
  1070  // so we can use index to reference the symbol.
  1071  // TODO(mdempsky): Store this information directly in the Type's Name.
  1072  var typeSymIdx = make(map[*types.Type][2]int64)
  1073  
  1074  func BaseTypeIndex(t *types.Type) int64 {
  1075  	tbase := t
  1076  	if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
  1077  		tbase = t.Elem()
  1078  	}
  1079  	i, ok := typeSymIdx[tbase]
  1080  	if !ok {
  1081  		return -1
  1082  	}
  1083  	if t != tbase {
  1084  		return i[1]
  1085  	}
  1086  	return i[0]
  1087  }
  1088  
  1089  func (r *importReader) doInline(fn *ir.Func) {
  1090  	if len(fn.Inl.Body) != 0 {
  1091  		base.Fatalf("%v already has inline body", fn)
  1092  	}
  1093  
  1094  	//fmt.Printf("Importing %s\n", fn.Nname.Sym().Name)
  1095  	r.funcBody(fn)
  1096  
  1097  	importlist = append(importlist, fn)
  1098  
  1099  	if base.Flag.E > 0 && base.Flag.LowerM > 2 {
  1100  		if base.Flag.LowerM > 3 {
  1101  			fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
  1102  		} else {
  1103  			fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
  1104  		}
  1105  	}
  1106  }
  1107  
  1108  // ----------------------------------------------------------------------------
  1109  // Inlined function bodies
  1110  
  1111  // Approach: Read nodes and use them to create/declare the same data structures
  1112  // as done originally by the (hidden) parser by closely following the parser's
  1113  // original code. In other words, "parsing" the import data (which happens to
  1114  // be encoded in binary rather textual form) is the best way at the moment to
  1115  // re-establish the syntax tree's invariants. At some future point we might be
  1116  // able to avoid this round-about way and create the rewritten nodes directly,
  1117  // possibly avoiding a lot of duplicate work (name resolution, type checking).
  1118  //
  1119  // Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
  1120  // unrefined nodes (since this is what the importer uses). The respective case
  1121  // entries are unreachable in the importer.
  1122  
  1123  func (r *importReader) funcBody(fn *ir.Func) {
  1124  	outerfn := r.curfn
  1125  	r.curfn = fn
  1126  
  1127  	// Import local declarations.
  1128  	fn.Inl.Dcl = r.readFuncDcls(fn)
  1129  
  1130  	// Import function body.
  1131  	body := r.stmtList()
  1132  	if body == nil {
  1133  		// Make sure empty body is not interpreted as
  1134  		// no inlineable body (see also parser.fnbody)
  1135  		// (not doing so can cause significant performance
  1136  		// degradation due to unnecessary calls to empty
  1137  		// functions).
  1138  		body = []ir.Node{}
  1139  	}
  1140  	if go117ExportTypes {
  1141  		ir.VisitList(body, func(n ir.Node) {
  1142  			n.SetTypecheck(1)
  1143  		})
  1144  	}
  1145  	fn.Inl.Body = body
  1146  
  1147  	r.curfn = outerfn
  1148  	if base.Flag.W >= 3 {
  1149  		fmt.Printf("Imported for %v", fn)
  1150  		ir.DumpList("", fn.Inl.Body)
  1151  	}
  1152  }
  1153  
  1154  func (r *importReader) readNames(fn *ir.Func) []*ir.Name {
  1155  	dcls := make([]*ir.Name, r.int64())
  1156  	for i := range dcls {
  1157  		n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent())
  1158  		n.Class = ir.PAUTO // overwritten below for parameters/results
  1159  		n.Curfn = fn
  1160  		n.SetType(r.typ())
  1161  		dcls[i] = n
  1162  	}
  1163  	r.allDcls = append(r.allDcls, dcls...)
  1164  	return dcls
  1165  }
  1166  
  1167  func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name {
  1168  	dcls := r.readNames(fn)
  1169  
  1170  	// Fixup parameter classes and associate with their
  1171  	// signature's type fields.
  1172  	i := 0
  1173  	fix := func(f *types.Field, class ir.Class) {
  1174  		if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") {
  1175  			return
  1176  		}
  1177  		n := dcls[i]
  1178  		n.Class = class
  1179  		f.Nname = n
  1180  		i++
  1181  	}
  1182  
  1183  	typ := fn.Type()
  1184  	if recv := typ.Recv(); recv != nil {
  1185  		fix(recv, ir.PPARAM)
  1186  	}
  1187  	for _, f := range typ.Params().FieldSlice() {
  1188  		fix(f, ir.PPARAM)
  1189  	}
  1190  	for _, f := range typ.Results().FieldSlice() {
  1191  		fix(f, ir.PPARAMOUT)
  1192  	}
  1193  	return dcls
  1194  }
  1195  
  1196  func (r *importReader) localName() *ir.Name {
  1197  	i := r.int64()
  1198  	if i == -1 {
  1199  		return ir.BlankNode.(*ir.Name)
  1200  	}
  1201  	if i < 0 {
  1202  		return r.allClosureVars[-i-2]
  1203  	}
  1204  	return r.allDcls[i]
  1205  }
  1206  
  1207  func (r *importReader) stmtList() []ir.Node {
  1208  	var list []ir.Node
  1209  	for {
  1210  		n := r.node()
  1211  		if n == nil {
  1212  			break
  1213  		}
  1214  		// OBLOCK nodes are not written to the import data directly,
  1215  		// but the handling of ODCL calls liststmt, which creates one.
  1216  		// Inline them into the statement list.
  1217  		if n.Op() == ir.OBLOCK {
  1218  			n := n.(*ir.BlockStmt)
  1219  			list = append(list, n.List...)
  1220  			continue
  1221  		}
  1222  		if len(list) > 0 {
  1223  			// check for an optional label that can only immediately
  1224  			// precede a for/range/select/switch statement.
  1225  			if last := list[len(list)-1]; last.Op() == ir.OLABEL {
  1226  				label := last.(*ir.LabelStmt).Label
  1227  				switch n.Op() {
  1228  				case ir.OFOR:
  1229  					n.(*ir.ForStmt).Label = label
  1230  				case ir.ORANGE:
  1231  					n.(*ir.RangeStmt).Label = label
  1232  				case ir.OSELECT:
  1233  					n.(*ir.SelectStmt).Label = label
  1234  				case ir.OSWITCH:
  1235  					n.(*ir.SwitchStmt).Label = label
  1236  				}
  1237  			}
  1238  		}
  1239  		list = append(list, n)
  1240  	}
  1241  	return list
  1242  }
  1243  
  1244  func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
  1245  	namedTypeSwitch := isNamedTypeSwitch(switchExpr)
  1246  
  1247  	cases := make([]*ir.CaseClause, r.uint64())
  1248  	for i := range cases {
  1249  		cas := ir.NewCaseStmt(r.pos(), nil, nil)
  1250  		cas.List = r.stmtList()
  1251  		if namedTypeSwitch {
  1252  			cas.Var = r.localName()
  1253  			cas.Var.Defn = switchExpr
  1254  		}
  1255  		cas.Body = r.stmtList()
  1256  		cases[i] = cas
  1257  	}
  1258  	return cases
  1259  }
  1260  
  1261  func (r *importReader) commList() []*ir.CommClause {
  1262  	cases := make([]*ir.CommClause, r.uint64())
  1263  	for i := range cases {
  1264  		pos := r.pos()
  1265  		defaultCase := r.bool()
  1266  		var comm ir.Node
  1267  		if !defaultCase {
  1268  			comm = r.node()
  1269  		}
  1270  		cases[i] = ir.NewCommStmt(pos, comm, r.stmtList())
  1271  	}
  1272  	return cases
  1273  }
  1274  
  1275  func (r *importReader) exprList() []ir.Node {
  1276  	var list []ir.Node
  1277  	for {
  1278  		n := r.expr()
  1279  		if n == nil {
  1280  			break
  1281  		}
  1282  		list = append(list, n)
  1283  	}
  1284  	return list
  1285  }
  1286  
  1287  func (r *importReader) expr() ir.Node {
  1288  	n := r.node()
  1289  	if n != nil && n.Op() == ir.OBLOCK {
  1290  		n := n.(*ir.BlockStmt)
  1291  		base.Fatalf("unexpected block node: %v", n)
  1292  	}
  1293  	return n
  1294  }
  1295  
  1296  // TODO(gri) split into expr and stmt
  1297  func (r *importReader) node() ir.Node {
  1298  	op := r.op()
  1299  	switch op {
  1300  	// expressions
  1301  	// case OPAREN:
  1302  	// 	unreachable - unpacked by exporter
  1303  
  1304  	case ir.ONIL:
  1305  		pos := r.pos()
  1306  		typ := r.typ()
  1307  
  1308  		n := ir.NewNilExpr(pos)
  1309  		n.SetType(typ)
  1310  		return n
  1311  
  1312  	case ir.OLITERAL:
  1313  		pos := r.pos()
  1314  		typ := r.typ()
  1315  
  1316  		n := ir.NewBasicLit(pos, r.value(typ))
  1317  		n.SetType(typ)
  1318  		return n
  1319  
  1320  	case ir.ONONAME:
  1321  		isKey := r.bool()
  1322  		n := r.qualifiedIdent()
  1323  		if go117ExportTypes {
  1324  			var n2 ir.Node = n
  1325  			// Key ONONAME entries should not be resolved - they should
  1326  			// stay as identifiers.
  1327  			if !isKey {
  1328  				n2 = Resolve(n)
  1329  			}
  1330  			typ := r.typ()
  1331  			if n2.Type() == nil {
  1332  				n2.SetType(typ)
  1333  			}
  1334  			return n2
  1335  		}
  1336  		return n
  1337  
  1338  	case ir.ONAME:
  1339  		isBuiltin := r.bool()
  1340  		if isBuiltin {
  1341  			pkg := types.BuiltinPkg
  1342  			if r.bool() {
  1343  				pkg = types.UnsafePkg
  1344  			}
  1345  			return pkg.Lookup(r.string()).Def.(*ir.Name)
  1346  		}
  1347  		return r.localName()
  1348  
  1349  	// case OPACK, ONONAME:
  1350  	// 	unreachable - should have been resolved by typechecking
  1351  
  1352  	case ir.OTYPE:
  1353  		return ir.TypeNode(r.typ())
  1354  
  1355  	case ir.ODYNAMICTYPE:
  1356  		n := ir.NewDynamicType(r.pos(), r.expr())
  1357  		if r.bool() {
  1358  			n.ITab = r.expr()
  1359  		}
  1360  		n.SetType(r.typ())
  1361  		return n
  1362  
  1363  	case ir.OTYPESW:
  1364  		pos := r.pos()
  1365  		var tag *ir.Ident
  1366  		if s := r.localIdent(); s != nil {
  1367  			tag = ir.NewIdent(pos, s)
  1368  		}
  1369  		return ir.NewTypeSwitchGuard(pos, tag, r.expr())
  1370  
  1371  	// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
  1372  	//      unreachable - should have been resolved by typechecking
  1373  
  1374  	case ir.OCLOSURE:
  1375  		//println("Importing CLOSURE")
  1376  		pos := r.pos()
  1377  		r.setPkg()
  1378  		typ := r.signature(nil, nil)
  1379  		r.setPkg()
  1380  
  1381  		// All the remaining code below is similar to (*noder).funcLit(), but
  1382  		// with Dcls and ClosureVars lists already set up
  1383  		fn := ir.NewClosureFunc(pos, true)
  1384  		fn.Nname.SetType(typ)
  1385  
  1386  		cvars := make([]*ir.Name, r.int64())
  1387  		for i := range cvars {
  1388  			cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
  1389  			if go117ExportTypes && cvars[i].Defn == nil {
  1390  				base.Fatalf("bad import of closure variable")
  1391  			}
  1392  		}
  1393  		fn.ClosureVars = cvars
  1394  		r.allClosureVars = append(r.allClosureVars, cvars...)
  1395  
  1396  		fn.Inl = &ir.Inline{}
  1397  		// Read in the Dcls and Body of the closure after temporarily
  1398  		// setting r.curfn to fn.
  1399  		r.funcBody(fn)
  1400  		fn.Dcl = fn.Inl.Dcl
  1401  		fn.Body = fn.Inl.Body
  1402  		if len(fn.Body) == 0 {
  1403  			// An empty closure must be represented as a single empty
  1404  			// block statement, else it will be dropped.
  1405  			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
  1406  		}
  1407  		fn.Inl = nil
  1408  
  1409  		ir.FinishCaptureNames(pos, r.curfn, fn)
  1410  
  1411  		clo := fn.OClosure
  1412  		if go117ExportTypes {
  1413  			clo.SetType(typ)
  1414  		}
  1415  		return clo
  1416  
  1417  	case ir.OSTRUCTLIT:
  1418  		if go117ExportTypes {
  1419  			pos := r.pos()
  1420  			typ := r.typ()
  1421  			list := r.fieldList()
  1422  			n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list)
  1423  			n.SetType(typ)
  1424  			return n
  1425  		}
  1426  		return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())
  1427  
  1428  	case ir.OCOMPLIT:
  1429  		pos := r.pos()
  1430  		t := r.typ()
  1431  		n := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ir.TypeNode(t), r.exprList())
  1432  		n.SetType(t)
  1433  		return n
  1434  
  1435  	case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
  1436  		if !go117ExportTypes {
  1437  			// unreachable - mapped to OCOMPLIT by exporter
  1438  			goto error
  1439  		}
  1440  		pos := r.pos()
  1441  		typ := r.typ()
  1442  		list := r.exprList()
  1443  		n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list)
  1444  		n.SetType(typ)
  1445  		if op == ir.OSLICELIT {
  1446  			n.Len = int64(r.uint64())
  1447  		}
  1448  		return n
  1449  
  1450  	case ir.OKEY:
  1451  		return ir.NewKeyExpr(r.pos(), r.expr(), r.expr())
  1452  
  1453  	// case OSTRUCTKEY:
  1454  	//	unreachable - handled in case OSTRUCTLIT by elemList
  1455  
  1456  	case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OMETHVALUE, ir.OMETHEXPR:
  1457  		// For !go117ExportTypes,  we should only see OXDOT.
  1458  		// For go117ExportTypes, we usually see all the other ops, but can see
  1459  		// OXDOT for generic functions.
  1460  		if op != ir.OXDOT && !go117ExportTypes {
  1461  			goto error
  1462  		}
  1463  		pos := r.pos()
  1464  		expr := r.expr()
  1465  		sel := r.exoticSelector()
  1466  		n := ir.NewSelectorExpr(pos, op, expr, sel)
  1467  		if go117ExportTypes {
  1468  			n.SetType(r.exoticType())
  1469  			switch op {
  1470  			case ir.OXDOT:
  1471  				hasSelection := r.bool()
  1472  				// We reconstruct n.Selection for method calls on
  1473  				// generic types and method calls due to type param
  1474  				// bounds.  Otherwise, n.Selection is nil.
  1475  				if hasSelection {
  1476  					n1 := ir.NewSelectorExpr(pos, op, expr, sel)
  1477  					AddImplicitDots(n1)
  1478  					var m *types.Field
  1479  					if n1.X.Type().IsTypeParam() {
  1480  						genType := n1.X.Type().Bound()
  1481  						m = Lookdot1(n1, sel, genType, genType.AllMethods(), 1)
  1482  					} else {
  1483  						genType := types.ReceiverBaseType(n1.X.Type())
  1484  						if genType.IsInstantiatedGeneric() {
  1485  							genType = genType.OrigType()
  1486  						}
  1487  						m = Lookdot1(n1, sel, genType, genType.Methods(), 1)
  1488  					}
  1489  					assert(m != nil)
  1490  					n.Selection = m
  1491  				}
  1492  			case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
  1493  				n.Selection = r.exoticField()
  1494  			case ir.OMETHEXPR:
  1495  				n = typecheckMethodExpr(n).(*ir.SelectorExpr)
  1496  			case ir.ODOTMETH, ir.OMETHVALUE:
  1497  				// These require a Lookup to link to the correct declaration.
  1498  				rcvrType := expr.Type()
  1499  				typ := n.Type()
  1500  				n.Selection = Lookdot(n, rcvrType, 1)
  1501  				if op == ir.OMETHVALUE {
  1502  					// Lookdot clobbers the opcode and type, undo that.
  1503  					n.SetOp(op)
  1504  					n.SetType(typ)
  1505  				}
  1506  			}
  1507  		}
  1508  		return n
  1509  
  1510  	case ir.ODOTTYPE, ir.ODOTTYPE2:
  1511  		n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil)
  1512  		n.SetType(r.typ())
  1513  		if go117ExportTypes {
  1514  			n.SetOp(op)
  1515  		}
  1516  		return n
  1517  
  1518  	case ir.ODYNAMICDOTTYPE, ir.ODYNAMICDOTTYPE2:
  1519  		n := ir.NewDynamicTypeAssertExpr(r.pos(), op, r.expr(), r.expr())
  1520  		n.SetType(r.typ())
  1521  		return n
  1522  
  1523  	case ir.OINDEX, ir.OINDEXMAP:
  1524  		n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr())
  1525  		if go117ExportTypes {
  1526  			n.SetOp(op)
  1527  			n.SetType(r.exoticType())
  1528  			if op == ir.OINDEXMAP {
  1529  				n.Assigned = r.bool()
  1530  			}
  1531  		}
  1532  		return n
  1533  
  1534  	case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
  1535  		pos, x := r.pos(), r.expr()
  1536  		low, high := r.exprsOrNil()
  1537  		var max ir.Node
  1538  		if op.IsSlice3() {
  1539  			max = r.expr()
  1540  		}
  1541  		n := ir.NewSliceExpr(pos, op, x, low, high, max)
  1542  		if go117ExportTypes {
  1543  			n.SetType(r.typ())
  1544  		}
  1545  		return n
  1546  
  1547  	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
  1548  		if !go117ExportTypes && op != ir.OCONV {
  1549  			// 	unreachable - mapped to OCONV case by exporter
  1550  			goto error
  1551  		}
  1552  		return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
  1553  
  1554  	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:
  1555  		if go117ExportTypes {
  1556  			switch op {
  1557  			case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
  1558  				n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
  1559  				n.SetType(r.typ())
  1560  				return n
  1561  			case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
  1562  				n := ir.NewUnaryExpr(r.pos(), op, r.expr())
  1563  				if op != ir.OPANIC {
  1564  					n.SetType(r.typ())
  1565  				}
  1566  				return n
  1567  			case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
  1568  				n := ir.NewCallExpr(r.pos(), op, nil, r.exprList())
  1569  				if op == ir.OAPPEND {
  1570  					n.IsDDD = r.bool()
  1571  				}
  1572  				if op == ir.OAPPEND || op == ir.ORECOVER {
  1573  					n.SetType(r.typ())
  1574  				}
  1575  				return n
  1576  			}
  1577  			// ir.OMAKE
  1578  			goto error
  1579  		}
  1580  		n := builtinCall(r.pos(), op)
  1581  		n.Args = r.exprList()
  1582  		if op == ir.OAPPEND {
  1583  			n.IsDDD = r.bool()
  1584  		}
  1585  		return n
  1586  
  1587  	case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
  1588  		pos := r.pos()
  1589  		init := r.stmtList()
  1590  		n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList())
  1591  		if go117ExportTypes {
  1592  			n.SetOp(op)
  1593  		}
  1594  		n.SetInit(init)
  1595  		n.IsDDD = r.bool()
  1596  		if go117ExportTypes {
  1597  			n.SetType(r.exoticType())
  1598  		}
  1599  		return n
  1600  
  1601  	case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
  1602  		if go117ExportTypes {
  1603  			pos := r.pos()
  1604  			typ := r.typ()
  1605  			list := r.exprList()
  1606  			var len_, cap_ ir.Node
  1607  			if len(list) > 0 {
  1608  				len_ = list[0]
  1609  			}
  1610  			if len(list) > 1 {
  1611  				cap_ = list[1]
  1612  			}
  1613  			n := ir.NewMakeExpr(pos, op, len_, cap_)
  1614  			n.SetType(typ)
  1615  			return n
  1616  		}
  1617  		n := builtinCall(r.pos(), ir.OMAKE)
  1618  		n.Args.Append(ir.TypeNode(r.typ()))
  1619  		n.Args.Append(r.exprList()...)
  1620  		return n
  1621  
  1622  	case ir.OLINKSYMOFFSET:
  1623  		pos := r.pos()
  1624  		name := r.string()
  1625  		off := r.uint64()
  1626  		typ := r.typ()
  1627  		return ir.NewLinksymOffsetExpr(pos, Lookup(name).Linksym(), int64(off), typ)
  1628  
  1629  	// unary expressions
  1630  	case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV, ir.OIDATA:
  1631  		n := ir.NewUnaryExpr(r.pos(), op, r.expr())
  1632  		if go117ExportTypes {
  1633  			n.SetType(r.typ())
  1634  		}
  1635  		return n
  1636  
  1637  	case ir.OADDR, ir.OPTRLIT:
  1638  		if go117ExportTypes {
  1639  			pos := r.pos()
  1640  			expr := r.expr()
  1641  			expr.SetTypecheck(1) // we do this for all nodes after importing, but do it now so markAddrOf can see it.
  1642  			n := NodAddrAt(pos, expr)
  1643  			n.SetOp(op)
  1644  			n.SetType(r.typ())
  1645  			return n
  1646  		}
  1647  		n := NodAddrAt(r.pos(), r.expr())
  1648  		return n
  1649  
  1650  	case ir.ODEREF:
  1651  		n := ir.NewStarExpr(r.pos(), r.expr())
  1652  		if go117ExportTypes {
  1653  			n.SetType(r.typ())
  1654  		}
  1655  		return n
  1656  
  1657  	// binary expressions
  1658  	case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
  1659  		ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR, ir.OEFACE:
  1660  		n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
  1661  		if go117ExportTypes {
  1662  			n.SetType(r.typ())
  1663  		}
  1664  		return n
  1665  
  1666  	case ir.OANDAND, ir.OOROR:
  1667  		n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
  1668  		if go117ExportTypes {
  1669  			n.SetType(r.typ())
  1670  		}
  1671  		return n
  1672  
  1673  	case ir.OSEND:
  1674  		return ir.NewSendStmt(r.pos(), r.expr(), r.expr())
  1675  
  1676  	case ir.OADDSTR:
  1677  		pos := r.pos()
  1678  		list := r.exprList()
  1679  		if go117ExportTypes {
  1680  			n := ir.NewAddStringExpr(pos, list)
  1681  			n.SetType(r.typ())
  1682  			return n
  1683  		}
  1684  		x := list[0]
  1685  		for _, y := range list[1:] {
  1686  			x = ir.NewBinaryExpr(pos, ir.OADD, x, y)
  1687  		}
  1688  		return x
  1689  
  1690  	// --------------------------------------------------------------------
  1691  	// statements
  1692  	case ir.ODCL:
  1693  		var stmts ir.Nodes
  1694  		n := r.localName()
  1695  		stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n))
  1696  		stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil))
  1697  		return ir.NewBlockStmt(n.Pos(), stmts)
  1698  
  1699  	// case OASWB:
  1700  	// 	unreachable - never exported
  1701  
  1702  	case ir.OAS:
  1703  		pos := r.pos()
  1704  		init := r.stmtList()
  1705  		n := ir.NewAssignStmt(pos, r.expr(), r.expr())
  1706  		n.SetInit(init)
  1707  		n.Def = r.bool()
  1708  		return n
  1709  
  1710  	case ir.OASOP:
  1711  		n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
  1712  		if !r.bool() {
  1713  			n.Y = ir.NewInt(1)
  1714  			n.IncDec = true
  1715  		} else {
  1716  			n.Y = r.expr()
  1717  		}
  1718  		return n
  1719  
  1720  	case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
  1721  		if !go117ExportTypes && op != ir.OAS2 {
  1722  			// unreachable - mapped to case OAS2 by exporter
  1723  			goto error
  1724  		}
  1725  		pos := r.pos()
  1726  		init := r.stmtList()
  1727  		n := ir.NewAssignListStmt(pos, op, r.exprList(), r.exprList())
  1728  		n.SetInit(init)
  1729  		n.Def = r.bool()
  1730  		return n
  1731  
  1732  	case ir.ORETURN:
  1733  		return ir.NewReturnStmt(r.pos(), r.exprList())
  1734  
  1735  	// case ORETJMP:
  1736  	// 	unreachable - generated by compiler for trampolin routines (not exported)
  1737  
  1738  	case ir.OGO, ir.ODEFER:
  1739  		return ir.NewGoDeferStmt(r.pos(), op, r.expr())
  1740  
  1741  	case ir.OIF:
  1742  		pos, init := r.pos(), r.stmtList()
  1743  		n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList())
  1744  		n.SetInit(init)
  1745  		return n
  1746  
  1747  	case ir.OFOR:
  1748  		pos, init := r.pos(), r.stmtList()
  1749  		cond, post := r.exprsOrNil()
  1750  		n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
  1751  		n.SetInit(init)
  1752  		return n
  1753  
  1754  	case ir.ORANGE:
  1755  		pos, init := r.pos(), r.stmtList()
  1756  		k, v := r.exprsOrNil()
  1757  		n := ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList())
  1758  		n.SetInit(init)
  1759  		return n
  1760  
  1761  	case ir.OSELECT:
  1762  		pos := r.pos()
  1763  		init := r.stmtList()
  1764  		n := ir.NewSelectStmt(pos, r.commList())
  1765  		n.SetInit(init)
  1766  		return n
  1767  
  1768  	case ir.OSWITCH:
  1769  		pos := r.pos()
  1770  		init := r.stmtList()
  1771  		x, _ := r.exprsOrNil()
  1772  		n := ir.NewSwitchStmt(pos, x, r.caseList(x))
  1773  		n.SetInit(init)
  1774  		return n
  1775  
  1776  	// case OCASE:
  1777  	//	handled by caseList
  1778  
  1779  	case ir.OFALL:
  1780  		return ir.NewBranchStmt(r.pos(), ir.OFALL, nil)
  1781  
  1782  	// case OEMPTY:
  1783  	// 	unreachable - not emitted by exporter
  1784  
  1785  	case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
  1786  		pos := r.pos()
  1787  		var sym *types.Sym
  1788  		if label := r.string(); label != "" {
  1789  			sym = Lookup(label)
  1790  		}
  1791  		return ir.NewBranchStmt(pos, op, sym)
  1792  
  1793  	case ir.OLABEL:
  1794  		return ir.NewLabelStmt(r.pos(), Lookup(r.string()))
  1795  
  1796  	case ir.OEND:
  1797  		return nil
  1798  
  1799  	case ir.OFUNCINST:
  1800  		pos := r.pos()
  1801  		x := r.expr()
  1802  		ntargs := r.uint64()
  1803  		var targs []ir.Node
  1804  		if ntargs > 0 {
  1805  			targs = make([]ir.Node, ntargs)
  1806  			for i := range targs {
  1807  				targs[i] = ir.TypeNode(r.typ())
  1808  			}
  1809  		}
  1810  		n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs)
  1811  		if go117ExportTypes {
  1812  			n.SetType(r.typ())
  1813  		}
  1814  		return n
  1815  
  1816  	case ir.OSELRECV2:
  1817  		pos := r.pos()
  1818  		init := r.stmtList()
  1819  		n := ir.NewAssignListStmt(pos, ir.OSELRECV2, r.exprList(), r.exprList())
  1820  		n.SetInit(init)
  1821  		n.Def = r.bool()
  1822  		return n
  1823  
  1824  	default:
  1825  		base.Fatalf("cannot import %v (%d) node\n"+
  1826  			"\t==> please file an issue and assign to gri@", op, int(op))
  1827  		panic("unreachable") // satisfy compiler
  1828  	}
  1829  error:
  1830  	base.Fatalf("cannot import %v (%d) node\n"+
  1831  		"\t==> please file an issue and assign to khr@", op, int(op))
  1832  	panic("unreachable") // satisfy compiler
  1833  }
  1834  
  1835  func (r *importReader) op() ir.Op {
  1836  	if debug && r.uint64() != magic {
  1837  		base.Fatalf("import stream has desynchronized")
  1838  	}
  1839  	return ir.Op(r.uint64())
  1840  }
  1841  
  1842  func (r *importReader) fieldList() []ir.Node {
  1843  	list := make([]ir.Node, r.uint64())
  1844  	for i := range list {
  1845  		list[i] = ir.NewStructKeyExpr(r.pos(), r.exoticField(), r.expr())
  1846  	}
  1847  	return list
  1848  }
  1849  
  1850  func (r *importReader) exprsOrNil() (a, b ir.Node) {
  1851  	ab := r.uint64()
  1852  	if ab&1 != 0 {
  1853  		a = r.expr()
  1854  	}
  1855  	if ab&2 != 0 {
  1856  		b = r.node()
  1857  	}
  1858  	return
  1859  }
  1860  
  1861  func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
  1862  	if go117ExportTypes {
  1863  		// These should all be encoded as direct ops, not OCALL.
  1864  		base.Fatalf("builtinCall should not be invoked when types are included in import/export")
  1865  	}
  1866  	return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
  1867  }
  1868  
  1869  // NewIncompleteNamedType returns a TFORW type t with name specified by sym, such
  1870  // that t.nod and sym.Def are set correctly. If there are any RParams for the type,
  1871  // they should be set soon after creating the TFORW type, before creating the
  1872  // underlying type. That ensures that the HasTParam and HasShape flags will be set
  1873  // properly, in case this type is part of some mutually recursive type.
  1874  func NewIncompleteNamedType(pos src.XPos, sym *types.Sym) *types.Type {
  1875  	name := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
  1876  	forw := types.NewNamed(name)
  1877  	name.SetType(forw)
  1878  	sym.Def = name
  1879  	return forw
  1880  }
  1881  
  1882  // Instantiate creates a new named type which is the instantiation of the base
  1883  // named generic type, with the specified type args.
  1884  func Instantiate(pos src.XPos, baseType *types.Type, targs []*types.Type) *types.Type {
  1885  	baseSym := baseType.Sym()
  1886  	if strings.Index(baseSym.Name, "[") >= 0 {
  1887  		base.Fatalf("arg to Instantiate is not a base generic type")
  1888  	}
  1889  	name := InstTypeName(baseSym.Name, targs)
  1890  	instSym := baseSym.Pkg.Lookup(name)
  1891  	if instSym.Def != nil {
  1892  		// May match existing type from previous import or
  1893  		// types2-to-types1 conversion.
  1894  		t := instSym.Def.Type()
  1895  		if t.Kind() != types.TFORW {
  1896  			return t
  1897  		}
  1898  		// Or, we have started creating this type in (*TSubster).Typ, but its
  1899  		// underlying type was not completed yet, so we need to add this type
  1900  		// to deferredInstStack, if not already there.
  1901  		found := false
  1902  		for _, t2 := range deferredInstStack {
  1903  			if t2 == t {
  1904  				found = true
  1905  				break
  1906  			}
  1907  		}
  1908  		if !found {
  1909  			deferredInstStack = append(deferredInstStack, t)
  1910  		}
  1911  		return t
  1912  	}
  1913  
  1914  	t := NewIncompleteNamedType(baseType.Pos(), instSym)
  1915  	t.SetRParams(targs)
  1916  	t.SetOrigType(baseType)
  1917  
  1918  	// baseType may still be TFORW or its methods may not be fully filled in
  1919  	// (since we are in the middle of importing it). So, delay call to
  1920  	// substInstType until we get back up to the top of the current top-most
  1921  	// type import.
  1922  	deferredInstStack = append(deferredInstStack, t)
  1923  
  1924  	return t
  1925  }
  1926  
  1927  var deferredInstStack []*types.Type
  1928  var deferInst int
  1929  
  1930  // deferDoInst defers substitution on instantiated types until we are at the
  1931  // top-most defined type, so the base types are fully defined.
  1932  func deferDoInst() {
  1933  	deferInst++
  1934  }
  1935  
  1936  func resumeDoInst() {
  1937  	if deferInst == 1 {
  1938  		for len(deferredInstStack) > 0 {
  1939  			t := deferredInstStack[0]
  1940  			deferredInstStack = deferredInstStack[1:]
  1941  			substInstType(t, t.OrigType(), t.RParams())
  1942  		}
  1943  	}
  1944  	deferInst--
  1945  }
  1946  
  1947  // doInst creates a new instantiation type (which will be added to
  1948  // deferredInstStack for completion later) for an incomplete type encountered
  1949  // during a type substitution for an instantiation. This is needed for
  1950  // instantiations of mutually recursive types.
  1951  func doInst(t *types.Type) *types.Type {
  1952  	assert(t.Kind() == types.TFORW)
  1953  	return Instantiate(t.Pos(), t.OrigType(), t.RParams())
  1954  }
  1955  
  1956  // substInstType completes the instantiation of a generic type by doing a
  1957  // substitution on the underlying type itself and any methods. t is the
  1958  // instantiation being created, baseType is the base generic type, and targs are
  1959  // the type arguments that baseType is being instantiated with.
  1960  func substInstType(t *types.Type, baseType *types.Type, targs []*types.Type) {
  1961  	assert(t.Kind() == types.TFORW)
  1962  	subst := Tsubster{
  1963  		Tparams:       baseType.RParams(),
  1964  		Targs:         targs,
  1965  		SubstForwFunc: doInst,
  1966  	}
  1967  	t.SetUnderlying(subst.Typ(baseType.Underlying()))
  1968  
  1969  	newfields := make([]*types.Field, baseType.Methods().Len())
  1970  	for i, f := range baseType.Methods().Slice() {
  1971  		if !f.IsMethod() || types.IsInterfaceMethod(f.Type) {
  1972  			// Do a normal substitution if this is a non-method (which
  1973  			// means this must be an interface used as a constraint) or
  1974  			// an interface method.
  1975  			t2 := subst.Typ(f.Type)
  1976  			newfields[i] = types.NewField(f.Pos, f.Sym, t2)
  1977  			continue
  1978  		}
  1979  		recvType := f.Type.Recv().Type
  1980  		if recvType.IsPtr() {
  1981  			recvType = recvType.Elem()
  1982  		}
  1983  		// Substitute in the method using the type params used in the
  1984  		// method (not the type params in the definition of the generic type).
  1985  		msubst := Tsubster{
  1986  			Tparams:       recvType.RParams(),
  1987  			Targs:         targs,
  1988  			SubstForwFunc: doInst,
  1989  		}
  1990  		t2 := msubst.Typ(f.Type)
  1991  		oldsym := f.Nname.Sym()
  1992  		newsym := MakeFuncInstSym(oldsym, targs, true, true)
  1993  		var nname *ir.Name
  1994  		if newsym.Def != nil {
  1995  			nname = newsym.Def.(*ir.Name)
  1996  		} else {
  1997  			nname = ir.NewNameAt(f.Pos, newsym)
  1998  			nname.SetType(t2)
  1999  			ir.MarkFunc(nname)
  2000  			newsym.Def = nname
  2001  		}
  2002  		newfields[i] = types.NewField(f.Pos, f.Sym, t2)
  2003  		newfields[i].Nname = nname
  2004  	}
  2005  	t.Methods().Set(newfields)
  2006  	if !t.HasTParam() && !t.HasShape() && t.Kind() != types.TINTER && t.Methods().Len() > 0 {
  2007  		// Generate all the methods for a new fully-instantiated,
  2008  		// non-interface, non-shape type.
  2009  		NeedInstType(t)
  2010  	}
  2011  }
  2012  

View as plain text