github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/noder/reader.go (about)

     1  // Copyright 2021 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  package noder
     6  
     7  import (
     8  	"fmt"
     9  	"github.com/bir3/gocompiler/src/go/constant"
    10  	"github.com/bir3/gocompiler/src/internal/buildcfg"
    11  	"github.com/bir3/gocompiler/src/internal/pkgbits"
    12  	"strings"
    13  
    14  	"github.com/bir3/gocompiler/src/cmd/compile/internal/base"
    15  	"github.com/bir3/gocompiler/src/cmd/compile/internal/deadcode"
    16  	"github.com/bir3/gocompiler/src/cmd/compile/internal/dwarfgen"
    17  	"github.com/bir3/gocompiler/src/cmd/compile/internal/inline"
    18  	"github.com/bir3/gocompiler/src/cmd/compile/internal/ir"
    19  	"github.com/bir3/gocompiler/src/cmd/compile/internal/objw"
    20  	"github.com/bir3/gocompiler/src/cmd/compile/internal/reflectdata"
    21  	"github.com/bir3/gocompiler/src/cmd/compile/internal/staticinit"
    22  	"github.com/bir3/gocompiler/src/cmd/compile/internal/typecheck"
    23  	"github.com/bir3/gocompiler/src/cmd/compile/internal/types"
    24  	"github.com/bir3/gocompiler/src/cmd/internal/obj"
    25  	"github.com/bir3/gocompiler/src/cmd/internal/objabi"
    26  	"github.com/bir3/gocompiler/src/cmd/internal/src"
    27  )
    28  
    29  // This file implements cmd/compile backend's reader for the Unified
    30  // IR export data.
    31  
    32  // A pkgReader reads Unified IR export data.
    33  type pkgReader struct {
    34  	pkgbits.PkgDecoder
    35  
    36  	// Indices for encoded things; lazily populated as needed.
    37  	//
    38  	// Note: Objects (i.e., ir.Names) are lazily instantiated by
    39  	// populating their types.Sym.Def; see objReader below.
    40  
    41  	posBases []*src.PosBase
    42  	pkgs     []*types.Pkg
    43  	typs     []*types.Type
    44  
    45  	// offset for rewriting the given (absolute!) index into the output,
    46  	// but bitwise inverted so we can detect if we're missing the entry
    47  	// or not.
    48  	newindex []pkgbits.Index
    49  }
    50  
    51  func newPkgReader(pr pkgbits.PkgDecoder) *pkgReader {
    52  	return &pkgReader{
    53  		PkgDecoder: pr,
    54  
    55  		posBases: make([]*src.PosBase, pr.NumElems(pkgbits.RelocPosBase)),
    56  		pkgs:     make([]*types.Pkg, pr.NumElems(pkgbits.RelocPkg)),
    57  		typs:     make([]*types.Type, pr.NumElems(pkgbits.RelocType)),
    58  
    59  		newindex: make([]pkgbits.Index, pr.TotalElems()),
    60  	}
    61  }
    62  
    63  // A pkgReaderIndex compactly identifies an index (and its
    64  // corresponding dictionary) within a package's export data.
    65  type pkgReaderIndex struct {
    66  	pr        *pkgReader
    67  	idx       pkgbits.Index
    68  	dict      *readerDict
    69  	methodSym *types.Sym
    70  
    71  	synthetic func(pos src.XPos, r *reader)
    72  }
    73  
    74  func (pri pkgReaderIndex) asReader(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *reader {
    75  	if pri.synthetic != nil {
    76  		return &reader{synthetic: pri.synthetic}
    77  	}
    78  
    79  	r := pri.pr.newReader(k, pri.idx, marker)
    80  	r.dict = pri.dict
    81  	r.methodSym = pri.methodSym
    82  	return r
    83  }
    84  
    85  func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
    86  	return &reader{
    87  		Decoder: pr.NewDecoder(k, idx, marker),
    88  		p:       pr,
    89  	}
    90  }
    91  
    92  // A reader provides APIs for reading an individual element.
    93  type reader struct {
    94  	pkgbits.Decoder
    95  
    96  	p *pkgReader
    97  
    98  	dict *readerDict
    99  
   100  	// TODO(mdempsky): The state below is all specific to reading
   101  	// function bodies. It probably makes sense to split it out
   102  	// separately so that it doesn't take up space in every reader
   103  	// instance.
   104  
   105  	curfn       *ir.Func
   106  	locals      []*ir.Name
   107  	closureVars []*ir.Name
   108  
   109  	funarghack bool
   110  
   111  	// methodSym is the name of method's name, if reading a method.
   112  	// It's nil if reading a normal function or closure body.
   113  	methodSym *types.Sym
   114  
   115  	// dictParam is the .dict param, if any.
   116  	dictParam *ir.Name
   117  
   118  	// synthetic is a callback function to construct a synthetic
   119  	// function body. It's used for creating the bodies of function
   120  	// literals used to curry arguments to shaped functions.
   121  	synthetic func(pos src.XPos, r *reader)
   122  
   123  	// scopeVars is a stack tracking the number of variables declared in
   124  	// the current function at the moment each open scope was opened.
   125  	scopeVars         []int
   126  	marker            dwarfgen.ScopeMarker
   127  	lastCloseScopePos src.XPos
   128  
   129  	// === details for handling inline body expansion ===
   130  
   131  	// If we're reading in a function body because of inlining, this is
   132  	// the call that we're inlining for.
   133  	inlCaller    *ir.Func
   134  	inlCall      *ir.CallExpr
   135  	inlFunc      *ir.Func
   136  	inlTreeIndex int
   137  	inlPosBases  map[*src.PosBase]*src.PosBase
   138  
   139  	// suppressInlPos tracks whether position base rewriting for
   140  	// inlining should be suppressed. See funcLit.
   141  	suppressInlPos int
   142  
   143  	delayResults bool
   144  
   145  	// Label to return to.
   146  	retlabel *types.Sym
   147  
   148  	// inlvars is the list of variables that the inlinee's arguments are
   149  	// assigned to, one for each receiver and normal parameter, in order.
   150  	inlvars ir.Nodes
   151  
   152  	// retvars is the list of variables that the inlinee's results are
   153  	// assigned to, one for each result parameter, in order.
   154  	retvars ir.Nodes
   155  }
   156  
   157  // A readerDict represents an instantiated "compile-time dictionary,"
   158  // used for resolving any derived types needed for instantiating a
   159  // generic object.
   160  //
   161  // A compile-time dictionary can either be "shaped" or "non-shaped."
   162  // Shaped compile-time dictionaries are only used for instantiating
   163  // shaped type definitions and function bodies, while non-shaped
   164  // compile-time dictionaries are used for instantiating runtime
   165  // dictionaries.
   166  type readerDict struct {
   167  	shaped bool // whether this is a shaped dictionary
   168  
   169  	// baseSym is the symbol for the object this dictionary belongs to.
   170  	// If the object is an instantiated function or defined type, then
   171  	// baseSym is the mangled symbol, including any type arguments.
   172  	baseSym *types.Sym
   173  
   174  	// For non-shaped dictionaries, shapedObj is a reference to the
   175  	// corresponding shaped object (always a function or defined type).
   176  	shapedObj *ir.Name
   177  
   178  	// targs holds the implicit and explicit type arguments in use for
   179  	// reading the current object. For example:
   180  	//
   181  	//	func F[T any]() {
   182  	//		type X[U any] struct { t T; u U }
   183  	//		var _ X[string]
   184  	//	}
   185  	//
   186  	//	var _ = F[int]
   187  	//
   188  	// While instantiating F[int], we need to in turn instantiate
   189  	// X[string]. [int] and [string] are explicit type arguments for F
   190  	// and X, respectively; but [int] is also the implicit type
   191  	// arguments for X.
   192  	//
   193  	// (As an analogy to function literals, explicits are the function
   194  	// literal's formal parameters, while implicits are variables
   195  	// captured by the function literal.)
   196  	targs []*types.Type
   197  
   198  	// implicits counts how many of types within targs are implicit type
   199  	// arguments; the rest are explicit.
   200  	implicits int
   201  
   202  	derived      []derivedInfo // reloc index of the derived type's descriptor
   203  	derivedTypes []*types.Type // slice of previously computed derived types
   204  
   205  	// These slices correspond to entries in the runtime dictionary.
   206  	typeParamMethodExprs []readerMethodExprInfo
   207  	subdicts             []objInfo
   208  	rtypes               []typeInfo
   209  	itabs                []itabInfo
   210  }
   211  
   212  type readerMethodExprInfo struct {
   213  	typeParamIdx int
   214  	method       *types.Sym
   215  }
   216  
   217  func setType(n ir.Node, typ *types.Type) {
   218  	n.SetType(typ)
   219  	n.SetTypecheck(1)
   220  }
   221  
   222  func setValue(name *ir.Name, val constant.Value) {
   223  	name.SetVal(val)
   224  	name.Defn = nil
   225  }
   226  
   227  // @@@ Positions
   228  
   229  // pos reads a position from the bitstream.
   230  func (r *reader) pos() src.XPos {
   231  	return base.Ctxt.PosTable.XPos(r.pos0())
   232  }
   233  
   234  // origPos reads a position from the bitstream, and returns both the
   235  // original raw position and an inlining-adjusted position.
   236  func (r *reader) origPos() (origPos, inlPos src.XPos) {
   237  	r.suppressInlPos++
   238  	origPos = r.pos()
   239  	r.suppressInlPos--
   240  	inlPos = r.inlPos(origPos)
   241  	return
   242  }
   243  
   244  func (r *reader) pos0() src.Pos {
   245  	r.Sync(pkgbits.SyncPos)
   246  	if !r.Bool() {
   247  		return src.NoPos
   248  	}
   249  
   250  	posBase := r.posBase()
   251  	line := r.Uint()
   252  	col := r.Uint()
   253  	return src.MakePos(posBase, line, col)
   254  }
   255  
   256  // posBase reads a position base from the bitstream.
   257  func (r *reader) posBase() *src.PosBase {
   258  	return r.inlPosBase(r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)))
   259  }
   260  
   261  // posBaseIdx returns the specified position base, reading it first if
   262  // needed.
   263  func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *src.PosBase {
   264  	if b := pr.posBases[idx]; b != nil {
   265  		return b
   266  	}
   267  
   268  	r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
   269  	var b *src.PosBase
   270  
   271  	absFilename := r.String()
   272  	filename := absFilename
   273  
   274  	// For build artifact stability, the export data format only
   275  	// contains the "absolute" filename as returned by objabi.AbsFile.
   276  	// However, some tests (e.g., test/run.go's asmcheck tests) expect
   277  	// to see the full, original filename printed out. Re-expanding
   278  	// "$GOROOT" to buildcfg.GOROOT is a close-enough approximation to
   279  	// satisfy this.
   280  	//
   281  	// TODO(mdempsky): De-duplicate this logic with similar logic in
   282  	// cmd/link/internal/ld's expandGoroot. However, this will probably
   283  	// require being more consistent about when we use native vs UNIX
   284  	// file paths.
   285  	const dollarGOROOT = "$GOROOT"
   286  	if buildcfg.GOROOT != "" && strings.HasPrefix(filename, dollarGOROOT) {
   287  		filename = buildcfg.GOROOT + filename[len(dollarGOROOT):]
   288  	}
   289  
   290  	if r.Bool() {
   291  		b = src.NewFileBase(filename, absFilename)
   292  	} else {
   293  		pos := r.pos0()
   294  		line := r.Uint()
   295  		col := r.Uint()
   296  		b = src.NewLinePragmaBase(pos, filename, absFilename, line, col)
   297  	}
   298  
   299  	pr.posBases[idx] = b
   300  	return b
   301  }
   302  
   303  // inlPosBase returns the inlining-adjusted src.PosBase corresponding
   304  // to oldBase, which must be a non-inlined position. When not
   305  // inlining, this is just oldBase.
   306  func (r *reader) inlPosBase(oldBase *src.PosBase) *src.PosBase {
   307  	if index := oldBase.InliningIndex(); index >= 0 {
   308  		base.Fatalf("oldBase %v already has inlining index %v", oldBase, index)
   309  	}
   310  
   311  	if r.inlCall == nil || r.suppressInlPos != 0 {
   312  		return oldBase
   313  	}
   314  
   315  	if newBase, ok := r.inlPosBases[oldBase]; ok {
   316  		return newBase
   317  	}
   318  
   319  	newBase := src.NewInliningBase(oldBase, r.inlTreeIndex)
   320  	r.inlPosBases[oldBase] = newBase
   321  	return newBase
   322  }
   323  
   324  // inlPos returns the inlining-adjusted src.XPos corresponding to
   325  // xpos, which must be a non-inlined position. When not inlining, this
   326  // is just xpos.
   327  func (r *reader) inlPos(xpos src.XPos) src.XPos {
   328  	pos := base.Ctxt.PosTable.Pos(xpos)
   329  	pos.SetBase(r.inlPosBase(pos.Base()))
   330  	return base.Ctxt.PosTable.XPos(pos)
   331  }
   332  
   333  // @@@ Packages
   334  
   335  // pkg reads a package reference from the bitstream.
   336  func (r *reader) pkg() *types.Pkg {
   337  	r.Sync(pkgbits.SyncPkg)
   338  	return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
   339  }
   340  
   341  // pkgIdx returns the specified package from the export data, reading
   342  // it first if needed.
   343  func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Pkg {
   344  	if pkg := pr.pkgs[idx]; pkg != nil {
   345  		return pkg
   346  	}
   347  
   348  	pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
   349  	pr.pkgs[idx] = pkg
   350  	return pkg
   351  }
   352  
   353  // doPkg reads a package definition from the bitstream.
   354  func (r *reader) doPkg() *types.Pkg {
   355  	path := r.String()
   356  	switch path {
   357  	case "":
   358  		path = r.p.PkgPath()
   359  	case "builtin":
   360  		return types.BuiltinPkg
   361  	case "unsafe":
   362  		return types.UnsafePkg
   363  	}
   364  
   365  	name := r.String()
   366  
   367  	pkg := types.NewPkg(path, "")
   368  
   369  	if pkg.Name == "" {
   370  		pkg.Name = name
   371  	} else {
   372  		base.Assertf(pkg.Name == name, "package %q has name %q, but want %q", pkg.Path, pkg.Name, name)
   373  	}
   374  
   375  	return pkg
   376  }
   377  
   378  // @@@ Types
   379  
   380  func (r *reader) typ() *types.Type {
   381  	return r.typWrapped(true)
   382  }
   383  
   384  // typWrapped is like typ, but allows suppressing generation of
   385  // unnecessary wrappers as a compile-time optimization.
   386  func (r *reader) typWrapped(wrapped bool) *types.Type {
   387  	return r.p.typIdx(r.typInfo(), r.dict, wrapped)
   388  }
   389  
   390  func (r *reader) typInfo() typeInfo {
   391  	r.Sync(pkgbits.SyncType)
   392  	if r.Bool() {
   393  		return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
   394  	}
   395  	return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
   396  }
   397  
   398  // typListIdx returns a list of the specified types, resolving derived
   399  // types within the given dictionary.
   400  func (pr *pkgReader) typListIdx(infos []typeInfo, dict *readerDict) []*types.Type {
   401  	typs := make([]*types.Type, len(infos))
   402  	for i, info := range infos {
   403  		typs[i] = pr.typIdx(info, dict, true)
   404  	}
   405  	return typs
   406  }
   407  
   408  // typIdx returns the specified type. If info specifies a derived
   409  // type, it's resolved within the given dictionary. If wrapped is
   410  // true, then method wrappers will be generated, if appropriate.
   411  func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict, wrapped bool) *types.Type {
   412  	idx := info.idx
   413  	var where **types.Type
   414  	if info.derived {
   415  		where = &dict.derivedTypes[idx]
   416  		idx = dict.derived[idx].idx
   417  	} else {
   418  		where = &pr.typs[idx]
   419  	}
   420  
   421  	if typ := *where; typ != nil {
   422  		return typ
   423  	}
   424  
   425  	r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
   426  	r.dict = dict
   427  
   428  	typ := r.doTyp()
   429  	assert(typ != nil)
   430  
   431  	// For recursive type declarations involving interfaces and aliases,
   432  	// above r.doTyp() call may have already set pr.typs[idx], so just
   433  	// double check and return the type.
   434  	//
   435  	// Example:
   436  	//
   437  	//     type F = func(I)
   438  	//
   439  	//     type I interface {
   440  	//         m(F)
   441  	//     }
   442  	//
   443  	// The writer writes data types in following index order:
   444  	//
   445  	//     0: func(I)
   446  	//     1: I
   447  	//     2: interface{m(func(I))}
   448  	//
   449  	// The reader resolves it in following index order:
   450  	//
   451  	//     0 -> 1 -> 2 -> 0 -> 1
   452  	//
   453  	// and can divide in logically 2 steps:
   454  	//
   455  	//  - 0 -> 1     : first time the reader reach type I,
   456  	//                 it creates new named type with symbol I.
   457  	//
   458  	//  - 2 -> 0 -> 1: the reader ends up reaching symbol I again,
   459  	//                 now the symbol I was setup in above step, so
   460  	//                 the reader just return the named type.
   461  	//
   462  	// Now, the functions called return, the pr.typs looks like below:
   463  	//
   464  	//  - 0 -> 1 -> 2 -> 0 : [<T> I <T>]
   465  	//  - 0 -> 1 -> 2      : [func(I) I <T>]
   466  	//  - 0 -> 1           : [func(I) I interface { "".m(func("".I)) }]
   467  	//
   468  	// The idx 1, corresponding with type I was resolved successfully
   469  	// after r.doTyp() call.
   470  
   471  	if prev := *where; prev != nil {
   472  		return prev
   473  	}
   474  
   475  	if wrapped {
   476  		// Only cache if we're adding wrappers, so that other callers that
   477  		// find a cached type know it was wrapped.
   478  		*where = typ
   479  
   480  		r.needWrapper(typ)
   481  	}
   482  
   483  	if !typ.IsUntyped() {
   484  		types.CheckSize(typ)
   485  	}
   486  
   487  	return typ
   488  }
   489  
   490  func (r *reader) doTyp() *types.Type {
   491  	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
   492  	default:
   493  		panic(fmt.Sprintf("unexpected type: %v", tag))
   494  
   495  	case pkgbits.TypeBasic:
   496  		return *basics[r.Len()]
   497  
   498  	case pkgbits.TypeNamed:
   499  		obj := r.obj()
   500  		assert(obj.Op() == ir.OTYPE)
   501  		return obj.Type()
   502  
   503  	case pkgbits.TypeTypeParam:
   504  		return r.dict.targs[r.Len()]
   505  
   506  	case pkgbits.TypeArray:
   507  		len := int64(r.Uint64())
   508  		return types.NewArray(r.typ(), len)
   509  	case pkgbits.TypeChan:
   510  		dir := dirs[r.Len()]
   511  		return types.NewChan(r.typ(), dir)
   512  	case pkgbits.TypeMap:
   513  		return types.NewMap(r.typ(), r.typ())
   514  	case pkgbits.TypePointer:
   515  		return types.NewPtr(r.typ())
   516  	case pkgbits.TypeSignature:
   517  		return r.signature(types.LocalPkg, nil)
   518  	case pkgbits.TypeSlice:
   519  		return types.NewSlice(r.typ())
   520  	case pkgbits.TypeStruct:
   521  		return r.structType()
   522  	case pkgbits.TypeInterface:
   523  		return r.interfaceType()
   524  	case pkgbits.TypeUnion:
   525  		return r.unionType()
   526  	}
   527  }
   528  
   529  func (r *reader) unionType() *types.Type {
   530  	// In the types1 universe, we only need to handle value types.
   531  	// Impure interfaces (i.e., interfaces with non-trivial type sets
   532  	// like "int | string") can only appear as type parameter bounds,
   533  	// and this is enforced by the types2 type checker.
   534  	//
   535  	// However, type unions can still appear in pure interfaces if the
   536  	// type union is equivalent to "any". E.g., typeparam/issue52124.go
   537  	// declares variables with the type "interface { any | int }".
   538  	//
   539  	// To avoid needing to represent type unions in types1 (since we
   540  	// don't have any uses for that today anyway), we simply fold them
   541  	// to "any". As a consistency check, we still read the union terms
   542  	// to make sure this substitution is safe.
   543  
   544  	pure := false
   545  	for i, n := 0, r.Len(); i < n; i++ {
   546  		_ = r.Bool() // tilde
   547  		term := r.typ()
   548  		if term.IsEmptyInterface() {
   549  			pure = true
   550  		}
   551  	}
   552  	if !pure {
   553  		base.Fatalf("impure type set used in value type")
   554  	}
   555  
   556  	return types.Types[types.TINTER]
   557  }
   558  
   559  func (r *reader) interfaceType() *types.Type {
   560  	tpkg := types.LocalPkg // TODO(mdempsky): Remove after iexport is gone.
   561  
   562  	nmethods, nembeddeds := r.Len(), r.Len()
   563  	implicit := nmethods == 0 && nembeddeds == 1 && r.Bool()
   564  	assert(!implicit) // implicit interfaces only appear in constraints
   565  
   566  	fields := make([]*types.Field, nmethods+nembeddeds)
   567  	methods, embeddeds := fields[:nmethods], fields[nmethods:]
   568  
   569  	for i := range methods {
   570  		pos := r.pos()
   571  		pkg, sym := r.selector()
   572  		tpkg = pkg
   573  		mtyp := r.signature(pkg, types.FakeRecv())
   574  		methods[i] = types.NewField(pos, sym, mtyp)
   575  	}
   576  	for i := range embeddeds {
   577  		embeddeds[i] = types.NewField(src.NoXPos, nil, r.typ())
   578  	}
   579  
   580  	if len(fields) == 0 {
   581  		return types.Types[types.TINTER] // empty interface
   582  	}
   583  	return types.NewInterface(tpkg, fields, false)
   584  }
   585  
   586  func (r *reader) structType() *types.Type {
   587  	tpkg := types.LocalPkg // TODO(mdempsky): Remove after iexport is gone.
   588  	fields := make([]*types.Field, r.Len())
   589  	for i := range fields {
   590  		pos := r.pos()
   591  		pkg, sym := r.selector()
   592  		tpkg = pkg
   593  		ftyp := r.typ()
   594  		tag := r.String()
   595  		embedded := r.Bool()
   596  
   597  		f := types.NewField(pos, sym, ftyp)
   598  		f.Note = tag
   599  		if embedded {
   600  			f.Embedded = 1
   601  		}
   602  		fields[i] = f
   603  	}
   604  	return types.NewStruct(tpkg, fields)
   605  }
   606  
   607  func (r *reader) signature(tpkg *types.Pkg, recv *types.Field) *types.Type {
   608  	r.Sync(pkgbits.SyncSignature)
   609  
   610  	params := r.params(&tpkg)
   611  	results := r.params(&tpkg)
   612  	if r.Bool() { // variadic
   613  		params[len(params)-1].SetIsDDD(true)
   614  	}
   615  
   616  	return types.NewSignature(tpkg, recv, nil, params, results)
   617  }
   618  
   619  func (r *reader) params(tpkg **types.Pkg) []*types.Field {
   620  	r.Sync(pkgbits.SyncParams)
   621  	fields := make([]*types.Field, r.Len())
   622  	for i := range fields {
   623  		*tpkg, fields[i] = r.param()
   624  	}
   625  	return fields
   626  }
   627  
   628  func (r *reader) param() (*types.Pkg, *types.Field) {
   629  	r.Sync(pkgbits.SyncParam)
   630  
   631  	pos := r.pos()
   632  	pkg, sym := r.localIdent()
   633  	typ := r.typ()
   634  
   635  	return pkg, types.NewField(pos, sym, typ)
   636  }
   637  
   638  // @@@ Objects
   639  
   640  // objReader maps qualified identifiers (represented as *types.Sym) to
   641  // a pkgReader and corresponding index that can be used for reading
   642  // that object's definition.
   643  var objReader = map[*types.Sym]pkgReaderIndex{}
   644  
   645  // obj reads an instantiated object reference from the bitstream.
   646  func (r *reader) obj() ir.Node {
   647  	return r.p.objInstIdx(r.objInfo(), r.dict, false)
   648  }
   649  
   650  // objInfo reads an instantiated object reference from the bitstream
   651  // and returns the encoded reference to it, without instantiating it.
   652  func (r *reader) objInfo() objInfo {
   653  	r.Sync(pkgbits.SyncObject)
   654  	assert(!r.Bool()) // TODO(mdempsky): Remove; was derived func inst.
   655  	idx := r.Reloc(pkgbits.RelocObj)
   656  
   657  	explicits := make([]typeInfo, r.Len())
   658  	for i := range explicits {
   659  		explicits[i] = r.typInfo()
   660  	}
   661  
   662  	return objInfo{idx, explicits}
   663  }
   664  
   665  // objInstIdx returns the encoded, instantiated object. If shaped is
   666  // true, then the shaped variant of the object is returned instead.
   667  func (pr *pkgReader) objInstIdx(info objInfo, dict *readerDict, shaped bool) ir.Node {
   668  	explicits := pr.typListIdx(info.explicits, dict)
   669  
   670  	var implicits []*types.Type
   671  	if dict != nil {
   672  		implicits = dict.targs
   673  	}
   674  
   675  	return pr.objIdx(info.idx, implicits, explicits, shaped)
   676  }
   677  
   678  // objIdx returns the specified object, instantiated with the given
   679  // type arguments, if any. If shaped is true, then the shaped variant
   680  // of the object is returned instead.
   681  func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) ir.Node {
   682  	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
   683  	_, sym := rname.qualifiedIdent()
   684  	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
   685  
   686  	if tag == pkgbits.ObjStub {
   687  		assert(!sym.IsBlank())
   688  		switch sym.Pkg {
   689  		case types.BuiltinPkg, types.UnsafePkg:
   690  			return sym.Def.(ir.Node)
   691  		}
   692  		if pri, ok := objReader[sym]; ok {
   693  			return pri.pr.objIdx(pri.idx, nil, explicits, shaped)
   694  		}
   695  		base.Fatalf("unresolved stub: %v", sym)
   696  	}
   697  
   698  	dict := pr.objDictIdx(sym, idx, implicits, explicits, shaped)
   699  
   700  	sym = dict.baseSym
   701  	if !sym.IsBlank() && sym.Def != nil {
   702  		return sym.Def.(*ir.Name)
   703  	}
   704  
   705  	r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
   706  	rext := pr.newReader(pkgbits.RelocObjExt, idx, pkgbits.SyncObject1)
   707  
   708  	r.dict = dict
   709  	rext.dict = dict
   710  
   711  	do := func(op ir.Op, hasTParams bool) *ir.Name {
   712  		pos := r.pos()
   713  		setBasePos(pos)
   714  		if hasTParams {
   715  			r.typeParamNames()
   716  		}
   717  
   718  		name := ir.NewDeclNameAt(pos, op, sym)
   719  		name.Class = ir.PEXTERN // may be overridden later
   720  		if !sym.IsBlank() {
   721  			if sym.Def != nil {
   722  				base.FatalfAt(name.Pos(), "already have a definition for %v", name)
   723  			}
   724  			assert(sym.Def == nil)
   725  			sym.Def = name
   726  		}
   727  		return name
   728  	}
   729  
   730  	switch tag {
   731  	default:
   732  		panic("unexpected object")
   733  
   734  	case pkgbits.ObjAlias:
   735  		name := do(ir.OTYPE, false)
   736  		setType(name, r.typ())
   737  		name.SetAlias(true)
   738  		return name
   739  
   740  	case pkgbits.ObjConst:
   741  		name := do(ir.OLITERAL, false)
   742  		typ := r.typ()
   743  		val := FixValue(typ, r.Value())
   744  		setType(name, typ)
   745  		setValue(name, val)
   746  		return name
   747  
   748  	case pkgbits.ObjFunc:
   749  		if sym.Name == "init" {
   750  			sym = Renameinit()
   751  		}
   752  		name := do(ir.ONAME, true)
   753  		setType(name, r.signature(sym.Pkg, nil))
   754  
   755  		name.Func = ir.NewFunc(r.pos())
   756  		name.Func.Nname = name
   757  
   758  		if r.hasTypeParams() {
   759  			name.Func.SetDupok(true)
   760  			if r.dict.shaped {
   761  				setType(name, shapeSig(name.Func, r.dict))
   762  			} else {
   763  				todoDicts = append(todoDicts, func() {
   764  					r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
   765  				})
   766  			}
   767  		}
   768  
   769  		rext.funcExt(name, nil)
   770  		return name
   771  
   772  	case pkgbits.ObjType:
   773  		name := do(ir.OTYPE, true)
   774  		typ := types.NewNamed(name)
   775  		setType(name, typ)
   776  		if r.hasTypeParams() && r.dict.shaped {
   777  			typ.SetHasShape(true)
   778  		}
   779  
   780  		// Important: We need to do this before SetUnderlying.
   781  		rext.typeExt(name)
   782  
   783  		// We need to defer CheckSize until we've called SetUnderlying to
   784  		// handle recursive types.
   785  		types.DeferCheckSize()
   786  		typ.SetUnderlying(r.typWrapped(false))
   787  		types.ResumeCheckSize()
   788  
   789  		if r.hasTypeParams() && !r.dict.shaped {
   790  			todoDicts = append(todoDicts, func() {
   791  				r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
   792  			})
   793  		}
   794  
   795  		methods := make([]*types.Field, r.Len())
   796  		for i := range methods {
   797  			methods[i] = r.method(rext)
   798  		}
   799  		if len(methods) != 0 {
   800  			typ.Methods().Set(methods)
   801  		}
   802  
   803  		if !r.dict.shaped {
   804  			r.needWrapper(typ)
   805  		}
   806  
   807  		return name
   808  
   809  	case pkgbits.ObjVar:
   810  		name := do(ir.ONAME, false)
   811  		setType(name, r.typ())
   812  		rext.varExt(name)
   813  		return name
   814  	}
   815  }
   816  
   817  func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
   818  	if !dict.hasTypeParams() {
   819  		return sym
   820  	}
   821  
   822  	// If sym is a locally defined generic type, we need the suffix to
   823  	// stay at the end after mangling so that types/fmt.go can strip it
   824  	// out again when writing the type's runtime descriptor (#54456).
   825  	base, suffix := types.SplitVargenSuffix(sym.Name)
   826  
   827  	var buf strings.Builder
   828  	buf.WriteString(base)
   829  	buf.WriteByte('[')
   830  	for i, targ := range dict.targs {
   831  		if i > 0 {
   832  			if i == dict.implicits {
   833  				buf.WriteByte(';')
   834  			} else {
   835  				buf.WriteByte(',')
   836  			}
   837  		}
   838  		buf.WriteString(targ.LinkString())
   839  	}
   840  	buf.WriteByte(']')
   841  	buf.WriteString(suffix)
   842  	return sym.Pkg.Lookup(buf.String())
   843  }
   844  
   845  // shapify returns the shape type for targ.
   846  //
   847  // If basic is true, then the type argument is used to instantiate a
   848  // type parameter whose constraint is a basic interface.
   849  func shapify(targ *types.Type, basic bool) *types.Type {
   850  	if targ.Kind() == types.TFORW {
   851  		if targ.IsFullyInstantiated() {
   852  			// For recursive instantiated type argument, it may  still be a TFORW
   853  			// when shapifying happens. If we don't have targ's underlying type,
   854  			// shapify won't work. The worst case is we end up not reusing code
   855  			// optimally in some tricky cases.
   856  			if base.Debug.Shapify != 0 {
   857  				base.Warn("skipping shaping of recursive type %v", targ)
   858  			}
   859  			if targ.HasShape() {
   860  				return targ
   861  			}
   862  		} else {
   863  			base.Fatalf("%v is missing its underlying type", targ)
   864  		}
   865  	}
   866  
   867  	// When a pointer type is used to instantiate a type parameter
   868  	// constrained by a basic interface, we know the pointer's element
   869  	// type can't matter to the generated code. In this case, we can use
   870  	// an arbitrary pointer type as the shape type. (To match the
   871  	// non-unified frontend, we use `*byte`.)
   872  	//
   873  	// Otherwise, we simply use the type's underlying type as its shape.
   874  	//
   875  	// TODO(mdempsky): It should be possible to do much more aggressive
   876  	// shaping still; e.g., collapsing all pointer-shaped types into a
   877  	// common type, collapsing scalars of the same size/alignment into a
   878  	// common type, recursively shaping the element types of composite
   879  	// types, and discarding struct field names and tags. However, we'll
   880  	// need to start tracking how type parameters are actually used to
   881  	// implement some of these optimizations.
   882  	under := targ.Underlying()
   883  	if basic && targ.IsPtr() && !targ.Elem().NotInHeap() {
   884  		under = types.NewPtr(types.Types[types.TUINT8])
   885  	}
   886  
   887  	sym := types.ShapePkg.Lookup(under.LinkString())
   888  	if sym.Def == nil {
   889  		name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
   890  		typ := types.NewNamed(name)
   891  		typ.SetUnderlying(under)
   892  		sym.Def = typed(typ, name)
   893  	}
   894  	res := sym.Def.Type()
   895  	assert(res.IsShape())
   896  	assert(res.HasShape())
   897  	return res
   898  }
   899  
   900  // objDictIdx reads and returns the specified object dictionary.
   901  func (pr *pkgReader) objDictIdx(sym *types.Sym, idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) *readerDict {
   902  	r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
   903  
   904  	dict := readerDict{
   905  		shaped: shaped,
   906  	}
   907  
   908  	nimplicits := r.Len()
   909  	nexplicits := r.Len()
   910  
   911  	if nimplicits > len(implicits) || nexplicits != len(explicits) {
   912  		base.Fatalf("%v has %v+%v params, but instantiated with %v+%v args", sym, nimplicits, nexplicits, len(implicits), len(explicits))
   913  	}
   914  
   915  	dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
   916  	dict.implicits = nimplicits
   917  
   918  	// Within the compiler, we can just skip over the type parameters.
   919  	for range dict.targs[dict.implicits:] {
   920  		// Skip past bounds without actually evaluating them.
   921  		r.typInfo()
   922  	}
   923  
   924  	dict.derived = make([]derivedInfo, r.Len())
   925  	dict.derivedTypes = make([]*types.Type, len(dict.derived))
   926  	for i := range dict.derived {
   927  		dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
   928  	}
   929  
   930  	// Runtime dictionary information; private to the compiler.
   931  
   932  	// If any type argument is already shaped, then we're constructing a
   933  	// shaped object, even if not explicitly requested (i.e., calling
   934  	// objIdx with shaped==true). This can happen with instantiating
   935  	// types that are referenced within a function body.
   936  	for _, targ := range dict.targs {
   937  		if targ.HasShape() {
   938  			dict.shaped = true
   939  			break
   940  		}
   941  	}
   942  
   943  	// And if we're constructing a shaped object, then shapify all type
   944  	// arguments.
   945  	for i, targ := range dict.targs {
   946  		basic := r.Bool()
   947  		if dict.shaped {
   948  			dict.targs[i] = shapify(targ, basic)
   949  		}
   950  	}
   951  
   952  	dict.baseSym = dict.mangle(sym)
   953  
   954  	dict.typeParamMethodExprs = make([]readerMethodExprInfo, r.Len())
   955  	for i := range dict.typeParamMethodExprs {
   956  		typeParamIdx := r.Len()
   957  		_, method := r.selector()
   958  
   959  		dict.typeParamMethodExprs[i] = readerMethodExprInfo{typeParamIdx, method}
   960  	}
   961  
   962  	dict.subdicts = make([]objInfo, r.Len())
   963  	for i := range dict.subdicts {
   964  		dict.subdicts[i] = r.objInfo()
   965  	}
   966  
   967  	dict.rtypes = make([]typeInfo, r.Len())
   968  	for i := range dict.rtypes {
   969  		dict.rtypes[i] = r.typInfo()
   970  	}
   971  
   972  	dict.itabs = make([]itabInfo, r.Len())
   973  	for i := range dict.itabs {
   974  		dict.itabs[i] = itabInfo{typ: r.typInfo(), iface: r.typInfo()}
   975  	}
   976  
   977  	return &dict
   978  }
   979  
   980  func (r *reader) typeParamNames() {
   981  	r.Sync(pkgbits.SyncTypeParamNames)
   982  
   983  	for range r.dict.targs[r.dict.implicits:] {
   984  		r.pos()
   985  		r.localIdent()
   986  	}
   987  }
   988  
   989  func (r *reader) method(rext *reader) *types.Field {
   990  	r.Sync(pkgbits.SyncMethod)
   991  	pos := r.pos()
   992  	pkg, sym := r.selector()
   993  	r.typeParamNames()
   994  	_, recv := r.param()
   995  	typ := r.signature(pkg, recv)
   996  
   997  	name := ir.NewNameAt(pos, ir.MethodSym(recv.Type, sym))
   998  	setType(name, typ)
   999  
  1000  	name.Func = ir.NewFunc(r.pos())
  1001  	name.Func.Nname = name
  1002  
  1003  	if r.hasTypeParams() {
  1004  		name.Func.SetDupok(true)
  1005  		if r.dict.shaped {
  1006  			typ = shapeSig(name.Func, r.dict)
  1007  			setType(name, typ)
  1008  		}
  1009  	}
  1010  
  1011  	rext.funcExt(name, sym)
  1012  
  1013  	meth := types.NewField(name.Func.Pos(), sym, typ)
  1014  	meth.Nname = name
  1015  	meth.SetNointerface(name.Func.Pragma&ir.Nointerface != 0)
  1016  
  1017  	return meth
  1018  }
  1019  
  1020  func (r *reader) qualifiedIdent() (pkg *types.Pkg, sym *types.Sym) {
  1021  	r.Sync(pkgbits.SyncSym)
  1022  	pkg = r.pkg()
  1023  	if name := r.String(); name != "" {
  1024  		sym = pkg.Lookup(name)
  1025  	}
  1026  	return
  1027  }
  1028  
  1029  func (r *reader) localIdent() (pkg *types.Pkg, sym *types.Sym) {
  1030  	r.Sync(pkgbits.SyncLocalIdent)
  1031  	pkg = r.pkg()
  1032  	if name := r.String(); name != "" {
  1033  		sym = pkg.Lookup(name)
  1034  	}
  1035  	return
  1036  }
  1037  
  1038  func (r *reader) selector() (origPkg *types.Pkg, sym *types.Sym) {
  1039  	r.Sync(pkgbits.SyncSelector)
  1040  	origPkg = r.pkg()
  1041  	name := r.String()
  1042  	pkg := origPkg
  1043  	if types.IsExported(name) {
  1044  		pkg = types.LocalPkg
  1045  	}
  1046  	sym = pkg.Lookup(name)
  1047  	return
  1048  }
  1049  
  1050  func (r *reader) hasTypeParams() bool {
  1051  	return r.dict.hasTypeParams()
  1052  }
  1053  
  1054  func (dict *readerDict) hasTypeParams() bool {
  1055  	return dict != nil && len(dict.targs) != 0
  1056  }
  1057  
  1058  // @@@ Compiler extensions
  1059  
  1060  func (r *reader) funcExt(name *ir.Name, method *types.Sym) {
  1061  	r.Sync(pkgbits.SyncFuncExt)
  1062  
  1063  	name.Class = 0 // so MarkFunc doesn't complain
  1064  	ir.MarkFunc(name)
  1065  
  1066  	fn := name.Func
  1067  
  1068  	// XXX: Workaround because linker doesn't know how to copy Pos.
  1069  	if !fn.Pos().IsKnown() {
  1070  		fn.SetPos(name.Pos())
  1071  	}
  1072  
  1073  	// Normally, we only compile local functions, which saves redundant compilation work.
  1074  	// n.Defn is not nil for local functions, and is nil for imported function. But for
  1075  	// generic functions, we might have an instantiation that no other package has seen before.
  1076  	// So we need to be conservative and compile it again.
  1077  	//
  1078  	// That's why name.Defn is set here, so ir.VisitFuncsBottomUp can analyze function.
  1079  	// TODO(mdempsky,cuonglm): find a cleaner way to handle this.
  1080  	if name.Sym().Pkg == types.LocalPkg || r.hasTypeParams() {
  1081  		name.Defn = fn
  1082  	}
  1083  
  1084  	fn.Pragma = r.pragmaFlag()
  1085  	r.linkname(name)
  1086  
  1087  	typecheck.Func(fn)
  1088  
  1089  	if r.Bool() {
  1090  		assert(name.Defn == nil)
  1091  
  1092  		fn.ABI = obj.ABI(r.Uint64())
  1093  
  1094  		// Escape analysis.
  1095  		for _, fs := range &types.RecvsParams {
  1096  			for _, f := range fs(name.Type()).FieldSlice() {
  1097  				f.Note = r.String()
  1098  			}
  1099  		}
  1100  
  1101  		if r.Bool() {
  1102  			fn.Inl = &ir.Inline{
  1103  				Cost:            int32(r.Len()),
  1104  				CanDelayResults: r.Bool(),
  1105  			}
  1106  		}
  1107  	} else {
  1108  		r.addBody(name.Func, method)
  1109  	}
  1110  	r.Sync(pkgbits.SyncEOF)
  1111  }
  1112  
  1113  func (r *reader) typeExt(name *ir.Name) {
  1114  	r.Sync(pkgbits.SyncTypeExt)
  1115  
  1116  	typ := name.Type()
  1117  
  1118  	if r.hasTypeParams() {
  1119  		// Set "RParams" (really type arguments here, not parameters) so
  1120  		// this type is treated as "fully instantiated". This ensures the
  1121  		// type descriptor is written out as DUPOK and method wrappers are
  1122  		// generated even for imported types.
  1123  		var targs []*types.Type
  1124  		targs = append(targs, r.dict.targs...)
  1125  		typ.SetRParams(targs)
  1126  	}
  1127  
  1128  	name.SetPragma(r.pragmaFlag())
  1129  
  1130  	typecheck.SetBaseTypeIndex(typ, r.Int64(), r.Int64())
  1131  }
  1132  
  1133  func (r *reader) varExt(name *ir.Name) {
  1134  	r.Sync(pkgbits.SyncVarExt)
  1135  	r.linkname(name)
  1136  }
  1137  
  1138  func (r *reader) linkname(name *ir.Name) {
  1139  	assert(name.Op() == ir.ONAME)
  1140  	r.Sync(pkgbits.SyncLinkname)
  1141  
  1142  	if idx := r.Int64(); idx >= 0 {
  1143  		lsym := name.Linksym()
  1144  		lsym.SymIdx = int32(idx)
  1145  		lsym.Set(obj.AttrIndexed, true)
  1146  	} else {
  1147  		name.Sym().Linkname = r.String()
  1148  	}
  1149  }
  1150  
  1151  func (r *reader) pragmaFlag() ir.PragmaFlag {
  1152  	r.Sync(pkgbits.SyncPragma)
  1153  	return ir.PragmaFlag(r.Int())
  1154  }
  1155  
  1156  // @@@ Function bodies
  1157  
  1158  // bodyReader tracks where the serialized IR for a local or imported,
  1159  // generic function's body can be found.
  1160  var bodyReader = map[*ir.Func]pkgReaderIndex{}
  1161  
  1162  // importBodyReader tracks where the serialized IR for an imported,
  1163  // static (i.e., non-generic) function body can be read.
  1164  var importBodyReader = map[*types.Sym]pkgReaderIndex{}
  1165  
  1166  // bodyReaderFor returns the pkgReaderIndex for reading fn's
  1167  // serialized IR, and whether one was found.
  1168  func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) {
  1169  	if fn.Nname.Defn != nil {
  1170  		pri, ok = bodyReader[fn]
  1171  		base.AssertfAt(ok, base.Pos, "must have bodyReader for %v", fn) // must always be available
  1172  	} else {
  1173  		pri, ok = importBodyReader[fn.Sym()]
  1174  	}
  1175  	return
  1176  }
  1177  
  1178  // todoDicts holds the list of dictionaries that still need their
  1179  // runtime dictionary objects constructed.
  1180  var todoDicts []func()
  1181  
  1182  // todoBodies holds the list of function bodies that still need to be
  1183  // constructed.
  1184  var todoBodies []*ir.Func
  1185  
  1186  // addBody reads a function body reference from the element bitstream,
  1187  // and associates it with fn.
  1188  func (r *reader) addBody(fn *ir.Func, method *types.Sym) {
  1189  	// addBody should only be called for local functions or imported
  1190  	// generic functions; see comment in funcExt.
  1191  	assert(fn.Nname.Defn != nil)
  1192  
  1193  	idx := r.Reloc(pkgbits.RelocBody)
  1194  
  1195  	pri := pkgReaderIndex{r.p, idx, r.dict, method, nil}
  1196  	bodyReader[fn] = pri
  1197  
  1198  	if r.curfn == nil {
  1199  		todoBodies = append(todoBodies, fn)
  1200  		return
  1201  	}
  1202  
  1203  	pri.funcBody(fn)
  1204  }
  1205  
  1206  func (pri pkgReaderIndex) funcBody(fn *ir.Func) {
  1207  	r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
  1208  	r.funcBody(fn)
  1209  }
  1210  
  1211  // funcBody reads a function body definition from the element
  1212  // bitstream, and populates fn with it.
  1213  func (r *reader) funcBody(fn *ir.Func) {
  1214  	r.curfn = fn
  1215  	r.closureVars = fn.ClosureVars
  1216  	if len(r.closureVars) != 0 && r.hasTypeParams() {
  1217  		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
  1218  	}
  1219  
  1220  	ir.WithFunc(fn, func() {
  1221  		r.funcargs(fn)
  1222  
  1223  		if r.syntheticBody(fn.Pos()) {
  1224  			return
  1225  		}
  1226  
  1227  		if !r.Bool() {
  1228  			return
  1229  		}
  1230  
  1231  		body := r.stmts()
  1232  		if body == nil {
  1233  			body = []ir.Node{typecheck.Stmt(ir.NewBlockStmt(src.NoXPos, nil))}
  1234  		}
  1235  		fn.Body = body
  1236  		fn.Endlineno = r.pos()
  1237  	})
  1238  
  1239  	r.marker.WriteTo(fn)
  1240  }
  1241  
  1242  // syntheticBody adds a synthetic body to r.curfn if appropriate, and
  1243  // reports whether it did.
  1244  func (r *reader) syntheticBody(pos src.XPos) bool {
  1245  	if r.synthetic != nil {
  1246  		r.synthetic(pos, r)
  1247  		return true
  1248  	}
  1249  
  1250  	// If this function has type parameters and isn't shaped, then we
  1251  	// just tail call its corresponding shaped variant.
  1252  	if r.hasTypeParams() && !r.dict.shaped {
  1253  		r.callShaped(pos)
  1254  		return true
  1255  	}
  1256  
  1257  	return false
  1258  }
  1259  
  1260  // callShaped emits a tail call to r.shapedFn, passing along the
  1261  // arguments to the current function.
  1262  func (r *reader) callShaped(pos src.XPos) {
  1263  	shapedObj := r.dict.shapedObj
  1264  	assert(shapedObj != nil)
  1265  
  1266  	var shapedFn ir.Node
  1267  	if r.methodSym == nil {
  1268  		// Instantiating a generic function; shapedObj is the shaped
  1269  		// function itself.
  1270  		assert(shapedObj.Op() == ir.ONAME && shapedObj.Class == ir.PFUNC)
  1271  		shapedFn = shapedObj
  1272  	} else {
  1273  		// Instantiating a generic type's method; shapedObj is the shaped
  1274  		// type, so we need to select it's corresponding method.
  1275  		shapedFn = shapedMethodExpr(pos, shapedObj, r.methodSym)
  1276  	}
  1277  
  1278  	recvs, params := r.syntheticArgs(pos)
  1279  
  1280  	// Construct the arguments list: receiver (if any), then runtime
  1281  	// dictionary, and finally normal parameters.
  1282  	//
  1283  	// Note: For simplicity, shaped methods are added as normal methods
  1284  	// on their shaped types. So existing code (e.g., packages ir and
  1285  	// typecheck) expects the shaped type to appear as the receiver
  1286  	// parameter (or first parameter, as a method expression). Hence
  1287  	// putting the dictionary parameter after that is the least invasive
  1288  	// solution at the moment.
  1289  	var args ir.Nodes
  1290  	args.Append(recvs...)
  1291  	args.Append(typecheck.Expr(ir.NewAddrExpr(pos, r.p.dictNameOf(r.dict))))
  1292  	args.Append(params...)
  1293  
  1294  	r.syntheticTailCall(pos, shapedFn, args)
  1295  }
  1296  
  1297  // syntheticArgs returns the recvs and params arguments passed to the
  1298  // current function.
  1299  func (r *reader) syntheticArgs(pos src.XPos) (recvs, params ir.Nodes) {
  1300  	sig := r.curfn.Nname.Type()
  1301  
  1302  	inlVarIdx := 0
  1303  	addParams := func(out *ir.Nodes, params []*types.Field) {
  1304  		for _, param := range params {
  1305  			var arg ir.Node
  1306  			if param.Nname != nil {
  1307  				name := param.Nname.(*ir.Name)
  1308  				if !ir.IsBlank(name) {
  1309  					if r.inlCall != nil {
  1310  						// During inlining, we want the respective inlvar where we
  1311  						// assigned the callee's arguments.
  1312  						arg = r.inlvars[inlVarIdx]
  1313  					} else {
  1314  						// Otherwise, we can use the parameter itself directly.
  1315  						base.AssertfAt(name.Curfn == r.curfn, name.Pos(), "%v has curfn %v, but want %v", name, name.Curfn, r.curfn)
  1316  						arg = name
  1317  					}
  1318  				}
  1319  			}
  1320  
  1321  			// For anonymous and blank parameters, we don't have an *ir.Name
  1322  			// to use as the argument. However, since we know the shaped
  1323  			// function won't use the value either, we can just pass the
  1324  			// zero value. (Also unfortunately, we don't have an easy
  1325  			// zero-value IR node; so we use a default-initialized temporary
  1326  			// variable.)
  1327  			if arg == nil {
  1328  				tmp := typecheck.TempAt(pos, r.curfn, param.Type)
  1329  				r.curfn.Body.Append(
  1330  					typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)),
  1331  					typecheck.Stmt(ir.NewAssignStmt(pos, tmp, nil)),
  1332  				)
  1333  				arg = tmp
  1334  			}
  1335  
  1336  			out.Append(arg)
  1337  			inlVarIdx++
  1338  		}
  1339  	}
  1340  
  1341  	addParams(&recvs, sig.Recvs().FieldSlice())
  1342  	addParams(&params, sig.Params().FieldSlice())
  1343  	return
  1344  }
  1345  
  1346  // syntheticTailCall emits a tail call to fn, passing the given
  1347  // arguments list.
  1348  func (r *reader) syntheticTailCall(pos src.XPos, fn ir.Node, args ir.Nodes) {
  1349  	// Mark the function as a wrapper so it doesn't show up in stack
  1350  	// traces.
  1351  	r.curfn.SetWrapper(true)
  1352  
  1353  	call := typecheck.Call(pos, fn, args, fn.Type().IsVariadic()).(*ir.CallExpr)
  1354  
  1355  	var stmt ir.Node
  1356  	if fn.Type().NumResults() != 0 {
  1357  		stmt = typecheck.Stmt(ir.NewReturnStmt(pos, []ir.Node{call}))
  1358  	} else {
  1359  		stmt = call
  1360  	}
  1361  	r.curfn.Body.Append(stmt)
  1362  }
  1363  
  1364  // dictNameOf returns the runtime dictionary corresponding to dict.
  1365  func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name {
  1366  	pos := base.AutogeneratedPos
  1367  
  1368  	// Check that we only instantiate runtime dictionaries with real types.
  1369  	base.AssertfAt(!dict.shaped, pos, "runtime dictionary of shaped object %v", dict.baseSym)
  1370  
  1371  	sym := dict.baseSym.Pkg.Lookup(objabi.GlobalDictPrefix + "." + dict.baseSym.Name)
  1372  	if sym.Def != nil {
  1373  		return sym.Def.(*ir.Name)
  1374  	}
  1375  
  1376  	name := ir.NewNameAt(pos, sym)
  1377  	name.Class = ir.PEXTERN
  1378  	sym.Def = name // break cycles with mutual subdictionaries
  1379  
  1380  	lsym := name.Linksym()
  1381  	ot := 0
  1382  
  1383  	assertOffset := func(section string, offset int) {
  1384  		base.AssertfAt(ot == offset*types.PtrSize, pos, "writing section %v at offset %v, but it should be at %v*%v", section, ot, offset, types.PtrSize)
  1385  	}
  1386  
  1387  	assertOffset("type param method exprs", dict.typeParamMethodExprsOffset())
  1388  	for _, info := range dict.typeParamMethodExprs {
  1389  		typeParam := dict.targs[info.typeParamIdx]
  1390  		method := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(typeParam), info.method)).(*ir.SelectorExpr)
  1391  		assert(method.Op() == ir.OMETHEXPR)
  1392  
  1393  		rsym := method.FuncName().Linksym()
  1394  		assert(rsym.ABI() == obj.ABIInternal) // must be ABIInternal; see ir.OCFUNC in ssagen/ssa.go
  1395  
  1396  		ot = objw.SymPtr(lsym, ot, rsym, 0)
  1397  	}
  1398  
  1399  	assertOffset("subdictionaries", dict.subdictsOffset())
  1400  	for _, info := range dict.subdicts {
  1401  		explicits := pr.typListIdx(info.explicits, dict)
  1402  
  1403  		// Careful: Due to subdictionary cycles, name may not be fully
  1404  		// initialized yet.
  1405  		name := pr.objDictName(info.idx, dict.targs, explicits)
  1406  
  1407  		ot = objw.SymPtr(lsym, ot, name.Linksym(), 0)
  1408  	}
  1409  
  1410  	assertOffset("rtypes", dict.rtypesOffset())
  1411  	for _, info := range dict.rtypes {
  1412  		typ := pr.typIdx(info, dict, true)
  1413  		ot = objw.SymPtr(lsym, ot, reflectdata.TypeLinksym(typ), 0)
  1414  
  1415  		// TODO(mdempsky): Double check this.
  1416  		reflectdata.MarkTypeUsedInInterface(typ, lsym)
  1417  	}
  1418  
  1419  	// For each (typ, iface) pair, we write the *runtime.itab pointer
  1420  	// for the pair. For pairs that don't actually require an itab
  1421  	// (i.e., typ is an interface, or iface is an empty interface), we
  1422  	// write a nil pointer instead. This is wasteful, but rare in
  1423  	// practice (e.g., instantiating a type parameter with an interface
  1424  	// type).
  1425  	assertOffset("itabs", dict.itabsOffset())
  1426  	for _, info := range dict.itabs {
  1427  		typ := pr.typIdx(info.typ, dict, true)
  1428  		iface := pr.typIdx(info.iface, dict, true)
  1429  
  1430  		if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
  1431  			ot = objw.SymPtr(lsym, ot, reflectdata.ITabLsym(typ, iface), 0)
  1432  		} else {
  1433  			ot += types.PtrSize
  1434  		}
  1435  
  1436  		// TODO(mdempsky): Double check this.
  1437  		reflectdata.MarkTypeUsedInInterface(typ, lsym)
  1438  		reflectdata.MarkTypeUsedInInterface(iface, lsym)
  1439  	}
  1440  
  1441  	objw.Global(lsym, int32(ot), obj.DUPOK|obj.RODATA)
  1442  
  1443  	name.SetType(dict.varType())
  1444  	name.SetTypecheck(1)
  1445  
  1446  	return name
  1447  }
  1448  
  1449  // typeParamMethodExprsOffset returns the offset of the runtime
  1450  // dictionary's type parameter method expressions section, in words.
  1451  func (dict *readerDict) typeParamMethodExprsOffset() int {
  1452  	return 0
  1453  }
  1454  
  1455  // subdictsOffset returns the offset of the runtime dictionary's
  1456  // subdictionary section, in words.
  1457  func (dict *readerDict) subdictsOffset() int {
  1458  	return dict.typeParamMethodExprsOffset() + len(dict.typeParamMethodExprs)
  1459  }
  1460  
  1461  // rtypesOffset returns the offset of the runtime dictionary's rtypes
  1462  // section, in words.
  1463  func (dict *readerDict) rtypesOffset() int {
  1464  	return dict.subdictsOffset() + len(dict.subdicts)
  1465  }
  1466  
  1467  // itabsOffset returns the offset of the runtime dictionary's itabs
  1468  // section, in words.
  1469  func (dict *readerDict) itabsOffset() int {
  1470  	return dict.rtypesOffset() + len(dict.rtypes)
  1471  }
  1472  
  1473  // numWords returns the total number of words that comprise dict's
  1474  // runtime dictionary variable.
  1475  func (dict *readerDict) numWords() int64 {
  1476  	return int64(dict.itabsOffset() + len(dict.itabs))
  1477  }
  1478  
  1479  // varType returns the type of dict's runtime dictionary variable.
  1480  func (dict *readerDict) varType() *types.Type {
  1481  	return types.NewArray(types.Types[types.TUINTPTR], dict.numWords())
  1482  }
  1483  
  1484  func (r *reader) funcargs(fn *ir.Func) {
  1485  	sig := fn.Nname.Type()
  1486  
  1487  	if recv := sig.Recv(); recv != nil {
  1488  		r.funcarg(recv, recv.Sym, ir.PPARAM)
  1489  	}
  1490  	for _, param := range sig.Params().FieldSlice() {
  1491  		r.funcarg(param, param.Sym, ir.PPARAM)
  1492  	}
  1493  
  1494  	for i, param := range sig.Results().FieldSlice() {
  1495  		sym := types.OrigSym(param.Sym)
  1496  
  1497  		if sym == nil || sym.IsBlank() {
  1498  			prefix := "~r"
  1499  			if r.inlCall != nil {
  1500  				prefix = "~R"
  1501  			} else if sym != nil {
  1502  				prefix = "~b"
  1503  			}
  1504  			sym = typecheck.LookupNum(prefix, i)
  1505  		}
  1506  
  1507  		r.funcarg(param, sym, ir.PPARAMOUT)
  1508  	}
  1509  }
  1510  
  1511  func (r *reader) funcarg(param *types.Field, sym *types.Sym, ctxt ir.Class) {
  1512  	if sym == nil {
  1513  		assert(ctxt == ir.PPARAM)
  1514  		if r.inlCall != nil {
  1515  			r.inlvars.Append(ir.BlankNode)
  1516  		}
  1517  		return
  1518  	}
  1519  
  1520  	name := ir.NewNameAt(r.inlPos(param.Pos), sym)
  1521  	setType(name, param.Type)
  1522  	r.addLocal(name, ctxt)
  1523  
  1524  	if r.inlCall == nil {
  1525  		if !r.funarghack {
  1526  			param.Sym = sym
  1527  			param.Nname = name
  1528  		}
  1529  	} else {
  1530  		if ctxt == ir.PPARAMOUT {
  1531  			r.retvars.Append(name)
  1532  		} else {
  1533  			r.inlvars.Append(name)
  1534  		}
  1535  	}
  1536  }
  1537  
  1538  func (r *reader) addLocal(name *ir.Name, ctxt ir.Class) {
  1539  	assert(ctxt == ir.PAUTO || ctxt == ir.PPARAM || ctxt == ir.PPARAMOUT)
  1540  
  1541  	if name.Sym().Name == dictParamName {
  1542  		r.dictParam = name
  1543  	} else {
  1544  		if r.synthetic == nil {
  1545  			r.Sync(pkgbits.SyncAddLocal)
  1546  			if r.p.SyncMarkers() {
  1547  				want := r.Int()
  1548  				if have := len(r.locals); have != want {
  1549  					base.FatalfAt(name.Pos(), "locals table has desynced")
  1550  				}
  1551  			}
  1552  			r.varDictIndex(name)
  1553  		}
  1554  
  1555  		r.locals = append(r.locals, name)
  1556  	}
  1557  
  1558  	name.SetUsed(true)
  1559  
  1560  	// TODO(mdempsky): Move earlier.
  1561  	if ir.IsBlank(name) {
  1562  		return
  1563  	}
  1564  
  1565  	if r.inlCall != nil {
  1566  		if ctxt == ir.PAUTO {
  1567  			name.SetInlLocal(true)
  1568  		} else {
  1569  			name.SetInlFormal(true)
  1570  			ctxt = ir.PAUTO
  1571  		}
  1572  
  1573  		// TODO(mdempsky): Rethink this hack.
  1574  		if strings.HasPrefix(name.Sym().Name, "~") || base.Flag.GenDwarfInl == 0 {
  1575  			name.SetPos(r.inlCall.Pos())
  1576  			name.SetInlFormal(false)
  1577  			name.SetInlLocal(false)
  1578  		}
  1579  	}
  1580  
  1581  	name.Class = ctxt
  1582  	name.Curfn = r.curfn
  1583  
  1584  	r.curfn.Dcl = append(r.curfn.Dcl, name)
  1585  
  1586  	if ctxt == ir.PAUTO {
  1587  		name.SetFrameOffset(0)
  1588  	}
  1589  }
  1590  
  1591  func (r *reader) useLocal() *ir.Name {
  1592  	r.Sync(pkgbits.SyncUseObjLocal)
  1593  	if r.Bool() {
  1594  		return r.locals[r.Len()]
  1595  	}
  1596  	return r.closureVars[r.Len()]
  1597  }
  1598  
  1599  func (r *reader) openScope() {
  1600  	r.Sync(pkgbits.SyncOpenScope)
  1601  	pos := r.pos()
  1602  
  1603  	if base.Flag.Dwarf {
  1604  		r.scopeVars = append(r.scopeVars, len(r.curfn.Dcl))
  1605  		r.marker.Push(pos)
  1606  	}
  1607  }
  1608  
  1609  func (r *reader) closeScope() {
  1610  	r.Sync(pkgbits.SyncCloseScope)
  1611  	r.lastCloseScopePos = r.pos()
  1612  
  1613  	r.closeAnotherScope()
  1614  }
  1615  
  1616  // closeAnotherScope is like closeScope, but it reuses the same mark
  1617  // position as the last closeScope call. This is useful for "for" and
  1618  // "if" statements, as their implicit blocks always end at the same
  1619  // position as an explicit block.
  1620  func (r *reader) closeAnotherScope() {
  1621  	r.Sync(pkgbits.SyncCloseAnotherScope)
  1622  
  1623  	if base.Flag.Dwarf {
  1624  		scopeVars := r.scopeVars[len(r.scopeVars)-1]
  1625  		r.scopeVars = r.scopeVars[:len(r.scopeVars)-1]
  1626  
  1627  		// Quirkish: noder decides which scopes to keep before
  1628  		// typechecking, whereas incremental typechecking during IR
  1629  		// construction can result in new autotemps being allocated. To
  1630  		// produce identical output, we ignore autotemps here for the
  1631  		// purpose of deciding whether to retract the scope.
  1632  		//
  1633  		// This is important for net/http/fcgi, because it contains:
  1634  		//
  1635  		//	var body io.ReadCloser
  1636  		//	if len(content) > 0 {
  1637  		//		body, req.pw = io.Pipe()
  1638  		//	} else { … }
  1639  		//
  1640  		// Notably, io.Pipe is inlinable, and inlining it introduces a ~R0
  1641  		// variable at the call site.
  1642  		//
  1643  		// Noder does not preserve the scope where the io.Pipe() call
  1644  		// resides, because it doesn't contain any declared variables in
  1645  		// source. So the ~R0 variable ends up being assigned to the
  1646  		// enclosing scope instead.
  1647  		//
  1648  		// However, typechecking this assignment also introduces
  1649  		// autotemps, because io.Pipe's results need conversion before
  1650  		// they can be assigned to their respective destination variables.
  1651  		//
  1652  		// TODO(mdempsky): We should probably just keep all scopes, and
  1653  		// let dwarfgen take care of pruning them instead.
  1654  		retract := true
  1655  		for _, n := range r.curfn.Dcl[scopeVars:] {
  1656  			if !n.AutoTemp() {
  1657  				retract = false
  1658  				break
  1659  			}
  1660  		}
  1661  
  1662  		if retract {
  1663  			// no variables were declared in this scope, so we can retract it.
  1664  			r.marker.Unpush()
  1665  		} else {
  1666  			r.marker.Pop(r.lastCloseScopePos)
  1667  		}
  1668  	}
  1669  }
  1670  
  1671  // @@@ Statements
  1672  
  1673  func (r *reader) stmt() ir.Node {
  1674  	switch stmts := r.stmts(); len(stmts) {
  1675  	case 0:
  1676  		return nil
  1677  	case 1:
  1678  		return stmts[0]
  1679  	default:
  1680  		return ir.NewBlockStmt(stmts[0].Pos(), stmts)
  1681  	}
  1682  }
  1683  
  1684  func (r *reader) stmts() []ir.Node {
  1685  	assert(ir.CurFunc == r.curfn)
  1686  	var res ir.Nodes
  1687  
  1688  	r.Sync(pkgbits.SyncStmts)
  1689  	for {
  1690  		tag := codeStmt(r.Code(pkgbits.SyncStmt1))
  1691  		if tag == stmtEnd {
  1692  			r.Sync(pkgbits.SyncStmtsEnd)
  1693  			return res
  1694  		}
  1695  
  1696  		if n := r.stmt1(tag, &res); n != nil {
  1697  			res.Append(typecheck.Stmt(n))
  1698  		}
  1699  	}
  1700  }
  1701  
  1702  func (r *reader) stmt1(tag codeStmt, out *ir.Nodes) ir.Node {
  1703  	var label *types.Sym
  1704  	if n := len(*out); n > 0 {
  1705  		if ls, ok := (*out)[n-1].(*ir.LabelStmt); ok {
  1706  			label = ls.Label
  1707  		}
  1708  	}
  1709  
  1710  	switch tag {
  1711  	default:
  1712  		panic("unexpected statement")
  1713  
  1714  	case stmtAssign:
  1715  		pos := r.pos()
  1716  		names, lhs := r.assignList()
  1717  		rhs := r.multiExpr()
  1718  
  1719  		if len(rhs) == 0 {
  1720  			for _, name := range names {
  1721  				as := ir.NewAssignStmt(pos, name, nil)
  1722  				as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, name))
  1723  				out.Append(typecheck.Stmt(as))
  1724  			}
  1725  			return nil
  1726  		}
  1727  
  1728  		if len(lhs) == 1 && len(rhs) == 1 {
  1729  			n := ir.NewAssignStmt(pos, lhs[0], rhs[0])
  1730  			n.Def = r.initDefn(n, names)
  1731  			return n
  1732  		}
  1733  
  1734  		n := ir.NewAssignListStmt(pos, ir.OAS2, lhs, rhs)
  1735  		n.Def = r.initDefn(n, names)
  1736  		return n
  1737  
  1738  	case stmtAssignOp:
  1739  		op := r.op()
  1740  		lhs := r.expr()
  1741  		pos := r.pos()
  1742  		rhs := r.expr()
  1743  		return ir.NewAssignOpStmt(pos, op, lhs, rhs)
  1744  
  1745  	case stmtIncDec:
  1746  		op := r.op()
  1747  		lhs := r.expr()
  1748  		pos := r.pos()
  1749  		n := ir.NewAssignOpStmt(pos, op, lhs, ir.NewBasicLit(pos, one))
  1750  		n.IncDec = true
  1751  		return n
  1752  
  1753  	case stmtBlock:
  1754  		out.Append(r.blockStmt()...)
  1755  		return nil
  1756  
  1757  	case stmtBranch:
  1758  		pos := r.pos()
  1759  		op := r.op()
  1760  		sym := r.optLabel()
  1761  		return ir.NewBranchStmt(pos, op, sym)
  1762  
  1763  	case stmtCall:
  1764  		pos := r.pos()
  1765  		op := r.op()
  1766  		call := r.expr()
  1767  		return ir.NewGoDeferStmt(pos, op, call)
  1768  
  1769  	case stmtExpr:
  1770  		return r.expr()
  1771  
  1772  	case stmtFor:
  1773  		return r.forStmt(label)
  1774  
  1775  	case stmtIf:
  1776  		return r.ifStmt()
  1777  
  1778  	case stmtLabel:
  1779  		pos := r.pos()
  1780  		sym := r.label()
  1781  		return ir.NewLabelStmt(pos, sym)
  1782  
  1783  	case stmtReturn:
  1784  		pos := r.pos()
  1785  		results := r.multiExpr()
  1786  		return ir.NewReturnStmt(pos, results)
  1787  
  1788  	case stmtSelect:
  1789  		return r.selectStmt(label)
  1790  
  1791  	case stmtSend:
  1792  		pos := r.pos()
  1793  		ch := r.expr()
  1794  		value := r.expr()
  1795  		return ir.NewSendStmt(pos, ch, value)
  1796  
  1797  	case stmtSwitch:
  1798  		return r.switchStmt(label)
  1799  	}
  1800  }
  1801  
  1802  func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
  1803  	lhs := make([]ir.Node, r.Len())
  1804  	var names []*ir.Name
  1805  
  1806  	for i := range lhs {
  1807  		expr, def := r.assign()
  1808  		lhs[i] = expr
  1809  		if def {
  1810  			names = append(names, expr.(*ir.Name))
  1811  		}
  1812  	}
  1813  
  1814  	return names, lhs
  1815  }
  1816  
  1817  // assign returns an assignee expression. It also reports whether the
  1818  // returned expression is a newly declared variable.
  1819  func (r *reader) assign() (ir.Node, bool) {
  1820  	switch tag := codeAssign(r.Code(pkgbits.SyncAssign)); tag {
  1821  	default:
  1822  		panic("unhandled assignee expression")
  1823  
  1824  	case assignBlank:
  1825  		return typecheck.AssignExpr(ir.BlankNode), false
  1826  
  1827  	case assignDef:
  1828  		pos := r.pos()
  1829  		setBasePos(pos)
  1830  		_, sym := r.localIdent()
  1831  		typ := r.typ()
  1832  
  1833  		name := ir.NewNameAt(pos, sym)
  1834  		setType(name, typ)
  1835  		r.addLocal(name, ir.PAUTO)
  1836  		return name, true
  1837  
  1838  	case assignExpr:
  1839  		return r.expr(), false
  1840  	}
  1841  }
  1842  
  1843  func (r *reader) blockStmt() []ir.Node {
  1844  	r.Sync(pkgbits.SyncBlockStmt)
  1845  	r.openScope()
  1846  	stmts := r.stmts()
  1847  	r.closeScope()
  1848  	return stmts
  1849  }
  1850  
  1851  func (r *reader) forStmt(label *types.Sym) ir.Node {
  1852  	r.Sync(pkgbits.SyncForStmt)
  1853  
  1854  	r.openScope()
  1855  
  1856  	if r.Bool() {
  1857  		pos := r.pos()
  1858  		rang := ir.NewRangeStmt(pos, nil, nil, nil, nil)
  1859  		rang.Label = label
  1860  
  1861  		names, lhs := r.assignList()
  1862  		if len(lhs) >= 1 {
  1863  			rang.Key = lhs[0]
  1864  			if len(lhs) >= 2 {
  1865  				rang.Value = lhs[1]
  1866  			}
  1867  		}
  1868  		rang.Def = r.initDefn(rang, names)
  1869  
  1870  		rang.X = r.expr()
  1871  		if rang.X.Type().IsMap() {
  1872  			rang.RType = r.rtype(pos)
  1873  		}
  1874  		if rang.Key != nil && !ir.IsBlank(rang.Key) {
  1875  			rang.KeyTypeWord, rang.KeySrcRType = r.convRTTI(pos)
  1876  		}
  1877  		if rang.Value != nil && !ir.IsBlank(rang.Value) {
  1878  			rang.ValueTypeWord, rang.ValueSrcRType = r.convRTTI(pos)
  1879  		}
  1880  
  1881  		rang.Body = r.blockStmt()
  1882  		r.closeAnotherScope()
  1883  
  1884  		return rang
  1885  	}
  1886  
  1887  	pos := r.pos()
  1888  	init := r.stmt()
  1889  	cond := r.optExpr()
  1890  	post := r.stmt()
  1891  	body := r.blockStmt()
  1892  	r.closeAnotherScope()
  1893  
  1894  	stmt := ir.NewForStmt(pos, init, cond, post, body)
  1895  	stmt.Label = label
  1896  	return stmt
  1897  }
  1898  
  1899  func (r *reader) ifStmt() ir.Node {
  1900  	r.Sync(pkgbits.SyncIfStmt)
  1901  	r.openScope()
  1902  	pos := r.pos()
  1903  	init := r.stmts()
  1904  	cond := r.expr()
  1905  	then := r.blockStmt()
  1906  	els := r.stmts()
  1907  	n := ir.NewIfStmt(pos, cond, then, els)
  1908  	n.SetInit(init)
  1909  	r.closeAnotherScope()
  1910  	return n
  1911  }
  1912  
  1913  func (r *reader) selectStmt(label *types.Sym) ir.Node {
  1914  	r.Sync(pkgbits.SyncSelectStmt)
  1915  
  1916  	pos := r.pos()
  1917  	clauses := make([]*ir.CommClause, r.Len())
  1918  	for i := range clauses {
  1919  		if i > 0 {
  1920  			r.closeScope()
  1921  		}
  1922  		r.openScope()
  1923  
  1924  		pos := r.pos()
  1925  		comm := r.stmt()
  1926  		body := r.stmts()
  1927  
  1928  		// "case i = <-c: ..." may require an implicit conversion (e.g.,
  1929  		// see fixedbugs/bug312.go). Currently, typecheck throws away the
  1930  		// implicit conversion and relies on it being reinserted later,
  1931  		// but that would lose any explicit RTTI operands too. To preserve
  1932  		// RTTI, we rewrite this as "case tmp := <-c: i = tmp; ...".
  1933  		if as, ok := comm.(*ir.AssignStmt); ok && as.Op() == ir.OAS && !as.Def {
  1934  			if conv, ok := as.Y.(*ir.ConvExpr); ok && conv.Op() == ir.OCONVIFACE {
  1935  				base.AssertfAt(conv.Implicit(), conv.Pos(), "expected implicit conversion: %v", conv)
  1936  
  1937  				recv := conv.X
  1938  				base.AssertfAt(recv.Op() == ir.ORECV, recv.Pos(), "expected receive expression: %v", recv)
  1939  
  1940  				tmp := r.temp(pos, recv.Type())
  1941  
  1942  				// Replace comm with `tmp := <-c`.
  1943  				tmpAs := ir.NewAssignStmt(pos, tmp, recv)
  1944  				tmpAs.Def = true
  1945  				tmpAs.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
  1946  				comm = tmpAs
  1947  
  1948  				// Change original assignment to `i = tmp`, and prepend to body.
  1949  				conv.X = tmp
  1950  				body = append([]ir.Node{as}, body...)
  1951  			}
  1952  		}
  1953  
  1954  		// multiExpr will have desugared a comma-ok receive expression
  1955  		// into a separate statement. However, the rest of the compiler
  1956  		// expects comm to be the OAS2RECV statement itself, so we need to
  1957  		// shuffle things around to fit that pattern.
  1958  		if as2, ok := comm.(*ir.AssignListStmt); ok && as2.Op() == ir.OAS2 {
  1959  			init := ir.TakeInit(as2.Rhs[0])
  1960  			base.AssertfAt(len(init) == 1 && init[0].Op() == ir.OAS2RECV, as2.Pos(), "unexpected assignment: %+v", as2)
  1961  
  1962  			comm = init[0]
  1963  			body = append([]ir.Node{as2}, body...)
  1964  		}
  1965  
  1966  		clauses[i] = ir.NewCommStmt(pos, comm, body)
  1967  	}
  1968  	if len(clauses) > 0 {
  1969  		r.closeScope()
  1970  	}
  1971  	n := ir.NewSelectStmt(pos, clauses)
  1972  	n.Label = label
  1973  	return n
  1974  }
  1975  
  1976  func (r *reader) switchStmt(label *types.Sym) ir.Node {
  1977  	r.Sync(pkgbits.SyncSwitchStmt)
  1978  
  1979  	r.openScope()
  1980  	pos := r.pos()
  1981  	init := r.stmt()
  1982  
  1983  	var tag ir.Node
  1984  	var ident *ir.Ident
  1985  	var iface *types.Type
  1986  	if r.Bool() {
  1987  		pos := r.pos()
  1988  		if r.Bool() {
  1989  			pos := r.pos()
  1990  			_, sym := r.localIdent()
  1991  			ident = ir.NewIdent(pos, sym)
  1992  		}
  1993  		x := r.expr()
  1994  		iface = x.Type()
  1995  		tag = ir.NewTypeSwitchGuard(pos, ident, x)
  1996  	} else {
  1997  		tag = r.optExpr()
  1998  	}
  1999  
  2000  	clauses := make([]*ir.CaseClause, r.Len())
  2001  	for i := range clauses {
  2002  		if i > 0 {
  2003  			r.closeScope()
  2004  		}
  2005  		r.openScope()
  2006  
  2007  		pos := r.pos()
  2008  		var cases, rtypes []ir.Node
  2009  		if iface != nil {
  2010  			cases = make([]ir.Node, r.Len())
  2011  			if len(cases) == 0 {
  2012  				cases = nil // TODO(mdempsky): Unclear if this matters.
  2013  			}
  2014  			for i := range cases {
  2015  				if r.Bool() { // case nil
  2016  					cases[i] = typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
  2017  				} else {
  2018  					cases[i] = r.exprType()
  2019  				}
  2020  			}
  2021  		} else {
  2022  			cases = r.exprList()
  2023  
  2024  			// For `switch { case any(true): }` (e.g., issue 3980 in
  2025  			// test/switch.go), the backend still creates a mixed bool/any
  2026  			// comparison, and we need to explicitly supply the RTTI for the
  2027  			// comparison.
  2028  			//
  2029  			// TODO(mdempsky): Change writer.go to desugar "switch {" into
  2030  			// "switch true {", which we already handle correctly.
  2031  			if tag == nil {
  2032  				for i, cas := range cases {
  2033  					if cas.Type().IsEmptyInterface() {
  2034  						for len(rtypes) < i {
  2035  							rtypes = append(rtypes, nil)
  2036  						}
  2037  						rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), types.Types[types.TBOOL]))
  2038  					}
  2039  				}
  2040  			}
  2041  		}
  2042  
  2043  		clause := ir.NewCaseStmt(pos, cases, nil)
  2044  		clause.RTypes = rtypes
  2045  
  2046  		if ident != nil {
  2047  			pos := r.pos()
  2048  			typ := r.typ()
  2049  
  2050  			name := ir.NewNameAt(pos, ident.Sym())
  2051  			setType(name, typ)
  2052  			r.addLocal(name, ir.PAUTO)
  2053  			clause.Var = name
  2054  			name.Defn = tag
  2055  		}
  2056  
  2057  		clause.Body = r.stmts()
  2058  		clauses[i] = clause
  2059  	}
  2060  	if len(clauses) > 0 {
  2061  		r.closeScope()
  2062  	}
  2063  	r.closeScope()
  2064  
  2065  	n := ir.NewSwitchStmt(pos, tag, clauses)
  2066  	n.Label = label
  2067  	if init != nil {
  2068  		n.SetInit([]ir.Node{init})
  2069  	}
  2070  	return n
  2071  }
  2072  
  2073  func (r *reader) label() *types.Sym {
  2074  	r.Sync(pkgbits.SyncLabel)
  2075  	name := r.String()
  2076  	if r.inlCall != nil {
  2077  		name = fmt.Sprintf("~%s·%d", name, inlgen)
  2078  	}
  2079  	return typecheck.Lookup(name)
  2080  }
  2081  
  2082  func (r *reader) optLabel() *types.Sym {
  2083  	r.Sync(pkgbits.SyncOptLabel)
  2084  	if r.Bool() {
  2085  		return r.label()
  2086  	}
  2087  	return nil
  2088  }
  2089  
  2090  // initDefn marks the given names as declared by defn and populates
  2091  // its Init field with ODCL nodes. It then reports whether any names
  2092  // were so declared, which can be used to initialize defn.Def.
  2093  func (r *reader) initDefn(defn ir.InitNode, names []*ir.Name) bool {
  2094  	if len(names) == 0 {
  2095  		return false
  2096  	}
  2097  
  2098  	init := make([]ir.Node, len(names))
  2099  	for i, name := range names {
  2100  		name.Defn = defn
  2101  		init[i] = ir.NewDecl(name.Pos(), ir.ODCL, name)
  2102  	}
  2103  	defn.SetInit(init)
  2104  	return true
  2105  }
  2106  
  2107  // @@@ Expressions
  2108  
  2109  // expr reads and returns a typechecked expression.
  2110  func (r *reader) expr() (res ir.Node) {
  2111  	defer func() {
  2112  		if res != nil && res.Typecheck() == 0 {
  2113  			base.FatalfAt(res.Pos(), "%v missed typecheck", res)
  2114  		}
  2115  	}()
  2116  
  2117  	switch tag := codeExpr(r.Code(pkgbits.SyncExpr)); tag {
  2118  	default:
  2119  		panic("unhandled expression")
  2120  
  2121  	case exprLocal:
  2122  		return typecheck.Expr(r.useLocal())
  2123  
  2124  	case exprGlobal:
  2125  		// Callee instead of Expr allows builtins
  2126  		// TODO(mdempsky): Handle builtins directly in exprCall, like method calls?
  2127  		return typecheck.Callee(r.obj())
  2128  
  2129  	case exprFuncInst:
  2130  		origPos, pos := r.origPos()
  2131  		wrapperFn, baseFn, dictPtr := r.funcInst(pos)
  2132  		if wrapperFn != nil {
  2133  			return wrapperFn
  2134  		}
  2135  		return r.curry(origPos, false, baseFn, dictPtr, nil)
  2136  
  2137  	case exprConst:
  2138  		pos := r.pos()
  2139  		typ := r.typ()
  2140  		val := FixValue(typ, r.Value())
  2141  		op := r.op()
  2142  		orig := r.String()
  2143  		return typecheck.Expr(OrigConst(pos, typ, val, op, orig))
  2144  
  2145  	case exprNil:
  2146  		pos := r.pos()
  2147  		typ := r.typ()
  2148  		return Nil(pos, typ)
  2149  
  2150  	case exprCompLit:
  2151  		return r.compLit()
  2152  
  2153  	case exprFuncLit:
  2154  		return r.funcLit()
  2155  
  2156  	case exprFieldVal:
  2157  		x := r.expr()
  2158  		pos := r.pos()
  2159  		_, sym := r.selector()
  2160  
  2161  		return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr)
  2162  
  2163  	case exprMethodVal:
  2164  		recv := r.expr()
  2165  		origPos, pos := r.origPos()
  2166  		wrapperFn, baseFn, dictPtr := r.methodExpr()
  2167  
  2168  		// For simple wrapperFn values, the existing machinery for creating
  2169  		// and deduplicating wrapperFn value wrappers still works fine.
  2170  		if wrapperFn, ok := wrapperFn.(*ir.SelectorExpr); ok && wrapperFn.Op() == ir.OMETHEXPR {
  2171  			// The receiver expression we constructed may have a shape type.
  2172  			// For example, in fixedbugs/issue54343.go, `New[int]()` is
  2173  			// constructed as `New[go.shape.int](&.dict.New[int])`, which
  2174  			// has type `*T[go.shape.int]`, not `*T[int]`.
  2175  			//
  2176  			// However, the method we want to select here is `(*T[int]).M`,
  2177  			// not `(*T[go.shape.int]).M`, so we need to manually convert
  2178  			// the type back so that the OXDOT resolves correctly.
  2179  			//
  2180  			// TODO(mdempsky): Logically it might make more sense for
  2181  			// exprCall to take responsibility for setting a non-shaped
  2182  			// result type, but this is the only place where we care
  2183  			// currently. And only because existing ir.OMETHVALUE backend
  2184  			// code relies on n.X.Type() instead of n.Selection.Recv().Type
  2185  			// (because the latter is types.FakeRecvType() in the case of
  2186  			// interface method values).
  2187  			//
  2188  			if recv.Type().HasShape() {
  2189  				typ := wrapperFn.Type().Params().Field(0).Type
  2190  				if !types.Identical(typ, recv.Type()) {
  2191  					base.FatalfAt(wrapperFn.Pos(), "receiver %L does not match %L", recv, wrapperFn)
  2192  				}
  2193  				recv = typecheck.Expr(ir.NewConvExpr(recv.Pos(), ir.OCONVNOP, typ, recv))
  2194  			}
  2195  
  2196  			n := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, recv, wrapperFn.Sel)).(*ir.SelectorExpr)
  2197  
  2198  			// As a consistency check here, we make sure "n" selected the
  2199  			// same method (represented by a types.Field) that wrapperFn
  2200  			// selected. However, for anonymous receiver types, there can be
  2201  			// multiple such types.Field instances (#58563). So we may need
  2202  			// to fallback to making sure Sym and Type (including the
  2203  			// receiver parameter's type) match.
  2204  			if n.Selection != wrapperFn.Selection {
  2205  				assert(n.Selection.Sym == wrapperFn.Selection.Sym)
  2206  				assert(types.Identical(n.Selection.Type, wrapperFn.Selection.Type))
  2207  				assert(types.Identical(n.Selection.Type.Recv().Type, wrapperFn.Selection.Type.Recv().Type))
  2208  			}
  2209  
  2210  			wrapper := methodValueWrapper{
  2211  				rcvr:   n.X.Type(),
  2212  				method: n.Selection,
  2213  			}
  2214  
  2215  			if r.importedDef() {
  2216  				haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
  2217  			} else {
  2218  				needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
  2219  			}
  2220  			return n
  2221  		}
  2222  
  2223  		// For more complicated method expressions, we construct a
  2224  		// function literal wrapper.
  2225  		return r.curry(origPos, true, baseFn, recv, dictPtr)
  2226  
  2227  	case exprMethodExpr:
  2228  		recv := r.typ()
  2229  
  2230  		implicits := make([]int, r.Len())
  2231  		for i := range implicits {
  2232  			implicits[i] = r.Len()
  2233  		}
  2234  		var deref, addr bool
  2235  		if r.Bool() {
  2236  			deref = true
  2237  		} else if r.Bool() {
  2238  			addr = true
  2239  		}
  2240  
  2241  		origPos, pos := r.origPos()
  2242  		wrapperFn, baseFn, dictPtr := r.methodExpr()
  2243  
  2244  		// If we already have a wrapper and don't need to do anything with
  2245  		// it, we can just return the wrapper directly.
  2246  		//
  2247  		// N.B., we use implicits/deref/addr here as the source of truth
  2248  		// rather than types.Identical, because the latter can be confused
  2249  		// by tricky promoted methods (e.g., typeparam/mdempsky/21.go).
  2250  		if wrapperFn != nil && len(implicits) == 0 && !deref && !addr {
  2251  			if !types.Identical(recv, wrapperFn.Type().Params().Field(0).Type) {
  2252  				base.FatalfAt(pos, "want receiver type %v, but have method %L", recv, wrapperFn)
  2253  			}
  2254  			return wrapperFn
  2255  		}
  2256  
  2257  		// Otherwise, if the wrapper function is a static method
  2258  		// expression (OMETHEXPR) and the receiver type is unshaped, then
  2259  		// we can rely on a statically generated wrapper being available.
  2260  		if method, ok := wrapperFn.(*ir.SelectorExpr); ok && method.Op() == ir.OMETHEXPR && !recv.HasShape() {
  2261  			return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), method.Sel)).(*ir.SelectorExpr)
  2262  		}
  2263  
  2264  		return r.methodExprWrap(origPos, recv, implicits, deref, addr, baseFn, dictPtr)
  2265  
  2266  	case exprIndex:
  2267  		x := r.expr()
  2268  		pos := r.pos()
  2269  		index := r.expr()
  2270  		n := typecheck.Expr(ir.NewIndexExpr(pos, x, index))
  2271  		switch n.Op() {
  2272  		case ir.OINDEXMAP:
  2273  			n := n.(*ir.IndexExpr)
  2274  			n.RType = r.rtype(pos)
  2275  		}
  2276  		return n
  2277  
  2278  	case exprSlice:
  2279  		x := r.expr()
  2280  		pos := r.pos()
  2281  		var index [3]ir.Node
  2282  		for i := range index {
  2283  			index[i] = r.optExpr()
  2284  		}
  2285  		op := ir.OSLICE
  2286  		if index[2] != nil {
  2287  			op = ir.OSLICE3
  2288  		}
  2289  		return typecheck.Expr(ir.NewSliceExpr(pos, op, x, index[0], index[1], index[2]))
  2290  
  2291  	case exprAssert:
  2292  		x := r.expr()
  2293  		pos := r.pos()
  2294  		typ := r.exprType()
  2295  		srcRType := r.rtype(pos)
  2296  
  2297  		// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
  2298  		if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
  2299  			assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
  2300  			assert.SrcRType = srcRType
  2301  			assert.ITab = typ.ITab
  2302  			return typed(typ.Type(), assert)
  2303  		}
  2304  		return typecheck.Expr(ir.NewTypeAssertExpr(pos, x, typ.Type()))
  2305  
  2306  	case exprUnaryOp:
  2307  		op := r.op()
  2308  		pos := r.pos()
  2309  		x := r.expr()
  2310  
  2311  		switch op {
  2312  		case ir.OADDR:
  2313  			return typecheck.Expr(typecheck.NodAddrAt(pos, x))
  2314  		case ir.ODEREF:
  2315  			return typecheck.Expr(ir.NewStarExpr(pos, x))
  2316  		}
  2317  		return typecheck.Expr(ir.NewUnaryExpr(pos, op, x))
  2318  
  2319  	case exprBinaryOp:
  2320  		op := r.op()
  2321  		x := r.expr()
  2322  		pos := r.pos()
  2323  		y := r.expr()
  2324  
  2325  		switch op {
  2326  		case ir.OANDAND, ir.OOROR:
  2327  			return typecheck.Expr(ir.NewLogicalExpr(pos, op, x, y))
  2328  		}
  2329  		return typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))
  2330  
  2331  	case exprRecv:
  2332  		x := r.expr()
  2333  		pos := r.pos()
  2334  		for i, n := 0, r.Len(); i < n; i++ {
  2335  			x = Implicit(DotField(pos, x, r.Len()))
  2336  		}
  2337  		if r.Bool() { // needs deref
  2338  			x = Implicit(Deref(pos, x.Type().Elem(), x))
  2339  		} else if r.Bool() { // needs addr
  2340  			x = Implicit(Addr(pos, x))
  2341  		}
  2342  		return x
  2343  
  2344  	case exprCall:
  2345  		var fun ir.Node
  2346  		var args ir.Nodes
  2347  		if r.Bool() { // method call
  2348  			recv := r.expr()
  2349  			_, method, dictPtr := r.methodExpr()
  2350  
  2351  			if recv.Type().IsInterface() && method.Op() == ir.OMETHEXPR {
  2352  				method := method.(*ir.SelectorExpr)
  2353  
  2354  				// The compiler backend (e.g., devirtualization) handle
  2355  				// OCALLINTER/ODOTINTER better than OCALLFUNC/OMETHEXPR for
  2356  				// interface calls, so we prefer to continue constructing
  2357  				// calls that way where possible.
  2358  				//
  2359  				// There are also corner cases where semantically it's perhaps
  2360  				// significant; e.g., fixedbugs/issue15975.go, #38634, #52025.
  2361  
  2362  				fun = typecheck.Callee(ir.NewSelectorExpr(method.Pos(), ir.OXDOT, recv, method.Sel))
  2363  			} else {
  2364  				if recv.Type().IsInterface() {
  2365  					// N.B., this happens currently for typeparam/issue51521.go
  2366  					// and typeparam/typeswitch3.go.
  2367  					if base.Flag.LowerM > 0 {
  2368  						base.WarnfAt(method.Pos(), "imprecise interface call")
  2369  					}
  2370  				}
  2371  
  2372  				fun = method
  2373  				args.Append(recv)
  2374  			}
  2375  			if dictPtr != nil {
  2376  				args.Append(dictPtr)
  2377  			}
  2378  		} else if r.Bool() { // call to instanced function
  2379  			pos := r.pos()
  2380  			_, shapedFn, dictPtr := r.funcInst(pos)
  2381  			fun = shapedFn
  2382  			args.Append(dictPtr)
  2383  		} else {
  2384  			fun = r.expr()
  2385  		}
  2386  		pos := r.pos()
  2387  		args.Append(r.multiExpr()...)
  2388  		dots := r.Bool()
  2389  		n := typecheck.Call(pos, fun, args, dots)
  2390  		switch n.Op() {
  2391  		case ir.OAPPEND:
  2392  			n := n.(*ir.CallExpr)
  2393  			n.RType = r.rtype(pos)
  2394  			// For append(a, b...), we don't need the implicit conversion. The typechecker already
  2395  			// ensured that a and b are both slices with the same base type, or []byte and string.
  2396  			if n.IsDDD {
  2397  				if conv, ok := n.Args[1].(*ir.ConvExpr); ok && conv.Op() == ir.OCONVNOP && conv.Implicit() {
  2398  					n.Args[1] = conv.X
  2399  				}
  2400  			}
  2401  		case ir.OCOPY:
  2402  			n := n.(*ir.BinaryExpr)
  2403  			n.RType = r.rtype(pos)
  2404  		case ir.ODELETE:
  2405  			n := n.(*ir.CallExpr)
  2406  			n.RType = r.rtype(pos)
  2407  		case ir.OUNSAFESLICE:
  2408  			n := n.(*ir.BinaryExpr)
  2409  			n.RType = r.rtype(pos)
  2410  		}
  2411  		return n
  2412  
  2413  	case exprMake:
  2414  		pos := r.pos()
  2415  		typ := r.exprType()
  2416  		extra := r.exprs()
  2417  		n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
  2418  		n.RType = r.rtype(pos)
  2419  		return n
  2420  
  2421  	case exprNew:
  2422  		pos := r.pos()
  2423  		typ := r.exprType()
  2424  		return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
  2425  
  2426  	case exprReshape:
  2427  		typ := r.typ()
  2428  		x := r.expr()
  2429  
  2430  		if types.IdenticalStrict(x.Type(), typ) {
  2431  			return x
  2432  		}
  2433  
  2434  		// Comparison expressions are constructed as "untyped bool" still.
  2435  		//
  2436  		// TODO(mdempsky): It should be safe to reshape them here too, but
  2437  		// maybe it's better to construct them with the proper type
  2438  		// instead.
  2439  		if x.Type() == types.UntypedBool && typ.IsBoolean() {
  2440  			return x
  2441  		}
  2442  
  2443  		base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
  2444  		base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
  2445  
  2446  		// We use ir.HasUniquePos here as a check that x only appears once
  2447  		// in the AST, so it's okay for us to call SetType without
  2448  		// breaking any other uses of it.
  2449  		//
  2450  		// Notably, any ONAMEs should already have the exactly right shape
  2451  		// type and been caught by types.IdenticalStrict above.
  2452  		base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
  2453  
  2454  		if base.Debug.Reshape != 0 {
  2455  			base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
  2456  		}
  2457  
  2458  		x.SetType(typ)
  2459  		return x
  2460  
  2461  	case exprConvert:
  2462  		implicit := r.Bool()
  2463  		typ := r.typ()
  2464  		pos := r.pos()
  2465  		typeWord, srcRType := r.convRTTI(pos)
  2466  		dstTypeParam := r.Bool()
  2467  		identical := r.Bool()
  2468  		x := r.expr()
  2469  
  2470  		// TODO(mdempsky): Stop constructing expressions of untyped type.
  2471  		x = typecheck.DefaultLit(x, typ)
  2472  
  2473  		ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
  2474  		ce.TypeWord, ce.SrcRType = typeWord, srcRType
  2475  		if implicit {
  2476  			ce.SetImplicit(true)
  2477  		}
  2478  		n := typecheck.Expr(ce)
  2479  
  2480  		// Conversions between non-identical, non-empty interfaces always
  2481  		// requires a runtime call, even if they have identical underlying
  2482  		// interfaces. This is because we create separate itab instances
  2483  		// for each unique interface type, not merely each unique
  2484  		// interface shape.
  2485  		//
  2486  		// However, due to shape types, typecheck.Expr might mistakenly
  2487  		// think a conversion between two non-empty interfaces are
  2488  		// identical and set ir.OCONVNOP, instead of ir.OCONVIFACE. To
  2489  		// ensure we update the itab field appropriately, we force it to
  2490  		// ir.OCONVIFACE instead when shape types are involved.
  2491  		//
  2492  		// TODO(mdempsky): Are there other places we might get this wrong?
  2493  		// Should this be moved down into typecheck.{Assign,Convert}op?
  2494  		// This would be a non-issue if itabs were unique for each
  2495  		// *underlying* interface type instead.
  2496  		if !identical {
  2497  			if n, ok := n.(*ir.ConvExpr); ok && n.Op() == ir.OCONVNOP && n.Type().IsInterface() && !n.Type().IsEmptyInterface() && (n.Type().HasShape() || n.X.Type().HasShape()) {
  2498  				n.SetOp(ir.OCONVIFACE)
  2499  			}
  2500  		}
  2501  
  2502  		// spec: "If the type is a type parameter, the constant is converted
  2503  		// into a non-constant value of the type parameter."
  2504  		if dstTypeParam && ir.IsConstNode(n) {
  2505  			// Wrap in an OCONVNOP node to ensure result is non-constant.
  2506  			n = Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, n.Type(), n))
  2507  			n.SetTypecheck(1)
  2508  		}
  2509  		return n
  2510  	}
  2511  }
  2512  
  2513  // funcInst reads an instantiated function reference, and returns
  2514  // three (possibly nil) expressions related to it:
  2515  //
  2516  // baseFn is always non-nil: it's either a function of the appropriate
  2517  // type already, or it has an extra dictionary parameter as the first
  2518  // parameter.
  2519  //
  2520  // If dictPtr is non-nil, then it's a dictionary argument that must be
  2521  // passed as the first argument to baseFn.
  2522  //
  2523  // If wrapperFn is non-nil, then it's either the same as baseFn (if
  2524  // dictPtr is nil), or it's semantically equivalent to currying baseFn
  2525  // to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
  2526  // that needs to be computed dynamically.)
  2527  //
  2528  // For callers that are creating a call to the returned function, it's
  2529  // best to emit a call to baseFn, and include dictPtr in the arguments
  2530  // list as appropriate.
  2531  //
  2532  // For callers that want to return the function without invoking it,
  2533  // they may return wrapperFn if it's non-nil; but otherwise, they need
  2534  // to create their own wrapper.
  2535  func (r *reader) funcInst(pos src.XPos) (wrapperFn, baseFn, dictPtr ir.Node) {
  2536  	// Like in methodExpr, I'm pretty sure this isn't needed.
  2537  	var implicits []*types.Type
  2538  	if r.dict != nil {
  2539  		implicits = r.dict.targs
  2540  	}
  2541  
  2542  	if r.Bool() { // dynamic subdictionary
  2543  		idx := r.Len()
  2544  		info := r.dict.subdicts[idx]
  2545  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2546  
  2547  		baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2548  
  2549  		// TODO(mdempsky): Is there a more robust way to get the
  2550  		// dictionary pointer type here?
  2551  		dictPtrType := baseFn.Type().Params().Field(0).Type
  2552  		dictPtr = typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
  2553  
  2554  		return
  2555  	}
  2556  
  2557  	info := r.objInfo()
  2558  	explicits := r.p.typListIdx(info.explicits, r.dict)
  2559  
  2560  	wrapperFn = r.p.objIdx(info.idx, implicits, explicits, false).(*ir.Name)
  2561  	baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2562  
  2563  	dictName := r.p.objDictName(info.idx, implicits, explicits)
  2564  	dictPtr = typecheck.Expr(ir.NewAddrExpr(pos, dictName))
  2565  
  2566  	return
  2567  }
  2568  
  2569  func (pr *pkgReader) objDictName(idx pkgbits.Index, implicits, explicits []*types.Type) *ir.Name {
  2570  	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
  2571  	_, sym := rname.qualifiedIdent()
  2572  	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
  2573  
  2574  	if tag == pkgbits.ObjStub {
  2575  		assert(!sym.IsBlank())
  2576  		if pri, ok := objReader[sym]; ok {
  2577  			return pri.pr.objDictName(pri.idx, nil, explicits)
  2578  		}
  2579  		base.Fatalf("unresolved stub: %v", sym)
  2580  	}
  2581  
  2582  	dict := pr.objDictIdx(sym, idx, implicits, explicits, false)
  2583  
  2584  	return pr.dictNameOf(dict)
  2585  }
  2586  
  2587  // curry returns a function literal that calls fun with arg0 and
  2588  // (optionally) arg1, accepting additional arguments to the function
  2589  // literal as necessary to satisfy fun's signature.
  2590  //
  2591  // If nilCheck is true and arg0 is an interface value, then it's
  2592  // checked to be non-nil as an initial step at the point of evaluating
  2593  // the function literal itself.
  2594  func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
  2595  	var captured ir.Nodes
  2596  	captured.Append(fun, arg0)
  2597  	if arg1 != nil {
  2598  		captured.Append(arg1)
  2599  	}
  2600  
  2601  	params, results := syntheticSig(fun.Type())
  2602  	params = params[len(captured)-1:] // skip curried parameters
  2603  	typ := types.NewSignature(types.NoPkg, nil, nil, params, results)
  2604  
  2605  	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
  2606  		recvs, params := r.syntheticArgs(pos)
  2607  		assert(len(recvs) == 0)
  2608  
  2609  		fun := captured[0]
  2610  
  2611  		var args ir.Nodes
  2612  		args.Append(captured[1:]...)
  2613  		args.Append(params...)
  2614  
  2615  		r.syntheticTailCall(pos, fun, args)
  2616  	}
  2617  
  2618  	return r.syntheticClosure(origPos, typ, ifaceHack, captured, addBody)
  2619  }
  2620  
  2621  // methodExprWrap returns a function literal that changes method's
  2622  // first parameter's type to recv, and uses implicits/deref/addr to
  2623  // select the appropriate receiver parameter to pass to method.
  2624  func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
  2625  	var captured ir.Nodes
  2626  	captured.Append(method)
  2627  
  2628  	params, results := syntheticSig(method.Type())
  2629  
  2630  	// Change first parameter to recv.
  2631  	params[0].Type = recv
  2632  
  2633  	// If we have a dictionary pointer argument to pass, then omit the
  2634  	// underlying method expression's dictionary parameter from the
  2635  	// returned signature too.
  2636  	if dictPtr != nil {
  2637  		captured.Append(dictPtr)
  2638  		params = append(params[:1], params[2:]...)
  2639  	}
  2640  
  2641  	typ := types.NewSignature(types.NoPkg, nil, nil, params, results)
  2642  
  2643  	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
  2644  		recvs, args := r.syntheticArgs(pos)
  2645  		assert(len(recvs) == 0)
  2646  
  2647  		fn := captured[0]
  2648  
  2649  		// Rewrite first argument based on implicits/deref/addr.
  2650  		{
  2651  			arg := args[0]
  2652  			for _, ix := range implicits {
  2653  				arg = Implicit(DotField(pos, arg, ix))
  2654  			}
  2655  			if deref {
  2656  				arg = Implicit(Deref(pos, arg.Type().Elem(), arg))
  2657  			} else if addr {
  2658  				arg = Implicit(Addr(pos, arg))
  2659  			}
  2660  			args[0] = arg
  2661  		}
  2662  
  2663  		// Insert dictionary argument, if provided.
  2664  		if dictPtr != nil {
  2665  			newArgs := make([]ir.Node, len(args)+1)
  2666  			newArgs[0] = args[0]
  2667  			newArgs[1] = captured[1]
  2668  			copy(newArgs[2:], args[1:])
  2669  			args = newArgs
  2670  		}
  2671  
  2672  		r.syntheticTailCall(pos, fn, args)
  2673  	}
  2674  
  2675  	return r.syntheticClosure(origPos, typ, false, captured, addBody)
  2676  }
  2677  
  2678  // syntheticClosure constructs a synthetic function literal for
  2679  // currying dictionary arguments. origPos is the position used for the
  2680  // closure, which must be a non-inlined position. typ is the function
  2681  // literal's signature type.
  2682  //
  2683  // captures is a list of expressions that need to be evaluated at the
  2684  // point of function literal evaluation and captured by the function
  2685  // literal. If ifaceHack is true and captures[1] is an interface type,
  2686  // it's checked to be non-nil after evaluation.
  2687  //
  2688  // addBody is a callback function to populate the function body. The
  2689  // list of captured values passed back has the captured variables for
  2690  // use within the function literal, corresponding to the expressions
  2691  // in captures.
  2692  func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node {
  2693  	// isSafe reports whether n is an expression that we can safely
  2694  	// defer to evaluating inside the closure instead, to avoid storing
  2695  	// them into the closure.
  2696  	//
  2697  	// In practice this is always (and only) the wrappee function.
  2698  	isSafe := func(n ir.Node) bool {
  2699  		if n.Op() == ir.ONAME && n.(*ir.Name).Class == ir.PFUNC {
  2700  			return true
  2701  		}
  2702  		if n.Op() == ir.OMETHEXPR {
  2703  			return true
  2704  		}
  2705  
  2706  		return false
  2707  	}
  2708  
  2709  	// The ODCLFUNC and its body need to use the original position, but
  2710  	// the OCLOSURE node and any Init statements should use the inlined
  2711  	// position instead. See also the explanation in reader.funcLit.
  2712  	inlPos := r.inlPos(origPos)
  2713  
  2714  	fn := ir.NewClosureFunc(origPos, r.curfn != nil)
  2715  	fn.SetWrapper(true)
  2716  	clo := fn.OClosure
  2717  	clo.SetPos(inlPos)
  2718  	ir.NameClosure(clo, r.curfn)
  2719  
  2720  	setType(fn.Nname, typ)
  2721  	typecheck.Func(fn)
  2722  	setType(clo, fn.Type())
  2723  
  2724  	var init ir.Nodes
  2725  	for i, n := range captures {
  2726  		if isSafe(n) {
  2727  			continue // skip capture; can reference directly
  2728  		}
  2729  
  2730  		tmp := r.tempCopy(inlPos, n, &init)
  2731  		ir.NewClosureVar(origPos, fn, tmp)
  2732  
  2733  		// We need to nil check interface receivers at the point of method
  2734  		// value evaluation, ugh.
  2735  		if ifaceHack && i == 1 && n.Type().IsInterface() {
  2736  			check := ir.NewUnaryExpr(inlPos, ir.OCHECKNIL, ir.NewUnaryExpr(inlPos, ir.OITAB, tmp))
  2737  			init.Append(typecheck.Stmt(check))
  2738  		}
  2739  	}
  2740  
  2741  	pri := pkgReaderIndex{synthetic: func(pos src.XPos, r *reader) {
  2742  		captured := make([]ir.Node, len(captures))
  2743  		next := 0
  2744  		for i, n := range captures {
  2745  			if isSafe(n) {
  2746  				captured[i] = n
  2747  			} else {
  2748  				captured[i] = r.closureVars[next]
  2749  				next++
  2750  			}
  2751  		}
  2752  		assert(next == len(r.closureVars))
  2753  
  2754  		addBody(origPos, r, captured)
  2755  	}}
  2756  	bodyReader[fn] = pri
  2757  	pri.funcBody(fn)
  2758  
  2759  	// TODO(mdempsky): Remove hard-coding of typecheck.Target.
  2760  	return ir.InitExpr(init, ir.UseClosure(clo, typecheck.Target))
  2761  }
  2762  
  2763  // syntheticSig duplicates and returns the params and results lists
  2764  // for sig, but renaming anonymous parameters so they can be assigned
  2765  // ir.Names.
  2766  func syntheticSig(sig *types.Type) (params, results []*types.Field) {
  2767  	clone := func(params []*types.Field) []*types.Field {
  2768  		res := make([]*types.Field, len(params))
  2769  		for i, param := range params {
  2770  			sym := param.Sym
  2771  			if sym == nil || sym.Name == "_" {
  2772  				sym = typecheck.LookupNum(".anon", i)
  2773  			}
  2774  			// TODO(mdempsky): It would be nice to preserve the original
  2775  			// parameter positions here instead, but at least
  2776  			// typecheck.NewMethodType replaces them with base.Pos, making
  2777  			// them useless. Worse, the positions copied from base.Pos may
  2778  			// have inlining contexts, which we definitely don't want here
  2779  			// (e.g., #54625).
  2780  			res[i] = types.NewField(base.AutogeneratedPos, sym, param.Type)
  2781  			res[i].SetIsDDD(param.IsDDD())
  2782  		}
  2783  		return res
  2784  	}
  2785  
  2786  	return clone(sig.Params().FieldSlice()), clone(sig.Results().FieldSlice())
  2787  }
  2788  
  2789  func (r *reader) optExpr() ir.Node {
  2790  	if r.Bool() {
  2791  		return r.expr()
  2792  	}
  2793  	return nil
  2794  }
  2795  
  2796  // methodExpr reads a method expression reference, and returns three
  2797  // (possibly nil) expressions related to it:
  2798  //
  2799  // baseFn is always non-nil: it's either a function of the appropriate
  2800  // type already, or it has an extra dictionary parameter as the second
  2801  // parameter (i.e., immediately after the promoted receiver
  2802  // parameter).
  2803  //
  2804  // If dictPtr is non-nil, then it's a dictionary argument that must be
  2805  // passed as the second argument to baseFn.
  2806  //
  2807  // If wrapperFn is non-nil, then it's either the same as baseFn (if
  2808  // dictPtr is nil), or it's semantically equivalent to currying baseFn
  2809  // to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
  2810  // that needs to be computed dynamically.)
  2811  //
  2812  // For callers that are creating a call to the returned method, it's
  2813  // best to emit a call to baseFn, and include dictPtr in the arguments
  2814  // list as appropriate.
  2815  //
  2816  // For callers that want to return a method expression without
  2817  // invoking it, they may return wrapperFn if it's non-nil; but
  2818  // otherwise, they need to create their own wrapper.
  2819  func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) {
  2820  	recv := r.typ()
  2821  	sig0 := r.typ()
  2822  	pos := r.pos()
  2823  	_, sym := r.selector()
  2824  
  2825  	// Signature type to return (i.e., recv prepended to the method's
  2826  	// normal parameters list).
  2827  	sig := typecheck.NewMethodType(sig0, recv)
  2828  
  2829  	if r.Bool() { // type parameter method expression
  2830  		idx := r.Len()
  2831  		word := r.dictWord(pos, r.dict.typeParamMethodExprsOffset()+idx)
  2832  
  2833  		// TODO(mdempsky): If the type parameter was instantiated with an
  2834  		// interface type (i.e., embed.IsInterface()), then we could
  2835  		// return the OMETHEXPR instead and save an indirection.
  2836  
  2837  		// We wrote the method expression's entry point PC into the
  2838  		// dictionary, but for Go `func` values we need to return a
  2839  		// closure (i.e., pointer to a structure with the PC as the first
  2840  		// field). Because method expressions don't have any closure
  2841  		// variables, we pun the dictionary entry as the closure struct.
  2842  		fn := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, sig, ir.NewAddrExpr(pos, word)))
  2843  		return fn, fn, nil
  2844  	}
  2845  
  2846  	// TODO(mdempsky): I'm pretty sure this isn't needed: implicits is
  2847  	// only relevant to locally defined types, but they can't have
  2848  	// (non-promoted) methods.
  2849  	var implicits []*types.Type
  2850  	if r.dict != nil {
  2851  		implicits = r.dict.targs
  2852  	}
  2853  
  2854  	if r.Bool() { // dynamic subdictionary
  2855  		idx := r.Len()
  2856  		info := r.dict.subdicts[idx]
  2857  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2858  
  2859  		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2860  		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
  2861  
  2862  		// TODO(mdempsky): Is there a more robust way to get the
  2863  		// dictionary pointer type here?
  2864  		dictPtrType := shapedFn.Type().Params().Field(1).Type
  2865  		dictPtr := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
  2866  
  2867  		return nil, shapedFn, dictPtr
  2868  	}
  2869  
  2870  	if r.Bool() { // static dictionary
  2871  		info := r.objInfo()
  2872  		explicits := r.p.typListIdx(info.explicits, r.dict)
  2873  
  2874  		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
  2875  		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
  2876  
  2877  		dict := r.p.objDictName(info.idx, implicits, explicits)
  2878  		dictPtr := typecheck.Expr(ir.NewAddrExpr(pos, dict))
  2879  
  2880  		// Check that dictPtr matches shapedFn's dictionary parameter.
  2881  		if !types.Identical(dictPtr.Type(), shapedFn.Type().Params().Field(1).Type) {
  2882  			base.FatalfAt(pos, "dict %L, but shaped method %L", dict, shapedFn)
  2883  		}
  2884  
  2885  		// For statically known instantiations, we can take advantage of
  2886  		// the stenciled wrapper.
  2887  		base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv)
  2888  		wrapperFn := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
  2889  		base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig)
  2890  
  2891  		return wrapperFn, shapedFn, dictPtr
  2892  	}
  2893  
  2894  	// Simple method expression; no dictionary needed.
  2895  	base.AssertfAt(!recv.HasShape() || recv.IsInterface(), pos, "shaped receiver %v", recv)
  2896  	fn := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
  2897  	return fn, fn, nil
  2898  }
  2899  
  2900  // shapedMethodExpr returns the specified method on the given shaped
  2901  // type.
  2902  func shapedMethodExpr(pos src.XPos, obj *ir.Name, sym *types.Sym) *ir.SelectorExpr {
  2903  	assert(obj.Op() == ir.OTYPE)
  2904  
  2905  	typ := obj.Type()
  2906  	assert(typ.HasShape())
  2907  
  2908  	method := func() *types.Field {
  2909  		for _, method := range typ.Methods().Slice() {
  2910  			if method.Sym == sym {
  2911  				return method
  2912  			}
  2913  		}
  2914  
  2915  		base.FatalfAt(pos, "failed to find method %v in shaped type %v", sym, typ)
  2916  		panic("unreachable")
  2917  	}()
  2918  
  2919  	// Construct an OMETHEXPR node.
  2920  	recv := method.Type.Recv().Type
  2921  	return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
  2922  }
  2923  
  2924  func (r *reader) multiExpr() []ir.Node {
  2925  	r.Sync(pkgbits.SyncMultiExpr)
  2926  
  2927  	if r.Bool() { // N:1
  2928  		pos := r.pos()
  2929  		expr := r.expr()
  2930  
  2931  		results := make([]ir.Node, r.Len())
  2932  		as := ir.NewAssignListStmt(pos, ir.OAS2, nil, []ir.Node{expr})
  2933  		as.Def = true
  2934  		for i := range results {
  2935  			tmp := r.temp(pos, r.typ())
  2936  			as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
  2937  			as.Lhs.Append(tmp)
  2938  
  2939  			res := ir.Node(tmp)
  2940  			if r.Bool() {
  2941  				n := ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)
  2942  				n.TypeWord, n.SrcRType = r.convRTTI(pos)
  2943  				n.SetImplicit(true)
  2944  				res = typecheck.Expr(n)
  2945  			}
  2946  			results[i] = res
  2947  		}
  2948  
  2949  		// TODO(mdempsky): Could use ir.InlinedCallExpr instead?
  2950  		results[0] = ir.InitExpr([]ir.Node{typecheck.Stmt(as)}, results[0])
  2951  		return results
  2952  	}
  2953  
  2954  	// N:N
  2955  	exprs := make([]ir.Node, r.Len())
  2956  	if len(exprs) == 0 {
  2957  		return nil
  2958  	}
  2959  	for i := range exprs {
  2960  		exprs[i] = r.expr()
  2961  	}
  2962  	return exprs
  2963  }
  2964  
  2965  // temp returns a new autotemp of the specified type.
  2966  func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name {
  2967  	// See typecheck.typecheckargs.
  2968  	curfn := r.curfn
  2969  	if curfn == nil {
  2970  		curfn = typecheck.InitTodoFunc
  2971  	}
  2972  
  2973  	return typecheck.TempAt(pos, curfn, typ)
  2974  }
  2975  
  2976  // tempCopy declares and returns a new autotemp initialized to the
  2977  // value of expr.
  2978  func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name {
  2979  	if r.curfn == nil {
  2980  		// Escape analysis doesn't know how to handle package-scope
  2981  		// function literals with free variables (i.e., that capture
  2982  		// temporary variables added to typecheck.InitTodoFunc).
  2983  		//
  2984  		// stencil.go works around this limitation by spilling values to
  2985  		// global variables instead, but that causes the value to stay
  2986  		// alive indefinitely; see go.dev/issue/54343.
  2987  		//
  2988  		// This code path (which implements the same workaround) isn't
  2989  		// actually needed by unified IR, because it creates uses normal
  2990  		// OMETHEXPR/OMETHVALUE nodes when statically-known instantiated
  2991  		// types are used. But it's kept around for now because it's handy
  2992  		// for testing that the generic fallback paths work correctly.
  2993  		base.Fatalf("tempCopy called at package scope")
  2994  
  2995  		tmp := staticinit.StaticName(expr.Type())
  2996  
  2997  		assign := ir.NewAssignStmt(pos, tmp, expr)
  2998  		assign.Def = true
  2999  		tmp.Defn = assign
  3000  
  3001  		typecheck.Target.Decls = append(typecheck.Target.Decls, typecheck.Stmt(assign))
  3002  
  3003  		return tmp
  3004  	}
  3005  
  3006  	tmp := r.temp(pos, expr.Type())
  3007  
  3008  	init.Append(typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)))
  3009  
  3010  	assign := ir.NewAssignStmt(pos, tmp, expr)
  3011  	assign.Def = true
  3012  	init.Append(typecheck.Stmt(ir.NewAssignStmt(pos, tmp, expr)))
  3013  
  3014  	tmp.Defn = assign
  3015  
  3016  	return tmp
  3017  }
  3018  
  3019  func (r *reader) compLit() ir.Node {
  3020  	r.Sync(pkgbits.SyncCompLit)
  3021  	pos := r.pos()
  3022  	typ0 := r.typ()
  3023  
  3024  	typ := typ0
  3025  	if typ.IsPtr() {
  3026  		typ = typ.Elem()
  3027  	}
  3028  	if typ.Kind() == types.TFORW {
  3029  		base.FatalfAt(pos, "unresolved composite literal type: %v", typ)
  3030  	}
  3031  	var rtype ir.Node
  3032  	if typ.IsMap() {
  3033  		rtype = r.rtype(pos)
  3034  	}
  3035  	isStruct := typ.Kind() == types.TSTRUCT
  3036  
  3037  	elems := make([]ir.Node, r.Len())
  3038  	for i := range elems {
  3039  		elemp := &elems[i]
  3040  
  3041  		if isStruct {
  3042  			sk := ir.NewStructKeyExpr(r.pos(), typ.Field(r.Len()), nil)
  3043  			*elemp, elemp = sk, &sk.Value
  3044  		} else if r.Bool() {
  3045  			kv := ir.NewKeyExpr(r.pos(), r.expr(), nil)
  3046  			*elemp, elemp = kv, &kv.Value
  3047  		}
  3048  
  3049  		*elemp = wrapName(r.pos(), r.expr())
  3050  	}
  3051  
  3052  	lit := typecheck.Expr(ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems))
  3053  	if rtype != nil {
  3054  		lit := lit.(*ir.CompLitExpr)
  3055  		lit.RType = rtype
  3056  	}
  3057  	if typ0.IsPtr() {
  3058  		lit = typecheck.Expr(typecheck.NodAddrAt(pos, lit))
  3059  		lit.SetType(typ0)
  3060  	}
  3061  	return lit
  3062  }
  3063  
  3064  func wrapName(pos src.XPos, x ir.Node) ir.Node {
  3065  	// These nodes do not carry line numbers.
  3066  	// Introduce a wrapper node to give them the correct line.
  3067  	switch ir.Orig(x).Op() {
  3068  	case ir.OTYPE, ir.OLITERAL:
  3069  		if x.Sym() == nil {
  3070  			break
  3071  		}
  3072  		fallthrough
  3073  	case ir.ONAME, ir.ONONAME, ir.ONIL:
  3074  		p := ir.NewParenExpr(pos, x)
  3075  		p.SetImplicit(true)
  3076  		return p
  3077  	}
  3078  	return x
  3079  }
  3080  
  3081  func (r *reader) funcLit() ir.Node {
  3082  	r.Sync(pkgbits.SyncFuncLit)
  3083  
  3084  	// The underlying function declaration (including its parameters'
  3085  	// positions, if any) need to remain the original, uninlined
  3086  	// positions. This is because we track inlining-context on nodes so
  3087  	// we can synthesize the extra implied stack frames dynamically when
  3088  	// generating tracebacks, whereas those stack frames don't make
  3089  	// sense *within* the function literal. (Any necessary inlining
  3090  	// adjustments will have been applied to the call expression
  3091  	// instead.)
  3092  	//
  3093  	// This is subtle, and getting it wrong leads to cycles in the
  3094  	// inlining tree, which lead to infinite loops during stack
  3095  	// unwinding (#46234, #54625).
  3096  	//
  3097  	// Note that we *do* want the inline-adjusted position for the
  3098  	// OCLOSURE node, because that position represents where any heap
  3099  	// allocation of the closure is credited (#49171).
  3100  	r.suppressInlPos++
  3101  	pos := r.pos()
  3102  	xtype2 := r.signature(types.LocalPkg, nil)
  3103  	r.suppressInlPos--
  3104  
  3105  	fn := ir.NewClosureFunc(pos, r.curfn != nil)
  3106  	clo := fn.OClosure
  3107  	clo.SetPos(r.inlPos(pos)) // see comment above
  3108  	ir.NameClosure(clo, r.curfn)
  3109  
  3110  	setType(fn.Nname, xtype2)
  3111  	typecheck.Func(fn)
  3112  	setType(clo, fn.Type())
  3113  
  3114  	fn.ClosureVars = make([]*ir.Name, 0, r.Len())
  3115  	for len(fn.ClosureVars) < cap(fn.ClosureVars) {
  3116  		ir.NewClosureVar(r.pos(), fn, r.useLocal())
  3117  	}
  3118  	if param := r.dictParam; param != nil {
  3119  		// If we have a dictionary parameter, capture it too. For
  3120  		// simplicity, we capture it last and unconditionally.
  3121  		ir.NewClosureVar(param.Pos(), fn, param)
  3122  	}
  3123  
  3124  	r.addBody(fn, nil)
  3125  
  3126  	// TODO(mdempsky): Remove hard-coding of typecheck.Target.
  3127  	return ir.UseClosure(clo, typecheck.Target)
  3128  }
  3129  
  3130  func (r *reader) exprList() []ir.Node {
  3131  	r.Sync(pkgbits.SyncExprList)
  3132  	return r.exprs()
  3133  }
  3134  
  3135  func (r *reader) exprs() []ir.Node {
  3136  	r.Sync(pkgbits.SyncExprs)
  3137  	nodes := make([]ir.Node, r.Len())
  3138  	if len(nodes) == 0 {
  3139  		return nil // TODO(mdempsky): Unclear if this matters.
  3140  	}
  3141  	for i := range nodes {
  3142  		nodes[i] = r.expr()
  3143  	}
  3144  	return nodes
  3145  }
  3146  
  3147  // dictWord returns an expression to return the specified
  3148  // uintptr-typed word from the dictionary parameter.
  3149  func (r *reader) dictWord(pos src.XPos, idx int) ir.Node {
  3150  	base.AssertfAt(r.dictParam != nil, pos, "expected dictParam in %v", r.curfn)
  3151  	return typecheck.Expr(ir.NewIndexExpr(pos, r.dictParam, ir.NewBasicLit(pos, constant.MakeInt64(int64(idx)))))
  3152  }
  3153  
  3154  // rttiWord is like dictWord, but converts it to *byte (the type used
  3155  // internally to represent *runtime._type and *runtime.itab).
  3156  func (r *reader) rttiWord(pos src.XPos, idx int) ir.Node {
  3157  	return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TUINT8]), r.dictWord(pos, idx)))
  3158  }
  3159  
  3160  // rtype reads a type reference from the element bitstream, and
  3161  // returns an expression of type *runtime._type representing that
  3162  // type.
  3163  func (r *reader) rtype(pos src.XPos) ir.Node {
  3164  	_, rtype := r.rtype0(pos)
  3165  	return rtype
  3166  }
  3167  
  3168  func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) {
  3169  	r.Sync(pkgbits.SyncRType)
  3170  	if r.Bool() { // derived type
  3171  		idx := r.Len()
  3172  		info := r.dict.rtypes[idx]
  3173  		typ = r.p.typIdx(info, r.dict, true)
  3174  		rtype = r.rttiWord(pos, r.dict.rtypesOffset()+idx)
  3175  		return
  3176  	}
  3177  
  3178  	typ = r.typ()
  3179  	rtype = reflectdata.TypePtrAt(pos, typ)
  3180  	return
  3181  }
  3182  
  3183  // varDictIndex populates name.DictIndex if name is a derived type.
  3184  func (r *reader) varDictIndex(name *ir.Name) {
  3185  	if r.Bool() {
  3186  		idx := 1 + r.dict.rtypesOffset() + r.Len()
  3187  		if int(uint16(idx)) != idx {
  3188  			base.FatalfAt(name.Pos(), "DictIndex overflow for %v: %v", name, idx)
  3189  		}
  3190  		name.DictIndex = uint16(idx)
  3191  	}
  3192  }
  3193  
  3194  // itab returns a (typ, iface) pair of types.
  3195  //
  3196  // typRType and ifaceRType are expressions that evaluate to the
  3197  // *runtime._type for typ and iface, respectively.
  3198  //
  3199  // If typ is a concrete type and iface is a non-empty interface type,
  3200  // then itab is an expression that evaluates to the *runtime.itab for
  3201  // the pair. Otherwise, itab is nil.
  3202  func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) {
  3203  	typ, typRType = r.rtype0(pos)
  3204  	iface, ifaceRType = r.rtype0(pos)
  3205  
  3206  	idx := -1
  3207  	if r.Bool() {
  3208  		idx = r.Len()
  3209  	}
  3210  
  3211  	if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
  3212  		if idx >= 0 {
  3213  			itab = r.rttiWord(pos, r.dict.itabsOffset()+idx)
  3214  		} else {
  3215  			base.AssertfAt(!typ.HasShape(), pos, "%v is a shape type", typ)
  3216  			base.AssertfAt(!iface.HasShape(), pos, "%v is a shape type", iface)
  3217  
  3218  			lsym := reflectdata.ITabLsym(typ, iface)
  3219  			itab = typecheck.LinksymAddr(pos, lsym, types.Types[types.TUINT8])
  3220  		}
  3221  	}
  3222  
  3223  	return
  3224  }
  3225  
  3226  // convRTTI returns expressions appropriate for populating an
  3227  // ir.ConvExpr's TypeWord and SrcRType fields, respectively.
  3228  func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) {
  3229  	r.Sync(pkgbits.SyncConvRTTI)
  3230  	src, srcRType0, dst, dstRType, itab := r.itab(pos)
  3231  	if !dst.IsInterface() {
  3232  		return
  3233  	}
  3234  
  3235  	// See reflectdata.ConvIfaceTypeWord.
  3236  	switch {
  3237  	case dst.IsEmptyInterface():
  3238  		if !src.IsInterface() {
  3239  			typeWord = srcRType0 // direct eface construction
  3240  		}
  3241  	case !src.IsInterface():
  3242  		typeWord = itab // direct iface construction
  3243  	default:
  3244  		typeWord = dstRType // convI2I
  3245  	}
  3246  
  3247  	// See reflectdata.ConvIfaceSrcRType.
  3248  	if !src.IsInterface() {
  3249  		srcRType = srcRType0
  3250  	}
  3251  
  3252  	return
  3253  }
  3254  
  3255  func (r *reader) exprType() ir.Node {
  3256  	r.Sync(pkgbits.SyncExprType)
  3257  	pos := r.pos()
  3258  
  3259  	var typ *types.Type
  3260  	var rtype, itab ir.Node
  3261  
  3262  	if r.Bool() {
  3263  		typ, rtype, _, _, itab = r.itab(pos)
  3264  		if !typ.IsInterface() {
  3265  			rtype = nil // TODO(mdempsky): Leave set?
  3266  		}
  3267  	} else {
  3268  		typ, rtype = r.rtype0(pos)
  3269  
  3270  		if !r.Bool() { // not derived
  3271  			// TODO(mdempsky): ir.TypeNode should probably return a typecheck'd node.
  3272  			n := ir.TypeNode(typ)
  3273  			n.SetTypecheck(1)
  3274  			return n
  3275  		}
  3276  	}
  3277  
  3278  	dt := ir.NewDynamicType(pos, rtype)
  3279  	dt.ITab = itab
  3280  	return typed(typ, dt)
  3281  }
  3282  
  3283  func (r *reader) op() ir.Op {
  3284  	r.Sync(pkgbits.SyncOp)
  3285  	return ir.Op(r.Len())
  3286  }
  3287  
  3288  // @@@ Package initialization
  3289  
  3290  func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) {
  3291  	cgoPragmas := make([][]string, r.Len())
  3292  	for i := range cgoPragmas {
  3293  		cgoPragmas[i] = r.Strings()
  3294  	}
  3295  	target.CgoPragmas = cgoPragmas
  3296  
  3297  	r.pkgDecls(target)
  3298  
  3299  	r.Sync(pkgbits.SyncEOF)
  3300  }
  3301  
  3302  func (r *reader) pkgDecls(target *ir.Package) {
  3303  	r.Sync(pkgbits.SyncDecls)
  3304  	for {
  3305  		switch code := codeDecl(r.Code(pkgbits.SyncDecl)); code {
  3306  		default:
  3307  			panic(fmt.Sprintf("unhandled decl: %v", code))
  3308  
  3309  		case declEnd:
  3310  			return
  3311  
  3312  		case declFunc:
  3313  			names := r.pkgObjs(target)
  3314  			assert(len(names) == 1)
  3315  			target.Decls = append(target.Decls, names[0].Func)
  3316  
  3317  		case declMethod:
  3318  			typ := r.typ()
  3319  			_, sym := r.selector()
  3320  
  3321  			method := typecheck.Lookdot1(nil, sym, typ, typ.Methods(), 0)
  3322  			target.Decls = append(target.Decls, method.Nname.(*ir.Name).Func)
  3323  
  3324  		case declVar:
  3325  			pos := r.pos()
  3326  			names := r.pkgObjs(target)
  3327  			values := r.exprList()
  3328  
  3329  			if len(names) > 1 && len(values) == 1 {
  3330  				as := ir.NewAssignListStmt(pos, ir.OAS2, nil, values)
  3331  				for _, name := range names {
  3332  					as.Lhs.Append(name)
  3333  					name.Defn = as
  3334  				}
  3335  				target.Decls = append(target.Decls, as)
  3336  			} else {
  3337  				for i, name := range names {
  3338  					as := ir.NewAssignStmt(pos, name, nil)
  3339  					if i < len(values) {
  3340  						as.Y = values[i]
  3341  					}
  3342  					name.Defn = as
  3343  					target.Decls = append(target.Decls, as)
  3344  				}
  3345  			}
  3346  
  3347  			if n := r.Len(); n > 0 {
  3348  				assert(len(names) == 1)
  3349  				embeds := make([]ir.Embed, n)
  3350  				for i := range embeds {
  3351  					embeds[i] = ir.Embed{Pos: r.pos(), Patterns: r.Strings()}
  3352  				}
  3353  				names[0].Embed = &embeds
  3354  				target.Embeds = append(target.Embeds, names[0])
  3355  			}
  3356  
  3357  		case declOther:
  3358  			r.pkgObjs(target)
  3359  		}
  3360  	}
  3361  }
  3362  
  3363  func (r *reader) pkgObjs(target *ir.Package) []*ir.Name {
  3364  	r.Sync(pkgbits.SyncDeclNames)
  3365  	nodes := make([]*ir.Name, r.Len())
  3366  	for i := range nodes {
  3367  		r.Sync(pkgbits.SyncDeclName)
  3368  
  3369  		name := r.obj().(*ir.Name)
  3370  		nodes[i] = name
  3371  
  3372  		sym := name.Sym()
  3373  		if sym.IsBlank() {
  3374  			continue
  3375  		}
  3376  
  3377  		switch name.Class {
  3378  		default:
  3379  			base.FatalfAt(name.Pos(), "unexpected class: %v", name.Class)
  3380  
  3381  		case ir.PEXTERN:
  3382  			target.Externs = append(target.Externs, name)
  3383  
  3384  		case ir.PFUNC:
  3385  			assert(name.Type().Recv() == nil)
  3386  
  3387  			// TODO(mdempsky): Cleaner way to recognize init?
  3388  			if strings.HasPrefix(sym.Name, "init.") {
  3389  				target.Inits = append(target.Inits, name.Func)
  3390  			}
  3391  		}
  3392  
  3393  		if types.IsExported(sym.Name) {
  3394  			assert(!sym.OnExportList())
  3395  			target.Exports = append(target.Exports, name)
  3396  			sym.SetOnExportList(true)
  3397  		}
  3398  
  3399  		if base.Flag.AsmHdr != "" {
  3400  			assert(!sym.Asm())
  3401  			target.Asms = append(target.Asms, name)
  3402  			sym.SetAsm(true)
  3403  		}
  3404  	}
  3405  
  3406  	return nodes
  3407  }
  3408  
  3409  // @@@ Inlining
  3410  
  3411  // unifiedHaveInlineBody reports whether we have the function body for
  3412  // fn, so we can inline it.
  3413  func unifiedHaveInlineBody(fn *ir.Func) bool {
  3414  	if fn.Inl == nil {
  3415  		return false
  3416  	}
  3417  
  3418  	_, ok := bodyReaderFor(fn)
  3419  	return ok
  3420  }
  3421  
  3422  var inlgen = 0
  3423  
  3424  // unifiedInlineCall implements inline.NewInline by re-reading the function
  3425  // body from its Unified IR export data.
  3426  func unifiedInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
  3427  	// TODO(mdempsky): Turn callerfn into an explicit parameter.
  3428  	callerfn := ir.CurFunc
  3429  
  3430  	pri, ok := bodyReaderFor(fn)
  3431  	if !ok {
  3432  		base.FatalfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
  3433  	}
  3434  
  3435  	if fn.Inl.Body == nil {
  3436  		expandInline(fn, pri)
  3437  	}
  3438  
  3439  	r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
  3440  
  3441  	// TODO(mdempsky): This still feels clumsy. Can we do better?
  3442  	tmpfn := ir.NewFunc(fn.Pos())
  3443  	tmpfn.Nname = ir.NewNameAt(fn.Nname.Pos(), callerfn.Sym())
  3444  	tmpfn.Closgen = callerfn.Closgen
  3445  	defer func() { callerfn.Closgen = tmpfn.Closgen }()
  3446  
  3447  	setType(tmpfn.Nname, fn.Type())
  3448  	r.curfn = tmpfn
  3449  
  3450  	r.inlCaller = callerfn
  3451  	r.inlCall = call
  3452  	r.inlFunc = fn
  3453  	r.inlTreeIndex = inlIndex
  3454  	r.inlPosBases = make(map[*src.PosBase]*src.PosBase)
  3455  
  3456  	r.closureVars = make([]*ir.Name, len(r.inlFunc.ClosureVars))
  3457  	for i, cv := range r.inlFunc.ClosureVars {
  3458  		r.closureVars[i] = cv.Outer
  3459  	}
  3460  	if len(r.closureVars) != 0 && r.hasTypeParams() {
  3461  		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
  3462  	}
  3463  
  3464  	r.funcargs(fn)
  3465  
  3466  	r.delayResults = fn.Inl.CanDelayResults
  3467  
  3468  	r.retlabel = typecheck.AutoLabel(".i")
  3469  	inlgen++
  3470  
  3471  	init := ir.TakeInit(call)
  3472  
  3473  	// For normal function calls, the function callee expression
  3474  	// may contain side effects. Make sure to preserve these,
  3475  	// if necessary (#42703).
  3476  	if call.Op() == ir.OCALLFUNC {
  3477  		inline.CalleeEffects(&init, call.X)
  3478  	}
  3479  
  3480  	var args ir.Nodes
  3481  	if call.Op() == ir.OCALLMETH {
  3482  		base.FatalfAt(call.Pos(), "OCALLMETH missed by typecheck")
  3483  	}
  3484  	args.Append(call.Args...)
  3485  
  3486  	// Create assignment to declare and initialize inlvars.
  3487  	as2 := ir.NewAssignListStmt(call.Pos(), ir.OAS2, r.inlvars, args)
  3488  	as2.Def = true
  3489  	var as2init ir.Nodes
  3490  	for _, name := range r.inlvars {
  3491  		if ir.IsBlank(name) {
  3492  			continue
  3493  		}
  3494  		// TODO(mdempsky): Use inlined position of name.Pos() instead?
  3495  		name := name.(*ir.Name)
  3496  		as2init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
  3497  		name.Defn = as2
  3498  	}
  3499  	as2.SetInit(as2init)
  3500  	init.Append(typecheck.Stmt(as2))
  3501  
  3502  	if !r.delayResults {
  3503  		// If not delaying retvars, declare and zero initialize the
  3504  		// result variables now.
  3505  		for _, name := range r.retvars {
  3506  			// TODO(mdempsky): Use inlined position of name.Pos() instead?
  3507  			name := name.(*ir.Name)
  3508  			init.Append(ir.NewDecl(call.Pos(), ir.ODCL, name))
  3509  			ras := ir.NewAssignStmt(call.Pos(), name, nil)
  3510  			init.Append(typecheck.Stmt(ras))
  3511  		}
  3512  	}
  3513  
  3514  	// Add an inline mark just before the inlined body.
  3515  	// This mark is inline in the code so that it's a reasonable spot
  3516  	// to put a breakpoint. Not sure if that's really necessary or not
  3517  	// (in which case it could go at the end of the function instead).
  3518  	// Note issue 28603.
  3519  	init.Append(ir.NewInlineMarkStmt(call.Pos().WithIsStmt(), int64(r.inlTreeIndex)))
  3520  
  3521  	nparams := len(r.curfn.Dcl)
  3522  
  3523  	ir.WithFunc(r.curfn, func() {
  3524  		if !r.syntheticBody(call.Pos()) {
  3525  			assert(r.Bool()) // have body
  3526  
  3527  			r.curfn.Body = r.stmts()
  3528  			r.curfn.Endlineno = r.pos()
  3529  		}
  3530  
  3531  		// TODO(mdempsky): This shouldn't be necessary. Inlining might
  3532  		// read in new function/method declarations, which could
  3533  		// potentially be recursively inlined themselves; but we shouldn't
  3534  		// need to read in the non-inlined bodies for the declarations
  3535  		// themselves. But currently it's an easy fix to #50552.
  3536  		readBodies(typecheck.Target, true)
  3537  
  3538  		deadcode.Func(r.curfn)
  3539  
  3540  		// Replace any "return" statements within the function body.
  3541  		var edit func(ir.Node) ir.Node
  3542  		edit = func(n ir.Node) ir.Node {
  3543  			if ret, ok := n.(*ir.ReturnStmt); ok {
  3544  				n = typecheck.Stmt(r.inlReturn(ret))
  3545  			}
  3546  			ir.EditChildren(n, edit)
  3547  			return n
  3548  		}
  3549  		edit(r.curfn)
  3550  	})
  3551  
  3552  	body := ir.Nodes(r.curfn.Body)
  3553  
  3554  	// Quirkish: We need to eagerly prune variables added during
  3555  	// inlining, but removed by deadcode.FuncBody above. Unused
  3556  	// variables will get removed during stack frame layout anyway, but
  3557  	// len(fn.Dcl) ends up influencing things like autotmp naming.
  3558  
  3559  	used := usedLocals(body)
  3560  
  3561  	for i, name := range r.curfn.Dcl {
  3562  		if i < nparams || used.Has(name) {
  3563  			name.Curfn = callerfn
  3564  			callerfn.Dcl = append(callerfn.Dcl, name)
  3565  
  3566  			// Quirkish. TODO(mdempsky): Document why.
  3567  			if name.AutoTemp() {
  3568  				name.SetEsc(ir.EscUnknown)
  3569  
  3570  				if base.Flag.GenDwarfInl != 0 {
  3571  					name.SetInlLocal(true)
  3572  				} else {
  3573  					name.SetPos(r.inlCall.Pos())
  3574  				}
  3575  			}
  3576  		}
  3577  	}
  3578  
  3579  	body.Append(ir.NewLabelStmt(call.Pos(), r.retlabel))
  3580  
  3581  	res := ir.NewInlinedCallExpr(call.Pos(), body, append([]ir.Node(nil), r.retvars...))
  3582  	res.SetInit(init)
  3583  	res.SetType(call.Type())
  3584  	res.SetTypecheck(1)
  3585  
  3586  	// Inlining shouldn't add any functions to todoBodies.
  3587  	assert(len(todoBodies) == 0)
  3588  
  3589  	return res
  3590  }
  3591  
  3592  // inlReturn returns a statement that can substitute for the given
  3593  // return statement when inlining.
  3594  func (r *reader) inlReturn(ret *ir.ReturnStmt) *ir.BlockStmt {
  3595  	pos := r.inlCall.Pos()
  3596  
  3597  	block := ir.TakeInit(ret)
  3598  
  3599  	if results := ret.Results; len(results) != 0 {
  3600  		assert(len(r.retvars) == len(results))
  3601  
  3602  		as2 := ir.NewAssignListStmt(pos, ir.OAS2, append([]ir.Node(nil), r.retvars...), ret.Results)
  3603  
  3604  		if r.delayResults {
  3605  			for _, name := range r.retvars {
  3606  				// TODO(mdempsky): Use inlined position of name.Pos() instead?
  3607  				name := name.(*ir.Name)
  3608  				block.Append(ir.NewDecl(pos, ir.ODCL, name))
  3609  				name.Defn = as2
  3610  			}
  3611  		}
  3612  
  3613  		block.Append(as2)
  3614  	}
  3615  
  3616  	block.Append(ir.NewBranchStmt(pos, ir.OGOTO, r.retlabel))
  3617  	return ir.NewBlockStmt(pos, block)
  3618  }
  3619  
  3620  // expandInline reads in an extra copy of IR to populate
  3621  // fn.Inl.{Dcl,Body}.
  3622  func expandInline(fn *ir.Func, pri pkgReaderIndex) {
  3623  	// TODO(mdempsky): Remove this function. It's currently needed by
  3624  	// dwarfgen/dwarf.go:preInliningDcls, which requires fn.Inl.Dcl to
  3625  	// create abstract function DIEs. But we should be able to provide it
  3626  	// with the same information some other way.
  3627  
  3628  	fndcls := len(fn.Dcl)
  3629  	topdcls := len(typecheck.Target.Decls)
  3630  
  3631  	tmpfn := ir.NewFunc(fn.Pos())
  3632  	tmpfn.Nname = ir.NewNameAt(fn.Nname.Pos(), fn.Sym())
  3633  	tmpfn.ClosureVars = fn.ClosureVars
  3634  
  3635  	{
  3636  		r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody)
  3637  		setType(tmpfn.Nname, fn.Type())
  3638  
  3639  		// Don't change parameter's Sym/Nname fields.
  3640  		r.funarghack = true
  3641  
  3642  		r.funcBody(tmpfn)
  3643  
  3644  		ir.WithFunc(tmpfn, func() {
  3645  			deadcode.Func(tmpfn)
  3646  		})
  3647  	}
  3648  
  3649  	used := usedLocals(tmpfn.Body)
  3650  
  3651  	for _, name := range tmpfn.Dcl {
  3652  		if name.Class != ir.PAUTO || used.Has(name) {
  3653  			name.Curfn = fn
  3654  			fn.Inl.Dcl = append(fn.Inl.Dcl, name)
  3655  		}
  3656  	}
  3657  	fn.Inl.Body = tmpfn.Body
  3658  
  3659  	// Double check that we didn't change fn.Dcl by accident.
  3660  	assert(fndcls == len(fn.Dcl))
  3661  
  3662  	// typecheck.Stmts may have added function literals to
  3663  	// typecheck.Target.Decls. Remove them again so we don't risk trying
  3664  	// to compile them multiple times.
  3665  	typecheck.Target.Decls = typecheck.Target.Decls[:topdcls]
  3666  }
  3667  
  3668  // usedLocals returns a set of local variables that are used within body.
  3669  func usedLocals(body []ir.Node) ir.NameSet {
  3670  	var used ir.NameSet
  3671  	ir.VisitList(body, func(n ir.Node) {
  3672  		if n, ok := n.(*ir.Name); ok && n.Op() == ir.ONAME && n.Class == ir.PAUTO {
  3673  			used.Add(n)
  3674  		}
  3675  	})
  3676  	return used
  3677  }
  3678  
  3679  // @@@ Method wrappers
  3680  
  3681  // needWrapperTypes lists types for which we may need to generate
  3682  // method wrappers.
  3683  var needWrapperTypes []*types.Type
  3684  
  3685  // haveWrapperTypes lists types for which we know we already have
  3686  // method wrappers, because we found the type in an imported package.
  3687  var haveWrapperTypes []*types.Type
  3688  
  3689  // needMethodValueWrappers lists methods for which we may need to
  3690  // generate method value wrappers.
  3691  var needMethodValueWrappers []methodValueWrapper
  3692  
  3693  // haveMethodValueWrappers lists methods for which we know we already
  3694  // have method value wrappers, because we found it in an imported
  3695  // package.
  3696  var haveMethodValueWrappers []methodValueWrapper
  3697  
  3698  type methodValueWrapper struct {
  3699  	rcvr   *types.Type
  3700  	method *types.Field
  3701  }
  3702  
  3703  func (r *reader) needWrapper(typ *types.Type) {
  3704  	if typ.IsPtr() {
  3705  		return
  3706  	}
  3707  
  3708  	// If a type was found in an imported package, then we can assume
  3709  	// that package (or one of its transitive dependencies) already
  3710  	// generated method wrappers for it.
  3711  	if r.importedDef() {
  3712  		haveWrapperTypes = append(haveWrapperTypes, typ)
  3713  	} else {
  3714  		needWrapperTypes = append(needWrapperTypes, typ)
  3715  	}
  3716  }
  3717  
  3718  // importedDef reports whether r is reading from an imported and
  3719  // non-generic element.
  3720  //
  3721  // If a type was found in an imported package, then we can assume that
  3722  // package (or one of its transitive dependencies) already generated
  3723  // method wrappers for it.
  3724  //
  3725  // Exception: If we're instantiating an imported generic type or
  3726  // function, we might be instantiating it with type arguments not
  3727  // previously seen before.
  3728  //
  3729  // TODO(mdempsky): Distinguish when a generic function or type was
  3730  // instantiated in an imported package so that we can add types to
  3731  // haveWrapperTypes instead.
  3732  func (r *reader) importedDef() bool {
  3733  	return r.p != localPkgReader && !r.hasTypeParams()
  3734  }
  3735  
  3736  func MakeWrappers(target *ir.Package) {
  3737  	// Only unified IR emits its own wrappers.
  3738  	if base.Debug.Unified == 0 {
  3739  		return
  3740  	}
  3741  
  3742  	// always generate a wrapper for error.Error (#29304)
  3743  	needWrapperTypes = append(needWrapperTypes, types.ErrorType)
  3744  
  3745  	seen := make(map[string]*types.Type)
  3746  
  3747  	for _, typ := range haveWrapperTypes {
  3748  		wrapType(typ, target, seen, false)
  3749  	}
  3750  	haveWrapperTypes = nil
  3751  
  3752  	for _, typ := range needWrapperTypes {
  3753  		wrapType(typ, target, seen, true)
  3754  	}
  3755  	needWrapperTypes = nil
  3756  
  3757  	for _, wrapper := range haveMethodValueWrappers {
  3758  		wrapMethodValue(wrapper.rcvr, wrapper.method, target, false)
  3759  	}
  3760  	haveMethodValueWrappers = nil
  3761  
  3762  	for _, wrapper := range needMethodValueWrappers {
  3763  		wrapMethodValue(wrapper.rcvr, wrapper.method, target, true)
  3764  	}
  3765  	needMethodValueWrappers = nil
  3766  }
  3767  
  3768  func wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) {
  3769  	key := typ.LinkString()
  3770  	if prev := seen[key]; prev != nil {
  3771  		if !types.Identical(typ, prev) {
  3772  			base.Fatalf("collision: types %v and %v have link string %q", typ, prev, key)
  3773  		}
  3774  		return
  3775  	}
  3776  	seen[key] = typ
  3777  
  3778  	if !needed {
  3779  		// Only called to add to 'seen'.
  3780  		return
  3781  	}
  3782  
  3783  	if !typ.IsInterface() {
  3784  		typecheck.CalcMethods(typ)
  3785  	}
  3786  	for _, meth := range typ.AllMethods().Slice() {
  3787  		if meth.Sym.IsBlank() || !meth.IsMethod() {
  3788  			base.FatalfAt(meth.Pos, "invalid method: %v", meth)
  3789  		}
  3790  
  3791  		methodWrapper(0, typ, meth, target)
  3792  
  3793  		// For non-interface types, we also want *T wrappers.
  3794  		if !typ.IsInterface() {
  3795  			methodWrapper(1, typ, meth, target)
  3796  
  3797  			// For not-in-heap types, *T is a scalar, not pointer shaped,
  3798  			// so the interface wrappers use **T.
  3799  			if typ.NotInHeap() {
  3800  				methodWrapper(2, typ, meth, target)
  3801  			}
  3802  		}
  3803  	}
  3804  }
  3805  
  3806  func methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) {
  3807  	wrapper := tbase
  3808  	for i := 0; i < derefs; i++ {
  3809  		wrapper = types.NewPtr(wrapper)
  3810  	}
  3811  
  3812  	sym := ir.MethodSym(wrapper, method.Sym)
  3813  	base.Assertf(!sym.Siggen(), "already generated wrapper %v", sym)
  3814  	sym.SetSiggen(true)
  3815  
  3816  	wrappee := method.Type.Recv().Type
  3817  	if types.Identical(wrapper, wrappee) ||
  3818  		!types.IsMethodApplicable(wrapper, method) ||
  3819  		!reflectdata.NeedEmit(tbase) {
  3820  		return
  3821  	}
  3822  
  3823  	// TODO(mdempsky): Use method.Pos instead?
  3824  	pos := base.AutogeneratedPos
  3825  
  3826  	fn := newWrapperFunc(pos, sym, wrapper, method)
  3827  
  3828  	var recv ir.Node = fn.Nname.Type().Recv().Nname.(*ir.Name)
  3829  
  3830  	// For simple *T wrappers around T methods, panicwrap produces a
  3831  	// nicer panic message.
  3832  	if wrapper.IsPtr() && types.Identical(wrapper.Elem(), wrappee) {
  3833  		cond := ir.NewBinaryExpr(pos, ir.OEQ, recv, types.BuiltinPkg.Lookup("nil").Def.(ir.Node))
  3834  		then := []ir.Node{ir.NewCallExpr(pos, ir.OCALL, typecheck.LookupRuntime("panicwrap"), nil)}
  3835  		fn.Body.Append(ir.NewIfStmt(pos, cond, then, nil))
  3836  	}
  3837  
  3838  	// typecheck will add one implicit deref, if necessary,
  3839  	// but not-in-heap types require more for their **T wrappers.
  3840  	for i := 1; i < derefs; i++ {
  3841  		recv = Implicit(ir.NewStarExpr(pos, recv))
  3842  	}
  3843  
  3844  	addTailCall(pos, fn, recv, method)
  3845  
  3846  	finishWrapperFunc(fn, target)
  3847  }
  3848  
  3849  func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) {
  3850  	sym := ir.MethodSymSuffix(recvType, method.Sym, "-fm")
  3851  	if sym.Uniq() {
  3852  		return
  3853  	}
  3854  	sym.SetUniq(true)
  3855  
  3856  	// TODO(mdempsky): Use method.Pos instead?
  3857  	pos := base.AutogeneratedPos
  3858  
  3859  	fn := newWrapperFunc(pos, sym, nil, method)
  3860  	sym.Def = fn.Nname
  3861  
  3862  	// Declare and initialize variable holding receiver.
  3863  	recv := ir.NewHiddenParam(pos, fn, typecheck.Lookup(".this"), recvType)
  3864  
  3865  	if !needed {
  3866  		typecheck.Func(fn)
  3867  		return
  3868  	}
  3869  
  3870  	addTailCall(pos, fn, recv, method)
  3871  
  3872  	finishWrapperFunc(fn, target)
  3873  }
  3874  
  3875  func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
  3876  	fn := ir.NewFunc(pos)
  3877  	fn.SetDupok(true) // TODO(mdempsky): Leave unset for local, non-generic wrappers?
  3878  
  3879  	name := ir.NewNameAt(pos, sym)
  3880  	ir.MarkFunc(name)
  3881  	name.Func = fn
  3882  	name.Defn = fn
  3883  	fn.Nname = name
  3884  
  3885  	sig := newWrapperType(wrapper, method)
  3886  	setType(name, sig)
  3887  
  3888  	// TODO(mdempsky): De-duplicate with similar logic in funcargs.
  3889  	defParams := func(class ir.Class, params *types.Type) {
  3890  		for _, param := range params.FieldSlice() {
  3891  			name := ir.NewNameAt(param.Pos, param.Sym)
  3892  			name.Class = class
  3893  			setType(name, param.Type)
  3894  
  3895  			name.Curfn = fn
  3896  			fn.Dcl = append(fn.Dcl, name)
  3897  
  3898  			param.Nname = name
  3899  		}
  3900  	}
  3901  
  3902  	defParams(ir.PPARAM, sig.Recvs())
  3903  	defParams(ir.PPARAM, sig.Params())
  3904  	defParams(ir.PPARAMOUT, sig.Results())
  3905  
  3906  	return fn
  3907  }
  3908  
  3909  func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
  3910  	typecheck.Func(fn)
  3911  
  3912  	ir.WithFunc(fn, func() {
  3913  		typecheck.Stmts(fn.Body)
  3914  	})
  3915  
  3916  	// We generate wrappers after the global inlining pass,
  3917  	// so we're responsible for applying inlining ourselves here.
  3918  	// TODO(prattmic): plumb PGO.
  3919  	inline.InlineCalls(fn, nil)
  3920  
  3921  	// The body of wrapper function after inlining may reveal new ir.OMETHVALUE node,
  3922  	// we don't know whether wrapper function has been generated for it or not, so
  3923  	// generate one immediately here.
  3924  	ir.VisitList(fn.Body, func(n ir.Node) {
  3925  		if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
  3926  			wrapMethodValue(n.X.Type(), n.Selection, target, true)
  3927  		}
  3928  	})
  3929  
  3930  	target.Decls = append(target.Decls, fn)
  3931  }
  3932  
  3933  // newWrapperType returns a copy of the given signature type, but with
  3934  // the receiver parameter type substituted with recvType.
  3935  // If recvType is nil, newWrapperType returns a signature
  3936  // without a receiver parameter.
  3937  func newWrapperType(recvType *types.Type, method *types.Field) *types.Type {
  3938  	clone := func(params []*types.Field) []*types.Field {
  3939  		res := make([]*types.Field, len(params))
  3940  		for i, param := range params {
  3941  			sym := param.Sym
  3942  			if sym == nil || sym.Name == "_" {
  3943  				sym = typecheck.LookupNum(".anon", i)
  3944  			}
  3945  			res[i] = types.NewField(param.Pos, sym, param.Type)
  3946  			res[i].SetIsDDD(param.IsDDD())
  3947  		}
  3948  		return res
  3949  	}
  3950  
  3951  	sig := method.Type
  3952  
  3953  	var recv *types.Field
  3954  	if recvType != nil {
  3955  		recv = types.NewField(sig.Recv().Pos, typecheck.Lookup(".this"), recvType)
  3956  	}
  3957  	params := clone(sig.Params().FieldSlice())
  3958  	results := clone(sig.Results().FieldSlice())
  3959  
  3960  	return types.NewSignature(types.NoPkg, recv, nil, params, results)
  3961  }
  3962  
  3963  func addTailCall(pos src.XPos, fn *ir.Func, recv ir.Node, method *types.Field) {
  3964  	sig := fn.Nname.Type()
  3965  	args := make([]ir.Node, sig.NumParams())
  3966  	for i, param := range sig.Params().FieldSlice() {
  3967  		args[i] = param.Nname.(*ir.Name)
  3968  	}
  3969  
  3970  	// TODO(mdempsky): Support creating OTAILCALL, when possible. See reflectdata.methodWrapper.
  3971  	// Not urgent though, because tail calls are currently incompatible with regabi anyway.
  3972  
  3973  	fn.SetWrapper(true) // TODO(mdempsky): Leave unset for tail calls?
  3974  
  3975  	dot := ir.NewSelectorExpr(pos, ir.OXDOT, recv, method.Sym)
  3976  	call := typecheck.Call(pos, dot, args, method.Type.IsVariadic()).(*ir.CallExpr)
  3977  
  3978  	if method.Type.NumResults() == 0 {
  3979  		fn.Body.Append(call)
  3980  		return
  3981  	}
  3982  
  3983  	ret := ir.NewReturnStmt(pos, nil)
  3984  	ret.Results = []ir.Node{call}
  3985  	fn.Body.Append(ret)
  3986  }
  3987  
  3988  func setBasePos(pos src.XPos) {
  3989  	// Set the position for any error messages we might print (e.g. too large types).
  3990  	base.Pos = pos
  3991  }
  3992  
  3993  // dictParamName is the name of the synthetic dictionary parameter
  3994  // added to shaped functions.
  3995  //
  3996  // N.B., this variable name is known to Delve:
  3997  // https://github.com/go-delve/delve/blob/cb91509630529e6055be845688fd21eb89ae8714/pkg/proc/eval.go#L28
  3998  const dictParamName = ".dict"
  3999  
  4000  // shapeSig returns a copy of fn's signature, except adding a
  4001  // dictionary parameter and promoting the receiver parameter (if any)
  4002  // to a normal parameter.
  4003  //
  4004  // The parameter types.Fields are all copied too, so their Nname
  4005  // fields can be initialized for use by the shape function.
  4006  func shapeSig(fn *ir.Func, dict *readerDict) *types.Type {
  4007  	sig := fn.Nname.Type()
  4008  	oldRecv := sig.Recv()
  4009  
  4010  	var recv *types.Field
  4011  	if oldRecv != nil {
  4012  		recv = types.NewField(oldRecv.Pos, oldRecv.Sym, oldRecv.Type)
  4013  	}
  4014  
  4015  	params := make([]*types.Field, 1+sig.Params().Fields().Len())
  4016  	params[0] = types.NewField(fn.Pos(), fn.Sym().Pkg.Lookup(dictParamName), types.NewPtr(dict.varType()))
  4017  	for i, param := range sig.Params().Fields().Slice() {
  4018  		d := types.NewField(param.Pos, param.Sym, param.Type)
  4019  		d.SetIsDDD(param.IsDDD())
  4020  		params[1+i] = d
  4021  	}
  4022  
  4023  	results := make([]*types.Field, sig.Results().Fields().Len())
  4024  	for i, result := range sig.Results().Fields().Slice() {
  4025  		results[i] = types.NewField(result.Pos, result.Sym, result.Type)
  4026  	}
  4027  
  4028  	return types.NewSignature(types.LocalPkg, recv, nil, params, results)
  4029  }