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