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