1
2
3
4
5
6
7
8 package typecheck
9
10 import (
11 "encoding/binary"
12 "fmt"
13 "go/constant"
14 "io"
15 "math/big"
16 "os"
17 "strings"
18
19 "cmd/compile/internal/base"
20 "cmd/compile/internal/ir"
21 "cmd/compile/internal/types"
22 "cmd/internal/bio"
23 "cmd/internal/goobj"
24 "cmd/internal/obj"
25 "cmd/internal/src"
26 )
27
28
29
30 type iimporterAndOffset struct {
31 p *iimporter
32 off uint64
33 }
34
35 var (
36
37
38 DeclImporter = map[*types.Sym]iimporterAndOffset{}
39
40
41
42 inlineImporter = map[*types.Sym]iimporterAndOffset{}
43 )
44
45
46
47
48 func expandDecl(n ir.Node) ir.Node {
49 if n, ok := n.(*ir.Name); ok {
50 return n
51 }
52
53 id := n.(*ir.Ident)
54 if n := id.Sym().PkgDef(); n != nil {
55 return n.(*ir.Name)
56 }
57
58 r := importReaderFor(id.Sym(), DeclImporter)
59 if r == nil {
60
61 return n
62 }
63
64 return r.doDecl(n.Sym())
65 }
66
67
68
69 func ImportBody(fn *ir.Func) {
70 if fn.Inl.Body != nil {
71 base.Fatalf("%v already has inline body", fn)
72 }
73
74 r := importReaderFor(fn.Nname.Sym(), inlineImporter)
75 if r == nil {
76 base.Fatalf("missing import reader for %v", fn)
77 }
78
79 if inimport {
80 base.Fatalf("recursive inimport")
81 }
82 inimport = true
83 r.doInline(fn)
84 inimport = false
85 }
86
87 func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader {
88 x, ok := importers[sym]
89 if !ok {
90 return nil
91 }
92
93 return x.p.newReader(x.off, sym.Pkg)
94 }
95
96 type intReader struct {
97 *bio.Reader
98 pkg *types.Pkg
99 }
100
101 func (r *intReader) int64() int64 {
102 i, err := binary.ReadVarint(r.Reader)
103 if err != nil {
104 base.Errorf("import %q: read error: %v", r.pkg.Path, err)
105 base.ErrorExit()
106 }
107 return i
108 }
109
110 func (r *intReader) uint64() uint64 {
111 i, err := binary.ReadUvarint(r.Reader)
112 if err != nil {
113 base.Errorf("import %q: read error: %v", r.pkg.Path, err)
114 base.ErrorExit()
115 }
116 return i
117 }
118
119 func ReadImports(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType) {
120 ird := &intReader{in, pkg}
121
122 version := ird.uint64()
123 if version != iexportVersion {
124 base.Errorf("import %q: unknown export format version %d", pkg.Path, version)
125 base.ErrorExit()
126 }
127
128 sLen := ird.uint64()
129 dLen := ird.uint64()
130
131
132
133
134 data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
135 if err != nil {
136 base.Errorf("import %q: mapping input: %v", pkg.Path, err)
137 base.ErrorExit()
138 }
139 stringData := data[:sLen]
140 declData := data[sLen:]
141
142 in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
143
144 p := &iimporter{
145 ipkg: pkg,
146
147 pkgCache: map[uint64]*types.Pkg{},
148 posBaseCache: map[uint64]*src.PosBase{},
149 typCache: map[uint64]*types.Type{},
150
151 stringData: stringData,
152 declData: declData,
153 }
154
155 for i, pt := range predeclared() {
156 p.typCache[uint64(i)] = pt
157 }
158
159
160 for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
161 pkg := p.pkgAt(ird.uint64())
162 pkgName := p.stringAt(ird.uint64())
163 pkgHeight := int(ird.uint64())
164 if pkg.Name == "" {
165 pkg.Name = pkgName
166 pkg.Height = pkgHeight
167 types.NumImport[pkgName]++
168
169
170 pkg.Lookup("_").Def = ir.BlankNode
171 } else {
172 if pkg.Name != pkgName {
173 base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
174 }
175 if pkg.Height != pkgHeight {
176 base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
177 }
178 }
179
180 for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
181 s := pkg.Lookup(p.stringAt(ird.uint64()))
182 off := ird.uint64()
183
184 if _, ok := DeclImporter[s]; !ok {
185 DeclImporter[s] = iimporterAndOffset{p, off}
186 }
187 }
188 }
189
190
191 for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
192 pkg := p.pkgAt(ird.uint64())
193
194 for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
195 s := pkg.Lookup(p.stringAt(ird.uint64()))
196 off := ird.uint64()
197
198 if _, ok := inlineImporter[s]; !ok {
199 inlineImporter[s] = iimporterAndOffset{p, off}
200 }
201 }
202 }
203
204
205 _, err = io.ReadFull(in, fingerprint[:])
206 if err != nil {
207 base.Errorf("import %s: error reading fingerprint", pkg.Path)
208 base.ErrorExit()
209 }
210 return fingerprint
211 }
212
213 type iimporter struct {
214 ipkg *types.Pkg
215
216 pkgCache map[uint64]*types.Pkg
217 posBaseCache map[uint64]*src.PosBase
218 typCache map[uint64]*types.Type
219
220 stringData string
221 declData string
222 }
223
224 func (p *iimporter) stringAt(off uint64) string {
225 var x [binary.MaxVarintLen64]byte
226 n := copy(x[:], p.stringData[off:])
227
228 slen, n := binary.Uvarint(x[:n])
229 if n <= 0 {
230 base.Fatalf("varint failed")
231 }
232 spos := off + uint64(n)
233 return p.stringData[spos : spos+slen]
234 }
235
236 func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
237 if posBase, ok := p.posBaseCache[off]; ok {
238 return posBase
239 }
240
241 file := p.stringAt(off)
242 posBase := src.NewFileBase(file, file)
243 p.posBaseCache[off] = posBase
244 return posBase
245 }
246
247 func (p *iimporter) pkgAt(off uint64) *types.Pkg {
248 if pkg, ok := p.pkgCache[off]; ok {
249 return pkg
250 }
251
252 pkg := p.ipkg
253 if pkgPath := p.stringAt(off); pkgPath != "" {
254 pkg = types.NewPkg(pkgPath, "")
255 }
256 p.pkgCache[off] = pkg
257 return pkg
258 }
259
260
261
262 type importReader struct {
263 strings.Reader
264 p *iimporter
265
266 currPkg *types.Pkg
267 prevBase *src.PosBase
268 prevLine int64
269 prevColumn int64
270
271
272 curfn *ir.Func
273
274 allDcls []*ir.Name
275 allClosureVars []*ir.Name
276 }
277
278 func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
279 r := &importReader{
280 p: p,
281 currPkg: pkg,
282 }
283
284
285 r.Reader = *strings.NewReader(p.declData[off:])
286 return r
287 }
288
289 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
290 func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
291 func (r *importReader) pkg() *types.Pkg { return r.p.pkgAt(r.uint64()) }
292
293 func (r *importReader) setPkg() {
294 r.currPkg = r.pkg()
295 }
296
297 func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
298 tag := r.byte()
299 pos := r.pos()
300
301 switch tag {
302 case 'A':
303 typ := r.typ()
304
305 return importalias(r.p.ipkg, pos, sym, typ)
306
307 case 'C':
308 typ := r.typ()
309 val := r.value(typ)
310
311 n := importconst(r.p.ipkg, pos, sym, typ, val)
312 r.constExt(n)
313 return n
314
315 case 'F':
316 typ := r.signature(nil)
317
318 n := importfunc(r.p.ipkg, pos, sym, typ)
319 r.funcExt(n)
320 return n
321
322 case 'T':
323
324
325 n := importtype(r.p.ipkg, pos, sym)
326 t := n.Type()
327
328
329
330 types.DeferCheckSize()
331 underlying := r.typ()
332 t.SetUnderlying(underlying)
333 types.ResumeCheckSize()
334
335 if underlying.IsInterface() {
336 r.typeExt(t)
337 return n
338 }
339
340 ms := make([]*types.Field, r.uint64())
341 for i := range ms {
342 mpos := r.pos()
343 msym := r.selector()
344 recv := r.param()
345 mtyp := r.signature(recv)
346
347
348 m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym))
349 m.Class = ir.PFUNC
350 m.SetType(mtyp)
351
352 m.Func = ir.NewFunc(mpos)
353 m.Func.Nname = m
354
355 f := types.NewField(mpos, msym, mtyp)
356 f.Nname = m
357 ms[i] = f
358 }
359 t.Methods().Set(ms)
360
361 r.typeExt(t)
362 for _, m := range ms {
363 r.methExt(m)
364 }
365 return n
366
367 case 'V':
368 typ := r.typ()
369
370 n := importvar(r.p.ipkg, pos, sym, typ)
371 r.varExt(n)
372 return n
373
374 default:
375 base.Fatalf("unexpected tag: %v", tag)
376 panic("unreachable")
377 }
378 }
379
380 func (p *importReader) value(typ *types.Type) constant.Value {
381 switch constTypeOf(typ) {
382 case constant.Bool:
383 return constant.MakeBool(p.bool())
384 case constant.String:
385 return constant.MakeString(p.string())
386 case constant.Int:
387 var i big.Int
388 p.mpint(&i, typ)
389 return constant.Make(&i)
390 case constant.Float:
391 return p.float(typ)
392 case constant.Complex:
393 return makeComplex(p.float(typ), p.float(typ))
394 }
395
396 base.Fatalf("unexpected value type: %v", typ)
397 panic("unreachable")
398 }
399
400 func (p *importReader) mpint(x *big.Int, typ *types.Type) {
401 signed, maxBytes := intSize(typ)
402
403 maxSmall := 256 - maxBytes
404 if signed {
405 maxSmall = 256 - 2*maxBytes
406 }
407 if maxBytes == 1 {
408 maxSmall = 256
409 }
410
411 n, _ := p.ReadByte()
412 if uint(n) < maxSmall {
413 v := int64(n)
414 if signed {
415 v >>= 1
416 if n&1 != 0 {
417 v = ^v
418 }
419 }
420 x.SetInt64(v)
421 return
422 }
423
424 v := -n
425 if signed {
426 v = -(n &^ 1) >> 1
427 }
428 if v < 1 || uint(v) > maxBytes {
429 base.Fatalf("weird decoding: %v, %v => %v", n, signed, v)
430 }
431 b := make([]byte, v)
432 p.Read(b)
433 x.SetBytes(b)
434 if signed && n&1 != 0 {
435 x.Neg(x)
436 }
437 }
438
439 func (p *importReader) float(typ *types.Type) constant.Value {
440 var mant big.Int
441 p.mpint(&mant, typ)
442 var f big.Float
443 f.SetInt(&mant)
444 if f.Sign() != 0 {
445 f.SetMantExp(&f, int(p.int64()))
446 }
447 return constant.Make(&f)
448 }
449
450 func (p *importReader) mprat(orig constant.Value) constant.Value {
451 if !p.bool() {
452 return orig
453 }
454 var rat big.Rat
455 rat.SetString(p.string())
456 return constant.Make(&rat)
457 }
458
459 func (r *importReader) ident(selector bool) *types.Sym {
460 name := r.string()
461 if name == "" {
462 return nil
463 }
464 pkg := r.currPkg
465 if selector && types.IsExported(name) {
466 pkg = types.LocalPkg
467 }
468 return pkg.Lookup(name)
469 }
470
471 func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
472 func (r *importReader) selector() *types.Sym { return r.ident(true) }
473
474 func (r *importReader) qualifiedIdent() *ir.Ident {
475 name := r.string()
476 pkg := r.pkg()
477 sym := pkg.Lookup(name)
478 return ir.NewIdent(src.NoXPos, sym)
479 }
480
481 func (r *importReader) pos() src.XPos {
482 delta := r.int64()
483 r.prevColumn += delta >> 1
484 if delta&1 != 0 {
485 delta = r.int64()
486 r.prevLine += delta >> 1
487 if delta&1 != 0 {
488 r.prevBase = r.posBase()
489 }
490 }
491
492 if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 {
493
494
495 return src.NoXPos
496 }
497
498 if r.prevBase == nil {
499 base.Fatalf("missing posbase")
500 }
501 pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn))
502 return base.Ctxt.PosTable.XPos(pos)
503 }
504
505 func (r *importReader) typ() *types.Type {
506 return r.p.typAt(r.uint64())
507 }
508
509 func (r *importReader) exoticType() *types.Type {
510 switch r.uint64() {
511 case exoticTypeNil:
512 return nil
513 case exoticTypeTuple:
514 funarg := types.Funarg(r.uint64())
515 n := r.uint64()
516 fs := make([]*types.Field, n)
517 for i := range fs {
518 pos := r.pos()
519 var sym *types.Sym
520 switch r.uint64() {
521 case exoticTypeSymNil:
522 sym = nil
523 case exoticTypeSymNoPkg:
524 sym = types.NoPkg.Lookup(r.string())
525 case exoticTypeSymWithPkg:
526 pkg := r.pkg()
527 sym = pkg.Lookup(r.string())
528 default:
529 base.Fatalf("unknown symbol kind")
530 }
531 typ := r.typ()
532 f := types.NewField(pos, sym, typ)
533 fs[i] = f
534 }
535 t := types.NewStruct(types.NoPkg, fs)
536 t.StructType().Funarg = funarg
537 return t
538 case exoticTypeRecv:
539 var rcvr *types.Field
540 if r.bool() {
541 rcvr = fakeRecvField()
542 } else {
543 rcvr = r.exoticParam()
544 }
545 return r.exoticSignature(rcvr)
546 case exoticTypeRegular:
547 return r.typ()
548 default:
549 base.Fatalf("bad kind of call type")
550 return nil
551 }
552 }
553
554 func (r *importReader) exoticSelector() *types.Sym {
555 name := r.string()
556 if name == "" {
557 return nil
558 }
559 pkg := r.currPkg
560 if types.IsExported(name) {
561 pkg = types.LocalPkg
562 }
563 if r.uint64() != 0 {
564 pkg = r.pkg()
565 }
566 return pkg.Lookup(name)
567 }
568
569 func (r *importReader) exoticSignature(recv *types.Field) *types.Type {
570 var pkg *types.Pkg
571 if r.bool() {
572 pkg = r.pkg()
573 }
574 params := r.exoticParamList()
575 results := r.exoticParamList()
576 return types.NewSignature(pkg, recv, nil, params, results)
577 }
578
579 func (r *importReader) exoticParamList() []*types.Field {
580 n := r.uint64()
581 fs := make([]*types.Field, n)
582 for i := range fs {
583 fs[i] = r.exoticParam()
584 }
585 return fs
586 }
587
588 func (r *importReader) exoticParam() *types.Field {
589 pos := r.pos()
590 sym := r.exoticSym()
591 off := r.uint64()
592 typ := r.exoticType()
593 ddd := r.bool()
594 f := types.NewField(pos, sym, typ)
595 f.Offset = int64(off)
596 if sym != nil {
597 f.Nname = ir.NewNameAt(pos, sym)
598 }
599 f.SetIsDDD(ddd)
600 return f
601 }
602
603 func (r *importReader) exoticField() *types.Field {
604 pos := r.pos()
605 sym := r.exoticSym()
606 off := r.uint64()
607 typ := r.exoticType()
608 note := r.string()
609 f := types.NewField(pos, sym, typ)
610 f.Offset = int64(off)
611 if sym != nil {
612 f.Nname = ir.NewNameAt(pos, sym)
613 }
614 f.Note = note
615 return f
616 }
617
618 func (r *importReader) exoticSym() *types.Sym {
619 name := r.string()
620 if name == "" {
621 return nil
622 }
623 var pkg *types.Pkg
624 if types.IsExported(name) {
625 pkg = types.LocalPkg
626 } else {
627 pkg = r.pkg()
628 }
629 return pkg.Lookup(name)
630 }
631
632 func (p *iimporter) typAt(off uint64) *types.Type {
633 t, ok := p.typCache[off]
634 if !ok {
635 if off < predeclReserved {
636 base.Fatalf("predeclared type missing from cache: %d", off)
637 }
638 t = p.newReader(off-predeclReserved, nil).typ1()
639
640
641
642
643
644 types.CheckSize(t)
645 p.typCache[off] = t
646 }
647 return t
648 }
649
650 func (r *importReader) typ1() *types.Type {
651 switch k := r.kind(); k {
652 default:
653 base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
654 return nil
655
656 case definedType:
657
658
659
660
661
662
663 n := expandDecl(r.qualifiedIdent())
664 if n.Op() != ir.OTYPE {
665 base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n)
666 }
667 return n.Type()
668 case pointerType:
669 return types.NewPtr(r.typ())
670 case sliceType:
671 return types.NewSlice(r.typ())
672 case arrayType:
673 n := r.uint64()
674 return types.NewArray(r.typ(), int64(n))
675 case chanType:
676 dir := types.ChanDir(r.uint64())
677 return types.NewChan(r.typ(), dir)
678 case mapType:
679 return types.NewMap(r.typ(), r.typ())
680
681 case signatureType:
682 r.setPkg()
683 return r.signature(nil)
684
685 case structType:
686 r.setPkg()
687
688 fs := make([]*types.Field, r.uint64())
689 for i := range fs {
690 pos := r.pos()
691 sym := r.selector()
692 typ := r.typ()
693 emb := r.bool()
694 note := r.string()
695
696 f := types.NewField(pos, sym, typ)
697 if emb {
698 f.Embedded = 1
699 }
700 f.Note = note
701 fs[i] = f
702 }
703
704 return types.NewStruct(r.currPkg, fs)
705
706 case interfaceType:
707 r.setPkg()
708
709 embeddeds := make([]*types.Field, r.uint64())
710 for i := range embeddeds {
711 pos := r.pos()
712 typ := r.typ()
713
714 embeddeds[i] = types.NewField(pos, nil, typ)
715 }
716
717 methods := make([]*types.Field, r.uint64())
718 for i := range methods {
719 pos := r.pos()
720 sym := r.selector()
721 typ := r.signature(fakeRecvField())
722
723 methods[i] = types.NewField(pos, sym, typ)
724 }
725
726 t := types.NewInterface(r.currPkg, append(embeddeds, methods...))
727
728
729 types.CheckSize(t)
730 return t
731 }
732 }
733
734 func (r *importReader) kind() itag {
735 return itag(r.uint64())
736 }
737
738 func (r *importReader) signature(recv *types.Field) *types.Type {
739 params := r.paramList()
740 results := r.paramList()
741 if n := len(params); n > 0 {
742 params[n-1].SetIsDDD(r.bool())
743 }
744 return types.NewSignature(r.currPkg, recv, nil, params, results)
745 }
746
747 func (r *importReader) paramList() []*types.Field {
748 fs := make([]*types.Field, r.uint64())
749 for i := range fs {
750 fs[i] = r.param()
751 }
752 return fs
753 }
754
755 func (r *importReader) param() *types.Field {
756 return types.NewField(r.pos(), r.localIdent(), r.typ())
757 }
758
759 func (r *importReader) bool() bool {
760 return r.uint64() != 0
761 }
762
763 func (r *importReader) int64() int64 {
764 n, err := binary.ReadVarint(r)
765 if err != nil {
766 base.Fatalf("readVarint: %v", err)
767 }
768 return n
769 }
770
771 func (r *importReader) uint64() uint64 {
772 n, err := binary.ReadUvarint(r)
773 if err != nil {
774 base.Fatalf("readVarint: %v", err)
775 }
776 return n
777 }
778
779 func (r *importReader) byte() byte {
780 x, err := r.ReadByte()
781 if err != nil {
782 base.Fatalf("declReader.ReadByte: %v", err)
783 }
784 return x
785 }
786
787
788
789 func (r *importReader) constExt(n *ir.Name) {
790 switch n.Type() {
791 case types.UntypedFloat:
792 n.SetVal(r.mprat(n.Val()))
793 case types.UntypedComplex:
794 v := n.Val()
795 re := r.mprat(constant.Real(v))
796 im := r.mprat(constant.Imag(v))
797 n.SetVal(makeComplex(re, im))
798 }
799 }
800
801 func (r *importReader) varExt(n *ir.Name) {
802 r.linkname(n.Sym())
803 r.symIdx(n.Sym())
804 }
805
806 func (r *importReader) funcExt(n *ir.Name) {
807 r.linkname(n.Sym())
808 r.symIdx(n.Sym())
809
810 n.Func.ABI = obj.ABI(r.uint64())
811
812 n.SetPragma(ir.PragmaFlag(r.uint64()))
813
814
815 for _, fs := range &types.RecvsParams {
816 for _, f := range fs(n.Type()).FieldSlice() {
817 f.Note = r.string()
818 }
819 }
820
821
822 if u := r.uint64(); u > 0 {
823 n.Func.Inl = &ir.Inline{
824 Cost: int32(u - 1),
825 }
826 n.Func.Endlineno = r.pos()
827 }
828 }
829
830 func (r *importReader) methExt(m *types.Field) {
831 if r.bool() {
832 m.SetNointerface(true)
833 }
834 r.funcExt(m.Nname.(*ir.Name))
835 }
836
837 func (r *importReader) linkname(s *types.Sym) {
838 s.Linkname = r.string()
839 }
840
841 func (r *importReader) symIdx(s *types.Sym) {
842 lsym := s.Linksym()
843 idx := int32(r.int64())
844 if idx != -1 {
845 if s.Linkname != "" {
846 base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx)
847 }
848 lsym.SymIdx = idx
849 lsym.Set(obj.AttrIndexed, true)
850 }
851 }
852
853 func (r *importReader) typeExt(t *types.Type) {
854 t.SetNotInHeap(r.bool())
855 i, pi := r.int64(), r.int64()
856 if i != -1 && pi != -1 {
857 typeSymIdx[t] = [2]int64{i, pi}
858 }
859 }
860
861
862
863 var typeSymIdx = make(map[*types.Type][2]int64)
864
865 func BaseTypeIndex(t *types.Type) int64 {
866 tbase := t
867 if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil {
868 tbase = t.Elem()
869 }
870 i, ok := typeSymIdx[tbase]
871 if !ok {
872 return -1
873 }
874 if t != tbase {
875 return i[1]
876 }
877 return i[0]
878 }
879
880 func (r *importReader) doInline(fn *ir.Func) {
881 if len(fn.Inl.Body) != 0 {
882 base.Fatalf("%v already has inline body", fn)
883 }
884
885
886 r.funcBody(fn)
887
888 importlist = append(importlist, fn)
889
890 if base.Flag.E > 0 && base.Flag.LowerM > 2 {
891 if base.Flag.LowerM > 3 {
892 fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
893 } else {
894 fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body))
895 }
896 }
897 }
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914 func (r *importReader) funcBody(fn *ir.Func) {
915 outerfn := r.curfn
916 r.curfn = fn
917
918
919 fn.Inl.Dcl = r.readFuncDcls(fn)
920
921
922 body := r.stmtList()
923 if body == nil {
924
925
926
927
928
929 body = []ir.Node{}
930 }
931 if go117ExportTypes {
932 ir.VisitList(body, func(n ir.Node) {
933 n.SetTypecheck(1)
934 })
935 }
936 fn.Inl.Body = body
937
938 r.curfn = outerfn
939 }
940
941 func (r *importReader) readNames(fn *ir.Func) []*ir.Name {
942 dcls := make([]*ir.Name, r.int64())
943 for i := range dcls {
944 n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent())
945 n.Class = ir.PAUTO
946 n.Curfn = fn
947 n.SetType(r.typ())
948 dcls[i] = n
949 }
950 r.allDcls = append(r.allDcls, dcls...)
951 return dcls
952 }
953
954 func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name {
955 dcls := r.readNames(fn)
956
957
958
959 i := 0
960 fix := func(f *types.Field, class ir.Class) {
961 if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") {
962 return
963 }
964 n := dcls[i]
965 n.Class = class
966 f.Nname = n
967 i++
968 }
969
970 typ := fn.Type()
971 if recv := typ.Recv(); recv != nil {
972 fix(recv, ir.PPARAM)
973 }
974 for _, f := range typ.Params().FieldSlice() {
975 fix(f, ir.PPARAM)
976 }
977 for _, f := range typ.Results().FieldSlice() {
978 fix(f, ir.PPARAMOUT)
979 }
980 return dcls
981 }
982
983 func (r *importReader) localName() *ir.Name {
984 i := r.int64()
985 if i == -1 {
986 return ir.BlankNode.(*ir.Name)
987 }
988 if i < 0 {
989 return r.allClosureVars[-i-2]
990 }
991 return r.allDcls[i]
992 }
993
994 func (r *importReader) stmtList() []ir.Node {
995 var list []ir.Node
996 for {
997 n := r.node()
998 if n == nil {
999 break
1000 }
1001
1002
1003
1004 if n.Op() == ir.OBLOCK {
1005 n := n.(*ir.BlockStmt)
1006 list = append(list, n.List...)
1007 } else {
1008 list = append(list, n)
1009 }
1010
1011 }
1012 return list
1013 }
1014
1015 func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
1016 namedTypeSwitch := isNamedTypeSwitch(switchExpr)
1017
1018 cases := make([]*ir.CaseClause, r.uint64())
1019 for i := range cases {
1020 cas := ir.NewCaseStmt(r.pos(), nil, nil)
1021 cas.List = r.stmtList()
1022 if namedTypeSwitch {
1023 cas.Var = r.localName()
1024 cas.Var.Defn = switchExpr
1025 }
1026 cas.Body = r.stmtList()
1027 cases[i] = cas
1028 }
1029 return cases
1030 }
1031
1032 func (r *importReader) commList() []*ir.CommClause {
1033 cases := make([]*ir.CommClause, r.uint64())
1034 for i := range cases {
1035 cases[i] = ir.NewCommStmt(r.pos(), r.node(), r.stmtList())
1036 }
1037 return cases
1038 }
1039
1040 func (r *importReader) exprList() []ir.Node {
1041 var list []ir.Node
1042 for {
1043 n := r.expr()
1044 if n == nil {
1045 break
1046 }
1047 list = append(list, n)
1048 }
1049 return list
1050 }
1051
1052 func (r *importReader) expr() ir.Node {
1053 n := r.node()
1054 if n != nil && n.Op() == ir.OBLOCK {
1055 n := n.(*ir.BlockStmt)
1056 base.Fatalf("unexpected block node: %v", n)
1057 }
1058 return n
1059 }
1060
1061
1062 func (r *importReader) node() ir.Node {
1063 op := r.op()
1064 switch op {
1065
1066
1067
1068
1069 case ir.ONIL:
1070 pos := r.pos()
1071 typ := r.typ()
1072
1073 n := ir.NewNilExpr(pos)
1074 n.SetType(typ)
1075 return n
1076
1077 case ir.OLITERAL:
1078 pos := r.pos()
1079 typ := r.typ()
1080
1081 n := ir.NewBasicLit(pos, r.value(typ))
1082 n.SetType(typ)
1083 return n
1084
1085 case ir.ONONAME:
1086 n := r.qualifiedIdent()
1087 if go117ExportTypes {
1088 n2 := Resolve(n)
1089 typ := r.typ()
1090 if n2.Type() == nil {
1091 n2.SetType(typ)
1092 }
1093 return n2
1094 }
1095 return n
1096
1097 case ir.ONAME:
1098 return r.localName()
1099
1100
1101
1102
1103 case ir.OTYPE:
1104 return ir.TypeNode(r.typ())
1105
1106 case ir.OTYPESW:
1107 pos := r.pos()
1108 var tag *ir.Ident
1109 if s := r.localIdent(); s != nil {
1110 tag = ir.NewIdent(pos, s)
1111 }
1112 return ir.NewTypeSwitchGuard(pos, tag, r.expr())
1113
1114
1115
1116
1117 case ir.OCLOSURE:
1118
1119 pos := r.pos()
1120 typ := r.signature(nil)
1121
1122
1123
1124 fn := ir.NewFunc(pos)
1125 fn.SetIsHiddenClosure(true)
1126 fn.Nname = ir.NewNameAt(pos, ir.BlankNode.Sym())
1127 fn.Nname.Func = fn
1128 fn.Nname.Ntype = ir.TypeNode(typ)
1129 fn.Nname.Defn = fn
1130 fn.Nname.SetType(typ)
1131
1132 cvars := make([]*ir.Name, r.int64())
1133 for i := range cvars {
1134 cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
1135 if go117ExportTypes {
1136 if cvars[i].Type() != nil || cvars[i].Defn == nil {
1137 base.Fatalf("bad import of closure variable")
1138 }
1139
1140
1141 cvars[i].SetType(cvars[i].Defn.Type())
1142 }
1143 }
1144 fn.ClosureVars = cvars
1145 r.allClosureVars = append(r.allClosureVars, cvars...)
1146
1147 fn.Inl = &ir.Inline{}
1148
1149
1150 r.funcBody(fn)
1151 fn.Dcl = fn.Inl.Dcl
1152 fn.Body = fn.Inl.Body
1153 if len(fn.Body) == 0 {
1154
1155
1156 fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
1157 }
1158 fn.Inl = nil
1159
1160 ir.FinishCaptureNames(pos, r.curfn, fn)
1161
1162 clo := ir.NewClosureExpr(pos, fn)
1163 fn.OClosure = clo
1164 if go117ExportTypes {
1165 clo.SetType(typ)
1166 }
1167
1168 return clo
1169
1170 case ir.OSTRUCTLIT:
1171 if go117ExportTypes {
1172 pos := r.pos()
1173 typ := r.typ()
1174 list := r.fieldList()
1175 n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list)
1176 n.SetType(typ)
1177 return n
1178 }
1179 return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())
1180
1181 case ir.OCOMPLIT:
1182 return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.exprList())
1183
1184 case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
1185 if !go117ExportTypes {
1186
1187 goto error
1188 }
1189 pos := r.pos()
1190 typ := r.typ()
1191 list := r.exprList()
1192 n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list)
1193 n.SetType(typ)
1194 if op == ir.OSLICELIT {
1195 n.Len = int64(r.uint64())
1196 }
1197 return n
1198
1199 case ir.OKEY:
1200 return ir.NewKeyExpr(r.pos(), r.expr(), r.expr())
1201
1202
1203
1204
1205 case ir.OXDOT:
1206
1207 if go117ExportTypes {
1208 base.Fatalf("shouldn't encounter XDOT in new importer")
1209 }
1210 return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.exoticSelector())
1211
1212 case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
1213 if !go117ExportTypes {
1214
1215 goto error
1216 }
1217 pos := r.pos()
1218 expr := r.expr()
1219 sel := r.exoticSelector()
1220 n := ir.NewSelectorExpr(pos, op, expr, sel)
1221 n.SetType(r.exoticType())
1222 switch op {
1223 case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
1224 n.Selection = r.exoticField()
1225 case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
1226
1227 rcvrType := expr.Type()
1228 typ := n.Type()
1229 n.Selection = Lookdot(n, rcvrType, 1)
1230 if op == ir.OCALLPART || op == ir.OMETHEXPR {
1231
1232 n.SetOp(op)
1233 n.SetType(typ)
1234 }
1235 }
1236 return n
1237
1238 case ir.ODOTTYPE, ir.ODOTTYPE2:
1239 n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil)
1240 n.SetType(r.typ())
1241 if go117ExportTypes {
1242 n.SetOp(op)
1243 }
1244 return n
1245
1246 case ir.OINDEX, ir.OINDEXMAP:
1247 n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr())
1248 if go117ExportTypes {
1249 n.SetOp(op)
1250 n.SetType(r.typ())
1251 if op == ir.OINDEXMAP {
1252 n.Assigned = r.bool()
1253 }
1254 }
1255 return n
1256
1257 case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
1258 pos, x := r.pos(), r.expr()
1259 low, high := r.exprsOrNil()
1260 var max ir.Node
1261 if op.IsSlice3() {
1262 max = r.expr()
1263 }
1264 n := ir.NewSliceExpr(pos, op, x, low, high, max)
1265 if go117ExportTypes {
1266 n.SetType(r.typ())
1267 }
1268 return n
1269
1270 case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
1271 if !go117ExportTypes && op != ir.OCONV {
1272
1273 goto error
1274 }
1275 return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
1276
1277 case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN, ir.OUNSAFEADD, ir.OUNSAFESLICE:
1278 if go117ExportTypes {
1279 switch op {
1280 case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
1281 n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
1282 n.SetType(r.typ())
1283 return n
1284 case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
1285 n := ir.NewUnaryExpr(r.pos(), op, r.expr())
1286 if op != ir.OPANIC {
1287 n.SetType(r.typ())
1288 }
1289 return n
1290 case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
1291 n := ir.NewCallExpr(r.pos(), op, nil, r.exprList())
1292 if op == ir.OAPPEND {
1293 n.IsDDD = r.bool()
1294 }
1295 if op == ir.OAPPEND || op == ir.ORECOVER {
1296 n.SetType(r.typ())
1297 }
1298 return n
1299 }
1300
1301 goto error
1302 }
1303 n := builtinCall(r.pos(), op)
1304 n.Args = r.exprList()
1305 if op == ir.OAPPEND {
1306 n.IsDDD = r.bool()
1307 }
1308 return n
1309
1310 case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
1311 pos := r.pos()
1312 init := r.stmtList()
1313 n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList())
1314 if go117ExportTypes {
1315 n.SetOp(op)
1316 }
1317 *n.PtrInit() = init
1318 n.IsDDD = r.bool()
1319 if go117ExportTypes {
1320 n.SetType(r.exoticType())
1321 n.Use = ir.CallUse(r.uint64())
1322 }
1323 return n
1324
1325 case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
1326 if go117ExportTypes {
1327 pos := r.pos()
1328 typ := r.typ()
1329 list := r.exprList()
1330 var len_, cap_ ir.Node
1331 if len(list) > 0 {
1332 len_ = list[0]
1333 }
1334 if len(list) > 1 {
1335 cap_ = list[1]
1336 }
1337 n := ir.NewMakeExpr(pos, op, len_, cap_)
1338 n.SetType(typ)
1339 return n
1340 }
1341 n := builtinCall(r.pos(), ir.OMAKE)
1342 n.Args.Append(ir.TypeNode(r.typ()))
1343 n.Args.Append(r.exprList()...)
1344 return n
1345
1346
1347 case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
1348 n := ir.NewUnaryExpr(r.pos(), op, r.expr())
1349 if go117ExportTypes {
1350 n.SetType(r.typ())
1351 }
1352 return n
1353
1354 case ir.OADDR, ir.OPTRLIT:
1355 n := NodAddrAt(r.pos(), r.expr())
1356 if go117ExportTypes {
1357 n.SetOp(op)
1358 n.SetType(r.typ())
1359 }
1360 return n
1361
1362 case ir.ODEREF:
1363 n := ir.NewStarExpr(r.pos(), r.expr())
1364 if go117ExportTypes {
1365 n.SetType(r.typ())
1366 }
1367 return n
1368
1369
1370 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
1371 ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
1372 n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr())
1373 if go117ExportTypes {
1374 n.SetType(r.typ())
1375 }
1376 return n
1377
1378 case ir.OANDAND, ir.OOROR:
1379 n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr())
1380 if go117ExportTypes {
1381 n.SetType(r.typ())
1382 }
1383 return n
1384
1385 case ir.OSEND:
1386 return ir.NewSendStmt(r.pos(), r.expr(), r.expr())
1387
1388 case ir.OADDSTR:
1389 pos := r.pos()
1390 list := r.exprList()
1391 if go117ExportTypes {
1392 n := ir.NewAddStringExpr(pos, list)
1393 n.SetType(r.typ())
1394 return n
1395 }
1396 x := list[0]
1397 for _, y := range list[1:] {
1398 x = ir.NewBinaryExpr(pos, ir.OADD, x, y)
1399 }
1400 return x
1401
1402
1403
1404 case ir.ODCL:
1405 var stmts ir.Nodes
1406 n := r.localName()
1407 stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n))
1408 stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil))
1409 return ir.NewBlockStmt(n.Pos(), stmts)
1410
1411
1412
1413
1414 case ir.OAS:
1415 return ir.NewAssignStmt(r.pos(), r.expr(), r.expr())
1416
1417 case ir.OASOP:
1418 n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil)
1419 if !r.bool() {
1420 n.Y = ir.NewInt(1)
1421 n.IncDec = true
1422 } else {
1423 n.Y = r.expr()
1424 }
1425 return n
1426
1427 case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
1428 if !go117ExportTypes && op != ir.OAS2 {
1429
1430 goto error
1431 }
1432 return ir.NewAssignListStmt(r.pos(), op, r.exprList(), r.exprList())
1433
1434 case ir.ORETURN:
1435 return ir.NewReturnStmt(r.pos(), r.exprList())
1436
1437
1438
1439
1440 case ir.OGO, ir.ODEFER:
1441 return ir.NewGoDeferStmt(r.pos(), op, r.expr())
1442
1443 case ir.OIF:
1444 pos, init := r.pos(), r.stmtList()
1445 n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList())
1446 *n.PtrInit() = init
1447 return n
1448
1449 case ir.OFOR:
1450 pos, init := r.pos(), r.stmtList()
1451 cond, post := r.exprsOrNil()
1452 n := ir.NewForStmt(pos, nil, cond, post, r.stmtList())
1453 *n.PtrInit() = init
1454 return n
1455
1456 case ir.ORANGE:
1457 pos := r.pos()
1458 k, v := r.exprsOrNil()
1459 return ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList())
1460
1461 case ir.OSELECT:
1462 pos := r.pos()
1463 init := r.stmtList()
1464 n := ir.NewSelectStmt(pos, r.commList())
1465 *n.PtrInit() = init
1466 return n
1467
1468 case ir.OSWITCH:
1469 pos := r.pos()
1470 init := r.stmtList()
1471 x, _ := r.exprsOrNil()
1472 n := ir.NewSwitchStmt(pos, x, r.caseList(x))
1473 *n.PtrInit() = init
1474 return n
1475
1476
1477
1478
1479 case ir.OFALL:
1480 return ir.NewBranchStmt(r.pos(), ir.OFALL, nil)
1481
1482
1483
1484
1485 case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
1486 pos := r.pos()
1487 var sym *types.Sym
1488 if label := r.string(); label != "" {
1489 sym = Lookup(label)
1490 }
1491 return ir.NewBranchStmt(pos, op, sym)
1492
1493 case ir.OLABEL:
1494 return ir.NewLabelStmt(r.pos(), Lookup(r.string()))
1495
1496 case ir.OEND:
1497 return nil
1498
1499 default:
1500 base.Fatalf("cannot import %v (%d) node\n"+
1501 "\t==> please file an issue and assign to gri@", op, int(op))
1502 panic("unreachable")
1503 }
1504 error:
1505 base.Fatalf("cannot import %v (%d) node\n"+
1506 "\t==> please file an issue and assign to khr@", op, int(op))
1507 panic("unreachable")
1508 }
1509
1510 func (r *importReader) op() ir.Op {
1511 if debug && r.uint64() != magic {
1512 base.Fatalf("import stream has desynchronized")
1513 }
1514 return ir.Op(r.uint64())
1515 }
1516
1517 func (r *importReader) fieldList() []ir.Node {
1518 list := make([]ir.Node, r.uint64())
1519 for i := range list {
1520 x := ir.NewStructKeyExpr(r.pos(), r.selector(), r.expr())
1521 if go117ExportTypes {
1522 x.Offset = int64(r.uint64())
1523 }
1524 list[i] = x
1525 }
1526 return list
1527 }
1528
1529 func (r *importReader) exprsOrNil() (a, b ir.Node) {
1530 ab := r.uint64()
1531 if ab&1 != 0 {
1532 a = r.expr()
1533 }
1534 if ab&2 != 0 {
1535 b = r.node()
1536 }
1537 return
1538 }
1539
1540 func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
1541 if go117ExportTypes {
1542
1543 base.Fatalf("builtinCall should not be invoked when types are included in import/export")
1544 }
1545 return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
1546 }
1547
View as plain text