Source file src/pkg/cmd/compile/internal/gc/iimport.go
1
2
3
4
5
6
7
8 package gc
9
10 import (
11 "cmd/compile/internal/types"
12 "cmd/internal/bio"
13 "cmd/internal/src"
14 "encoding/binary"
15 "fmt"
16 "math/big"
17 "os"
18 "strings"
19 )
20
21
22
23 type iimporterAndOffset struct {
24 p *iimporter
25 off uint64
26 }
27
28 var (
29
30
31 declImporter = map[*types.Sym]iimporterAndOffset{}
32
33
34
35 inlineImporter = map[*types.Sym]iimporterAndOffset{}
36 )
37
38 func expandDecl(n *Node) {
39 if n.Op != ONONAME {
40 return
41 }
42
43 r := importReaderFor(n, declImporter)
44 if r == nil {
45
46 return
47 }
48
49 r.doDecl(n)
50 }
51
52 func expandInline(fn *Node) {
53 if fn.Func.Inl.Body != nil {
54 return
55 }
56
57 r := importReaderFor(fn, inlineImporter)
58 if r == nil {
59 Fatalf("missing import reader for %v", fn)
60 }
61
62 r.doInline(fn)
63 }
64
65 func importReaderFor(n *Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
66 x, ok := importers[n.Sym]
67 if !ok {
68 return nil
69 }
70
71 return x.p.newReader(x.off, n.Sym.Pkg)
72 }
73
74 type intReader struct {
75 *bio.Reader
76 pkg *types.Pkg
77 }
78
79 func (r *intReader) int64() int64 {
80 i, err := binary.ReadVarint(r.Reader)
81 if err != nil {
82 yyerror("import %q: read error: %v", r.pkg.Path, err)
83 errorexit()
84 }
85 return i
86 }
87
88 func (r *intReader) uint64() uint64 {
89 i, err := binary.ReadUvarint(r.Reader)
90 if err != nil {
91 yyerror("import %q: read error: %v", r.pkg.Path, err)
92 errorexit()
93 }
94 return i
95 }
96
97 func iimport(pkg *types.Pkg, in *bio.Reader) {
98 ir := &intReader{in, pkg}
99
100 version := ir.uint64()
101 if version != iexportVersion {
102 yyerror("import %q: unknown export format version %d", pkg.Path, version)
103 errorexit()
104 }
105
106 sLen := ir.uint64()
107 dLen := ir.uint64()
108
109
110
111
112 data, err := mapFile(in.File(), in.Offset(), int64(sLen+dLen))
113 if err != nil {
114 yyerror("import %q: mapping input: %v", pkg.Path, err)
115 errorexit()
116 }
117 stringData := data[:sLen]
118 declData := data[sLen:]
119
120 in.MustSeek(int64(sLen+dLen), os.SEEK_CUR)
121
122 p := &iimporter{
123 ipkg: pkg,
124
125 pkgCache: map[uint64]*types.Pkg{},
126 posBaseCache: map[uint64]*src.PosBase{},
127 typCache: map[uint64]*types.Type{},
128
129 stringData: stringData,
130 declData: declData,
131 }
132
133 for i, pt := range predeclared() {
134 p.typCache[uint64(i)] = pt
135 }
136
137
138 for nPkgs := ir.uint64(); nPkgs > 0; nPkgs-- {
139 pkg := p.pkgAt(ir.uint64())
140 pkgName := p.stringAt(ir.uint64())
141 pkgHeight := int(ir.uint64())
142 if pkg.Name == "" {
143 pkg.Name = pkgName
144 pkg.Height = pkgHeight
145 numImport[pkgName]++
146
147
148 pkg.Lookup("_").Def = asTypesNode(nblank)
149 } else {
150 if pkg.Name != pkgName {
151 Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
152 }
153 if pkg.Height != pkgHeight {
154 Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
155 }
156 }
157
158 for nSyms := ir.uint64(); nSyms > 0; nSyms-- {
159 s := pkg.Lookup(p.stringAt(ir.uint64()))
160 off := ir.uint64()
161
162 if _, ok := declImporter[s]; ok {
163 continue
164 }
165 declImporter[s] = iimporterAndOffset{p, off}
166
167
168
169 if s.Def != nil {
170 Fatalf("unexpected definition for %v: %v", s, asNode(s.Def))
171 }
172 s.Def = asTypesNode(npos(src.NoXPos, dclname(s)))
173 }
174 }
175
176
177 for nPkgs := ir.uint64(); nPkgs > 0; nPkgs-- {
178 pkg := p.pkgAt(ir.uint64())
179
180 for nSyms := ir.uint64(); nSyms > 0; nSyms-- {
181 s := pkg.Lookup(p.stringAt(ir.uint64()))
182 off := ir.uint64()
183
184 if _, ok := inlineImporter[s]; ok {
185 continue
186 }
187 inlineImporter[s] = iimporterAndOffset{p, off}
188 }
189 }
190 }
191
192 type iimporter struct {
193 ipkg *types.Pkg
194
195 pkgCache map[uint64]*types.Pkg
196 posBaseCache map[uint64]*src.PosBase
197 typCache map[uint64]*types.Type
198
199 stringData string
200 declData string
201 }
202
203 func (p *iimporter) stringAt(off uint64) string {
204 var x [binary.MaxVarintLen64]byte
205 n := copy(x[:], p.stringData[off:])
206
207 slen, n := binary.Uvarint(x[:n])
208 if n <= 0 {
209 Fatalf("varint failed")
210 }
211 spos := off + uint64(n)
212 return p.stringData[spos : spos+slen]
213 }
214
215 func (p *iimporter) posBaseAt(off uint64) *src.PosBase {
216 if posBase, ok := p.posBaseCache[off]; ok {
217 return posBase
218 }
219
220 file := p.stringAt(off)
221 posBase := src.NewFileBase(file, file)
222 p.posBaseCache[off] = posBase
223 return posBase
224 }
225
226 func (p *iimporter) pkgAt(off uint64) *types.Pkg {
227 if pkg, ok := p.pkgCache[off]; ok {
228 return pkg
229 }
230
231 pkg := p.ipkg
232 if pkgPath := p.stringAt(off); pkgPath != "" {
233 pkg = types.NewPkg(pkgPath, "")
234 }
235 p.pkgCache[off] = pkg
236 return pkg
237 }
238
239
240
241 type importReader struct {
242 strings.Reader
243 p *iimporter
244
245 currPkg *types.Pkg
246 prevBase *src.PosBase
247 prevLine int64
248 }
249
250 func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader {
251 r := &importReader{
252 p: p,
253 currPkg: pkg,
254 }
255
256
257 r.Reader = *strings.NewReader(p.declData[off:])
258 return r
259 }
260
261 func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
262 func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) }
263 func (r *importReader) pkg() *types.Pkg { return r.p.pkgAt(r.uint64()) }
264
265 func (r *importReader) setPkg() {
266 r.currPkg = r.pkg()
267 }
268
269 func (r *importReader) doDecl(n *Node) {
270 if n.Op != ONONAME {
271 Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
272 }
273
274 tag := r.byte()
275 pos := r.pos()
276
277 switch tag {
278 case 'A':
279 typ := r.typ()
280
281 importalias(r.p.ipkg, pos, n.Sym, typ)
282
283 case 'C':
284 typ, val := r.value()
285
286 importconst(r.p.ipkg, pos, n.Sym, typ, val)
287
288 case 'F':
289 typ := r.signature(nil)
290
291 importfunc(r.p.ipkg, pos, n.Sym, typ)
292 r.funcExt(n)
293
294 case 'T':
295
296
297 t := importtype(r.p.ipkg, pos, n.Sym)
298
299
300
301
302
303
304
305
306
307 deferring := defercalc != 0
308 if !deferring {
309 defercheckwidth()
310 }
311 underlying := r.typ()
312 copytype(typenod(t), underlying)
313 if !deferring {
314 resumecheckwidth()
315 }
316
317 if underlying.IsInterface() {
318 break
319 }
320
321 ms := make([]*types.Field, r.uint64())
322 for i := range ms {
323 mpos := r.pos()
324 msym := r.ident()
325 recv := r.param()
326 mtyp := r.signature(recv)
327
328 f := types.NewField()
329 f.Pos = mpos
330 f.Sym = msym
331 f.Type = mtyp
332 ms[i] = f
333
334 m := newfuncnamel(mpos, methodSym(recv.Type, msym))
335 m.Type = mtyp
336 m.SetClass(PFUNC)
337
338
339
340
341
342
343
344 mtyp.SetNname(asTypesNode(m))
345 }
346 t.Methods().Set(ms)
347
348 for _, m := range ms {
349 r.methExt(m)
350 }
351
352 case 'V':
353 typ := r.typ()
354
355 importvar(r.p.ipkg, pos, n.Sym, typ)
356 r.varExt(n)
357
358 default:
359 Fatalf("unexpected tag: %v", tag)
360 }
361 }
362
363 func (p *importReader) value() (typ *types.Type, v Val) {
364 typ = p.typ()
365
366 switch constTypeOf(typ) {
367 case CTNIL:
368 v.U = &NilVal{}
369 case CTBOOL:
370 v.U = p.bool()
371 case CTSTR:
372 v.U = p.string()
373 case CTINT:
374 x := new(Mpint)
375 x.Rune = typ == types.Idealrune
376 p.mpint(&x.Val, typ)
377 v.U = x
378 case CTFLT:
379 x := newMpflt()
380 p.float(x, typ)
381 v.U = x
382 case CTCPLX:
383 x := newMpcmplx()
384 p.float(&x.Real, typ)
385 p.float(&x.Imag, typ)
386 v.U = x
387 }
388
389 typ = idealType(typ)
390 return
391 }
392
393 func (p *importReader) mpint(x *big.Int, typ *types.Type) {
394 signed, maxBytes := intSize(typ)
395
396 maxSmall := 256 - maxBytes
397 if signed {
398 maxSmall = 256 - 2*maxBytes
399 }
400 if maxBytes == 1 {
401 maxSmall = 256
402 }
403
404 n, _ := p.ReadByte()
405 if uint(n) < maxSmall {
406 v := int64(n)
407 if signed {
408 v >>= 1
409 if n&1 != 0 {
410 v = ^v
411 }
412 }
413 x.SetInt64(v)
414 return
415 }
416
417 v := -n
418 if signed {
419 v = -(n &^ 1) >> 1
420 }
421 if v < 1 || uint(v) > maxBytes {
422 Fatalf("weird decoding: %v, %v => %v", n, signed, v)
423 }
424 b := make([]byte, v)
425 p.Read(b)
426 x.SetBytes(b)
427 if signed && n&1 != 0 {
428 x.Neg(x)
429 }
430 }
431
432 func (p *importReader) float(x *Mpflt, typ *types.Type) {
433 var mant big.Int
434 p.mpint(&mant, typ)
435 m := x.Val.SetInt(&mant)
436 if m.Sign() == 0 {
437 return
438 }
439 m.SetMantExp(m, int(p.int64()))
440 }
441
442 func (r *importReader) ident() *types.Sym {
443 name := r.string()
444 if name == "" {
445 return nil
446 }
447 pkg := r.currPkg
448 if types.IsExported(name) {
449 pkg = localpkg
450 }
451 return pkg.Lookup(name)
452 }
453
454 func (r *importReader) qualifiedIdent() *types.Sym {
455 name := r.string()
456 pkg := r.pkg()
457 return pkg.Lookup(name)
458 }
459
460 func (r *importReader) pos() src.XPos {
461 delta := r.int64()
462 if delta != deltaNewFile {
463 r.prevLine += delta
464 } else if l := r.int64(); l == -1 {
465 r.prevLine += deltaNewFile
466 } else {
467 r.prevBase = r.posBase()
468 r.prevLine = l
469 }
470
471 if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 {
472
473
474 return src.NoXPos
475 }
476
477 if r.prevBase == nil {
478 Fatalf("missing posbase")
479 }
480 pos := src.MakePos(r.prevBase, uint(r.prevLine), 0)
481 return Ctxt.PosTable.XPos(pos)
482 }
483
484 func (r *importReader) typ() *types.Type {
485 return r.p.typAt(r.uint64())
486 }
487
488 func (p *iimporter) typAt(off uint64) *types.Type {
489 t, ok := p.typCache[off]
490 if !ok {
491 if off < predeclReserved {
492 Fatalf("predeclared type missing from cache: %d", off)
493 }
494 t = p.newReader(off-predeclReserved, nil).typ1()
495 p.typCache[off] = t
496 }
497 return t
498 }
499
500 func (r *importReader) typ1() *types.Type {
501 switch k := r.kind(); k {
502 default:
503 Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k)
504 return nil
505
506 case definedType:
507
508
509
510
511
512
513 n := asNode(r.qualifiedIdent().PkgDef())
514 if n.Op == ONONAME {
515 expandDecl(n)
516 }
517 if n.Op != OTYPE {
518 Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
519 }
520 return n.Type
521 case pointerType:
522 return types.NewPtr(r.typ())
523 case sliceType:
524 return types.NewSlice(r.typ())
525 case arrayType:
526 n := r.uint64()
527 return types.NewArray(r.typ(), int64(n))
528 case chanType:
529 dir := types.ChanDir(r.uint64())
530 return types.NewChan(r.typ(), dir)
531 case mapType:
532 return types.NewMap(r.typ(), r.typ())
533
534 case signatureType:
535 r.setPkg()
536 return r.signature(nil)
537
538 case structType:
539 r.setPkg()
540
541 fs := make([]*types.Field, r.uint64())
542 for i := range fs {
543 pos := r.pos()
544 sym := r.ident()
545 typ := r.typ()
546 emb := r.bool()
547 note := r.string()
548
549 f := types.NewField()
550 f.Pos = pos
551 f.Sym = sym
552 f.Type = typ
553 if emb {
554 f.Embedded = 1
555 }
556 f.Note = note
557 fs[i] = f
558 }
559
560 t := types.New(TSTRUCT)
561 t.SetPkg(r.currPkg)
562 t.SetFields(fs)
563 return t
564
565 case interfaceType:
566 r.setPkg()
567
568 embeddeds := make([]*types.Field, r.uint64())
569 for i := range embeddeds {
570 pos := r.pos()
571 typ := r.typ()
572
573 f := types.NewField()
574 f.Pos = pos
575 f.Type = typ
576 embeddeds[i] = f
577 }
578
579 methods := make([]*types.Field, r.uint64())
580 for i := range methods {
581 pos := r.pos()
582 sym := r.ident()
583 typ := r.signature(fakeRecvField())
584
585 f := types.NewField()
586 f.Pos = pos
587 f.Sym = sym
588 f.Type = typ
589 methods[i] = f
590 }
591
592 t := types.New(TINTER)
593 t.SetPkg(r.currPkg)
594 t.SetInterface(append(embeddeds, methods...))
595
596
597 checkwidth(t)
598
599 return t
600 }
601 }
602
603 func (r *importReader) kind() itag {
604 return itag(r.uint64())
605 }
606
607 func (r *importReader) signature(recv *types.Field) *types.Type {
608 params := r.paramList()
609 results := r.paramList()
610 if n := len(params); n > 0 {
611 params[n-1].SetIsDDD(r.bool())
612 }
613 t := functypefield(recv, params, results)
614 t.SetPkg(r.currPkg)
615 return t
616 }
617
618 func (r *importReader) paramList() []*types.Field {
619 fs := make([]*types.Field, r.uint64())
620 for i := range fs {
621 fs[i] = r.param()
622 }
623 return fs
624 }
625
626 func (r *importReader) param() *types.Field {
627 f := types.NewField()
628 f.Pos = r.pos()
629 f.Sym = r.ident()
630 f.Type = r.typ()
631 return f
632 }
633
634 func (r *importReader) bool() bool {
635 return r.uint64() != 0
636 }
637
638 func (r *importReader) int64() int64 {
639 n, err := binary.ReadVarint(r)
640 if err != nil {
641 Fatalf("readVarint: %v", err)
642 }
643 return n
644 }
645
646 func (r *importReader) uint64() uint64 {
647 n, err := binary.ReadUvarint(r)
648 if err != nil {
649 Fatalf("readVarint: %v", err)
650 }
651 return n
652 }
653
654 func (r *importReader) byte() byte {
655 x, err := r.ReadByte()
656 if err != nil {
657 Fatalf("declReader.ReadByte: %v", err)
658 }
659 return x
660 }
661
662
663
664 func (r *importReader) varExt(n *Node) {
665 r.linkname(n.Sym)
666 }
667
668 func (r *importReader) funcExt(n *Node) {
669 r.linkname(n.Sym)
670
671
672 for _, fs := range types.RecvsParams {
673 for _, f := range fs(n.Type).FieldSlice() {
674 f.Note = r.string()
675 }
676 }
677
678
679 if u := r.uint64(); u > 0 {
680 n.Func.Inl = &Inline{
681 Cost: int32(u - 1),
682 }
683 n.Func.Endlineno = r.pos()
684 }
685 }
686
687 func (r *importReader) methExt(m *types.Field) {
688 if r.bool() {
689 m.SetNointerface(true)
690 }
691 r.funcExt(asNode(m.Type.Nname()))
692 }
693
694 func (r *importReader) linkname(s *types.Sym) {
695 s.Linkname = r.string()
696 }
697
698 func (r *importReader) doInline(n *Node) {
699 if len(n.Func.Inl.Body) != 0 {
700 Fatalf("%v already has inline body", n)
701 }
702
703 funchdr(n)
704 body := r.stmtList()
705 funcbody()
706 if body == nil {
707
708
709
710
711
712
713 body = []*Node{}
714 }
715 n.Func.Inl.Body = body
716
717 importlist = append(importlist, n)
718
719 if Debug['E'] > 0 && Debug['m'] > 2 {
720 if Debug['m'] > 3 {
721 fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
722 } else {
723 fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
724 }
725 }
726 }
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743 func (r *importReader) stmtList() []*Node {
744 var list []*Node
745 for {
746 n := r.node()
747 if n == nil {
748 break
749 }
750
751 if n.Op == OBLOCK {
752 list = append(list, n.List.Slice()...)
753 } else {
754 list = append(list, n)
755 }
756
757 }
758 return list
759 }
760
761 func (r *importReader) exprList() []*Node {
762 var list []*Node
763 for {
764 n := r.expr()
765 if n == nil {
766 break
767 }
768 list = append(list, n)
769 }
770 return list
771 }
772
773 func (r *importReader) expr() *Node {
774 n := r.node()
775 if n != nil && n.Op == OBLOCK {
776 Fatalf("unexpected block node: %v", n)
777 }
778 return n
779 }
780
781
782 func (r *importReader) node() *Node {
783 switch op := r.op(); op {
784
785
786
787
788
789
790
791 case OLITERAL:
792 pos := r.pos()
793 typ, val := r.value()
794
795 n := npos(pos, nodlit(val))
796 n.Type = typ
797 return n
798
799 case ONONAME:
800 return mkname(r.qualifiedIdent())
801
802 case ONAME:
803 return mkname(r.ident())
804
805
806
807
808 case OTYPE:
809 return typenod(r.typ())
810
811
812
813
814
815
816
817 case OPTRLIT:
818 pos := r.pos()
819 n := npos(pos, r.expr())
820 if !r.bool() {
821 if n.Op == OCOMPLIT {
822
823 n.Right = nodl(pos, ODEREF, n.Right, nil)
824 n.Right.SetImplicit(true)
825 } else {
826 n = nodl(pos, OADDR, n, nil)
827 }
828 }
829 return n
830
831 case OSTRUCTLIT:
832
833 savedlineno := lineno
834 lineno = r.pos()
835 n := nodl(lineno, OCOMPLIT, nil, typenod(r.typ()))
836 n.List.Set(r.elemList())
837 lineno = savedlineno
838 return n
839
840
841
842
843 case OCOMPLIT:
844 n := nodl(r.pos(), OCOMPLIT, nil, typenod(r.typ()))
845 n.List.Set(r.exprList())
846 return n
847
848 case OKEY:
849 pos := r.pos()
850 left, right := r.exprsOrNil()
851 return nodl(pos, OKEY, left, right)
852
853
854
855
856
857
858
859
860
861
862 case OXDOT:
863
864 return npos(r.pos(), nodSym(OXDOT, r.expr(), r.ident()))
865
866
867
868
869 case ODOTTYPE:
870 n := nodl(r.pos(), ODOTTYPE, r.expr(), nil)
871 n.Type = r.typ()
872 return n
873
874
875
876
877 case OINDEX:
878 return nodl(r.pos(), op, r.expr(), r.expr())
879
880 case OSLICE, OSLICE3:
881 n := nodl(r.pos(), op, r.expr(), nil)
882 low, high := r.exprsOrNil()
883 var max *Node
884 if n.Op.IsSlice3() {
885 max = r.expr()
886 }
887 n.SetSliceBounds(low, high, max)
888 return n
889
890
891
892
893 case OCONV:
894 n := nodl(r.pos(), OCONV, r.expr(), nil)
895 n.Type = r.typ()
896 return n
897
898 case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
899 n := npos(r.pos(), builtinCall(op))
900 n.List.Set(r.exprList())
901 if op == OAPPEND {
902 n.SetIsDDD(r.bool())
903 }
904 return n
905
906
907
908
909 case OCALL:
910 n := nodl(r.pos(), OCALL, nil, nil)
911 n.Ninit.Set(r.stmtList())
912 n.Left = r.expr()
913 n.List.Set(r.exprList())
914 n.SetIsDDD(r.bool())
915 return n
916
917 case OMAKEMAP, OMAKECHAN, OMAKESLICE:
918 n := npos(r.pos(), builtinCall(OMAKE))
919 n.List.Append(typenod(r.typ()))
920 n.List.Append(r.exprList()...)
921 return n
922
923
924 case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
925 return nodl(r.pos(), op, r.expr(), nil)
926
927
928 case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
929 OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
930 return nodl(r.pos(), op, r.expr(), r.expr())
931
932 case OADDSTR:
933 pos := r.pos()
934 list := r.exprList()
935 x := npos(pos, list[0])
936 for _, y := range list[1:] {
937 x = nodl(pos, OADD, x, y)
938 }
939 return x
940
941
942
943 case ODCL:
944 pos := r.pos()
945 lhs := npos(pos, dclname(r.ident()))
946 typ := typenod(r.typ())
947 return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil)))
948
949
950
951
952
953
954
955 case OAS:
956 return nodl(r.pos(), OAS, r.expr(), r.expr())
957
958 case OASOP:
959 n := nodl(r.pos(), OASOP, nil, nil)
960 n.SetSubOp(r.op())
961 n.Left = r.expr()
962 if !r.bool() {
963 n.Right = nodintconst(1)
964 n.SetImplicit(true)
965 } else {
966 n.Right = r.expr()
967 }
968 return n
969
970
971
972
973 case OAS2:
974 n := nodl(r.pos(), OAS2, nil, nil)
975 n.List.Set(r.exprList())
976 n.Rlist.Set(r.exprList())
977 return n
978
979 case ORETURN:
980 n := nodl(r.pos(), ORETURN, nil, nil)
981 n.List.Set(r.exprList())
982 return n
983
984
985
986
987 case OGO, ODEFER:
988 return nodl(r.pos(), op, r.expr(), nil)
989
990 case OIF:
991 n := nodl(r.pos(), OIF, nil, nil)
992 n.Ninit.Set(r.stmtList())
993 n.Left = r.expr()
994 n.Nbody.Set(r.stmtList())
995 n.Rlist.Set(r.stmtList())
996 return n
997
998 case OFOR:
999 n := nodl(r.pos(), OFOR, nil, nil)
1000 n.Ninit.Set(r.stmtList())
1001 n.Left, n.Right = r.exprsOrNil()
1002 n.Nbody.Set(r.stmtList())
1003 return n
1004
1005 case ORANGE:
1006 n := nodl(r.pos(), ORANGE, nil, nil)
1007 n.List.Set(r.stmtList())
1008 n.Right = r.expr()
1009 n.Nbody.Set(r.stmtList())
1010 return n
1011
1012 case OSELECT, OSWITCH:
1013 n := nodl(r.pos(), op, nil, nil)
1014 n.Ninit.Set(r.stmtList())
1015 n.Left, _ = r.exprsOrNil()
1016 n.List.Set(r.stmtList())
1017 return n
1018
1019
1020
1021
1022 case OXCASE:
1023 n := nodl(r.pos(), OXCASE, nil, nil)
1024 n.List.Set(r.exprList())
1025
1026
1027 n.Nbody.Set(r.stmtList())
1028 return n
1029
1030
1031
1032
1033 case OFALL:
1034 n := nodl(r.pos(), OFALL, nil, nil)
1035 return n
1036
1037 case OBREAK, OCONTINUE:
1038 pos := r.pos()
1039 left, _ := r.exprsOrNil()
1040 if left != nil {
1041 left = newname(left.Sym)
1042 }
1043 return nodl(pos, op, left, nil)
1044
1045
1046
1047
1048 case OGOTO, OLABEL:
1049 n := nodl(r.pos(), op, nil, nil)
1050 n.Sym = lookup(r.string())
1051 return n
1052
1053 case OEND:
1054 return nil
1055
1056 default:
1057 Fatalf("cannot import %v (%d) node\n"+
1058 "\t==> please file an issue and assign to gri@", op, int(op))
1059 panic("unreachable")
1060 }
1061 }
1062
1063 func (r *importReader) op() Op {
1064 return Op(r.uint64())
1065 }
1066
1067 func (r *importReader) elemList() []*Node {
1068 c := r.uint64()
1069 list := make([]*Node, c)
1070 for i := range list {
1071 s := r.ident()
1072 list[i] = nodSym(OSTRUCTKEY, r.expr(), s)
1073 }
1074 return list
1075 }
1076
1077 func (r *importReader) exprsOrNil() (a, b *Node) {
1078 ab := r.uint64()
1079 if ab&1 != 0 {
1080 a = r.expr()
1081 }
1082 if ab&2 != 0 {
1083 b = r.node()
1084 }
1085 return
1086 }
1087
View as plain text