github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/noder/writer.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/internal/pkgbits"
    10  
    11  	"github.com/bir3/gocompiler/src/cmd/compile/internal/base"
    12  	"github.com/bir3/gocompiler/src/cmd/compile/internal/ir"
    13  	"github.com/bir3/gocompiler/src/cmd/compile/internal/syntax"
    14  	"github.com/bir3/gocompiler/src/cmd/compile/internal/types"
    15  	"github.com/bir3/gocompiler/src/cmd/compile/internal/types2"
    16  )
    17  
    18  // This file implements the Unified IR package writer and defines the
    19  // Unified IR export data format.
    20  //
    21  // Low-level coding details (e.g., byte-encoding of individual
    22  // primitive values, or handling element bitstreams and
    23  // cross-references) are handled by internal/pkgbits, so here we only
    24  // concern ourselves with higher-level worries like mapping Go
    25  // language constructs into elements.
    26  
    27  // There are two central types in the writing process: the "writer"
    28  // type handles writing out individual elements, while the "pkgWriter"
    29  // type keeps track of which elements have already been created.
    30  //
    31  // For each sort of "thing" (e.g., position, package, object, type)
    32  // that can be written into the export data, there are generally
    33  // several methods that work together:
    34  //
    35  // - writer.thing handles writing out a *use* of a thing, which often
    36  //   means writing a relocation to that thing's encoded index.
    37  //
    38  // - pkgWriter.thingIdx handles reserving an index for a thing, and
    39  //   writing out any elements needed for the thing.
    40  //
    41  // - writer.doThing handles writing out the *definition* of a thing,
    42  //   which in general is a mix of low-level coding primitives (e.g.,
    43  //   ints and strings) or uses of other things.
    44  //
    45  // A design goal of Unified IR is to have a single, canonical writer
    46  // implementation, but multiple reader implementations each tailored
    47  // to their respective needs. For example, within cmd/compile's own
    48  // backend, inlining is implemented largely by just re-running the
    49  // function body reading code.
    50  
    51  // TODO(mdempsky): Add an importer for Unified IR to the x/tools repo,
    52  // and better document the file format boundary between public and
    53  // private data.
    54  
    55  // A pkgWriter constructs Unified IR export data from the results of
    56  // running the types2 type checker on a Go compilation unit.
    57  type pkgWriter struct {
    58  	pkgbits.PkgEncoder
    59  
    60  	m      posMap
    61  	curpkg *types2.Package
    62  	info   *types2.Info
    63  
    64  	// Indices for previously written syntax and types2 things.
    65  
    66  	posBasesIdx map[*syntax.PosBase]pkgbits.Index
    67  	pkgsIdx     map[*types2.Package]pkgbits.Index
    68  	typsIdx     map[types2.Type]pkgbits.Index
    69  	objsIdx     map[types2.Object]pkgbits.Index
    70  
    71  	// Maps from types2.Objects back to their syntax.Decl.
    72  
    73  	funDecls map[*types2.Func]*syntax.FuncDecl
    74  	typDecls map[*types2.TypeName]typeDeclGen
    75  
    76  	// linknames maps package-scope objects to their linker symbol name,
    77  	// if specified by a //go:linkname directive.
    78  	linknames map[types2.Object]string
    79  
    80  	// cgoPragmas accumulates any //go:cgo_* pragmas that need to be
    81  	// passed through to cmd/link.
    82  	cgoPragmas [][]string
    83  }
    84  
    85  // newPkgWriter returns an initialized pkgWriter for the specified
    86  // package.
    87  func newPkgWriter(m posMap, pkg *types2.Package, info *types2.Info) *pkgWriter {
    88  	return &pkgWriter{
    89  		PkgEncoder: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
    90  
    91  		m:      m,
    92  		curpkg: pkg,
    93  		info:   info,
    94  
    95  		pkgsIdx: make(map[*types2.Package]pkgbits.Index),
    96  		objsIdx: make(map[types2.Object]pkgbits.Index),
    97  		typsIdx: make(map[types2.Type]pkgbits.Index),
    98  
    99  		posBasesIdx: make(map[*syntax.PosBase]pkgbits.Index),
   100  
   101  		funDecls: make(map[*types2.Func]*syntax.FuncDecl),
   102  		typDecls: make(map[*types2.TypeName]typeDeclGen),
   103  
   104  		linknames: make(map[types2.Object]string),
   105  	}
   106  }
   107  
   108  // errorf reports a user error about thing p.
   109  func (pw *pkgWriter) errorf(p poser, msg string, args ...interface{}) {
   110  	base.ErrorfAt(pw.m.pos(p), msg, args...)
   111  }
   112  
   113  // fatalf reports an internal compiler error about thing p.
   114  func (pw *pkgWriter) fatalf(p poser, msg string, args ...interface{}) {
   115  	base.FatalfAt(pw.m.pos(p), msg, args...)
   116  }
   117  
   118  // unexpected reports a fatal error about a thing of unexpected
   119  // dynamic type.
   120  func (pw *pkgWriter) unexpected(what string, p poser) {
   121  	pw.fatalf(p, "unexpected %s: %v (%T)", what, p, p)
   122  }
   123  
   124  func (pw *pkgWriter) typeAndValue(x syntax.Expr) syntax.TypeAndValue {
   125  	tv := x.GetTypeInfo()
   126  	if tv.Type == nil {
   127  		pw.fatalf(x, "missing Types entry: %v", syntax.String(x))
   128  	}
   129  	return tv
   130  }
   131  func (pw *pkgWriter) maybeTypeAndValue(x syntax.Expr) (syntax.TypeAndValue, bool) {
   132  	tv := x.GetTypeInfo()
   133  	return tv, tv.Type != nil
   134  }
   135  
   136  // typeOf returns the Type of the given value expression.
   137  func (pw *pkgWriter) typeOf(expr syntax.Expr) types2.Type {
   138  	tv := pw.typeAndValue(expr)
   139  	if !tv.IsValue() {
   140  		pw.fatalf(expr, "expected value: %v", syntax.String(expr))
   141  	}
   142  	return tv.Type
   143  }
   144  
   145  // A writer provides APIs for writing out an individual element.
   146  type writer struct {
   147  	p *pkgWriter
   148  
   149  	pkgbits.Encoder
   150  
   151  	// sig holds the signature for the current function body, if any.
   152  	sig *types2.Signature
   153  
   154  	// TODO(mdempsky): We should be able to prune localsIdx whenever a
   155  	// scope closes, and then maybe we can just use the same map for
   156  	// storing the TypeParams too (as their TypeName instead).
   157  
   158  	// localsIdx tracks any local variables declared within this
   159  	// function body. It's unused for writing out non-body things.
   160  	localsIdx map[*types2.Var]int
   161  
   162  	// closureVars tracks any free variables that are referenced by this
   163  	// function body. It's unused for writing out non-body things.
   164  	closureVars    []posVar
   165  	closureVarsIdx map[*types2.Var]int // index of previously seen free variables
   166  
   167  	dict *writerDict
   168  
   169  	// derived tracks whether the type being written out references any
   170  	// type parameters. It's unused for writing non-type things.
   171  	derived bool
   172  }
   173  
   174  // A writerDict tracks types and objects that are used by a declaration.
   175  type writerDict struct {
   176  	implicits []*types2.TypeName
   177  
   178  	// derived is a slice of type indices for computing derived types
   179  	// (i.e., types that depend on the declaration's type parameters).
   180  	derived []derivedInfo
   181  
   182  	// derivedIdx maps a Type to its corresponding index within the
   183  	// derived slice, if present.
   184  	derivedIdx map[types2.Type]pkgbits.Index
   185  
   186  	// These slices correspond to entries in the runtime dictionary.
   187  	typeParamMethodExprs []writerMethodExprInfo
   188  	subdicts             []objInfo
   189  	rtypes               []typeInfo
   190  	itabs                []itabInfo
   191  }
   192  
   193  type itabInfo struct {
   194  	typ   typeInfo
   195  	iface typeInfo
   196  }
   197  
   198  // typeParamIndex returns the index of the given type parameter within
   199  // the dictionary. This may differ from typ.Index() when there are
   200  // implicit type parameters due to defined types declared within a
   201  // generic function or method.
   202  func (dict *writerDict) typeParamIndex(typ *types2.TypeParam) int {
   203  	for idx, implicit := range dict.implicits {
   204  		if implicit.Type().(*types2.TypeParam) == typ {
   205  			return idx
   206  		}
   207  	}
   208  
   209  	return len(dict.implicits) + typ.Index()
   210  }
   211  
   212  // A derivedInfo represents a reference to an encoded generic Go type.
   213  type derivedInfo struct {
   214  	idx    pkgbits.Index
   215  	needed bool // TODO(mdempsky): Remove.
   216  }
   217  
   218  // A typeInfo represents a reference to an encoded Go type.
   219  //
   220  // If derived is true, then the typeInfo represents a generic Go type
   221  // that contains type parameters. In this case, idx is an index into
   222  // the readerDict.derived{,Types} arrays.
   223  //
   224  // Otherwise, the typeInfo represents a non-generic Go type, and idx
   225  // is an index into the reader.typs array instead.
   226  type typeInfo struct {
   227  	idx     pkgbits.Index
   228  	derived bool
   229  }
   230  
   231  // An objInfo represents a reference to an encoded, instantiated (if
   232  // applicable) Go object.
   233  type objInfo struct {
   234  	idx       pkgbits.Index // index for the generic function declaration
   235  	explicits []typeInfo    // info for the type arguments
   236  }
   237  
   238  // A selectorInfo represents a reference to an encoded field or method
   239  // name (i.e., objects that can only be accessed using selector
   240  // expressions).
   241  type selectorInfo struct {
   242  	pkgIdx  pkgbits.Index
   243  	nameIdx pkgbits.Index
   244  }
   245  
   246  // anyDerived reports whether any of info's explicit type arguments
   247  // are derived types.
   248  func (info objInfo) anyDerived() bool {
   249  	for _, explicit := range info.explicits {
   250  		if explicit.derived {
   251  			return true
   252  		}
   253  	}
   254  	return false
   255  }
   256  
   257  // equals reports whether info and other represent the same Go object
   258  // (i.e., same base object and identical type arguments, if any).
   259  func (info objInfo) equals(other objInfo) bool {
   260  	if info.idx != other.idx {
   261  		return false
   262  	}
   263  	assert(len(info.explicits) == len(other.explicits))
   264  	for i, targ := range info.explicits {
   265  		if targ != other.explicits[i] {
   266  			return false
   267  		}
   268  	}
   269  	return true
   270  }
   271  
   272  type writerMethodExprInfo struct {
   273  	typeParamIdx int
   274  	methodInfo   selectorInfo
   275  }
   276  
   277  // typeParamMethodExprIdx returns the index where the given encoded
   278  // method expression function pointer appears within this dictionary's
   279  // type parameters method expressions section, adding it if necessary.
   280  func (dict *writerDict) typeParamMethodExprIdx(typeParamIdx int, methodInfo selectorInfo) int {
   281  	newInfo := writerMethodExprInfo{typeParamIdx, methodInfo}
   282  
   283  	for idx, oldInfo := range dict.typeParamMethodExprs {
   284  		if oldInfo == newInfo {
   285  			return idx
   286  		}
   287  	}
   288  
   289  	idx := len(dict.typeParamMethodExprs)
   290  	dict.typeParamMethodExprs = append(dict.typeParamMethodExprs, newInfo)
   291  	return idx
   292  }
   293  
   294  // subdictIdx returns the index where the given encoded object's
   295  // runtime dictionary appears within this dictionary's subdictionary
   296  // section, adding it if necessary.
   297  func (dict *writerDict) subdictIdx(newInfo objInfo) int {
   298  	for idx, oldInfo := range dict.subdicts {
   299  		if oldInfo.equals(newInfo) {
   300  			return idx
   301  		}
   302  	}
   303  
   304  	idx := len(dict.subdicts)
   305  	dict.subdicts = append(dict.subdicts, newInfo)
   306  	return idx
   307  }
   308  
   309  // rtypeIdx returns the index where the given encoded type's
   310  // *runtime._type value appears within this dictionary's rtypes
   311  // section, adding it if necessary.
   312  func (dict *writerDict) rtypeIdx(newInfo typeInfo) int {
   313  	for idx, oldInfo := range dict.rtypes {
   314  		if oldInfo == newInfo {
   315  			return idx
   316  		}
   317  	}
   318  
   319  	idx := len(dict.rtypes)
   320  	dict.rtypes = append(dict.rtypes, newInfo)
   321  	return idx
   322  }
   323  
   324  // itabIdx returns the index where the given encoded type pair's
   325  // *runtime.itab value appears within this dictionary's itabs section,
   326  // adding it if necessary.
   327  func (dict *writerDict) itabIdx(typInfo, ifaceInfo typeInfo) int {
   328  	newInfo := itabInfo{typInfo, ifaceInfo}
   329  
   330  	for idx, oldInfo := range dict.itabs {
   331  		if oldInfo == newInfo {
   332  			return idx
   333  		}
   334  	}
   335  
   336  	idx := len(dict.itabs)
   337  	dict.itabs = append(dict.itabs, newInfo)
   338  	return idx
   339  }
   340  
   341  func (pw *pkgWriter) newWriter(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *writer {
   342  	return &writer{
   343  		Encoder: pw.NewEncoder(k, marker),
   344  		p:       pw,
   345  	}
   346  }
   347  
   348  // @@@ Positions
   349  
   350  // pos writes the position of p into the element bitstream.
   351  func (w *writer) pos(p poser) {
   352  	w.Sync(pkgbits.SyncPos)
   353  	pos := p.Pos()
   354  
   355  	// TODO(mdempsky): Track down the remaining cases here and fix them.
   356  	if !w.Bool(pos.IsKnown()) {
   357  		return
   358  	}
   359  
   360  	// TODO(mdempsky): Delta encoding.
   361  	w.posBase(pos.Base())
   362  	w.Uint(pos.Line())
   363  	w.Uint(pos.Col())
   364  }
   365  
   366  // posBase writes a reference to the given PosBase into the element
   367  // bitstream.
   368  func (w *writer) posBase(b *syntax.PosBase) {
   369  	w.Reloc(pkgbits.RelocPosBase, w.p.posBaseIdx(b))
   370  }
   371  
   372  // posBaseIdx returns the index for the given PosBase.
   373  func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) pkgbits.Index {
   374  	if idx, ok := pw.posBasesIdx[b]; ok {
   375  		return idx
   376  	}
   377  
   378  	w := pw.newWriter(pkgbits.RelocPosBase, pkgbits.SyncPosBase)
   379  	w.p.posBasesIdx[b] = w.Idx
   380  
   381  	w.String(trimFilename(b))
   382  
   383  	if !w.Bool(b.IsFileBase()) {
   384  		w.pos(b)
   385  		w.Uint(b.Line())
   386  		w.Uint(b.Col())
   387  	}
   388  
   389  	return w.Flush()
   390  }
   391  
   392  // @@@ Packages
   393  
   394  // pkg writes a use of the given Package into the element bitstream.
   395  func (w *writer) pkg(pkg *types2.Package) {
   396  	w.pkgRef(w.p.pkgIdx(pkg))
   397  }
   398  
   399  func (w *writer) pkgRef(idx pkgbits.Index) {
   400  	w.Sync(pkgbits.SyncPkg)
   401  	w.Reloc(pkgbits.RelocPkg, idx)
   402  }
   403  
   404  // pkgIdx returns the index for the given package, adding it to the
   405  // package export data if needed.
   406  func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
   407  	if idx, ok := pw.pkgsIdx[pkg]; ok {
   408  		return idx
   409  	}
   410  
   411  	w := pw.newWriter(pkgbits.RelocPkg, pkgbits.SyncPkgDef)
   412  	pw.pkgsIdx[pkg] = w.Idx
   413  
   414  	// The universe and package unsafe need to be handled specially by
   415  	// importers anyway, so we serialize them using just their package
   416  	// path. This ensures that readers don't confuse them for
   417  	// user-defined packages.
   418  	switch pkg {
   419  	case nil: // universe
   420  		w.String("builtin") // same package path used by godoc
   421  	case types2.Unsafe:
   422  		w.String("unsafe")
   423  	default:
   424  		// TODO(mdempsky): Write out pkg.Path() for curpkg too.
   425  		var path string
   426  		if pkg != w.p.curpkg {
   427  			path = pkg.Path()
   428  		}
   429  		base.Assertf(path != "builtin" && path != "unsafe", "unexpected path for user-defined package: %q", path)
   430  		w.String(path)
   431  		w.String(pkg.Name())
   432  
   433  		w.Len(len(pkg.Imports()))
   434  		for _, imp := range pkg.Imports() {
   435  			w.pkg(imp)
   436  		}
   437  	}
   438  
   439  	return w.Flush()
   440  }
   441  
   442  // @@@ Types
   443  
   444  var (
   445  	anyTypeName        = types2.Universe.Lookup("any").(*types2.TypeName)
   446  	comparableTypeName = types2.Universe.Lookup("comparable").(*types2.TypeName)
   447  	runeTypeName       = types2.Universe.Lookup("rune").(*types2.TypeName)
   448  )
   449  
   450  // typ writes a use of the given type into the bitstream.
   451  func (w *writer) typ(typ types2.Type) {
   452  	w.typInfo(w.p.typIdx(typ, w.dict))
   453  }
   454  
   455  // typInfo writes a use of the given type (specified as a typeInfo
   456  // instead) into the bitstream.
   457  func (w *writer) typInfo(info typeInfo) {
   458  	w.Sync(pkgbits.SyncType)
   459  	if w.Bool(info.derived) {
   460  		w.Len(int(info.idx))
   461  		w.derived = true
   462  	} else {
   463  		w.Reloc(pkgbits.RelocType, info.idx)
   464  	}
   465  }
   466  
   467  // typIdx returns the index where the export data description of type
   468  // can be read back in. If no such index exists yet, it's created.
   469  //
   470  // typIdx also reports whether typ is a derived type; that is, whether
   471  // its identity depends on type parameters.
   472  func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
   473  	if idx, ok := pw.typsIdx[typ]; ok {
   474  		return typeInfo{idx: idx, derived: false}
   475  	}
   476  	if dict != nil {
   477  		if idx, ok := dict.derivedIdx[typ]; ok {
   478  			return typeInfo{idx: idx, derived: true}
   479  		}
   480  	}
   481  
   482  	w := pw.newWriter(pkgbits.RelocType, pkgbits.SyncTypeIdx)
   483  	w.dict = dict
   484  
   485  	switch typ := typ.(type) {
   486  	default:
   487  		base.Fatalf("unexpected type: %v (%T)", typ, typ)
   488  
   489  	case *types2.Basic:
   490  		switch kind := typ.Kind(); {
   491  		case kind == types2.Invalid:
   492  			base.Fatalf("unexpected types2.Invalid")
   493  
   494  		case types2.Typ[kind] == typ:
   495  			w.Code(pkgbits.TypeBasic)
   496  			w.Len(int(kind))
   497  
   498  		default:
   499  			// Handle "byte" and "rune" as references to their TypeNames.
   500  			obj := types2.Universe.Lookup(typ.Name())
   501  			assert(obj.Type() == typ)
   502  
   503  			w.Code(pkgbits.TypeNamed)
   504  			w.obj(obj, nil)
   505  		}
   506  
   507  	case *types2.Named:
   508  		obj, targs := splitNamed(typ)
   509  
   510  		// Defined types that are declared within a generic function (and
   511  		// thus have implicit type parameters) are always derived types.
   512  		if w.p.hasImplicitTypeParams(obj) {
   513  			w.derived = true
   514  		}
   515  
   516  		w.Code(pkgbits.TypeNamed)
   517  		w.obj(obj, targs)
   518  
   519  	case *types2.TypeParam:
   520  		w.derived = true
   521  		w.Code(pkgbits.TypeTypeParam)
   522  		w.Len(w.dict.typeParamIndex(typ))
   523  
   524  	case *types2.Array:
   525  		w.Code(pkgbits.TypeArray)
   526  		w.Uint64(uint64(typ.Len()))
   527  		w.typ(typ.Elem())
   528  
   529  	case *types2.Chan:
   530  		w.Code(pkgbits.TypeChan)
   531  		w.Len(int(typ.Dir()))
   532  		w.typ(typ.Elem())
   533  
   534  	case *types2.Map:
   535  		w.Code(pkgbits.TypeMap)
   536  		w.typ(typ.Key())
   537  		w.typ(typ.Elem())
   538  
   539  	case *types2.Pointer:
   540  		w.Code(pkgbits.TypePointer)
   541  		w.typ(typ.Elem())
   542  
   543  	case *types2.Signature:
   544  		base.Assertf(typ.TypeParams() == nil, "unexpected type params: %v", typ)
   545  		w.Code(pkgbits.TypeSignature)
   546  		w.signature(typ)
   547  
   548  	case *types2.Slice:
   549  		w.Code(pkgbits.TypeSlice)
   550  		w.typ(typ.Elem())
   551  
   552  	case *types2.Struct:
   553  		w.Code(pkgbits.TypeStruct)
   554  		w.structType(typ)
   555  
   556  	case *types2.Interface:
   557  		// Handle "any" as reference to its TypeName.
   558  		if typ == anyTypeName.Type() {
   559  			w.Code(pkgbits.TypeNamed)
   560  			w.obj(anyTypeName, nil)
   561  			break
   562  		}
   563  
   564  		w.Code(pkgbits.TypeInterface)
   565  		w.interfaceType(typ)
   566  
   567  	case *types2.Union:
   568  		w.Code(pkgbits.TypeUnion)
   569  		w.unionType(typ)
   570  	}
   571  
   572  	if w.derived {
   573  		idx := pkgbits.Index(len(dict.derived))
   574  		dict.derived = append(dict.derived, derivedInfo{idx: w.Flush()})
   575  		dict.derivedIdx[typ] = idx
   576  		return typeInfo{idx: idx, derived: true}
   577  	}
   578  
   579  	pw.typsIdx[typ] = w.Idx
   580  	return typeInfo{idx: w.Flush(), derived: false}
   581  }
   582  
   583  func (w *writer) structType(typ *types2.Struct) {
   584  	w.Len(typ.NumFields())
   585  	for i := 0; i < typ.NumFields(); i++ {
   586  		f := typ.Field(i)
   587  		w.pos(f)
   588  		w.selector(f)
   589  		w.typ(f.Type())
   590  		w.String(typ.Tag(i))
   591  		w.Bool(f.Embedded())
   592  	}
   593  }
   594  
   595  func (w *writer) unionType(typ *types2.Union) {
   596  	w.Len(typ.Len())
   597  	for i := 0; i < typ.Len(); i++ {
   598  		t := typ.Term(i)
   599  		w.Bool(t.Tilde())
   600  		w.typ(t.Type())
   601  	}
   602  }
   603  
   604  func (w *writer) interfaceType(typ *types2.Interface) {
   605  	// If typ has no embedded types but it's not a basic interface, then
   606  	// the natural description we write out below will fail to
   607  	// reconstruct it.
   608  	if typ.NumEmbeddeds() == 0 && !typ.IsMethodSet() {
   609  		// Currently, this can only happen for the underlying Interface of
   610  		// "comparable", which is needed to handle type declarations like
   611  		// "type C comparable".
   612  		assert(typ == comparableTypeName.Type().(*types2.Named).Underlying())
   613  
   614  		// Export as "interface{ comparable }".
   615  		w.Len(0)                         // NumExplicitMethods
   616  		w.Len(1)                         // NumEmbeddeds
   617  		w.Bool(false)                    // IsImplicit
   618  		w.typ(comparableTypeName.Type()) // EmbeddedType(0)
   619  		return
   620  	}
   621  
   622  	w.Len(typ.NumExplicitMethods())
   623  	w.Len(typ.NumEmbeddeds())
   624  
   625  	if typ.NumExplicitMethods() == 0 && typ.NumEmbeddeds() == 1 {
   626  		w.Bool(typ.IsImplicit())
   627  	} else {
   628  		// Implicit interfaces always have 0 explicit methods and 1
   629  		// embedded type, so we skip writing out the implicit flag
   630  		// otherwise as a space optimization.
   631  		assert(!typ.IsImplicit())
   632  	}
   633  
   634  	for i := 0; i < typ.NumExplicitMethods(); i++ {
   635  		m := typ.ExplicitMethod(i)
   636  		sig := m.Type().(*types2.Signature)
   637  		assert(sig.TypeParams() == nil)
   638  
   639  		w.pos(m)
   640  		w.selector(m)
   641  		w.signature(sig)
   642  	}
   643  
   644  	for i := 0; i < typ.NumEmbeddeds(); i++ {
   645  		w.typ(typ.EmbeddedType(i))
   646  	}
   647  }
   648  
   649  func (w *writer) signature(sig *types2.Signature) {
   650  	w.Sync(pkgbits.SyncSignature)
   651  	w.params(sig.Params())
   652  	w.params(sig.Results())
   653  	w.Bool(sig.Variadic())
   654  }
   655  
   656  func (w *writer) params(typ *types2.Tuple) {
   657  	w.Sync(pkgbits.SyncParams)
   658  	w.Len(typ.Len())
   659  	for i := 0; i < typ.Len(); i++ {
   660  		w.param(typ.At(i))
   661  	}
   662  }
   663  
   664  func (w *writer) param(param *types2.Var) {
   665  	w.Sync(pkgbits.SyncParam)
   666  	w.pos(param)
   667  	w.localIdent(param)
   668  	w.typ(param.Type())
   669  }
   670  
   671  // @@@ Objects
   672  
   673  // obj writes a use of the given object into the bitstream.
   674  //
   675  // If obj is a generic object, then explicits are the explicit type
   676  // arguments used to instantiate it (i.e., used to substitute the
   677  // object's own declared type parameters).
   678  func (w *writer) obj(obj types2.Object, explicits *types2.TypeList) {
   679  	w.objInfo(w.p.objInstIdx(obj, explicits, w.dict))
   680  }
   681  
   682  // objInfo writes a use of the given encoded object into the
   683  // bitstream.
   684  func (w *writer) objInfo(info objInfo) {
   685  	w.Sync(pkgbits.SyncObject)
   686  	w.Bool(false) // TODO(mdempsky): Remove; was derived func inst.
   687  	w.Reloc(pkgbits.RelocObj, info.idx)
   688  
   689  	w.Len(len(info.explicits))
   690  	for _, info := range info.explicits {
   691  		w.typInfo(info)
   692  	}
   693  }
   694  
   695  // objInstIdx returns the indices for an object and a corresponding
   696  // list of type arguments used to instantiate it, adding them to the
   697  // export data as needed.
   698  func (pw *pkgWriter) objInstIdx(obj types2.Object, explicits *types2.TypeList, dict *writerDict) objInfo {
   699  	explicitInfos := make([]typeInfo, explicits.Len())
   700  	for i := range explicitInfos {
   701  		explicitInfos[i] = pw.typIdx(explicits.At(i), dict)
   702  	}
   703  	return objInfo{idx: pw.objIdx(obj), explicits: explicitInfos}
   704  }
   705  
   706  // objIdx returns the index for the given Object, adding it to the
   707  // export data as needed.
   708  func (pw *pkgWriter) objIdx(obj types2.Object) pkgbits.Index {
   709  	// TODO(mdempsky): Validate that obj is a global object (or a local
   710  	// defined type, which we hoist to global scope anyway).
   711  
   712  	if idx, ok := pw.objsIdx[obj]; ok {
   713  		return idx
   714  	}
   715  
   716  	dict := &writerDict{
   717  		derivedIdx: make(map[types2.Type]pkgbits.Index),
   718  	}
   719  
   720  	if isDefinedType(obj) && obj.Pkg() == pw.curpkg {
   721  		decl, ok := pw.typDecls[obj.(*types2.TypeName)]
   722  		assert(ok)
   723  		dict.implicits = decl.implicits
   724  	}
   725  
   726  	// We encode objects into 4 elements across different sections, all
   727  	// sharing the same index:
   728  	//
   729  	// - RelocName has just the object's qualified name (i.e.,
   730  	//   Object.Pkg and Object.Name) and the CodeObj indicating what
   731  	//   specific type of Object it is (Var, Func, etc).
   732  	//
   733  	// - RelocObj has the remaining public details about the object,
   734  	//   relevant to go/types importers.
   735  	//
   736  	// - RelocObjExt has additional private details about the object,
   737  	//   which are only relevant to cmd/compile itself. This is
   738  	//   separated from RelocObj so that go/types importers are
   739  	//   unaffected by internal compiler changes.
   740  	//
   741  	// - RelocObjDict has public details about the object's type
   742  	//   parameters and derived type's used by the object. This is
   743  	//   separated to facilitate the eventual introduction of
   744  	//   shape-based stenciling.
   745  	//
   746  	// TODO(mdempsky): Re-evaluate whether RelocName still makes sense
   747  	// to keep separate from RelocObj.
   748  
   749  	w := pw.newWriter(pkgbits.RelocObj, pkgbits.SyncObject1)
   750  	wext := pw.newWriter(pkgbits.RelocObjExt, pkgbits.SyncObject1)
   751  	wname := pw.newWriter(pkgbits.RelocName, pkgbits.SyncObject1)
   752  	wdict := pw.newWriter(pkgbits.RelocObjDict, pkgbits.SyncObject1)
   753  
   754  	pw.objsIdx[obj] = w.Idx // break cycles
   755  	assert(wext.Idx == w.Idx)
   756  	assert(wname.Idx == w.Idx)
   757  	assert(wdict.Idx == w.Idx)
   758  
   759  	w.dict = dict
   760  	wext.dict = dict
   761  
   762  	code := w.doObj(wext, obj)
   763  	w.Flush()
   764  	wext.Flush()
   765  
   766  	wname.qualifiedIdent(obj)
   767  	wname.Code(code)
   768  	wname.Flush()
   769  
   770  	wdict.objDict(obj, w.dict)
   771  	wdict.Flush()
   772  
   773  	return w.Idx
   774  }
   775  
   776  // doObj writes the RelocObj definition for obj to w, and the
   777  // RelocObjExt definition to wext.
   778  func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
   779  	if obj.Pkg() != w.p.curpkg {
   780  		return pkgbits.ObjStub
   781  	}
   782  
   783  	switch obj := obj.(type) {
   784  	default:
   785  		w.p.unexpected("object", obj)
   786  		panic("unreachable")
   787  
   788  	case *types2.Const:
   789  		w.pos(obj)
   790  		w.typ(obj.Type())
   791  		w.Value(obj.Val())
   792  		return pkgbits.ObjConst
   793  
   794  	case *types2.Func:
   795  		decl, ok := w.p.funDecls[obj]
   796  		assert(ok)
   797  		sig := obj.Type().(*types2.Signature)
   798  
   799  		w.pos(obj)
   800  		w.typeParamNames(sig.TypeParams())
   801  		w.signature(sig)
   802  		w.pos(decl)
   803  		wext.funcExt(obj)
   804  		return pkgbits.ObjFunc
   805  
   806  	case *types2.TypeName:
   807  		if obj.IsAlias() {
   808  			w.pos(obj)
   809  			w.typ(obj.Type())
   810  			return pkgbits.ObjAlias
   811  		}
   812  
   813  		named := obj.Type().(*types2.Named)
   814  		assert(named.TypeArgs() == nil)
   815  
   816  		w.pos(obj)
   817  		w.typeParamNames(named.TypeParams())
   818  		wext.typeExt(obj)
   819  		w.typ(named.Underlying())
   820  
   821  		w.Len(named.NumMethods())
   822  		for i := 0; i < named.NumMethods(); i++ {
   823  			w.method(wext, named.Method(i))
   824  		}
   825  
   826  		return pkgbits.ObjType
   827  
   828  	case *types2.Var:
   829  		w.pos(obj)
   830  		w.typ(obj.Type())
   831  		wext.varExt(obj)
   832  		return pkgbits.ObjVar
   833  	}
   834  }
   835  
   836  // objDict writes the dictionary needed for reading the given object.
   837  func (w *writer) objDict(obj types2.Object, dict *writerDict) {
   838  	// TODO(mdempsky): Split objDict into multiple entries? reader.go
   839  	// doesn't care about the type parameter bounds, and reader2.go
   840  	// doesn't care about referenced functions.
   841  
   842  	w.dict = dict // TODO(mdempsky): This is a bit sketchy.
   843  
   844  	w.Len(len(dict.implicits))
   845  
   846  	tparams := objTypeParams(obj)
   847  	ntparams := tparams.Len()
   848  	w.Len(ntparams)
   849  	for i := 0; i < ntparams; i++ {
   850  		w.typ(tparams.At(i).Constraint())
   851  	}
   852  
   853  	nderived := len(dict.derived)
   854  	w.Len(nderived)
   855  	for _, typ := range dict.derived {
   856  		w.Reloc(pkgbits.RelocType, typ.idx)
   857  		w.Bool(typ.needed)
   858  	}
   859  
   860  	// Write runtime dictionary information.
   861  	//
   862  	// N.B., the go/types importer reads up to the section, but doesn't
   863  	// read any further, so it's safe to change. (See TODO above.)
   864  
   865  	// For each type parameter, write out whether the constraint is a
   866  	// basic interface. This is used to determine how aggressively we
   867  	// can shape corresponding type arguments.
   868  	//
   869  	// This is somewhat redundant with writing out the full type
   870  	// parameter constraints above, but the compiler currently skips
   871  	// over those. Also, we don't care about the *declared* constraints,
   872  	// but how the type parameters are actually *used*. E.g., if a type
   873  	// parameter is constrained to `int | uint` but then never used in
   874  	// arithmetic/conversions/etc, we could shape those together.
   875  	for _, implicit := range dict.implicits {
   876  		tparam := implicit.Type().(*types2.TypeParam)
   877  		w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
   878  	}
   879  	for i := 0; i < ntparams; i++ {
   880  		tparam := tparams.At(i)
   881  		w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
   882  	}
   883  
   884  	w.Len(len(dict.typeParamMethodExprs))
   885  	for _, info := range dict.typeParamMethodExprs {
   886  		w.Len(info.typeParamIdx)
   887  		w.selectorInfo(info.methodInfo)
   888  	}
   889  
   890  	w.Len(len(dict.subdicts))
   891  	for _, info := range dict.subdicts {
   892  		w.objInfo(info)
   893  	}
   894  
   895  	w.Len(len(dict.rtypes))
   896  	for _, info := range dict.rtypes {
   897  		w.typInfo(info)
   898  	}
   899  
   900  	w.Len(len(dict.itabs))
   901  	for _, info := range dict.itabs {
   902  		w.typInfo(info.typ)
   903  		w.typInfo(info.iface)
   904  	}
   905  
   906  	assert(len(dict.derived) == nderived)
   907  }
   908  
   909  func (w *writer) typeParamNames(tparams *types2.TypeParamList) {
   910  	w.Sync(pkgbits.SyncTypeParamNames)
   911  
   912  	ntparams := tparams.Len()
   913  	for i := 0; i < ntparams; i++ {
   914  		tparam := tparams.At(i).Obj()
   915  		w.pos(tparam)
   916  		w.localIdent(tparam)
   917  	}
   918  }
   919  
   920  func (w *writer) method(wext *writer, meth *types2.Func) {
   921  	decl, ok := w.p.funDecls[meth]
   922  	assert(ok)
   923  	sig := meth.Type().(*types2.Signature)
   924  
   925  	w.Sync(pkgbits.SyncMethod)
   926  	w.pos(meth)
   927  	w.selector(meth)
   928  	w.typeParamNames(sig.RecvTypeParams())
   929  	w.param(sig.Recv())
   930  	w.signature(sig)
   931  
   932  	w.pos(decl) // XXX: Hack to workaround linker limitations.
   933  	wext.funcExt(meth)
   934  }
   935  
   936  // qualifiedIdent writes out the name of an object declared at package
   937  // scope. (For now, it's also used to refer to local defined types.)
   938  func (w *writer) qualifiedIdent(obj types2.Object) {
   939  	w.Sync(pkgbits.SyncSym)
   940  
   941  	name := obj.Name()
   942  	if isDefinedType(obj) && obj.Pkg() == w.p.curpkg {
   943  		decl, ok := w.p.typDecls[obj.(*types2.TypeName)]
   944  		assert(ok)
   945  		if decl.gen != 0 {
   946  			// For local defined types, we embed a scope-disambiguation
   947  			// number directly into their name. types.SplitVargenSuffix then
   948  			// knows to look for this.
   949  			//
   950  			// TODO(mdempsky): Find a better solution; this is terrible.
   951  			name = fmt.Sprintf("%s·%v", name, decl.gen)
   952  		}
   953  	}
   954  
   955  	w.pkg(obj.Pkg())
   956  	w.String(name)
   957  }
   958  
   959  // TODO(mdempsky): We should be able to omit pkg from both localIdent
   960  // and selector, because they should always be known from context.
   961  // However, past frustrations with this optimization in iexport make
   962  // me a little nervous to try it again.
   963  
   964  // localIdent writes the name of a locally declared object (i.e.,
   965  // objects that can only be accessed by non-qualified name, within the
   966  // context of a particular function).
   967  func (w *writer) localIdent(obj types2.Object) {
   968  	assert(!isGlobal(obj))
   969  	w.Sync(pkgbits.SyncLocalIdent)
   970  	w.pkg(obj.Pkg())
   971  	w.String(obj.Name())
   972  }
   973  
   974  // selector writes the name of a field or method (i.e., objects that
   975  // can only be accessed using selector expressions).
   976  func (w *writer) selector(obj types2.Object) {
   977  	w.selectorInfo(w.p.selectorIdx(obj))
   978  }
   979  
   980  func (w *writer) selectorInfo(info selectorInfo) {
   981  	w.Sync(pkgbits.SyncSelector)
   982  	w.pkgRef(info.pkgIdx)
   983  	w.StringRef(info.nameIdx)
   984  }
   985  
   986  func (pw *pkgWriter) selectorIdx(obj types2.Object) selectorInfo {
   987  	pkgIdx := pw.pkgIdx(obj.Pkg())
   988  	nameIdx := pw.StringIdx(obj.Name())
   989  	return selectorInfo{pkgIdx: pkgIdx, nameIdx: nameIdx}
   990  }
   991  
   992  // @@@ Compiler extensions
   993  
   994  func (w *writer) funcExt(obj *types2.Func) {
   995  	decl, ok := w.p.funDecls[obj]
   996  	assert(ok)
   997  
   998  	// TODO(mdempsky): Extend these pragma validation flags to account
   999  	// for generics. E.g., linkname probably doesn't make sense at
  1000  	// least.
  1001  
  1002  	pragma := asPragmaFlag(decl.Pragma)
  1003  	if pragma&ir.Systemstack != 0 && pragma&ir.Nosplit != 0 {
  1004  		w.p.errorf(decl, "go:nosplit and go:systemstack cannot be combined")
  1005  	}
  1006  
  1007  	if decl.Body != nil {
  1008  		if pragma&ir.Noescape != 0 {
  1009  			w.p.errorf(decl, "can only use //go:noescape with external func implementations")
  1010  		}
  1011  		if (pragma&ir.UintptrKeepAlive != 0 && pragma&ir.UintptrEscapes == 0) && pragma&ir.Nosplit == 0 {
  1012  			// Stack growth can't handle uintptr arguments that may
  1013  			// be pointers (as we don't know which are pointers
  1014  			// when creating the stack map). Thus uintptrkeepalive
  1015  			// functions (and all transitive callees) must be
  1016  			// nosplit.
  1017  			//
  1018  			// N.B. uintptrescapes implies uintptrkeepalive but it
  1019  			// is OK since the arguments must escape to the heap.
  1020  			//
  1021  			// TODO(prattmic): Add recursive nosplit check of callees.
  1022  			// TODO(prattmic): Functions with no body (i.e.,
  1023  			// assembly) must also be nosplit, but we can't check
  1024  			// that here.
  1025  			w.p.errorf(decl, "go:uintptrkeepalive requires go:nosplit")
  1026  		}
  1027  	} else {
  1028  		if base.Flag.Complete || decl.Name.Value == "init" {
  1029  			// Linknamed functions are allowed to have no body. Hopefully
  1030  			// the linkname target has a body. See issue 23311.
  1031  			if _, ok := w.p.linknames[obj]; !ok {
  1032  				w.p.errorf(decl, "missing function body")
  1033  			}
  1034  		}
  1035  	}
  1036  
  1037  	sig, block := obj.Type().(*types2.Signature), decl.Body
  1038  	body, closureVars := w.p.bodyIdx(sig, block, w.dict)
  1039  	assert(len(closureVars) == 0)
  1040  
  1041  	w.Sync(pkgbits.SyncFuncExt)
  1042  	w.pragmaFlag(pragma)
  1043  	w.linkname(obj)
  1044  	w.Bool(false) // stub extension
  1045  	w.Reloc(pkgbits.RelocBody, body)
  1046  	w.Sync(pkgbits.SyncEOF)
  1047  }
  1048  
  1049  func (w *writer) typeExt(obj *types2.TypeName) {
  1050  	decl, ok := w.p.typDecls[obj]
  1051  	assert(ok)
  1052  
  1053  	w.Sync(pkgbits.SyncTypeExt)
  1054  
  1055  	w.pragmaFlag(asPragmaFlag(decl.Pragma))
  1056  
  1057  	// No LSym.SymIdx info yet.
  1058  	w.Int64(-1)
  1059  	w.Int64(-1)
  1060  }
  1061  
  1062  func (w *writer) varExt(obj *types2.Var) {
  1063  	w.Sync(pkgbits.SyncVarExt)
  1064  	w.linkname(obj)
  1065  }
  1066  
  1067  func (w *writer) linkname(obj types2.Object) {
  1068  	w.Sync(pkgbits.SyncLinkname)
  1069  	w.Int64(-1)
  1070  	w.String(w.p.linknames[obj])
  1071  }
  1072  
  1073  func (w *writer) pragmaFlag(p ir.PragmaFlag) {
  1074  	w.Sync(pkgbits.SyncPragma)
  1075  	w.Int(int(p))
  1076  }
  1077  
  1078  // @@@ Function bodies
  1079  
  1080  // bodyIdx returns the index for the given function body (specified by
  1081  // block), adding it to the export data
  1082  func (pw *pkgWriter) bodyIdx(sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posVar) {
  1083  	w := pw.newWriter(pkgbits.RelocBody, pkgbits.SyncFuncBody)
  1084  	w.sig = sig
  1085  	w.dict = dict
  1086  
  1087  	w.funcargs(sig)
  1088  	if w.Bool(block != nil) {
  1089  		w.stmts(block.List)
  1090  		w.pos(block.Rbrace)
  1091  	}
  1092  
  1093  	return w.Flush(), w.closureVars
  1094  }
  1095  
  1096  func (w *writer) funcargs(sig *types2.Signature) {
  1097  	do := func(params *types2.Tuple, result bool) {
  1098  		for i := 0; i < params.Len(); i++ {
  1099  			w.funcarg(params.At(i), result)
  1100  		}
  1101  	}
  1102  
  1103  	if recv := sig.Recv(); recv != nil {
  1104  		w.funcarg(recv, false)
  1105  	}
  1106  	do(sig.Params(), false)
  1107  	do(sig.Results(), true)
  1108  }
  1109  
  1110  func (w *writer) funcarg(param *types2.Var, result bool) {
  1111  	if param.Name() != "" || result {
  1112  		w.addLocal(param)
  1113  	}
  1114  }
  1115  
  1116  // addLocal records the declaration of a new local variable.
  1117  func (w *writer) addLocal(obj *types2.Var) {
  1118  	idx := len(w.localsIdx)
  1119  
  1120  	w.Sync(pkgbits.SyncAddLocal)
  1121  	if w.p.SyncMarkers() {
  1122  		w.Int(idx)
  1123  	}
  1124  	w.varDictIndex(obj)
  1125  
  1126  	if w.localsIdx == nil {
  1127  		w.localsIdx = make(map[*types2.Var]int)
  1128  	}
  1129  	w.localsIdx[obj] = idx
  1130  }
  1131  
  1132  // useLocal writes a reference to the given local or free variable
  1133  // into the bitstream.
  1134  func (w *writer) useLocal(pos syntax.Pos, obj *types2.Var) {
  1135  	w.Sync(pkgbits.SyncUseObjLocal)
  1136  
  1137  	if idx, ok := w.localsIdx[obj]; w.Bool(ok) {
  1138  		w.Len(idx)
  1139  		return
  1140  	}
  1141  
  1142  	idx, ok := w.closureVarsIdx[obj]
  1143  	if !ok {
  1144  		if w.closureVarsIdx == nil {
  1145  			w.closureVarsIdx = make(map[*types2.Var]int)
  1146  		}
  1147  		idx = len(w.closureVars)
  1148  		w.closureVars = append(w.closureVars, posVar{pos, obj})
  1149  		w.closureVarsIdx[obj] = idx
  1150  	}
  1151  	w.Len(idx)
  1152  }
  1153  
  1154  func (w *writer) openScope(pos syntax.Pos) {
  1155  	w.Sync(pkgbits.SyncOpenScope)
  1156  	w.pos(pos)
  1157  }
  1158  
  1159  func (w *writer) closeScope(pos syntax.Pos) {
  1160  	w.Sync(pkgbits.SyncCloseScope)
  1161  	w.pos(pos)
  1162  	w.closeAnotherScope()
  1163  }
  1164  
  1165  func (w *writer) closeAnotherScope() {
  1166  	w.Sync(pkgbits.SyncCloseAnotherScope)
  1167  }
  1168  
  1169  // @@@ Statements
  1170  
  1171  // stmt writes the given statement into the function body bitstream.
  1172  func (w *writer) stmt(stmt syntax.Stmt) {
  1173  	var stmts []syntax.Stmt
  1174  	if stmt != nil {
  1175  		stmts = []syntax.Stmt{stmt}
  1176  	}
  1177  	w.stmts(stmts)
  1178  }
  1179  
  1180  func (w *writer) stmts(stmts []syntax.Stmt) {
  1181  	w.Sync(pkgbits.SyncStmts)
  1182  	for _, stmt := range stmts {
  1183  		w.stmt1(stmt)
  1184  	}
  1185  	w.Code(stmtEnd)
  1186  	w.Sync(pkgbits.SyncStmtsEnd)
  1187  }
  1188  
  1189  func (w *writer) stmt1(stmt syntax.Stmt) {
  1190  	switch stmt := stmt.(type) {
  1191  	default:
  1192  		w.p.unexpected("statement", stmt)
  1193  
  1194  	case nil, *syntax.EmptyStmt:
  1195  		return
  1196  
  1197  	case *syntax.AssignStmt:
  1198  		switch {
  1199  		case stmt.Rhs == nil:
  1200  			w.Code(stmtIncDec)
  1201  			w.op(binOps[stmt.Op])
  1202  			w.expr(stmt.Lhs)
  1203  			w.pos(stmt)
  1204  
  1205  		case stmt.Op != 0 && stmt.Op != syntax.Def:
  1206  			w.Code(stmtAssignOp)
  1207  			w.op(binOps[stmt.Op])
  1208  			w.expr(stmt.Lhs)
  1209  			w.pos(stmt)
  1210  
  1211  			var typ types2.Type
  1212  			if stmt.Op != syntax.Shl && stmt.Op != syntax.Shr {
  1213  				typ = w.p.typeOf(stmt.Lhs)
  1214  			}
  1215  			w.implicitConvExpr(typ, stmt.Rhs)
  1216  
  1217  		default:
  1218  			w.assignStmt(stmt, stmt.Lhs, stmt.Rhs)
  1219  		}
  1220  
  1221  	case *syntax.BlockStmt:
  1222  		w.Code(stmtBlock)
  1223  		w.blockStmt(stmt)
  1224  
  1225  	case *syntax.BranchStmt:
  1226  		w.Code(stmtBranch)
  1227  		w.pos(stmt)
  1228  		w.op(branchOps[stmt.Tok])
  1229  		w.optLabel(stmt.Label)
  1230  
  1231  	case *syntax.CallStmt:
  1232  		w.Code(stmtCall)
  1233  		w.pos(stmt)
  1234  		w.op(callOps[stmt.Tok])
  1235  		w.expr(stmt.Call)
  1236  
  1237  	case *syntax.DeclStmt:
  1238  		for _, decl := range stmt.DeclList {
  1239  			w.declStmt(decl)
  1240  		}
  1241  
  1242  	case *syntax.ExprStmt:
  1243  		w.Code(stmtExpr)
  1244  		w.expr(stmt.X)
  1245  
  1246  	case *syntax.ForStmt:
  1247  		w.Code(stmtFor)
  1248  		w.forStmt(stmt)
  1249  
  1250  	case *syntax.IfStmt:
  1251  		w.Code(stmtIf)
  1252  		w.ifStmt(stmt)
  1253  
  1254  	case *syntax.LabeledStmt:
  1255  		w.Code(stmtLabel)
  1256  		w.pos(stmt)
  1257  		w.label(stmt.Label)
  1258  		w.stmt1(stmt.Stmt)
  1259  
  1260  	case *syntax.ReturnStmt:
  1261  		w.Code(stmtReturn)
  1262  		w.pos(stmt)
  1263  
  1264  		resultTypes := w.sig.Results()
  1265  		dstType := func(i int) types2.Type {
  1266  			return resultTypes.At(i).Type()
  1267  		}
  1268  		w.multiExpr(stmt, dstType, unpackListExpr(stmt.Results))
  1269  
  1270  	case *syntax.SelectStmt:
  1271  		w.Code(stmtSelect)
  1272  		w.selectStmt(stmt)
  1273  
  1274  	case *syntax.SendStmt:
  1275  		chanType := types2.CoreType(w.p.typeOf(stmt.Chan)).(*types2.Chan)
  1276  
  1277  		w.Code(stmtSend)
  1278  		w.pos(stmt)
  1279  		w.expr(stmt.Chan)
  1280  		w.implicitConvExpr(chanType.Elem(), stmt.Value)
  1281  
  1282  	case *syntax.SwitchStmt:
  1283  		w.Code(stmtSwitch)
  1284  		w.switchStmt(stmt)
  1285  	}
  1286  }
  1287  
  1288  func (w *writer) assignList(expr syntax.Expr) {
  1289  	exprs := unpackListExpr(expr)
  1290  	w.Len(len(exprs))
  1291  
  1292  	for _, expr := range exprs {
  1293  		w.assign(expr)
  1294  	}
  1295  }
  1296  
  1297  func (w *writer) assign(expr syntax.Expr) {
  1298  	expr = unparen(expr)
  1299  
  1300  	if name, ok := expr.(*syntax.Name); ok {
  1301  		if name.Value == "_" {
  1302  			w.Code(assignBlank)
  1303  			return
  1304  		}
  1305  
  1306  		if obj, ok := w.p.info.Defs[name]; ok {
  1307  			obj := obj.(*types2.Var)
  1308  
  1309  			w.Code(assignDef)
  1310  			w.pos(obj)
  1311  			w.localIdent(obj)
  1312  			w.typ(obj.Type())
  1313  
  1314  			// TODO(mdempsky): Minimize locals index size by deferring
  1315  			// this until the variables actually come into scope.
  1316  			w.addLocal(obj)
  1317  			return
  1318  		}
  1319  	}
  1320  
  1321  	w.Code(assignExpr)
  1322  	w.expr(expr)
  1323  }
  1324  
  1325  func (w *writer) declStmt(decl syntax.Decl) {
  1326  	switch decl := decl.(type) {
  1327  	default:
  1328  		w.p.unexpected("declaration", decl)
  1329  
  1330  	case *syntax.ConstDecl, *syntax.TypeDecl:
  1331  
  1332  	case *syntax.VarDecl:
  1333  		w.assignStmt(decl, namesAsExpr(decl.NameList), decl.Values)
  1334  	}
  1335  }
  1336  
  1337  // assignStmt writes out an assignment for "lhs = rhs".
  1338  func (w *writer) assignStmt(pos poser, lhs0, rhs0 syntax.Expr) {
  1339  	lhs := unpackListExpr(lhs0)
  1340  	rhs := unpackListExpr(rhs0)
  1341  
  1342  	w.Code(stmtAssign)
  1343  	w.pos(pos)
  1344  
  1345  	// As if w.assignList(lhs0).
  1346  	w.Len(len(lhs))
  1347  	for _, expr := range lhs {
  1348  		w.assign(expr)
  1349  	}
  1350  
  1351  	dstType := func(i int) types2.Type {
  1352  		dst := lhs[i]
  1353  
  1354  		// Finding dstType is somewhat involved, because for VarDecl
  1355  		// statements, the Names are only added to the info.{Defs,Uses}
  1356  		// maps, not to info.Types.
  1357  		if name, ok := unparen(dst).(*syntax.Name); ok {
  1358  			if name.Value == "_" {
  1359  				return nil // ok: no implicit conversion
  1360  			} else if def, ok := w.p.info.Defs[name].(*types2.Var); ok {
  1361  				return def.Type()
  1362  			} else if use, ok := w.p.info.Uses[name].(*types2.Var); ok {
  1363  				return use.Type()
  1364  			} else {
  1365  				w.p.fatalf(dst, "cannot find type of destination object: %v", dst)
  1366  			}
  1367  		}
  1368  
  1369  		return w.p.typeOf(dst)
  1370  	}
  1371  
  1372  	w.multiExpr(pos, dstType, rhs)
  1373  }
  1374  
  1375  func (w *writer) blockStmt(stmt *syntax.BlockStmt) {
  1376  	w.Sync(pkgbits.SyncBlockStmt)
  1377  	w.openScope(stmt.Pos())
  1378  	w.stmts(stmt.List)
  1379  	w.closeScope(stmt.Rbrace)
  1380  }
  1381  
  1382  func (w *writer) forStmt(stmt *syntax.ForStmt) {
  1383  	w.Sync(pkgbits.SyncForStmt)
  1384  	w.openScope(stmt.Pos())
  1385  
  1386  	if rang, ok := stmt.Init.(*syntax.RangeClause); w.Bool(ok) {
  1387  		w.pos(rang)
  1388  		w.assignList(rang.Lhs)
  1389  		w.expr(rang.X)
  1390  
  1391  		xtyp := w.p.typeOf(rang.X)
  1392  		if _, isMap := types2.CoreType(xtyp).(*types2.Map); isMap {
  1393  			w.rtype(xtyp)
  1394  		}
  1395  		{
  1396  			lhs := unpackListExpr(rang.Lhs)
  1397  			assign := func(i int, src types2.Type) {
  1398  				if i >= len(lhs) {
  1399  					return
  1400  				}
  1401  				dst := unparen(lhs[i])
  1402  				if name, ok := dst.(*syntax.Name); ok && name.Value == "_" {
  1403  					return
  1404  				}
  1405  
  1406  				var dstType types2.Type
  1407  				if rang.Def {
  1408  					// For `:=` assignments, the LHS names only appear in Defs,
  1409  					// not Types (as used by typeOf).
  1410  					dstType = w.p.info.Defs[dst.(*syntax.Name)].(*types2.Var).Type()
  1411  				} else {
  1412  					dstType = w.p.typeOf(dst)
  1413  				}
  1414  
  1415  				w.convRTTI(src, dstType)
  1416  			}
  1417  
  1418  			keyType, valueType := w.p.rangeTypes(rang.X)
  1419  			assign(0, keyType)
  1420  			assign(1, valueType)
  1421  		}
  1422  
  1423  	} else {
  1424  		w.pos(stmt)
  1425  		w.stmt(stmt.Init)
  1426  		w.optExpr(stmt.Cond)
  1427  		w.stmt(stmt.Post)
  1428  	}
  1429  
  1430  	w.blockStmt(stmt.Body)
  1431  	w.closeAnotherScope()
  1432  }
  1433  
  1434  // rangeTypes returns the types of values produced by ranging over
  1435  // expr.
  1436  func (pw *pkgWriter) rangeTypes(expr syntax.Expr) (key, value types2.Type) {
  1437  	typ := pw.typeOf(expr)
  1438  	switch typ := types2.CoreType(typ).(type) {
  1439  	case *types2.Pointer: // must be pointer to array
  1440  		return types2.Typ[types2.Int], types2.CoreType(typ.Elem()).(*types2.Array).Elem()
  1441  	case *types2.Array:
  1442  		return types2.Typ[types2.Int], typ.Elem()
  1443  	case *types2.Slice:
  1444  		return types2.Typ[types2.Int], typ.Elem()
  1445  	case *types2.Basic:
  1446  		if typ.Info()&types2.IsString != 0 {
  1447  			return types2.Typ[types2.Int], runeTypeName.Type()
  1448  		}
  1449  	case *types2.Map:
  1450  		return typ.Key(), typ.Elem()
  1451  	case *types2.Chan:
  1452  		return typ.Elem(), nil
  1453  	}
  1454  	pw.fatalf(expr, "unexpected range type: %v", typ)
  1455  	panic("unreachable")
  1456  }
  1457  
  1458  func (w *writer) ifStmt(stmt *syntax.IfStmt) {
  1459  	w.Sync(pkgbits.SyncIfStmt)
  1460  	w.openScope(stmt.Pos())
  1461  	w.pos(stmt)
  1462  	w.stmt(stmt.Init)
  1463  	w.expr(stmt.Cond)
  1464  	w.blockStmt(stmt.Then)
  1465  	w.stmt(stmt.Else)
  1466  	w.closeAnotherScope()
  1467  }
  1468  
  1469  func (w *writer) selectStmt(stmt *syntax.SelectStmt) {
  1470  	w.Sync(pkgbits.SyncSelectStmt)
  1471  
  1472  	w.pos(stmt)
  1473  	w.Len(len(stmt.Body))
  1474  	for i, clause := range stmt.Body {
  1475  		if i > 0 {
  1476  			w.closeScope(clause.Pos())
  1477  		}
  1478  		w.openScope(clause.Pos())
  1479  
  1480  		w.pos(clause)
  1481  		w.stmt(clause.Comm)
  1482  		w.stmts(clause.Body)
  1483  	}
  1484  	if len(stmt.Body) > 0 {
  1485  		w.closeScope(stmt.Rbrace)
  1486  	}
  1487  }
  1488  
  1489  func (w *writer) switchStmt(stmt *syntax.SwitchStmt) {
  1490  	w.Sync(pkgbits.SyncSwitchStmt)
  1491  
  1492  	w.openScope(stmt.Pos())
  1493  	w.pos(stmt)
  1494  	w.stmt(stmt.Init)
  1495  
  1496  	var iface, tagType types2.Type
  1497  	if guard, ok := stmt.Tag.(*syntax.TypeSwitchGuard); w.Bool(ok) {
  1498  		iface = w.p.typeOf(guard.X)
  1499  
  1500  		w.pos(guard)
  1501  		if tag := guard.Lhs; w.Bool(tag != nil) {
  1502  			w.pos(tag)
  1503  
  1504  			// Like w.localIdent, but we don't have a types2.Object.
  1505  			w.Sync(pkgbits.SyncLocalIdent)
  1506  			w.pkg(w.p.curpkg)
  1507  			w.String(tag.Value)
  1508  		}
  1509  		w.expr(guard.X)
  1510  	} else {
  1511  		tag := stmt.Tag
  1512  
  1513  		if tag != nil {
  1514  			tagType = w.p.typeOf(tag)
  1515  		} else {
  1516  			tagType = types2.Typ[types2.Bool]
  1517  		}
  1518  
  1519  		// Walk is going to emit comparisons between the tag value and
  1520  		// each case expression, and we want these comparisons to always
  1521  		// have the same type. If there are any case values that can't be
  1522  		// converted to the tag value's type, then convert everything to
  1523  		// `any` instead.
  1524  	Outer:
  1525  		for _, clause := range stmt.Body {
  1526  			for _, cas := range unpackListExpr(clause.Cases) {
  1527  				if casType := w.p.typeOf(cas); !types2.AssignableTo(casType, tagType) {
  1528  					tagType = types2.NewInterfaceType(nil, nil)
  1529  					break Outer
  1530  				}
  1531  			}
  1532  		}
  1533  
  1534  		if w.Bool(tag != nil) {
  1535  			w.implicitConvExpr(tagType, tag)
  1536  		}
  1537  	}
  1538  
  1539  	w.Len(len(stmt.Body))
  1540  	for i, clause := range stmt.Body {
  1541  		if i > 0 {
  1542  			w.closeScope(clause.Pos())
  1543  		}
  1544  		w.openScope(clause.Pos())
  1545  
  1546  		w.pos(clause)
  1547  
  1548  		cases := unpackListExpr(clause.Cases)
  1549  		if iface != nil {
  1550  			w.Len(len(cases))
  1551  			for _, cas := range cases {
  1552  				if w.Bool(isNil(w.p, cas)) {
  1553  					continue
  1554  				}
  1555  				w.exprType(iface, cas)
  1556  			}
  1557  		} else {
  1558  			// As if w.exprList(clause.Cases),
  1559  			// but with implicit conversions to tagType.
  1560  
  1561  			w.Sync(pkgbits.SyncExprList)
  1562  			w.Sync(pkgbits.SyncExprs)
  1563  			w.Len(len(cases))
  1564  			for _, cas := range cases {
  1565  				w.implicitConvExpr(tagType, cas)
  1566  			}
  1567  		}
  1568  
  1569  		if obj, ok := w.p.info.Implicits[clause]; ok {
  1570  			// TODO(mdempsky): These pos details are quirkish, but also
  1571  			// necessary so the variable's position is correct for DWARF
  1572  			// scope assignment later. It would probably be better for us to
  1573  			// instead just set the variable's DWARF scoping info earlier so
  1574  			// we can give it the correct position information.
  1575  			pos := clause.Pos()
  1576  			if typs := unpackListExpr(clause.Cases); len(typs) != 0 {
  1577  				pos = typeExprEndPos(typs[len(typs)-1])
  1578  			}
  1579  			w.pos(pos)
  1580  
  1581  			obj := obj.(*types2.Var)
  1582  			w.typ(obj.Type())
  1583  			w.addLocal(obj)
  1584  		}
  1585  
  1586  		w.stmts(clause.Body)
  1587  	}
  1588  	if len(stmt.Body) > 0 {
  1589  		w.closeScope(stmt.Rbrace)
  1590  	}
  1591  
  1592  	w.closeScope(stmt.Rbrace)
  1593  }
  1594  
  1595  func (w *writer) label(label *syntax.Name) {
  1596  	w.Sync(pkgbits.SyncLabel)
  1597  
  1598  	// TODO(mdempsky): Replace label strings with dense indices.
  1599  	w.String(label.Value)
  1600  }
  1601  
  1602  func (w *writer) optLabel(label *syntax.Name) {
  1603  	w.Sync(pkgbits.SyncOptLabel)
  1604  	if w.Bool(label != nil) {
  1605  		w.label(label)
  1606  	}
  1607  }
  1608  
  1609  // @@@ Expressions
  1610  
  1611  // expr writes the given expression into the function body bitstream.
  1612  func (w *writer) expr(expr syntax.Expr) {
  1613  	base.Assertf(expr != nil, "missing expression")
  1614  
  1615  	expr = unparen(expr) // skip parens; unneeded after typecheck
  1616  
  1617  	obj, inst := lookupObj(w.p, expr)
  1618  	targs := inst.TypeArgs
  1619  
  1620  	if tv, ok := w.p.maybeTypeAndValue(expr); ok {
  1621  		if tv.IsType() {
  1622  			w.p.fatalf(expr, "unexpected type expression %v", syntax.String(expr))
  1623  		}
  1624  
  1625  		if tv.Value != nil {
  1626  			w.Code(exprConst)
  1627  			w.pos(expr)
  1628  			typ := idealType(tv)
  1629  			assert(typ != nil)
  1630  			w.typ(typ)
  1631  			w.Value(tv.Value)
  1632  
  1633  			// TODO(mdempsky): These details are only important for backend
  1634  			// diagnostics. Explore writing them out separately.
  1635  			w.op(constExprOp(expr))
  1636  			w.String(syntax.String(expr))
  1637  			return
  1638  		}
  1639  
  1640  		if _, isNil := obj.(*types2.Nil); isNil {
  1641  			w.Code(exprNil)
  1642  			w.pos(expr)
  1643  			w.typ(tv.Type)
  1644  			return
  1645  		}
  1646  
  1647  		// With shape types (and particular pointer shaping), we may have
  1648  		// an expression of type "go.shape.*uint8", but need to reshape it
  1649  		// to another shape-identical type to allow use in field
  1650  		// selection, indexing, etc.
  1651  		if typ := tv.Type; !tv.IsBuiltin() && !isTuple(typ) && !isUntyped(typ) {
  1652  			w.Code(exprReshape)
  1653  			w.typ(typ)
  1654  			// fallthrough
  1655  		}
  1656  	}
  1657  
  1658  	if obj != nil {
  1659  		if targs.Len() != 0 {
  1660  			obj := obj.(*types2.Func)
  1661  
  1662  			w.Code(exprFuncInst)
  1663  			w.pos(expr)
  1664  			w.funcInst(obj, targs)
  1665  			return
  1666  		}
  1667  
  1668  		if isGlobal(obj) {
  1669  			w.Code(exprGlobal)
  1670  			w.obj(obj, nil)
  1671  			return
  1672  		}
  1673  
  1674  		obj := obj.(*types2.Var)
  1675  		assert(!obj.IsField())
  1676  
  1677  		w.Code(exprLocal)
  1678  		w.useLocal(expr.Pos(), obj)
  1679  		return
  1680  	}
  1681  
  1682  	switch expr := expr.(type) {
  1683  	default:
  1684  		w.p.unexpected("expression", expr)
  1685  
  1686  	case *syntax.CompositeLit:
  1687  		w.Code(exprCompLit)
  1688  		w.compLit(expr)
  1689  
  1690  	case *syntax.FuncLit:
  1691  		w.Code(exprFuncLit)
  1692  		w.funcLit(expr)
  1693  
  1694  	case *syntax.SelectorExpr:
  1695  		sel, ok := w.p.info.Selections[expr]
  1696  		assert(ok)
  1697  
  1698  		switch sel.Kind() {
  1699  		default:
  1700  			w.p.fatalf(expr, "unexpected selection kind: %v", sel.Kind())
  1701  
  1702  		case types2.FieldVal:
  1703  			w.Code(exprFieldVal)
  1704  			w.expr(expr.X)
  1705  			w.pos(expr)
  1706  			w.selector(sel.Obj())
  1707  
  1708  		case types2.MethodVal:
  1709  			w.Code(exprMethodVal)
  1710  			typ := w.recvExpr(expr, sel)
  1711  			w.pos(expr)
  1712  			w.methodExpr(expr, typ, sel)
  1713  
  1714  		case types2.MethodExpr:
  1715  			w.Code(exprMethodExpr)
  1716  
  1717  			tv := w.p.typeAndValue(expr.X)
  1718  			assert(tv.IsType())
  1719  
  1720  			index := sel.Index()
  1721  			implicits := index[:len(index)-1]
  1722  
  1723  			typ := tv.Type
  1724  			w.typ(typ)
  1725  
  1726  			w.Len(len(implicits))
  1727  			for _, ix := range implicits {
  1728  				w.Len(ix)
  1729  				typ = deref2(typ).Underlying().(*types2.Struct).Field(ix).Type()
  1730  			}
  1731  
  1732  			recv := sel.Obj().(*types2.Func).Type().(*types2.Signature).Recv().Type()
  1733  			if w.Bool(isPtrTo(typ, recv)) { // need deref
  1734  				typ = recv
  1735  			} else if w.Bool(isPtrTo(recv, typ)) { // need addr
  1736  				typ = recv
  1737  			}
  1738  
  1739  			w.pos(expr)
  1740  			w.methodExpr(expr, typ, sel)
  1741  		}
  1742  
  1743  	case *syntax.IndexExpr:
  1744  		_ = w.p.typeOf(expr.Index) // ensure this is an index expression, not an instantiation
  1745  
  1746  		xtyp := w.p.typeOf(expr.X)
  1747  
  1748  		var keyType types2.Type
  1749  		if mapType, ok := types2.CoreType(xtyp).(*types2.Map); ok {
  1750  			keyType = mapType.Key()
  1751  		}
  1752  
  1753  		w.Code(exprIndex)
  1754  		w.expr(expr.X)
  1755  		w.pos(expr)
  1756  		w.implicitConvExpr(keyType, expr.Index)
  1757  		if keyType != nil {
  1758  			w.rtype(xtyp)
  1759  		}
  1760  
  1761  	case *syntax.SliceExpr:
  1762  		w.Code(exprSlice)
  1763  		w.expr(expr.X)
  1764  		w.pos(expr)
  1765  		for _, n := range &expr.Index {
  1766  			w.optExpr(n)
  1767  		}
  1768  
  1769  	case *syntax.AssertExpr:
  1770  		iface := w.p.typeOf(expr.X)
  1771  
  1772  		w.Code(exprAssert)
  1773  		w.expr(expr.X)
  1774  		w.pos(expr)
  1775  		w.exprType(iface, expr.Type)
  1776  		w.rtype(iface)
  1777  
  1778  	case *syntax.Operation:
  1779  		if expr.Y == nil {
  1780  			w.Code(exprUnaryOp)
  1781  			w.op(unOps[expr.Op])
  1782  			w.pos(expr)
  1783  			w.expr(expr.X)
  1784  			break
  1785  		}
  1786  
  1787  		var commonType types2.Type
  1788  		switch expr.Op {
  1789  		case syntax.Shl, syntax.Shr:
  1790  			// ok: operands are allowed to have different types
  1791  		default:
  1792  			xtyp := w.p.typeOf(expr.X)
  1793  			ytyp := w.p.typeOf(expr.Y)
  1794  			switch {
  1795  			case types2.AssignableTo(xtyp, ytyp):
  1796  				commonType = ytyp
  1797  			case types2.AssignableTo(ytyp, xtyp):
  1798  				commonType = xtyp
  1799  			default:
  1800  				w.p.fatalf(expr, "failed to find common type between %v and %v", xtyp, ytyp)
  1801  			}
  1802  		}
  1803  
  1804  		w.Code(exprBinaryOp)
  1805  		w.op(binOps[expr.Op])
  1806  		w.implicitConvExpr(commonType, expr.X)
  1807  		w.pos(expr)
  1808  		w.implicitConvExpr(commonType, expr.Y)
  1809  
  1810  	case *syntax.CallExpr:
  1811  		tv := w.p.typeAndValue(expr.Fun)
  1812  		if tv.IsType() {
  1813  			assert(len(expr.ArgList) == 1)
  1814  			assert(!expr.HasDots)
  1815  			w.convertExpr(tv.Type, expr.ArgList[0], false)
  1816  			break
  1817  		}
  1818  
  1819  		var rtype types2.Type
  1820  		if tv.IsBuiltin() {
  1821  			switch obj, _ := lookupObj(w.p, expr.Fun); obj.Name() {
  1822  			case "make":
  1823  				assert(len(expr.ArgList) >= 1)
  1824  				assert(!expr.HasDots)
  1825  
  1826  				w.Code(exprMake)
  1827  				w.pos(expr)
  1828  				w.exprType(nil, expr.ArgList[0])
  1829  				w.exprs(expr.ArgList[1:])
  1830  
  1831  				typ := w.p.typeOf(expr)
  1832  				switch coreType := types2.CoreType(typ).(type) {
  1833  				default:
  1834  					w.p.fatalf(expr, "unexpected core type: %v", coreType)
  1835  				case *types2.Chan:
  1836  					w.rtype(typ)
  1837  				case *types2.Map:
  1838  					w.rtype(typ)
  1839  				case *types2.Slice:
  1840  					w.rtype(sliceElem(typ))
  1841  				}
  1842  
  1843  				return
  1844  
  1845  			case "new":
  1846  				assert(len(expr.ArgList) == 1)
  1847  				assert(!expr.HasDots)
  1848  
  1849  				w.Code(exprNew)
  1850  				w.pos(expr)
  1851  				w.exprType(nil, expr.ArgList[0])
  1852  				return
  1853  
  1854  			case "append":
  1855  				rtype = sliceElem(w.p.typeOf(expr))
  1856  			case "copy":
  1857  				typ := w.p.typeOf(expr.ArgList[0])
  1858  				if tuple, ok := typ.(*types2.Tuple); ok { // "copy(g())"
  1859  					typ = tuple.At(0).Type()
  1860  				}
  1861  				rtype = sliceElem(typ)
  1862  			case "delete":
  1863  				typ := w.p.typeOf(expr.ArgList[0])
  1864  				if tuple, ok := typ.(*types2.Tuple); ok { // "delete(g())"
  1865  					typ = tuple.At(0).Type()
  1866  				}
  1867  				rtype = typ
  1868  			case "Slice":
  1869  				rtype = sliceElem(w.p.typeOf(expr))
  1870  			}
  1871  		}
  1872  
  1873  		writeFunExpr := func() {
  1874  			fun := unparen(expr.Fun)
  1875  
  1876  			if selector, ok := fun.(*syntax.SelectorExpr); ok {
  1877  				if sel, ok := w.p.info.Selections[selector]; ok && sel.Kind() == types2.MethodVal {
  1878  					w.Bool(true) // method call
  1879  					typ := w.recvExpr(selector, sel)
  1880  					w.methodExpr(selector, typ, sel)
  1881  					return
  1882  				}
  1883  			}
  1884  
  1885  			w.Bool(false) // not a method call (i.e., normal function call)
  1886  
  1887  			if obj, inst := lookupObj(w.p, fun); w.Bool(obj != nil && inst.TypeArgs.Len() != 0) {
  1888  				obj := obj.(*types2.Func)
  1889  
  1890  				w.pos(fun)
  1891  				w.funcInst(obj, inst.TypeArgs)
  1892  				return
  1893  			}
  1894  
  1895  			w.expr(fun)
  1896  		}
  1897  
  1898  		sigType := types2.CoreType(tv.Type).(*types2.Signature)
  1899  		paramTypes := sigType.Params()
  1900  
  1901  		w.Code(exprCall)
  1902  		writeFunExpr()
  1903  		w.pos(expr)
  1904  
  1905  		paramType := func(i int) types2.Type {
  1906  			if sigType.Variadic() && !expr.HasDots && i >= paramTypes.Len()-1 {
  1907  				return paramTypes.At(paramTypes.Len() - 1).Type().(*types2.Slice).Elem()
  1908  			}
  1909  			return paramTypes.At(i).Type()
  1910  		}
  1911  
  1912  		w.multiExpr(expr, paramType, expr.ArgList)
  1913  		w.Bool(expr.HasDots)
  1914  		if rtype != nil {
  1915  			w.rtype(rtype)
  1916  		}
  1917  	}
  1918  }
  1919  
  1920  func sliceElem(typ types2.Type) types2.Type {
  1921  	return types2.CoreType(typ).(*types2.Slice).Elem()
  1922  }
  1923  
  1924  func (w *writer) optExpr(expr syntax.Expr) {
  1925  	if w.Bool(expr != nil) {
  1926  		w.expr(expr)
  1927  	}
  1928  }
  1929  
  1930  // recvExpr writes out expr.X, but handles any implicit addressing,
  1931  // dereferencing, and field selections appropriate for the method
  1932  // selection.
  1933  func (w *writer) recvExpr(expr *syntax.SelectorExpr, sel *types2.Selection) types2.Type {
  1934  	index := sel.Index()
  1935  	implicits := index[:len(index)-1]
  1936  
  1937  	w.Code(exprRecv)
  1938  	w.expr(expr.X)
  1939  	w.pos(expr)
  1940  	w.Len(len(implicits))
  1941  
  1942  	typ := w.p.typeOf(expr.X)
  1943  	for _, ix := range implicits {
  1944  		typ = deref2(typ).Underlying().(*types2.Struct).Field(ix).Type()
  1945  		w.Len(ix)
  1946  	}
  1947  
  1948  	recv := sel.Obj().(*types2.Func).Type().(*types2.Signature).Recv().Type()
  1949  	if w.Bool(isPtrTo(typ, recv)) { // needs deref
  1950  		typ = recv
  1951  	} else if w.Bool(isPtrTo(recv, typ)) { // needs addr
  1952  		typ = recv
  1953  	}
  1954  
  1955  	return typ
  1956  }
  1957  
  1958  // funcInst writes a reference to an instantiated function.
  1959  func (w *writer) funcInst(obj *types2.Func, targs *types2.TypeList) {
  1960  	info := w.p.objInstIdx(obj, targs, w.dict)
  1961  
  1962  	// Type arguments list contains derived types; we can emit a static
  1963  	// call to the shaped function, but need to dynamically compute the
  1964  	// runtime dictionary pointer.
  1965  	if w.Bool(info.anyDerived()) {
  1966  		w.Len(w.dict.subdictIdx(info))
  1967  		return
  1968  	}
  1969  
  1970  	// Type arguments list is statically known; we can emit a static
  1971  	// call with a statically reference to the respective runtime
  1972  	// dictionary.
  1973  	w.objInfo(info)
  1974  }
  1975  
  1976  // methodExpr writes out a reference to the method selected by
  1977  // expr. sel should be the corresponding types2.Selection, and recv
  1978  // the type produced after any implicit addressing, dereferencing, and
  1979  // field selection. (Note: recv might differ from sel.Obj()'s receiver
  1980  // parameter in the case of interface types, and is needed for
  1981  // handling type parameter methods.)
  1982  func (w *writer) methodExpr(expr *syntax.SelectorExpr, recv types2.Type, sel *types2.Selection) {
  1983  	fun := sel.Obj().(*types2.Func)
  1984  	sig := fun.Type().(*types2.Signature)
  1985  
  1986  	w.typ(recv)
  1987  	w.typ(sig)
  1988  	w.pos(expr)
  1989  	w.selector(fun)
  1990  
  1991  	// Method on a type parameter. These require an indirect call
  1992  	// through the current function's runtime dictionary.
  1993  	if typeParam, ok := recv.(*types2.TypeParam); w.Bool(ok) {
  1994  		typeParamIdx := w.dict.typeParamIndex(typeParam)
  1995  		methodInfo := w.p.selectorIdx(fun)
  1996  
  1997  		w.Len(w.dict.typeParamMethodExprIdx(typeParamIdx, methodInfo))
  1998  		return
  1999  	}
  2000  
  2001  	if isInterface(recv) != isInterface(sig.Recv().Type()) {
  2002  		w.p.fatalf(expr, "isInterface inconsistency: %v and %v", recv, sig.Recv().Type())
  2003  	}
  2004  
  2005  	if !isInterface(recv) {
  2006  		if named, ok := deref2(recv).(*types2.Named); ok {
  2007  			obj, targs := splitNamed(named)
  2008  			info := w.p.objInstIdx(obj, targs, w.dict)
  2009  
  2010  			// Method on a derived receiver type. These can be handled by a
  2011  			// static call to the shaped method, but require dynamically
  2012  			// looking up the appropriate dictionary argument in the current
  2013  			// function's runtime dictionary.
  2014  			if w.p.hasImplicitTypeParams(obj) || info.anyDerived() {
  2015  				w.Bool(true) // dynamic subdictionary
  2016  				w.Len(w.dict.subdictIdx(info))
  2017  				return
  2018  			}
  2019  
  2020  			// Method on a fully known receiver type. These can be handled
  2021  			// by a static call to the shaped method, and with a static
  2022  			// reference to the receiver type's dictionary.
  2023  			if targs.Len() != 0 {
  2024  				w.Bool(false) // no dynamic subdictionary
  2025  				w.Bool(true)  // static dictionary
  2026  				w.objInfo(info)
  2027  				return
  2028  			}
  2029  		}
  2030  	}
  2031  
  2032  	w.Bool(false) // no dynamic subdictionary
  2033  	w.Bool(false) // no static dictionary
  2034  }
  2035  
  2036  // multiExpr writes a sequence of expressions, where the i'th value is
  2037  // implicitly converted to dstType(i). It also handles when exprs is a
  2038  // single, multi-valued expression (e.g., the multi-valued argument in
  2039  // an f(g()) call, or the RHS operand in a comma-ok assignment).
  2040  func (w *writer) multiExpr(pos poser, dstType func(int) types2.Type, exprs []syntax.Expr) {
  2041  	w.Sync(pkgbits.SyncMultiExpr)
  2042  
  2043  	if len(exprs) == 1 {
  2044  		expr := exprs[0]
  2045  		if tuple, ok := w.p.typeOf(expr).(*types2.Tuple); ok {
  2046  			assert(tuple.Len() > 1)
  2047  			w.Bool(true) // N:1 assignment
  2048  			w.pos(pos)
  2049  			w.expr(expr)
  2050  
  2051  			w.Len(tuple.Len())
  2052  			for i := 0; i < tuple.Len(); i++ {
  2053  				src := tuple.At(i).Type()
  2054  				// TODO(mdempsky): Investigate not writing src here. I think
  2055  				// the reader should be able to infer it from expr anyway.
  2056  				w.typ(src)
  2057  				if dst := dstType(i); w.Bool(dst != nil && !types2.Identical(src, dst)) {
  2058  					if src == nil || dst == nil {
  2059  						w.p.fatalf(pos, "src is %v, dst is %v", src, dst)
  2060  					}
  2061  					if !types2.AssignableTo(src, dst) {
  2062  						w.p.fatalf(pos, "%v is not assignable to %v", src, dst)
  2063  					}
  2064  					w.typ(dst)
  2065  					w.convRTTI(src, dst)
  2066  				}
  2067  			}
  2068  			return
  2069  		}
  2070  	}
  2071  
  2072  	w.Bool(false) // N:N assignment
  2073  	w.Len(len(exprs))
  2074  	for i, expr := range exprs {
  2075  		w.implicitConvExpr(dstType(i), expr)
  2076  	}
  2077  }
  2078  
  2079  // implicitConvExpr is like expr, but if dst is non-nil and different
  2080  // from expr's type, then an implicit conversion operation is inserted
  2081  // at expr's position.
  2082  func (w *writer) implicitConvExpr(dst types2.Type, expr syntax.Expr) {
  2083  	w.convertExpr(dst, expr, true)
  2084  }
  2085  
  2086  func (w *writer) convertExpr(dst types2.Type, expr syntax.Expr, implicit bool) {
  2087  	src := w.p.typeOf(expr)
  2088  
  2089  	// Omit implicit no-op conversions.
  2090  	identical := dst == nil || types2.Identical(src, dst)
  2091  	if implicit && identical {
  2092  		w.expr(expr)
  2093  		return
  2094  	}
  2095  
  2096  	if implicit && !types2.AssignableTo(src, dst) {
  2097  		w.p.fatalf(expr, "%v is not assignable to %v", src, dst)
  2098  	}
  2099  
  2100  	w.Code(exprConvert)
  2101  	w.Bool(implicit)
  2102  	w.typ(dst)
  2103  	w.pos(expr)
  2104  	w.convRTTI(src, dst)
  2105  	w.Bool(isTypeParam(dst))
  2106  	w.Bool(identical)
  2107  	w.expr(expr)
  2108  }
  2109  
  2110  func (w *writer) compLit(lit *syntax.CompositeLit) {
  2111  	typ := w.p.typeOf(lit)
  2112  
  2113  	w.Sync(pkgbits.SyncCompLit)
  2114  	w.pos(lit)
  2115  	w.typ(typ)
  2116  
  2117  	if ptr, ok := types2.CoreType(typ).(*types2.Pointer); ok {
  2118  		typ = ptr.Elem()
  2119  	}
  2120  	var keyType, elemType types2.Type
  2121  	var structType *types2.Struct
  2122  	switch typ0 := typ; typ := types2.CoreType(typ).(type) {
  2123  	default:
  2124  		w.p.fatalf(lit, "unexpected composite literal type: %v", typ)
  2125  	case *types2.Array:
  2126  		elemType = typ.Elem()
  2127  	case *types2.Map:
  2128  		w.rtype(typ0)
  2129  		keyType, elemType = typ.Key(), typ.Elem()
  2130  	case *types2.Slice:
  2131  		elemType = typ.Elem()
  2132  	case *types2.Struct:
  2133  		structType = typ
  2134  	}
  2135  
  2136  	w.Len(len(lit.ElemList))
  2137  	for i, elem := range lit.ElemList {
  2138  		elemType := elemType
  2139  		if structType != nil {
  2140  			if kv, ok := elem.(*syntax.KeyValueExpr); ok {
  2141  				// use position of expr.Key rather than of elem (which has position of ':')
  2142  				w.pos(kv.Key)
  2143  				i = fieldIndex(w.p.info, structType, kv.Key.(*syntax.Name))
  2144  				elem = kv.Value
  2145  			} else {
  2146  				w.pos(elem)
  2147  			}
  2148  			elemType = structType.Field(i).Type()
  2149  			w.Len(i)
  2150  		} else {
  2151  			if kv, ok := elem.(*syntax.KeyValueExpr); w.Bool(ok) {
  2152  				// use position of expr.Key rather than of elem (which has position of ':')
  2153  				w.pos(kv.Key)
  2154  				w.implicitConvExpr(keyType, kv.Key)
  2155  				elem = kv.Value
  2156  			}
  2157  		}
  2158  		w.pos(elem)
  2159  		w.implicitConvExpr(elemType, elem)
  2160  	}
  2161  }
  2162  
  2163  func (w *writer) funcLit(expr *syntax.FuncLit) {
  2164  	sig := w.p.typeOf(expr).(*types2.Signature)
  2165  
  2166  	body, closureVars := w.p.bodyIdx(sig, expr.Body, w.dict)
  2167  
  2168  	w.Sync(pkgbits.SyncFuncLit)
  2169  	w.pos(expr)
  2170  	w.signature(sig)
  2171  
  2172  	w.Len(len(closureVars))
  2173  	for _, cv := range closureVars {
  2174  		w.pos(cv.pos)
  2175  		w.useLocal(cv.pos, cv.var_)
  2176  	}
  2177  
  2178  	w.Reloc(pkgbits.RelocBody, body)
  2179  }
  2180  
  2181  type posVar struct {
  2182  	pos  syntax.Pos
  2183  	var_ *types2.Var
  2184  }
  2185  
  2186  func (w *writer) exprList(expr syntax.Expr) {
  2187  	w.Sync(pkgbits.SyncExprList)
  2188  	w.exprs(unpackListExpr(expr))
  2189  }
  2190  
  2191  func (w *writer) exprs(exprs []syntax.Expr) {
  2192  	w.Sync(pkgbits.SyncExprs)
  2193  	w.Len(len(exprs))
  2194  	for _, expr := range exprs {
  2195  		w.expr(expr)
  2196  	}
  2197  }
  2198  
  2199  // rtype writes information so that the reader can construct an
  2200  // expression of type *runtime._type representing typ.
  2201  func (w *writer) rtype(typ types2.Type) {
  2202  	typ = types2.Default(typ)
  2203  
  2204  	info := w.p.typIdx(typ, w.dict)
  2205  	w.rtypeInfo(info)
  2206  }
  2207  
  2208  func (w *writer) rtypeInfo(info typeInfo) {
  2209  	w.Sync(pkgbits.SyncRType)
  2210  
  2211  	if w.Bool(info.derived) {
  2212  		w.Len(w.dict.rtypeIdx(info))
  2213  	} else {
  2214  		w.typInfo(info)
  2215  	}
  2216  }
  2217  
  2218  // varDictIndex writes out information for populating DictIndex for
  2219  // the ir.Name that will represent obj.
  2220  func (w *writer) varDictIndex(obj *types2.Var) {
  2221  	info := w.p.typIdx(obj.Type(), w.dict)
  2222  	if w.Bool(info.derived) {
  2223  		w.Len(w.dict.rtypeIdx(info))
  2224  	}
  2225  }
  2226  
  2227  func isUntyped(typ types2.Type) bool {
  2228  	basic, ok := typ.(*types2.Basic)
  2229  	return ok && basic.Info()&types2.IsUntyped != 0
  2230  }
  2231  
  2232  func isTuple(typ types2.Type) bool {
  2233  	_, ok := typ.(*types2.Tuple)
  2234  	return ok
  2235  }
  2236  
  2237  func (w *writer) itab(typ, iface types2.Type) {
  2238  	typ = types2.Default(typ)
  2239  	iface = types2.Default(iface)
  2240  
  2241  	typInfo := w.p.typIdx(typ, w.dict)
  2242  	ifaceInfo := w.p.typIdx(iface, w.dict)
  2243  
  2244  	w.rtypeInfo(typInfo)
  2245  	w.rtypeInfo(ifaceInfo)
  2246  	if w.Bool(typInfo.derived || ifaceInfo.derived) {
  2247  		w.Len(w.dict.itabIdx(typInfo, ifaceInfo))
  2248  	}
  2249  }
  2250  
  2251  // convRTTI writes information so that the reader can construct
  2252  // expressions for converting from src to dst.
  2253  func (w *writer) convRTTI(src, dst types2.Type) {
  2254  	w.Sync(pkgbits.SyncConvRTTI)
  2255  	w.itab(src, dst)
  2256  }
  2257  
  2258  func (w *writer) exprType(iface types2.Type, typ syntax.Expr) {
  2259  	base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
  2260  
  2261  	tv := w.p.typeAndValue(typ)
  2262  	assert(tv.IsType())
  2263  
  2264  	w.Sync(pkgbits.SyncExprType)
  2265  	w.pos(typ)
  2266  
  2267  	if w.Bool(iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
  2268  		w.itab(tv.Type, iface)
  2269  	} else {
  2270  		w.rtype(tv.Type)
  2271  
  2272  		info := w.p.typIdx(tv.Type, w.dict)
  2273  		w.Bool(info.derived)
  2274  	}
  2275  }
  2276  
  2277  // isInterface reports whether typ is known to be an interface type.
  2278  // If typ is a type parameter, then isInterface reports an internal
  2279  // compiler error instead.
  2280  func isInterface(typ types2.Type) bool {
  2281  	if _, ok := typ.(*types2.TypeParam); ok {
  2282  		// typ is a type parameter and may be instantiated as either a
  2283  		// concrete or interface type, so the writer can't depend on
  2284  		// knowing this.
  2285  		base.Fatalf("%v is a type parameter", typ)
  2286  	}
  2287  
  2288  	_, ok := typ.Underlying().(*types2.Interface)
  2289  	return ok
  2290  }
  2291  
  2292  // op writes an Op into the bitstream.
  2293  func (w *writer) op(op ir.Op) {
  2294  	// TODO(mdempsky): Remove in favor of explicit codes? Would make
  2295  	// export data more stable against internal refactorings, but low
  2296  	// priority at the moment.
  2297  	assert(op != 0)
  2298  	w.Sync(pkgbits.SyncOp)
  2299  	w.Len(int(op))
  2300  }
  2301  
  2302  // @@@ Package initialization
  2303  
  2304  // Caution: This code is still clumsy, because toolstash -cmp is
  2305  // particularly sensitive to it.
  2306  
  2307  type typeDeclGen struct {
  2308  	*syntax.TypeDecl
  2309  	gen int
  2310  
  2311  	// Implicit type parameters in scope at this type declaration.
  2312  	implicits []*types2.TypeName
  2313  }
  2314  
  2315  type fileImports struct {
  2316  	importedEmbed, importedUnsafe bool
  2317  }
  2318  
  2319  // declCollector is a visitor type that collects compiler-needed
  2320  // information about declarations that types2 doesn't track.
  2321  //
  2322  // Notably, it maps declared types and functions back to their
  2323  // declaration statement, keeps track of implicit type parameters, and
  2324  // assigns unique type "generation" numbers to local defined types.
  2325  type declCollector struct {
  2326  	pw         *pkgWriter
  2327  	typegen    *int
  2328  	file       *fileImports
  2329  	withinFunc bool
  2330  	implicits  []*types2.TypeName
  2331  }
  2332  
  2333  func (c *declCollector) withTParams(obj types2.Object) *declCollector {
  2334  	tparams := objTypeParams(obj)
  2335  	n := tparams.Len()
  2336  	if n == 0 {
  2337  		return c
  2338  	}
  2339  
  2340  	copy := *c
  2341  	copy.implicits = copy.implicits[:len(copy.implicits):len(copy.implicits)]
  2342  	for i := 0; i < n; i++ {
  2343  		copy.implicits = append(copy.implicits, tparams.At(i).Obj())
  2344  	}
  2345  	return &copy
  2346  }
  2347  
  2348  func (c *declCollector) Visit(n syntax.Node) syntax.Visitor {
  2349  	pw := c.pw
  2350  
  2351  	switch n := n.(type) {
  2352  	case *syntax.File:
  2353  		pw.checkPragmas(n.Pragma, ir.GoBuildPragma, false)
  2354  
  2355  	case *syntax.ImportDecl:
  2356  		pw.checkPragmas(n.Pragma, 0, false)
  2357  
  2358  		switch pkgNameOf(pw.info, n).Imported().Path() {
  2359  		case "embed":
  2360  			c.file.importedEmbed = true
  2361  		case "unsafe":
  2362  			c.file.importedUnsafe = true
  2363  		}
  2364  
  2365  	case *syntax.ConstDecl:
  2366  		pw.checkPragmas(n.Pragma, 0, false)
  2367  
  2368  	case *syntax.FuncDecl:
  2369  		pw.checkPragmas(n.Pragma, funcPragmas, false)
  2370  
  2371  		obj := pw.info.Defs[n.Name].(*types2.Func)
  2372  		pw.funDecls[obj] = n
  2373  
  2374  		return c.withTParams(obj)
  2375  
  2376  	case *syntax.TypeDecl:
  2377  		obj := pw.info.Defs[n.Name].(*types2.TypeName)
  2378  		d := typeDeclGen{TypeDecl: n, implicits: c.implicits}
  2379  
  2380  		if n.Alias {
  2381  			pw.checkPragmas(n.Pragma, 0, false)
  2382  		} else {
  2383  			pw.checkPragmas(n.Pragma, 0, false)
  2384  
  2385  			// Assign a unique ID to function-scoped defined types.
  2386  			if c.withinFunc {
  2387  				*c.typegen++
  2388  				d.gen = *c.typegen
  2389  			}
  2390  		}
  2391  
  2392  		pw.typDecls[obj] = d
  2393  
  2394  		// TODO(mdempsky): Omit? Not strictly necessary; only matters for
  2395  		// type declarations within function literals within parameterized
  2396  		// type declarations, but types2 the function literals will be
  2397  		// constant folded away.
  2398  		return c.withTParams(obj)
  2399  
  2400  	case *syntax.VarDecl:
  2401  		pw.checkPragmas(n.Pragma, 0, true)
  2402  
  2403  		if p, ok := n.Pragma.(*pragmas); ok && len(p.Embeds) > 0 {
  2404  			if err := checkEmbed(n, c.file.importedEmbed, c.withinFunc); err != nil {
  2405  				pw.errorf(p.Embeds[0].Pos, "%s", err)
  2406  			}
  2407  		}
  2408  
  2409  	case *syntax.BlockStmt:
  2410  		if !c.withinFunc {
  2411  			copy := *c
  2412  			copy.withinFunc = true
  2413  			return &copy
  2414  		}
  2415  	}
  2416  
  2417  	return c
  2418  }
  2419  
  2420  func (pw *pkgWriter) collectDecls(noders []*noder) {
  2421  	var typegen int
  2422  	for _, p := range noders {
  2423  		var file fileImports
  2424  
  2425  		syntax.Walk(p.file, &declCollector{
  2426  			pw:      pw,
  2427  			typegen: &typegen,
  2428  			file:    &file,
  2429  		})
  2430  
  2431  		pw.cgoPragmas = append(pw.cgoPragmas, p.pragcgobuf...)
  2432  
  2433  		for _, l := range p.linknames {
  2434  			if !file.importedUnsafe {
  2435  				pw.errorf(l.pos, "//go:linkname only allowed in Go files that import \"unsafe\"")
  2436  				continue
  2437  			}
  2438  
  2439  			switch obj := pw.curpkg.Scope().Lookup(l.local).(type) {
  2440  			case *types2.Func, *types2.Var:
  2441  				if _, ok := pw.linknames[obj]; !ok {
  2442  					pw.linknames[obj] = l.remote
  2443  				} else {
  2444  					pw.errorf(l.pos, "duplicate //go:linkname for %s", l.local)
  2445  				}
  2446  
  2447  			default:
  2448  				if types.AllowsGoVersion(1, 18) {
  2449  					pw.errorf(l.pos, "//go:linkname must refer to declared function or variable")
  2450  				}
  2451  			}
  2452  		}
  2453  	}
  2454  }
  2455  
  2456  func (pw *pkgWriter) checkPragmas(p syntax.Pragma, allowed ir.PragmaFlag, embedOK bool) {
  2457  	if p == nil {
  2458  		return
  2459  	}
  2460  	pragma := p.(*pragmas)
  2461  
  2462  	for _, pos := range pragma.Pos {
  2463  		if pos.Flag&^allowed != 0 {
  2464  			pw.errorf(pos.Pos, "misplaced compiler directive")
  2465  		}
  2466  	}
  2467  
  2468  	if !embedOK {
  2469  		for _, e := range pragma.Embeds {
  2470  			pw.errorf(e.Pos, "misplaced go:embed directive")
  2471  		}
  2472  	}
  2473  }
  2474  
  2475  func (w *writer) pkgInit(noders []*noder) {
  2476  	w.Len(len(w.p.cgoPragmas))
  2477  	for _, cgoPragma := range w.p.cgoPragmas {
  2478  		w.Strings(cgoPragma)
  2479  	}
  2480  
  2481  	w.Sync(pkgbits.SyncDecls)
  2482  	for _, p := range noders {
  2483  		for _, decl := range p.file.DeclList {
  2484  			w.pkgDecl(decl)
  2485  		}
  2486  	}
  2487  	w.Code(declEnd)
  2488  
  2489  	w.Sync(pkgbits.SyncEOF)
  2490  }
  2491  
  2492  func (w *writer) pkgDecl(decl syntax.Decl) {
  2493  	switch decl := decl.(type) {
  2494  	default:
  2495  		w.p.unexpected("declaration", decl)
  2496  
  2497  	case *syntax.ImportDecl:
  2498  
  2499  	case *syntax.ConstDecl:
  2500  		w.Code(declOther)
  2501  		w.pkgObjs(decl.NameList...)
  2502  
  2503  	case *syntax.FuncDecl:
  2504  		if decl.Name.Value == "_" {
  2505  			break // skip blank functions
  2506  		}
  2507  
  2508  		obj := w.p.info.Defs[decl.Name].(*types2.Func)
  2509  		sig := obj.Type().(*types2.Signature)
  2510  
  2511  		if sig.RecvTypeParams() != nil || sig.TypeParams() != nil {
  2512  			break // skip generic functions
  2513  		}
  2514  
  2515  		if recv := sig.Recv(); recv != nil {
  2516  			w.Code(declMethod)
  2517  			w.typ(recvBase(recv))
  2518  			w.selector(obj)
  2519  			break
  2520  		}
  2521  
  2522  		w.Code(declFunc)
  2523  		w.pkgObjs(decl.Name)
  2524  
  2525  	case *syntax.TypeDecl:
  2526  		if len(decl.TParamList) != 0 {
  2527  			break // skip generic type decls
  2528  		}
  2529  
  2530  		if decl.Name.Value == "_" {
  2531  			break // skip blank type decls
  2532  		}
  2533  
  2534  		name := w.p.info.Defs[decl.Name].(*types2.TypeName)
  2535  		// Skip type declarations for interfaces that are only usable as
  2536  		// type parameter bounds.
  2537  		if iface, ok := name.Type().Underlying().(*types2.Interface); ok && !iface.IsMethodSet() {
  2538  			break
  2539  		}
  2540  
  2541  		w.Code(declOther)
  2542  		w.pkgObjs(decl.Name)
  2543  
  2544  	case *syntax.VarDecl:
  2545  		w.Code(declVar)
  2546  		w.pos(decl)
  2547  		w.pkgObjs(decl.NameList...)
  2548  
  2549  		// TODO(mdempsky): It would make sense to use multiExpr here, but
  2550  		// that results in IR that confuses pkginit/initorder.go. So we
  2551  		// continue using exprList, and let typecheck handle inserting any
  2552  		// implicit conversions. That's okay though, because package-scope
  2553  		// assignments never require dictionaries.
  2554  		w.exprList(decl.Values)
  2555  
  2556  		var embeds []pragmaEmbed
  2557  		if p, ok := decl.Pragma.(*pragmas); ok {
  2558  			embeds = p.Embeds
  2559  		}
  2560  		w.Len(len(embeds))
  2561  		for _, embed := range embeds {
  2562  			w.pos(embed.Pos)
  2563  			w.Strings(embed.Patterns)
  2564  		}
  2565  	}
  2566  }
  2567  
  2568  func (w *writer) pkgObjs(names ...*syntax.Name) {
  2569  	w.Sync(pkgbits.SyncDeclNames)
  2570  	w.Len(len(names))
  2571  
  2572  	for _, name := range names {
  2573  		obj, ok := w.p.info.Defs[name]
  2574  		assert(ok)
  2575  
  2576  		w.Sync(pkgbits.SyncDeclName)
  2577  		w.obj(obj, nil)
  2578  	}
  2579  }
  2580  
  2581  // @@@ Helpers
  2582  
  2583  // hasImplicitTypeParams reports whether obj is a defined type with
  2584  // implicit type parameters (e.g., declared within a generic function
  2585  // or method).
  2586  func (p *pkgWriter) hasImplicitTypeParams(obj *types2.TypeName) bool {
  2587  	if obj.Pkg() == p.curpkg {
  2588  		decl, ok := p.typDecls[obj]
  2589  		assert(ok)
  2590  		if len(decl.implicits) != 0 {
  2591  			return true
  2592  		}
  2593  	}
  2594  	return false
  2595  }
  2596  
  2597  // isDefinedType reports whether obj is a defined type.
  2598  func isDefinedType(obj types2.Object) bool {
  2599  	if obj, ok := obj.(*types2.TypeName); ok {
  2600  		return !obj.IsAlias()
  2601  	}
  2602  	return false
  2603  }
  2604  
  2605  // isGlobal reports whether obj was declared at package scope.
  2606  //
  2607  // Caveat: blank objects are not declared.
  2608  func isGlobal(obj types2.Object) bool {
  2609  	return obj.Parent() == obj.Pkg().Scope()
  2610  }
  2611  
  2612  // lookupObj returns the object that expr refers to, if any. If expr
  2613  // is an explicit instantiation of a generic object, then the instance
  2614  // object is returned as well.
  2615  func lookupObj(p *pkgWriter, expr syntax.Expr) (obj types2.Object, inst types2.Instance) {
  2616  	if index, ok := expr.(*syntax.IndexExpr); ok {
  2617  		args := unpackListExpr(index.Index)
  2618  		if len(args) == 1 {
  2619  			tv := p.typeAndValue(args[0])
  2620  			if tv.IsValue() {
  2621  				return // normal index expression
  2622  			}
  2623  		}
  2624  
  2625  		expr = index.X
  2626  	}
  2627  
  2628  	// Strip package qualifier, if present.
  2629  	if sel, ok := expr.(*syntax.SelectorExpr); ok {
  2630  		if !isPkgQual(p.info, sel) {
  2631  			return // normal selector expression
  2632  		}
  2633  		expr = sel.Sel
  2634  	}
  2635  
  2636  	if name, ok := expr.(*syntax.Name); ok {
  2637  		obj = p.info.Uses[name]
  2638  		inst = p.info.Instances[name]
  2639  	}
  2640  	return
  2641  }
  2642  
  2643  // isPkgQual reports whether the given selector expression is a
  2644  // package-qualified identifier.
  2645  func isPkgQual(info *types2.Info, sel *syntax.SelectorExpr) bool {
  2646  	if name, ok := sel.X.(*syntax.Name); ok {
  2647  		_, isPkgName := info.Uses[name].(*types2.PkgName)
  2648  		return isPkgName
  2649  	}
  2650  	return false
  2651  }
  2652  
  2653  // isNil reports whether expr is a (possibly parenthesized) reference
  2654  // to the predeclared nil value.
  2655  func isNil(p *pkgWriter, expr syntax.Expr) bool {
  2656  	tv := p.typeAndValue(expr)
  2657  	return tv.IsNil()
  2658  }
  2659  
  2660  // recvBase returns the base type for the given receiver parameter.
  2661  func recvBase(recv *types2.Var) *types2.Named {
  2662  	typ := recv.Type()
  2663  	if ptr, ok := typ.(*types2.Pointer); ok {
  2664  		typ = ptr.Elem()
  2665  	}
  2666  	return typ.(*types2.Named)
  2667  }
  2668  
  2669  // namesAsExpr returns a list of names as a syntax.Expr.
  2670  func namesAsExpr(names []*syntax.Name) syntax.Expr {
  2671  	if len(names) == 1 {
  2672  		return names[0]
  2673  	}
  2674  
  2675  	exprs := make([]syntax.Expr, len(names))
  2676  	for i, name := range names {
  2677  		exprs[i] = name
  2678  	}
  2679  	return &syntax.ListExpr{ElemList: exprs}
  2680  }
  2681  
  2682  // fieldIndex returns the index of the struct field named by key.
  2683  func fieldIndex(info *types2.Info, str *types2.Struct, key *syntax.Name) int {
  2684  	field := info.Uses[key].(*types2.Var)
  2685  
  2686  	for i := 0; i < str.NumFields(); i++ {
  2687  		if str.Field(i) == field {
  2688  			return i
  2689  		}
  2690  	}
  2691  
  2692  	panic(fmt.Sprintf("%s: %v is not a field of %v", key.Pos(), field, str))
  2693  }
  2694  
  2695  // objTypeParams returns the type parameters on the given object.
  2696  func objTypeParams(obj types2.Object) *types2.TypeParamList {
  2697  	switch obj := obj.(type) {
  2698  	case *types2.Func:
  2699  		sig := obj.Type().(*types2.Signature)
  2700  		if sig.Recv() != nil {
  2701  			return sig.RecvTypeParams()
  2702  		}
  2703  		return sig.TypeParams()
  2704  	case *types2.TypeName:
  2705  		if !obj.IsAlias() {
  2706  			return obj.Type().(*types2.Named).TypeParams()
  2707  		}
  2708  	}
  2709  	return nil
  2710  }
  2711  
  2712  // splitNamed decomposes a use of a defined type into its original
  2713  // type definition and the type arguments used to instantiate it.
  2714  func splitNamed(typ *types2.Named) (*types2.TypeName, *types2.TypeList) {
  2715  	base.Assertf(typ.TypeParams().Len() == typ.TypeArgs().Len(), "use of uninstantiated type: %v", typ)
  2716  
  2717  	orig := typ.Origin()
  2718  	base.Assertf(orig.TypeArgs() == nil, "origin %v of %v has type arguments", orig, typ)
  2719  	base.Assertf(typ.Obj() == orig.Obj(), "%v has object %v, but %v has object %v", typ, typ.Obj(), orig, orig.Obj())
  2720  
  2721  	return typ.Obj(), typ.TypeArgs()
  2722  }
  2723  
  2724  func asPragmaFlag(p syntax.Pragma) ir.PragmaFlag {
  2725  	if p == nil {
  2726  		return 0
  2727  	}
  2728  	return p.(*pragmas).Flag
  2729  }
  2730  
  2731  // isPtrTo reports whether from is the type *to.
  2732  func isPtrTo(from, to types2.Type) bool {
  2733  	ptr, ok := from.(*types2.Pointer)
  2734  	return ok && types2.Identical(ptr.Elem(), to)
  2735  }