1// Copyright 2018 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// Indexed package import. 6// See iexport.go for the export data format. 7 8package typecheck 9 10import ( 11 "encoding/binary" 12 "fmt" 13 "go/constant" 14 "math/big" 15 "os" 16 "strings" 17 18 "cmd/compile/internal/base" 19 "cmd/compile/internal/ir" 20 "cmd/compile/internal/types" 21 "cmd/internal/obj" 22 "cmd/internal/src" 23) 24 25// An iimporterAndOffset identifies an importer and an offset within 26// its data section. 27type iimporterAndOffset struct { 28 p *iimporter 29 off uint64 30} 31 32var ( 33 // DeclImporter maps from imported identifiers to an importer 34 // and offset where that identifier's declaration can be read. 35 DeclImporter = map[*types.Sym]iimporterAndOffset{} 36 37 // inlineImporter is like DeclImporter, but for inline bodies 38 // for function and method symbols. 39 inlineImporter = map[*types.Sym]iimporterAndOffset{} 40) 41 42// expandDecl returns immediately if n is already a Name node. Otherwise, n should 43// be an Ident node, and expandDecl reads in the definition of the specified 44// identifier from the appropriate package. 45func expandDecl(n ir.Node) ir.Node { 46 if n, ok := n.(*ir.Name); ok { 47 return n 48 } 49 50 id := n.(*ir.Ident) 51 if n := id.Sym().PkgDef(); n != nil { 52 return n.(*ir.Name) 53 } 54 55 r := importReaderFor(id.Sym(), DeclImporter) 56 if r == nil { 57 // Can happen if user tries to reference an undeclared name. 58 return n 59 } 60 61 return r.doDecl(n.Sym()) 62} 63 64// ImportBody reads in the dcls and body of an imported function (which should not 65// yet have been read in). 66func ImportBody(fn *ir.Func) { 67 if fn.Inl.Body != nil { 68 base.Fatalf("%v already has inline body", fn) 69 } 70 71 r := importReaderFor(fn.Nname.Sym(), inlineImporter) 72 if r == nil { 73 base.Fatalf("missing import reader for %v", fn) 74 } 75 76 if inimport { 77 base.Fatalf("recursive inimport") 78 } 79 inimport = true 80 r.doInline(fn) 81 inimport = false 82} 83 84// HaveInlineBody reports whether we have fn's inline body available 85// for inlining. 86func HaveInlineBody(fn *ir.Func) bool { 87 if fn.Inl == nil { 88 return false 89 } 90 91 // Unified IR is much more conservative about pruning unreachable 92 // methods (at the cost of increased build artifact size). 93 if base.Debug.Unified != 0 { 94 return true 95 } 96 97 if fn.Inl.Body != nil { 98 return true 99 } 100 101 _, ok := inlineImporter[fn.Nname.Sym()] 102 return ok 103} 104 105func importReaderFor(sym *types.Sym, importers map[*types.Sym]iimporterAndOffset) *importReader { 106 x, ok := importers[sym] 107 if !ok { 108 return nil 109 } 110 111 return x.p.newReader(x.off, sym.Pkg) 112} 113 114type intReader struct { 115 *strings.Reader 116 pkg *types.Pkg 117} 118 119func (r *intReader) int64() int64 { 120 i, err := binary.ReadVarint(r.Reader) 121 if err != nil { 122 base.Errorf("import %q: read error: %v", r.pkg.Path, err) 123 base.ErrorExit() 124 } 125 return i 126} 127 128func (r *intReader) uint64() uint64 { 129 i, err := binary.ReadUvarint(r.Reader) 130 if err != nil { 131 base.Errorf("import %q: read error: %v", r.pkg.Path, err) 132 base.ErrorExit() 133 } 134 return i 135} 136 137func ReadImports(pkg *types.Pkg, data string) { 138 ird := &intReader{strings.NewReader(data), pkg} 139 140 version := ird.uint64() 141 switch version { 142 case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: 143 default: 144 base.Errorf("import %q: unknown export format version %d", pkg.Path, version) 145 base.ErrorExit() 146 } 147 148 sLen := int64(ird.uint64()) 149 dLen := int64(ird.uint64()) 150 151 // TODO(mdempsky): Replace os.SEEK_CUR with io.SeekCurrent after 152 // #44505 is fixed. 153 whence, _ := ird.Seek(0, os.SEEK_CUR) 154 stringData := data[whence : whence+sLen] 155 declData := data[whence+sLen : whence+sLen+dLen] 156 ird.Seek(sLen+dLen, os.SEEK_CUR) 157 158 p := &iimporter{ 159 exportVersion: version, 160 ipkg: pkg, 161 162 pkgCache: map[uint64]*types.Pkg{}, 163 posBaseCache: map[uint64]*src.PosBase{}, 164 typCache: map[uint64]*types.Type{}, 165 166 stringData: stringData, 167 declData: declData, 168 } 169 170 for i, pt := range predeclared() { 171 p.typCache[uint64(i)] = pt 172 } 173 174 // Declaration index. 175 for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- { 176 pkg := p.pkgAt(ird.uint64()) 177 pkgName := p.stringAt(ird.uint64()) 178 pkgHeight := int(ird.uint64()) 179 if pkg.Name == "" { 180 pkg.Name = pkgName 181 pkg.Height = pkgHeight 182 types.NumImport[pkgName]++ 183 184 // TODO(mdempsky): This belongs somewhere else. 185 pkg.Lookup("_").Def = ir.BlankNode 186 } else { 187 if pkg.Name != pkgName { 188 base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path) 189 } 190 if pkg.Height != pkgHeight { 191 base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path) 192 } 193 } 194 195 for nSyms := ird.uint64(); nSyms > 0; nSyms-- { 196 s := pkg.Lookup(p.nameAt(ird.uint64())) 197 off := ird.uint64() 198 199 if _, ok := DeclImporter[s]; !ok { 200 DeclImporter[s] = iimporterAndOffset{p, off} 201 } 202 } 203 } 204 205 // Inline body index. 206 for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- { 207 pkg := p.pkgAt(ird.uint64()) 208 209 for nSyms := ird.uint64(); nSyms > 0; nSyms-- { 210 s := pkg.Lookup(p.nameAt(ird.uint64())) 211 off := ird.uint64() 212 213 if _, ok := inlineImporter[s]; !ok { 214 inlineImporter[s] = iimporterAndOffset{p, off} 215 } 216 } 217 } 218} 219 220type iimporter struct { 221 exportVersion uint64 222 ipkg *types.Pkg 223 224 pkgCache map[uint64]*types.Pkg 225 posBaseCache map[uint64]*src.PosBase 226 typCache map[uint64]*types.Type 227 228 stringData string 229 declData string 230} 231 232func (p *iimporter) stringAt(off uint64) string { 233 var x [binary.MaxVarintLen64]byte 234 n := copy(x[:], p.stringData[off:]) 235 236 slen, n := binary.Uvarint(x[:n]) 237 if n <= 0 { 238 base.Fatalf("varint failed") 239 } 240 spos := off + uint64(n) 241 return p.stringData[spos : spos+slen] 242} 243 244// nameAt is the same as stringAt, except it replaces instances 245// of "" with the path of the package being imported. 246func (p *iimporter) nameAt(off uint64) string { 247 s := p.stringAt(off) 248 // Names of objects (functions, methods, globals) may include "" 249 // to represent the path name of the imported package. 250 // Replace "" with the imported package prefix. This occurs 251 // specifically for generics where the names of instantiations 252 // and dictionaries contain package-qualified type names. 253 // Include the dot to avoid matching with struct tags ending in '"'. 254 if strings.Contains(s, "\"\".") { 255 s = strings.Replace(s, "\"\".", p.ipkg.Prefix+".", -1) 256 } 257 return s 258} 259 260func (p *iimporter) posBaseAt(off uint64) *src.PosBase { 261 if posBase, ok := p.posBaseCache[off]; ok { 262 return posBase 263 } 264 265 file := p.stringAt(off) 266 posBase := src.NewFileBase(file, file) 267 p.posBaseCache[off] = posBase 268 return posBase 269} 270 271func (p *iimporter) pkgAt(off uint64) *types.Pkg { 272 if pkg, ok := p.pkgCache[off]; ok { 273 return pkg 274 } 275 276 pkg := p.ipkg 277 if pkgPath := p.stringAt(off); pkgPath != "" { 278 pkg = types.NewPkg(pkgPath, "") 279 } 280 p.pkgCache[off] = pkg 281 return pkg 282} 283 284// An importReader keeps state for reading an individual imported 285// object (declaration or inline body). 286type importReader struct { 287 strings.Reader 288 p *iimporter 289 290 currPkg *types.Pkg 291 prevBase *src.PosBase 292 prevLine int64 293 prevColumn int64 294 295 // curfn is the current function we're importing into. 296 curfn *ir.Func 297 // Slice of all dcls for function, including any interior closures 298 allDcls []*ir.Name 299 allClosureVars []*ir.Name 300 autotmpgen int 301} 302 303func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader { 304 r := &importReader{ 305 p: p, 306 currPkg: pkg, 307 } 308 // (*strings.Reader).Reset wasn't added until Go 1.7, and we 309 // need to build with Go 1.4. 310 r.Reader = *strings.NewReader(p.declData[off:]) 311 return r 312} 313 314func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } 315func (r *importReader) name() string { return r.p.nameAt(r.uint64()) } 316func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) } 317func (r *importReader) pkg() *types.Pkg { return r.p.pkgAt(r.uint64()) } 318 319func (r *importReader) setPkg() { 320 r.currPkg = r.pkg() 321} 322 323func (r *importReader) doDecl(sym *types.Sym) *ir.Name { 324 tag := r.byte() 325 pos := r.pos() 326 327 switch tag { 328 case 'A': 329 typ := r.typ() 330 331 return importalias(pos, sym, typ) 332 333 case 'C': 334 typ := r.typ() 335 val := r.value(typ) 336 337 n := importconst(pos, sym, typ, val) 338 r.constExt(n) 339 return n 340 341 case 'F', 'G': 342 var tparams []*types.Field 343 if tag == 'G' { 344 tparams = r.tparamList() 345 } 346 typ := r.signature(nil, tparams) 347 348 n := importfunc(pos, sym, typ) 349 r.funcExt(n) 350 return n 351 352 case 'T', 'U': 353 // Types can be recursive. We need to setup a stub 354 // declaration before recursing. 355 n := importtype(pos, sym) 356 t := n.Type() 357 if tag == 'U' { 358 rparams := r.typeList() 359 t.SetRParams(rparams) 360 } 361 362 // We also need to defer width calculations until 363 // after the underlying type has been assigned. 364 types.DeferCheckSize() 365 deferDoInst() 366 underlying := r.typ() 367 t.SetUnderlying(underlying) 368 369 if underlying.IsInterface() { 370 // Finish up all type instantiations and CheckSize calls 371 // now that a top-level type is fully constructed. 372 resumeDoInst() 373 types.ResumeCheckSize() 374 r.typeExt(t) 375 return n 376 } 377 378 ms := make([]*types.Field, r.uint64()) 379 for i := range ms { 380 mpos := r.pos() 381 msym := r.selector() 382 recv := r.param() 383 mtyp := r.signature(recv, nil) 384 385 // MethodSym already marked m.Sym as a function. 386 m := ir.NewNameAt(mpos, ir.MethodSym(recv.Type, msym)) 387 m.Class = ir.PFUNC 388 m.SetType(mtyp) 389 390 m.Func = ir.NewFunc(mpos) 391 m.Func.Nname = m 392 393 f := types.NewField(mpos, msym, mtyp) 394 f.Nname = m 395 ms[i] = f 396 } 397 t.Methods().Set(ms) 398 399 // Finish up all instantiations and CheckSize calls now 400 // that a top-level type is fully constructed. 401 resumeDoInst() 402 types.ResumeCheckSize() 403 404 r.typeExt(t) 405 for _, m := range ms { 406 r.methExt(m) 407 } 408 return n 409 410 case 'P': 411 if r.p.exportVersion < iexportVersionGenerics { 412 base.Fatalf("unexpected type param type") 413 } 414 if sym.Def != nil { 415 // Make sure we use the same type param type for the same 416 // name, whether it is created during types1-import or 417 // this types2-to-types1 translation. 418 return sym.Def.(*ir.Name) 419 } 420 // The typeparam index is set at the point where the containing type 421 // param list is imported. 422 t := types.NewTypeParam(sym, 0) 423 // Nname needed to save the pos. 424 nname := ir.NewDeclNameAt(pos, ir.OTYPE, sym) 425 sym.Def = nname 426 nname.SetType(t) 427 t.SetNod(nname) 428 implicit := false 429 if r.p.exportVersion >= iexportVersionGo1_18 { 430 implicit = r.bool() 431 } 432 bound := r.typ() 433 if implicit { 434 bound.MarkImplicit() 435 } 436 t.SetBound(bound) 437 return nname 438 439 case 'V': 440 typ := r.typ() 441 442 n := importvar(pos, sym, typ) 443 r.varExt(n) 444 return n 445 446 default: 447 base.Fatalf("unexpected tag: %v", tag) 448 panic("unreachable") 449 } 450} 451 452func (r *importReader) value(typ *types.Type) constant.Value { 453 var kind constant.Kind 454 var valType *types.Type 455 456 if r.p.exportVersion >= iexportVersionGo1_18 { 457 // TODO: add support for using the kind in the non-typeparam case. 458 kind = constant.Kind(r.int64()) 459 } 460 461 if typ.IsTypeParam() { 462 if r.p.exportVersion < iexportVersionGo1_18 { 463 // If a constant had a typeparam type, then we wrote out its 464 // actual constant kind as well. 465 kind = constant.Kind(r.int64()) 466 } 467 switch kind { 468 case constant.Int: 469 valType = types.Types[types.TINT64] 470 case constant.Float: 471 valType = types.Types[types.TFLOAT64] 472 case constant.Complex: 473 valType = types.Types[types.TCOMPLEX128] 474 } 475 } else { 476 kind = constTypeOf(typ) 477 valType = typ 478 } 479 480 switch kind { 481 case constant.Bool: 482 return constant.MakeBool(r.bool()) 483 case constant.String: 484 return constant.MakeString(r.string()) 485 case constant.Int: 486 var i big.Int 487 r.mpint(&i, valType) 488 return constant.Make(&i) 489 case constant.Float: 490 return r.float(valType) 491 case constant.Complex: 492 return makeComplex(r.float(valType), r.float(valType)) 493 } 494 495 base.Fatalf("unexpected value type: %v", typ) 496 panic("unreachable") 497} 498 499func (r *importReader) mpint(x *big.Int, typ *types.Type) { 500 signed, maxBytes := intSize(typ) 501 502 maxSmall := 256 - maxBytes 503 if signed { 504 maxSmall = 256 - 2*maxBytes 505 } 506 if maxBytes == 1 { 507 maxSmall = 256 508 } 509 510 n, _ := r.ReadByte() 511 if uint(n) < maxSmall { 512 v := int64(n) 513 if signed { 514 v >>= 1 515 if n&1 != 0 { 516 v = ^v 517 } 518 } 519 x.SetInt64(v) 520 return 521 } 522 523 v := -n 524 if signed { 525 v = -(n &^ 1) >> 1 526 } 527 if v < 1 || uint(v) > maxBytes { 528 base.Fatalf("weird decoding: %v, %v => %v", n, signed, v) 529 } 530 b := make([]byte, v) 531 r.Read(b) 532 x.SetBytes(b) 533 if signed && n&1 != 0 { 534 x.Neg(x) 535 } 536} 537 538func (r *importReader) float(typ *types.Type) constant.Value { 539 var mant big.Int 540 r.mpint(&mant, typ) 541 var f big.Float 542 f.SetInt(&mant) 543 if f.Sign() != 0 { 544 f.SetMantExp(&f, int(r.int64())) 545 } 546 return constant.Make(&f) 547} 548 549func (r *importReader) mprat(orig constant.Value) constant.Value { 550 if !r.bool() { 551 return orig 552 } 553 var rat big.Rat 554 rat.SetString(r.string()) 555 return constant.Make(&rat) 556} 557 558func (r *importReader) ident(selector bool) *types.Sym { 559 name := r.string() 560 if name == "" { 561 return nil 562 } 563 pkg := r.currPkg 564 if selector { 565 if types.IsExported(name) { 566 pkg = types.LocalPkg 567 } 568 } else { 569 if name == "$autotmp" { 570 name = autotmpname(r.autotmpgen) 571 r.autotmpgen++ 572 } 573 } 574 return pkg.Lookup(name) 575} 576 577func (r *importReader) localIdent() *types.Sym { return r.ident(false) } 578func (r *importReader) selector() *types.Sym { return r.ident(true) } 579 580func (r *importReader) qualifiedIdent() *ir.Ident { 581 name := r.name() 582 pkg := r.pkg() 583 sym := pkg.Lookup(name) 584 return ir.NewIdent(src.NoXPos, sym) 585} 586 587func (r *importReader) pos() src.XPos { 588 delta := r.int64() 589 r.prevColumn += delta >> 1 590 if delta&1 != 0 { 591 delta = r.int64() 592 r.prevLine += delta >> 1 593 if delta&1 != 0 { 594 r.prevBase = r.posBase() 595 } 596 } 597 598 if (r.prevBase == nil || r.prevBase.AbsFilename() == "") && r.prevLine == 0 && r.prevColumn == 0 { 599 // TODO(mdempsky): Remove once we reliably write 600 // position information for all nodes. 601 return src.NoXPos 602 } 603 604 if r.prevBase == nil { 605 base.Fatalf("missing posbase") 606 } 607 pos := src.MakePos(r.prevBase, uint(r.prevLine), uint(r.prevColumn)) 608 return base.Ctxt.PosTable.XPos(pos) 609} 610 611func (r *importReader) typ() *types.Type { 612 // If this is a top-level type call, defer type instantiations until the 613 // type is fully constructed. 614 types.DeferCheckSize() 615 deferDoInst() 616 t := r.p.typAt(r.uint64()) 617 resumeDoInst() 618 types.ResumeCheckSize() 619 return t 620} 621 622func (r *importReader) exoticType() *types.Type { 623 switch r.uint64() { 624 case exoticTypeNil: 625 return nil 626 case exoticTypeTuple: 627 funarg := types.Funarg(r.uint64()) 628 n := r.uint64() 629 fs := make([]*types.Field, n) 630 for i := range fs { 631 pos := r.pos() 632 var sym *types.Sym 633 switch r.uint64() { 634 case exoticTypeSymNil: 635 sym = nil 636 case exoticTypeSymNoPkg: 637 sym = types.NoPkg.Lookup(r.string()) 638 case exoticTypeSymWithPkg: 639 pkg := r.pkg() 640 sym = pkg.Lookup(r.string()) 641 default: 642 base.Fatalf("unknown symbol kind") 643 } 644 typ := r.typ() 645 f := types.NewField(pos, sym, typ) 646 fs[i] = f 647 } 648 t := types.NewStruct(types.NoPkg, fs) 649 t.StructType().Funarg = funarg 650 return t 651 case exoticTypeRecv: 652 var rcvr *types.Field 653 if r.bool() { // isFakeRecv 654 rcvr = types.FakeRecv() 655 } else { 656 rcvr = r.exoticParam() 657 } 658 return r.exoticSignature(rcvr) 659 case exoticTypeRegular: 660 return r.typ() 661 default: 662 base.Fatalf("bad kind of call type") 663 return nil 664 } 665} 666 667func (r *importReader) exoticSelector() *types.Sym { 668 name := r.string() 669 if name == "" { 670 return nil 671 } 672 pkg := r.currPkg 673 if types.IsExported(name) { 674 pkg = types.LocalPkg 675 } 676 if r.uint64() != 0 { 677 pkg = r.pkg() 678 } 679 return pkg.Lookup(name) 680} 681 682func (r *importReader) exoticSignature(recv *types.Field) *types.Type { 683 var pkg *types.Pkg 684 if r.bool() { // hasPkg 685 pkg = r.pkg() 686 } 687 params := r.exoticParamList() 688 results := r.exoticParamList() 689 return types.NewSignature(pkg, recv, nil, params, results) 690} 691 692func (r *importReader) exoticParamList() []*types.Field { 693 n := r.uint64() 694 fs := make([]*types.Field, n) 695 for i := range fs { 696 fs[i] = r.exoticParam() 697 } 698 return fs 699} 700 701func (r *importReader) exoticParam() *types.Field { 702 pos := r.pos() 703 sym := r.exoticSym() 704 off := r.uint64() 705 typ := r.exoticType() 706 ddd := r.bool() 707 f := types.NewField(pos, sym, typ) 708 f.Offset = int64(off) 709 if sym != nil { 710 f.Nname = ir.NewNameAt(pos, sym) 711 } 712 f.SetIsDDD(ddd) 713 return f 714} 715 716func (r *importReader) exoticField() *types.Field { 717 pos := r.pos() 718 sym := r.exoticSym() 719 off := r.uint64() 720 typ := r.exoticType() 721 note := r.string() 722 f := types.NewField(pos, sym, typ) 723 f.Offset = int64(off) 724 if sym != nil { 725 f.Nname = ir.NewNameAt(pos, sym) 726 } 727 f.Note = note 728 return f 729} 730 731func (r *importReader) exoticSym() *types.Sym { 732 name := r.string() 733 if name == "" { 734 return nil 735 } 736 var pkg *types.Pkg 737 if types.IsExported(name) { 738 pkg = types.LocalPkg 739 } else { 740 pkg = r.pkg() 741 } 742 return pkg.Lookup(name) 743} 744 745func (p *iimporter) typAt(off uint64) *types.Type { 746 t, ok := p.typCache[off] 747 if !ok { 748 if off < predeclReserved { 749 base.Fatalf("predeclared type missing from cache: %d", off) 750 } 751 t = p.newReader(off-predeclReserved, nil).typ1() 752 // Ensure size is calculated for imported types. Since CL 283313, the compiler 753 // does not compile the function immediately when it sees them. Instead, funtions 754 // are pushed to compile queue, then draining from the queue for compiling. 755 // During this process, the size calculation is disabled, so it is not safe for 756 // calculating size during SSA generation anymore. See issue #44732. 757 // 758 // No need to calc sizes for re-instantiated generic types, and 759 // they are not necessarily resolved until the top-level type is 760 // defined (because of recursive types). 761 if t.OrigSym() == nil || !t.HasTParam() { 762 types.CheckSize(t) 763 } 764 p.typCache[off] = t 765 } 766 return t 767} 768 769func (r *importReader) typ1() *types.Type { 770 switch k := r.kind(); k { 771 default: 772 base.Fatalf("unexpected kind tag in %q: %v", r.p.ipkg.Path, k) 773 return nil 774 775 case definedType: 776 // We might be called from within doInline, in which 777 // case Sym.Def can point to declared parameters 778 // instead of the top-level types. Also, we don't 779 // support inlining functions with local defined 780 // types. Therefore, this must be a package-scope 781 // type. 782 n := expandDecl(r.qualifiedIdent()) 783 if n.Op() != ir.OTYPE { 784 base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n) 785 } 786 return n.Type() 787 case pointerType: 788 return types.NewPtr(r.typ()) 789 case sliceType: 790 return types.NewSlice(r.typ()) 791 case arrayType: 792 n := r.uint64() 793 return types.NewArray(r.typ(), int64(n)) 794 case chanType: 795 dir := types.ChanDir(r.uint64()) 796 return types.NewChan(r.typ(), dir) 797 case mapType: 798 return types.NewMap(r.typ(), r.typ()) 799 800 case signatureType: 801 r.setPkg() 802 return r.signature(nil, nil) 803 804 case structType: 805 r.setPkg() 806 807 fs := make([]*types.Field, r.uint64()) 808 for i := range fs { 809 pos := r.pos() 810 sym := r.selector() 811 typ := r.typ() 812 emb := r.bool() 813 note := r.string() 814 815 f := types.NewField(pos, sym, typ) 816 if emb { 817 f.Embedded = 1 818 } 819 f.Note = note 820 fs[i] = f 821 } 822 823 return types.NewStruct(r.currPkg, fs) 824 825 case interfaceType: 826 r.setPkg() 827 828 embeddeds := make([]*types.Field, r.uint64()) 829 for i := range embeddeds { 830 pos := r.pos() 831 typ := r.typ() 832 833 embeddeds[i] = types.NewField(pos, nil, typ) 834 } 835 836 methods := make([]*types.Field, r.uint64()) 837 for i := range methods { 838 pos := r.pos() 839 sym := r.selector() 840 typ := r.signature(types.FakeRecv(), nil) 841 842 methods[i] = types.NewField(pos, sym, typ) 843 } 844 845 if len(embeddeds)+len(methods) == 0 { 846 return types.Types[types.TINTER] 847 } 848 849 t := types.NewInterface(r.currPkg, append(embeddeds, methods...), false) 850 851 // Ensure we expand the interface in the frontend (#25055). 852 types.CheckSize(t) 853 return t 854 855 case typeParamType: 856 if r.p.exportVersion < iexportVersionGenerics { 857 base.Fatalf("unexpected type param type") 858 } 859 // Similar to code for defined types, since we "declared" 860 // typeparams to deal with recursion (typeparam is used within its 861 // own type bound). 862 ident := r.qualifiedIdent() 863 if ident.Sym().Def != nil { 864 return ident.Sym().Def.(*ir.Name).Type() 865 } 866 n := expandDecl(ident) 867 if n.Op() != ir.OTYPE { 868 base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op(), n.Sym(), n) 869 } 870 return n.Type() 871 872 case instanceType: 873 if r.p.exportVersion < iexportVersionGenerics { 874 base.Fatalf("unexpected instantiation type") 875 } 876 pos := r.pos() 877 len := r.uint64() 878 targs := make([]*types.Type, len) 879 for i := range targs { 880 targs[i] = r.typ() 881 } 882 baseType := r.typ() 883 t := Instantiate(pos, baseType, targs) 884 return t 885 886 case unionType: 887 if r.p.exportVersion < iexportVersionGenerics { 888 base.Fatalf("unexpected instantiation type") 889 } 890 nt := int(r.uint64()) 891 terms := make([]*types.Type, nt) 892 tildes := make([]bool, nt) 893 for i := range terms { 894 tildes[i] = r.bool() 895 terms[i] = r.typ() 896 } 897 return types.NewUnion(terms, tildes) 898 } 899} 900 901func (r *importReader) kind() itag { 902 return itag(r.uint64()) 903} 904 905func (r *importReader) signature(recv *types.Field, tparams []*types.Field) *types.Type { 906 params := r.paramList() 907 results := r.paramList() 908 if n := len(params); n > 0 { 909 params[n-1].SetIsDDD(r.bool()) 910 } 911 return types.NewSignature(r.currPkg, recv, tparams, params, results) 912} 913 914func (r *importReader) typeList() []*types.Type { 915 n := r.uint64() 916 if n == 0 { 917 return nil 918 } 919 ts := make([]*types.Type, n) 920 for i := range ts { 921 ts[i] = r.typ() 922 if ts[i].IsTypeParam() { 923 ts[i].SetIndex(i) 924 } 925 } 926 return ts 927} 928 929func (r *importReader) tparamList() []*types.Field { 930 n := r.uint64() 931 if n == 0 { 932 return nil 933 } 934 fs := make([]*types.Field, n) 935 for i := range fs { 936 typ := r.typ() 937 typ.SetIndex(i) 938 fs[i] = types.NewField(typ.Pos(), typ.Sym(), typ) 939 } 940 return fs 941} 942 943func (r *importReader) paramList() []*types.Field { 944 fs := make([]*types.Field, r.uint64()) 945 for i := range fs { 946 fs[i] = r.param() 947 } 948 return fs 949} 950 951func (r *importReader) param() *types.Field { 952 return types.NewField(r.pos(), r.localIdent(), r.typ()) 953} 954 955func (r *importReader) bool() bool { 956 return r.uint64() != 0 957} 958 959func (r *importReader) int64() int64 { 960 n, err := binary.ReadVarint(r) 961 if err != nil { 962 base.Fatalf("readVarint: %v", err) 963 } 964 return n 965} 966 967func (r *importReader) uint64() uint64 { 968 n, err := binary.ReadUvarint(r) 969 if err != nil { 970 base.Fatalf("readVarint: %v", err) 971 } 972 return n 973} 974 975func (r *importReader) byte() byte { 976 x, err := r.ReadByte() 977 if err != nil { 978 base.Fatalf("declReader.ReadByte: %v", err) 979 } 980 return x 981} 982 983// Compiler-specific extensions. 984 985func (r *importReader) constExt(n *ir.Name) { 986 switch n.Type() { 987 case types.UntypedFloat: 988 n.SetVal(r.mprat(n.Val())) 989 case types.UntypedComplex: 990 v := n.Val() 991 re := r.mprat(constant.Real(v)) 992 im := r.mprat(constant.Imag(v)) 993 n.SetVal(makeComplex(re, im)) 994 } 995} 996 997func (r *importReader) varExt(n *ir.Name) { 998 r.linkname(n.Sym()) 999 r.symIdx(n.Sym()) 1000} 1001 1002func (r *importReader) funcExt(n *ir.Name) { 1003 r.linkname(n.Sym()) 1004 r.symIdx(n.Sym()) 1005 1006 n.Func.ABI = obj.ABI(r.uint64()) 1007 1008 // Make sure //go:noinline pragma is imported (so stenciled functions have 1009 // same noinline status as the corresponding generic function.) 1010 n.Func.Pragma = ir.PragmaFlag(r.uint64()) 1011 1012 // Escape analysis. 1013 for _, fs := range &types.RecvsParams { 1014 for _, f := range fs(n.Type()).FieldSlice() { 1015 f.Note = r.string() 1016 } 1017 } 1018 1019 // Inline body. 1020 if u := r.uint64(); u > 0 { 1021 n.Func.Inl = &ir.Inline{ 1022 Cost: int32(u - 1), 1023 CanDelayResults: r.bool(), 1024 } 1025 n.Func.Endlineno = r.pos() 1026 } 1027} 1028 1029func (r *importReader) methExt(m *types.Field) { 1030 if r.bool() { 1031 m.SetNointerface(true) 1032 } 1033 r.funcExt(m.Nname.(*ir.Name)) 1034} 1035 1036func (r *importReader) linkname(s *types.Sym) { 1037 s.Linkname = r.string() 1038} 1039 1040func (r *importReader) symIdx(s *types.Sym) { 1041 lsym := s.Linksym() 1042 idx := int32(r.int64()) 1043 if idx != -1 { 1044 if s.Linkname != "" { 1045 base.Fatalf("bad index for linknamed symbol: %v %d\n", lsym, idx) 1046 } 1047 lsym.SymIdx = idx 1048 lsym.Set(obj.AttrIndexed, true) 1049 } 1050} 1051 1052func (r *importReader) typeExt(t *types.Type) { 1053 t.SetNotInHeap(r.bool()) 1054 SetBaseTypeIndex(t, r.int64(), r.int64()) 1055} 1056 1057func SetBaseTypeIndex(t *types.Type, i, pi int64) { 1058 if t.Obj() == nil { 1059 base.Fatalf("SetBaseTypeIndex on non-defined type %v", t) 1060 } 1061 if i != -1 && pi != -1 { 1062 typeSymIdx[t] = [2]int64{i, pi} 1063 } 1064} 1065 1066// Map imported type T to the index of type descriptor symbols of T and *T, 1067// so we can use index to reference the symbol. 1068// TODO(mdempsky): Store this information directly in the Type's Name. 1069var typeSymIdx = make(map[*types.Type][2]int64) 1070 1071func BaseTypeIndex(t *types.Type) int64 { 1072 tbase := t 1073 if t.IsPtr() && t.Sym() == nil && t.Elem().Sym() != nil { 1074 tbase = t.Elem() 1075 } 1076 i, ok := typeSymIdx[tbase] 1077 if !ok { 1078 return -1 1079 } 1080 if t != tbase { 1081 return i[1] 1082 } 1083 return i[0] 1084} 1085 1086func (r *importReader) doInline(fn *ir.Func) { 1087 if len(fn.Inl.Body) != 0 { 1088 base.Fatalf("%v already has inline body", fn) 1089 } 1090 1091 //fmt.Printf("Importing %s\n", fn.Nname.Sym().Name) 1092 r.funcBody(fn) 1093 1094 importlist = append(importlist, fn) 1095 1096 if base.Flag.E > 0 && base.Flag.LowerM > 2 { 1097 if base.Flag.LowerM > 3 { 1098 fmt.Printf("inl body for %v %v: %+v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body)) 1099 } else { 1100 fmt.Printf("inl body for %v %v: %v\n", fn, fn.Type(), ir.Nodes(fn.Inl.Body)) 1101 } 1102 } 1103} 1104 1105// ---------------------------------------------------------------------------- 1106// Inlined function bodies 1107 1108// Approach: Read nodes and use them to create/declare the same data structures 1109// as done originally by the (hidden) parser by closely following the parser's 1110// original code. In other words, "parsing" the import data (which happens to 1111// be encoded in binary rather textual form) is the best way at the moment to 1112// re-establish the syntax tree's invariants. At some future point we might be 1113// able to avoid this round-about way and create the rewritten nodes directly, 1114// possibly avoiding a lot of duplicate work (name resolution, type checking). 1115// 1116// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their 1117// unrefined nodes (since this is what the importer uses). The respective case 1118// entries are unreachable in the importer. 1119 1120func (r *importReader) funcBody(fn *ir.Func) { 1121 outerfn := r.curfn 1122 r.curfn = fn 1123 1124 // Import local declarations. 1125 fn.Inl.Dcl = r.readFuncDcls(fn) 1126 1127 // Import function body. 1128 body := r.stmtList() 1129 if body == nil { 1130 // Make sure empty body is not interpreted as 1131 // no inlineable body (see also parser.fnbody) 1132 // (not doing so can cause significant performance 1133 // degradation due to unnecessary calls to empty 1134 // functions). 1135 body = []ir.Node{} 1136 } 1137 if go117ExportTypes { 1138 ir.VisitList(body, func(n ir.Node) { 1139 n.SetTypecheck(1) 1140 }) 1141 } 1142 fn.Inl.Body = body 1143 1144 r.curfn = outerfn 1145 if base.Flag.W >= 3 { 1146 fmt.Printf("Imported for %v", fn) 1147 ir.DumpList("", fn.Inl.Body) 1148 } 1149} 1150 1151func (r *importReader) readNames(fn *ir.Func) []*ir.Name { 1152 dcls := make([]*ir.Name, r.int64()) 1153 for i := range dcls { 1154 n := ir.NewDeclNameAt(r.pos(), ir.ONAME, r.localIdent()) 1155 n.Class = ir.PAUTO // overwritten below for parameters/results 1156 n.Curfn = fn 1157 n.SetType(r.typ()) 1158 dcls[i] = n 1159 } 1160 r.allDcls = append(r.allDcls, dcls...) 1161 return dcls 1162} 1163 1164func (r *importReader) readFuncDcls(fn *ir.Func) []*ir.Name { 1165 dcls := r.readNames(fn) 1166 1167 // Fixup parameter classes and associate with their 1168 // signature's type fields. 1169 i := 0 1170 fix := func(f *types.Field, class ir.Class) { 1171 if class == ir.PPARAM && (f.Sym == nil || f.Sym.Name == "_") { 1172 return 1173 } 1174 n := dcls[i] 1175 n.Class = class 1176 f.Nname = n 1177 i++ 1178 } 1179 1180 typ := fn.Type() 1181 if recv := typ.Recv(); recv != nil { 1182 fix(recv, ir.PPARAM) 1183 } 1184 for _, f := range typ.Params().FieldSlice() { 1185 fix(f, ir.PPARAM) 1186 } 1187 for _, f := range typ.Results().FieldSlice() { 1188 fix(f, ir.PPARAMOUT) 1189 } 1190 return dcls 1191} 1192 1193func (r *importReader) localName() *ir.Name { 1194 i := r.int64() 1195 if i == -1 { 1196 return ir.BlankNode.(*ir.Name) 1197 } 1198 if i < 0 { 1199 return r.allClosureVars[-i-2] 1200 } 1201 return r.allDcls[i] 1202} 1203 1204func (r *importReader) stmtList() []ir.Node { 1205 var list []ir.Node 1206 for { 1207 n := r.node() 1208 if n == nil { 1209 break 1210 } 1211 // OBLOCK nodes are not written to the import data directly, 1212 // but the handling of ODCL calls liststmt, which creates one. 1213 // Inline them into the statement list. 1214 if n.Op() == ir.OBLOCK { 1215 n := n.(*ir.BlockStmt) 1216 list = append(list, n.List...) 1217 continue 1218 } 1219 if len(list) > 0 { 1220 // check for an optional label that can only immediately 1221 // precede a for/range/select/switch statement. 1222 if last := list[len(list)-1]; last.Op() == ir.OLABEL { 1223 label := last.(*ir.LabelStmt).Label 1224 switch n.Op() { 1225 case ir.OFOR: 1226 n.(*ir.ForStmt).Label = label 1227 case ir.ORANGE: 1228 n.(*ir.RangeStmt).Label = label 1229 case ir.OSELECT: 1230 n.(*ir.SelectStmt).Label = label 1231 case ir.OSWITCH: 1232 n.(*ir.SwitchStmt).Label = label 1233 } 1234 } 1235 } 1236 list = append(list, n) 1237 } 1238 return list 1239} 1240 1241func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause { 1242 namedTypeSwitch := isNamedTypeSwitch(switchExpr) 1243 1244 cases := make([]*ir.CaseClause, r.uint64()) 1245 for i := range cases { 1246 cas := ir.NewCaseStmt(r.pos(), nil, nil) 1247 cas.List = r.stmtList() 1248 if namedTypeSwitch { 1249 cas.Var = r.localName() 1250 cas.Var.Defn = switchExpr 1251 } 1252 cas.Body = r.stmtList() 1253 cases[i] = cas 1254 } 1255 return cases 1256} 1257 1258func (r *importReader) commList() []*ir.CommClause { 1259 cases := make([]*ir.CommClause, r.uint64()) 1260 for i := range cases { 1261 pos := r.pos() 1262 defaultCase := r.bool() 1263 var comm ir.Node 1264 if !defaultCase { 1265 comm = r.node() 1266 } 1267 cases[i] = ir.NewCommStmt(pos, comm, r.stmtList()) 1268 } 1269 return cases 1270} 1271 1272func (r *importReader) exprList() []ir.Node { 1273 var list []ir.Node 1274 for { 1275 n := r.expr() 1276 if n == nil { 1277 break 1278 } 1279 list = append(list, n) 1280 } 1281 return list 1282} 1283 1284func (r *importReader) expr() ir.Node { 1285 n := r.node() 1286 if n != nil && n.Op() == ir.OBLOCK { 1287 n := n.(*ir.BlockStmt) 1288 base.Fatalf("unexpected block node: %v", n) 1289 } 1290 return n 1291} 1292 1293// TODO(gri) split into expr and stmt 1294func (r *importReader) node() ir.Node { 1295 op := r.op() 1296 switch op { 1297 // expressions 1298 // case OPAREN: 1299 // unreachable - unpacked by exporter 1300 1301 case ir.ONIL: 1302 pos := r.pos() 1303 typ := r.typ() 1304 1305 n := ir.NewNilExpr(pos) 1306 n.SetType(typ) 1307 return n 1308 1309 case ir.OLITERAL: 1310 pos := r.pos() 1311 typ := r.typ() 1312 1313 n := ir.NewBasicLit(pos, r.value(typ)) 1314 n.SetType(typ) 1315 return n 1316 1317 case ir.ONONAME: 1318 isKey := r.bool() 1319 n := r.qualifiedIdent() 1320 if go117ExportTypes { 1321 var n2 ir.Node = n 1322 // Key ONONAME entries should not be resolved - they should 1323 // stay as identifiers. 1324 if !isKey { 1325 n2 = Resolve(n) 1326 } 1327 typ := r.typ() 1328 if n2.Type() == nil { 1329 n2.SetType(typ) 1330 } 1331 return n2 1332 } 1333 return n 1334 1335 case ir.ONAME: 1336 isBuiltin := r.bool() 1337 if isBuiltin { 1338 pkg := types.BuiltinPkg 1339 if r.bool() { 1340 pkg = types.UnsafePkg 1341 } 1342 return pkg.Lookup(r.string()).Def.(*ir.Name) 1343 } 1344 return r.localName() 1345 1346 // case OPACK, ONONAME: 1347 // unreachable - should have been resolved by typechecking 1348 1349 case ir.OTYPE: 1350 return ir.TypeNode(r.typ()) 1351 1352 case ir.ODYNAMICTYPE: 1353 n := ir.NewDynamicType(r.pos(), r.expr()) 1354 if r.bool() { 1355 n.ITab = r.expr() 1356 } 1357 n.SetType(r.typ()) 1358 return n 1359 1360 case ir.OTYPESW: 1361 pos := r.pos() 1362 var tag *ir.Ident 1363 if s := r.localIdent(); s != nil { 1364 tag = ir.NewIdent(pos, s) 1365 } 1366 return ir.NewTypeSwitchGuard(pos, tag, r.expr()) 1367 1368 // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC: 1369 // unreachable - should have been resolved by typechecking 1370 1371 case ir.OCLOSURE: 1372 //println("Importing CLOSURE") 1373 pos := r.pos() 1374 typ := r.signature(nil, nil) 1375 1376 // All the remaining code below is similar to (*noder).funcLit(), but 1377 // with Dcls and ClosureVars lists already set up 1378 fn := ir.NewClosureFunc(pos, true) 1379 fn.Nname.SetType(typ) 1380 1381 cvars := make([]*ir.Name, r.int64()) 1382 for i := range cvars { 1383 cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical()) 1384 if go117ExportTypes && cvars[i].Defn == nil { 1385 base.Fatalf("bad import of closure variable") 1386 } 1387 } 1388 fn.ClosureVars = cvars 1389 r.allClosureVars = append(r.allClosureVars, cvars...) 1390 1391 fn.Inl = &ir.Inline{} 1392 // Read in the Dcls and Body of the closure after temporarily 1393 // setting r.curfn to fn. 1394 r.funcBody(fn) 1395 fn.Dcl = fn.Inl.Dcl 1396 fn.Body = fn.Inl.Body 1397 if len(fn.Body) == 0 { 1398 // An empty closure must be represented as a single empty 1399 // block statement, else it will be dropped. 1400 fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)} 1401 } 1402 fn.Inl = nil 1403 1404 ir.FinishCaptureNames(pos, r.curfn, fn) 1405 1406 clo := fn.OClosure 1407 if go117ExportTypes { 1408 clo.SetType(typ) 1409 } 1410 return clo 1411 1412 case ir.OSTRUCTLIT: 1413 if go117ExportTypes { 1414 pos := r.pos() 1415 typ := r.typ() 1416 list := r.fieldList() 1417 n := ir.NewCompLitExpr(pos, ir.OSTRUCTLIT, nil, list) 1418 n.SetType(typ) 1419 return n 1420 } 1421 return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList()) 1422 1423 case ir.OCOMPLIT: 1424 pos := r.pos() 1425 t := r.typ() 1426 n := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ir.TypeNode(t), r.exprList()) 1427 n.SetType(t) 1428 return n 1429 1430 case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT: 1431 if !go117ExportTypes { 1432 // unreachable - mapped to OCOMPLIT by exporter 1433 goto error 1434 } 1435 pos := r.pos() 1436 typ := r.typ() 1437 list := r.exprList() 1438 n := ir.NewCompLitExpr(pos, op, ir.TypeNode(typ), list) 1439 n.SetType(typ) 1440 if op == ir.OSLICELIT { 1441 n.Len = int64(r.uint64()) 1442 } 1443 return n 1444 1445 case ir.OKEY: 1446 return ir.NewKeyExpr(r.pos(), r.expr(), r.expr()) 1447 1448 // case OSTRUCTKEY: 1449 // unreachable - handled in case OSTRUCTLIT by elemList 1450 1451 case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH, ir.OMETHVALUE, ir.OMETHEXPR: 1452 // For !go117ExportTypes, we should only see OXDOT. 1453 // For go117ExportTypes, we usually see all the other ops, but can see 1454 // OXDOT for generic functions. 1455 if op != ir.OXDOT && !go117ExportTypes { 1456 goto error 1457 } 1458 pos := r.pos() 1459 expr := r.expr() 1460 sel := r.exoticSelector() 1461 n := ir.NewSelectorExpr(pos, op, expr, sel) 1462 if go117ExportTypes { 1463 n.SetType(r.exoticType()) 1464 switch op { 1465 case ir.OXDOT: 1466 hasSelection := r.bool() 1467 // We reconstruct n.Selection for method calls on 1468 // generic types and method calls due to type param 1469 // bounds. Otherwise, n.Selection is nil. 1470 if hasSelection { 1471 n1 := ir.NewSelectorExpr(pos, op, expr, sel) 1472 AddImplicitDots(n1) 1473 var m *types.Field 1474 if n1.X.Type().IsTypeParam() { 1475 genType := n1.X.Type().Bound() 1476 m = Lookdot1(n1, sel, genType, genType.AllMethods(), 1) 1477 } else { 1478 genType := types.ReceiverBaseType(n1.X.Type()) 1479 if genType.IsInstantiatedGeneric() { 1480 genType = genType.OrigSym().Def.Type() 1481 } 1482 m = Lookdot1(n1, sel, genType, genType.Methods(), 1) 1483 } 1484 assert(m != nil) 1485 n.Selection = m 1486 } 1487 case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER: 1488 n.Selection = r.exoticField() 1489 case ir.OMETHEXPR: 1490 n = typecheckMethodExpr(n).(*ir.SelectorExpr) 1491 case ir.ODOTMETH, ir.OMETHVALUE: 1492 // These require a Lookup to link to the correct declaration. 1493 rcvrType := expr.Type() 1494 typ := n.Type() 1495 n.Selection = Lookdot(n, rcvrType, 1) 1496 if op == ir.OMETHVALUE { 1497 // Lookdot clobbers the opcode and type, undo that. 1498 n.SetOp(op) 1499 n.SetType(typ) 1500 } 1501 } 1502 } 1503 return n 1504 1505 case ir.ODOTTYPE, ir.ODOTTYPE2: 1506 n := ir.NewTypeAssertExpr(r.pos(), r.expr(), nil) 1507 n.SetType(r.typ()) 1508 if go117ExportTypes { 1509 n.SetOp(op) 1510 } 1511 return n 1512 1513 case ir.ODYNAMICDOTTYPE, ir.ODYNAMICDOTTYPE2: 1514 n := ir.NewDynamicTypeAssertExpr(r.pos(), op, r.expr(), r.expr()) 1515 n.SetType(r.typ()) 1516 return n 1517 1518 case ir.OINDEX, ir.OINDEXMAP: 1519 n := ir.NewIndexExpr(r.pos(), r.expr(), r.expr()) 1520 if go117ExportTypes { 1521 n.SetOp(op) 1522 n.SetType(r.exoticType()) 1523 if op == ir.OINDEXMAP { 1524 n.Assigned = r.bool() 1525 } 1526 } 1527 return n 1528 1529 case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR: 1530 pos, x := r.pos(), r.expr() 1531 low, high := r.exprsOrNil() 1532 var max ir.Node 1533 if op.IsSlice3() { 1534 max = r.expr() 1535 } 1536 n := ir.NewSliceExpr(pos, op, x, low, high, max) 1537 if go117ExportTypes { 1538 n.SetType(r.typ()) 1539 } 1540 return n 1541 1542 case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR: 1543 if !go117ExportTypes && op != ir.OCONV { 1544 // unreachable - mapped to OCONV case by exporter 1545 goto error 1546 } 1547 return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr()) 1548 1549 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: 1550 if go117ExportTypes { 1551 switch op { 1552 case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE: 1553 n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr()) 1554 n.SetType(r.typ()) 1555 return n 1556 case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC: 1557 n := ir.NewUnaryExpr(r.pos(), op, r.expr()) 1558 if op != ir.OPANIC { 1559 n.SetType(r.typ()) 1560 } 1561 return n 1562 case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN: 1563 n := ir.NewCallExpr(r.pos(), op, nil, r.exprList()) 1564 if op == ir.OAPPEND { 1565 n.IsDDD = r.bool() 1566 } 1567 if op == ir.OAPPEND || op == ir.ORECOVER { 1568 n.SetType(r.typ()) 1569 } 1570 return n 1571 } 1572 // ir.OMAKE 1573 goto error 1574 } 1575 n := builtinCall(r.pos(), op) 1576 n.Args = r.exprList() 1577 if op == ir.OAPPEND { 1578 n.IsDDD = r.bool() 1579 } 1580 return n 1581 1582 case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG: 1583 pos := r.pos() 1584 init := r.stmtList() 1585 n := ir.NewCallExpr(pos, ir.OCALL, r.expr(), r.exprList()) 1586 if go117ExportTypes { 1587 n.SetOp(op) 1588 } 1589 n.SetInit(init) 1590 n.IsDDD = r.bool() 1591 if go117ExportTypes { 1592 n.SetType(r.exoticType()) 1593 } 1594 return n 1595 1596 case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE: 1597 if go117ExportTypes { 1598 pos := r.pos() 1599 typ := r.typ() 1600 list := r.exprList() 1601 var len_, cap_ ir.Node 1602 if len(list) > 0 { 1603 len_ = list[0] 1604 } 1605 if len(list) > 1 { 1606 cap_ = list[1] 1607 } 1608 n := ir.NewMakeExpr(pos, op, len_, cap_) 1609 n.SetType(typ) 1610 return n 1611 } 1612 n := builtinCall(r.pos(), ir.OMAKE) 1613 n.Args.Append(ir.TypeNode(r.typ())) 1614 n.Args.Append(r.exprList()...) 1615 return n 1616 1617 case ir.OLINKSYMOFFSET: 1618 pos := r.pos() 1619 name := r.string() 1620 off := r.uint64() 1621 typ := r.typ() 1622 return ir.NewLinksymOffsetExpr(pos, Lookup(name).Linksym(), int64(off), typ) 1623 1624 // unary expressions 1625 case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV, ir.OIDATA: 1626 n := ir.NewUnaryExpr(r.pos(), op, r.expr()) 1627 if go117ExportTypes { 1628 n.SetType(r.typ()) 1629 } 1630 return n 1631 1632 case ir.OADDR, ir.OPTRLIT: 1633 n := NodAddrAt(r.pos(), r.expr()) 1634 if go117ExportTypes { 1635 n.SetOp(op) 1636 n.SetType(r.typ()) 1637 } 1638 return n 1639 1640 case ir.ODEREF: 1641 n := ir.NewStarExpr(r.pos(), r.expr()) 1642 if go117ExportTypes { 1643 n.SetType(r.typ()) 1644 } 1645 return n 1646 1647 // binary expressions 1648 case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT, 1649 ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR, ir.OEFACE: 1650 n := ir.NewBinaryExpr(r.pos(), op, r.expr(), r.expr()) 1651 if go117ExportTypes { 1652 n.SetType(r.typ()) 1653 } 1654 return n 1655 1656 case ir.OANDAND, ir.OOROR: 1657 n := ir.NewLogicalExpr(r.pos(), op, r.expr(), r.expr()) 1658 if go117ExportTypes { 1659 n.SetType(r.typ()) 1660 } 1661 return n 1662 1663 case ir.OSEND: 1664 return ir.NewSendStmt(r.pos(), r.expr(), r.expr()) 1665 1666 case ir.OADDSTR: 1667 pos := r.pos() 1668 list := r.exprList() 1669 if go117ExportTypes { 1670 n := ir.NewAddStringExpr(pos, list) 1671 n.SetType(r.typ()) 1672 return n 1673 } 1674 x := list[0] 1675 for _, y := range list[1:] { 1676 x = ir.NewBinaryExpr(pos, ir.OADD, x, y) 1677 } 1678 return x 1679 1680 // -------------------------------------------------------------------- 1681 // statements 1682 case ir.ODCL: 1683 var stmts ir.Nodes 1684 n := r.localName() 1685 stmts.Append(ir.NewDecl(n.Pos(), ir.ODCL, n)) 1686 stmts.Append(ir.NewAssignStmt(n.Pos(), n, nil)) 1687 return ir.NewBlockStmt(n.Pos(), stmts) 1688 1689 // case OASWB: 1690 // unreachable - never exported 1691 1692 case ir.OAS: 1693 pos := r.pos() 1694 init := r.stmtList() 1695 n := ir.NewAssignStmt(pos, r.expr(), r.expr()) 1696 n.SetInit(init) 1697 n.Def = r.bool() 1698 return n 1699 1700 case ir.OASOP: 1701 n := ir.NewAssignOpStmt(r.pos(), r.op(), r.expr(), nil) 1702 if !r.bool() { 1703 n.Y = ir.NewInt(1) 1704 n.IncDec = true 1705 } else { 1706 n.Y = r.expr() 1707 } 1708 return n 1709 1710 case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV: 1711 if !go117ExportTypes && op != ir.OAS2 { 1712 // unreachable - mapped to case OAS2 by exporter 1713 goto error 1714 } 1715 pos := r.pos() 1716 init := r.stmtList() 1717 n := ir.NewAssignListStmt(pos, op, r.exprList(), r.exprList()) 1718 n.SetInit(init) 1719 n.Def = r.bool() 1720 return n 1721 1722 case ir.ORETURN: 1723 return ir.NewReturnStmt(r.pos(), r.exprList()) 1724 1725 // case ORETJMP: 1726 // unreachable - generated by compiler for trampolin routines (not exported) 1727 1728 case ir.OGO, ir.ODEFER: 1729 return ir.NewGoDeferStmt(r.pos(), op, r.expr()) 1730 1731 case ir.OIF: 1732 pos, init := r.pos(), r.stmtList() 1733 n := ir.NewIfStmt(pos, r.expr(), r.stmtList(), r.stmtList()) 1734 n.SetInit(init) 1735 return n 1736 1737 case ir.OFOR: 1738 pos, init := r.pos(), r.stmtList() 1739 cond, post := r.exprsOrNil() 1740 n := ir.NewForStmt(pos, nil, cond, post, r.stmtList()) 1741 n.SetInit(init) 1742 return n 1743 1744 case ir.ORANGE: 1745 pos, init := r.pos(), r.stmtList() 1746 k, v := r.exprsOrNil() 1747 n := ir.NewRangeStmt(pos, k, v, r.expr(), r.stmtList()) 1748 n.SetInit(init) 1749 return n 1750 1751 case ir.OSELECT: 1752 pos := r.pos() 1753 init := r.stmtList() 1754 n := ir.NewSelectStmt(pos, r.commList()) 1755 n.SetInit(init) 1756 return n 1757 1758 case ir.OSWITCH: 1759 pos := r.pos() 1760 init := r.stmtList() 1761 x, _ := r.exprsOrNil() 1762 n := ir.NewSwitchStmt(pos, x, r.caseList(x)) 1763 n.SetInit(init) 1764 return n 1765 1766 // case OCASE: 1767 // handled by caseList 1768 1769 case ir.OFALL: 1770 return ir.NewBranchStmt(r.pos(), ir.OFALL, nil) 1771 1772 // case OEMPTY: 1773 // unreachable - not emitted by exporter 1774 1775 case ir.OBREAK, ir.OCONTINUE, ir.OGOTO: 1776 pos := r.pos() 1777 var sym *types.Sym 1778 if label := r.string(); label != "" { 1779 sym = Lookup(label) 1780 } 1781 return ir.NewBranchStmt(pos, op, sym) 1782 1783 case ir.OLABEL: 1784 return ir.NewLabelStmt(r.pos(), Lookup(r.string())) 1785 1786 case ir.OEND: 1787 return nil 1788 1789 case ir.OFUNCINST: 1790 pos := r.pos() 1791 x := r.expr() 1792 ntargs := r.uint64() 1793 var targs []ir.Node 1794 if ntargs > 0 { 1795 targs = make([]ir.Node, ntargs) 1796 for i := range targs { 1797 targs[i] = ir.TypeNode(r.typ()) 1798 } 1799 } 1800 n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs) 1801 if go117ExportTypes { 1802 n.SetType(r.typ()) 1803 } 1804 return n 1805 1806 case ir.OSELRECV2: 1807 pos := r.pos() 1808 init := r.stmtList() 1809 n := ir.NewAssignListStmt(pos, ir.OSELRECV2, r.exprList(), r.exprList()) 1810 n.SetInit(init) 1811 n.Def = r.bool() 1812 return n 1813 1814 default: 1815 base.Fatalf("cannot import %v (%d) node\n"+ 1816 "\t==> please file an issue and assign to gri@", op, int(op)) 1817 panic("unreachable") // satisfy compiler 1818 } 1819error: 1820 base.Fatalf("cannot import %v (%d) node\n"+ 1821 "\t==> please file an issue and assign to khr@", op, int(op)) 1822 panic("unreachable") // satisfy compiler 1823} 1824 1825func (r *importReader) op() ir.Op { 1826 if debug && r.uint64() != magic { 1827 base.Fatalf("import stream has desynchronized") 1828 } 1829 return ir.Op(r.uint64()) 1830} 1831 1832func (r *importReader) fieldList() []ir.Node { 1833 list := make([]ir.Node, r.uint64()) 1834 for i := range list { 1835 list[i] = ir.NewStructKeyExpr(r.pos(), r.exoticField(), r.expr()) 1836 } 1837 return list 1838} 1839 1840func (r *importReader) exprsOrNil() (a, b ir.Node) { 1841 ab := r.uint64() 1842 if ab&1 != 0 { 1843 a = r.expr() 1844 } 1845 if ab&2 != 0 { 1846 b = r.node() 1847 } 1848 return 1849} 1850 1851func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr { 1852 if go117ExportTypes { 1853 // These should all be encoded as direct ops, not OCALL. 1854 base.Fatalf("builtinCall should not be invoked when types are included in import/export") 1855 } 1856 return ir.NewCallExpr(pos, ir.OCALL, ir.NewIdent(base.Pos, types.BuiltinPkg.Lookup(ir.OpNames[op])), nil) 1857} 1858 1859// NewIncompleteNamedType returns a TFORW type t with name specified by sym, such 1860// that t.nod and sym.Def are set correctly. If there are any RParams for the type, 1861// they should be set soon after creating the TFORW type, before creating the 1862// underlying type. That ensures that the HasTParam and HasShape flags will be set 1863// properly, in case this type is part of some mutually recursive type. 1864func NewIncompleteNamedType(pos src.XPos, sym *types.Sym) *types.Type { 1865 name := ir.NewDeclNameAt(pos, ir.OTYPE, sym) 1866 forw := types.NewNamed(name) 1867 name.SetType(forw) 1868 sym.Def = name 1869 return forw 1870} 1871 1872// Instantiate creates a new named type which is the instantiation of the base 1873// named generic type, with the specified type args. 1874func Instantiate(pos src.XPos, baseType *types.Type, targs []*types.Type) *types.Type { 1875 baseSym := baseType.Sym() 1876 if strings.Index(baseSym.Name, "[") >= 0 { 1877 base.Fatalf("arg to Instantiate is not a base generic type") 1878 } 1879 name := InstTypeName(baseSym.Name, targs) 1880 instSym := baseSym.Pkg.Lookup(name) 1881 if instSym.Def != nil { 1882 // May match existing type from previous import or 1883 // types2-to-types1 conversion. 1884 t := instSym.Def.Type() 1885 if t.Kind() != types.TFORW { 1886 return t 1887 } 1888 // Or, we have started creating this type in (*TSubster).Typ, but its 1889 // underlying type was not completed yet, so we need to add this type 1890 // to deferredInstStack, if not already there. 1891 found := false 1892 for _, t2 := range deferredInstStack { 1893 if t2 == t { 1894 found = true 1895 break 1896 } 1897 } 1898 if !found { 1899 deferredInstStack = append(deferredInstStack, t) 1900 } 1901 return t 1902 } 1903 1904 t := NewIncompleteNamedType(baseType.Pos(), instSym) 1905 t.SetRParams(targs) 1906 t.SetOrigSym(baseSym) 1907 1908 // baseType may still be TFORW or its methods may not be fully filled in 1909 // (since we are in the middle of importing it). So, delay call to 1910 // substInstType until we get back up to the top of the current top-most 1911 // type import. 1912 deferredInstStack = append(deferredInstStack, t) 1913 1914 return t 1915} 1916 1917var deferredInstStack []*types.Type 1918var deferInst int 1919 1920// deferDoInst defers substitution on instantiated types until we are at the 1921// top-most defined type, so the base types are fully defined. 1922func deferDoInst() { 1923 deferInst++ 1924} 1925 1926func resumeDoInst() { 1927 if deferInst == 1 { 1928 for len(deferredInstStack) > 0 { 1929 t := deferredInstStack[0] 1930 deferredInstStack = deferredInstStack[1:] 1931 substInstType(t, t.OrigSym().Def.(*ir.Name).Type(), t.RParams()) 1932 } 1933 } 1934 deferInst-- 1935} 1936 1937// doInst creates a new instantiation type (which will be added to 1938// deferredInstStack for completion later) for an incomplete type encountered 1939// during a type substitution for an instantiation. This is needed for 1940// instantiations of mutually recursive types. 1941func doInst(t *types.Type) *types.Type { 1942 assert(t.Kind() == types.TFORW) 1943 return Instantiate(t.Pos(), t.OrigSym().Def.(*ir.Name).Type(), t.RParams()) 1944} 1945 1946// substInstType completes the instantiation of a generic type by doing a 1947// substitution on the underlying type itself and any methods. t is the 1948// instantiation being created, baseType is the base generic type, and targs are 1949// the type arguments that baseType is being instantiated with. 1950func substInstType(t *types.Type, baseType *types.Type, targs []*types.Type) { 1951 assert(t.Kind() == types.TFORW) 1952 subst := Tsubster{ 1953 Tparams: baseType.RParams(), 1954 Targs: targs, 1955 SubstForwFunc: doInst, 1956 } 1957 t.SetUnderlying(subst.Typ(baseType.Underlying())) 1958 1959 newfields := make([]*types.Field, baseType.Methods().Len()) 1960 for i, f := range baseType.Methods().Slice() { 1961 if !f.IsMethod() || types.IsInterfaceMethod(f.Type) { 1962 // Do a normal substitution if this is a non-method (which 1963 // means this must be an interface used as a constraint) or 1964 // an interface method. 1965 t2 := subst.Typ(f.Type) 1966 newfields[i] = types.NewField(f.Pos, f.Sym, t2) 1967 continue 1968 } 1969 recvType := f.Type.Recv().Type 1970 if recvType.IsPtr() { 1971 recvType = recvType.Elem() 1972 } 1973 // Substitute in the method using the type params used in the 1974 // method (not the type params in the definition of the generic type). 1975 msubst := Tsubster{ 1976 Tparams: recvType.RParams(), 1977 Targs: targs, 1978 SubstForwFunc: doInst, 1979 } 1980 t2 := msubst.Typ(f.Type) 1981 oldsym := f.Nname.Sym() 1982 newsym := MakeFuncInstSym(oldsym, targs, true, true) 1983 var nname *ir.Name 1984 if newsym.Def != nil { 1985 nname = newsym.Def.(*ir.Name) 1986 } else { 1987 nname = ir.NewNameAt(f.Pos, newsym) 1988 nname.SetType(t2) 1989 ir.MarkFunc(nname) 1990 newsym.Def = nname 1991 } 1992 newfields[i] = types.NewField(f.Pos, f.Sym, t2) 1993 newfields[i].Nname = nname 1994 } 1995 t.Methods().Set(newfields) 1996 if !t.HasTParam() && !t.HasShape() && t.Kind() != types.TINTER && t.Methods().Len() > 0 { 1997 // Generate all the methods for a new fully-instantiated, 1998 // non-interface, non-shape type. 1999 NeedInstType(t) 2000 } 2001} 2002