mirror of
https://github.com/golang/go
synced 2024-11-22 19:44:57 -07:00
[dev.regabi] cmd/compile: cleanup for concrete types - import/export
An automated rewrite will add concrete type assertions after a test of n.Op(), when n can be safely type-asserted (meaning, n is not reassigned a different type, n is not reassigned and then used outside the scope of the type assertion, and so on). This sequence of CLs handles the code that the automated rewrite does not: adding specific types to function arguments, adjusting code not to call n.Left() etc when n may have multiple representations, and so on. This CL focuses on iimport.go and iexport.go. Passes buildall w/ toolstash -cmp. Change-Id: I63edee54991ae5d982e99efa7a2894478d511910 Reviewed-on: https://go-review.googlesource.com/c/go/+/277925 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
aa55d4e54b
commit
5fe64298a4
@ -15,8 +15,11 @@ type exporter struct {
|
|||||||
|
|
||||||
// markObject visits a reachable object.
|
// markObject visits a reachable object.
|
||||||
func (p *exporter) markObject(n ir.Node) {
|
func (p *exporter) markObject(n ir.Node) {
|
||||||
if n.Op() == ir.ONAME && n.Class() == ir.PFUNC {
|
if n.Op() == ir.ONAME {
|
||||||
inlFlood(n.(*ir.Name))
|
n := n.(*ir.Name)
|
||||||
|
if n.Class() == ir.PFUNC {
|
||||||
|
inlFlood(n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.markType(n.Type())
|
p.markType(n.Type())
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package gc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"cmd/compile/internal/ir"
|
|
||||||
"cmd/compile/internal/types"
|
|
||||||
"cmd/internal/src"
|
|
||||||
)
|
|
||||||
|
|
||||||
func npos(pos src.XPos, n ir.Node) ir.Node {
|
|
||||||
n.SetPos(pos)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func builtinCall(op ir.Op) ir.Node {
|
|
||||||
return ir.Nod(ir.OCALL, mkname(types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
|
|
||||||
}
|
|
@ -1069,7 +1069,7 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch op := n.Op(); op {
|
switch n.Op() {
|
||||||
case ir.OBLOCK:
|
case ir.OBLOCK:
|
||||||
// No OBLOCK in export data.
|
// No OBLOCK in export data.
|
||||||
// Inline content into this statement list,
|
// Inline content into this statement list,
|
||||||
@ -1084,7 +1084,7 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
case ir.ODCL:
|
case ir.ODCL:
|
||||||
w.op(ir.ODCL)
|
w.op(ir.ODCL)
|
||||||
w.pos(n.Left().Pos())
|
w.pos(n.Left().Pos())
|
||||||
w.localName(n.Left())
|
w.localName(n.Left().(*ir.Name))
|
||||||
w.typ(n.Left().Type())
|
w.typ(n.Left().Type())
|
||||||
|
|
||||||
case ir.OAS:
|
case ir.OAS:
|
||||||
@ -1099,9 +1099,10 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ir.OASOP:
|
case ir.OASOP:
|
||||||
|
n := n.(*ir.AssignOpStmt)
|
||||||
w.op(ir.OASOP)
|
w.op(ir.OASOP)
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.op(n.SubOp())
|
w.op(n.AsOp)
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
if w.bool(!n.Implicit()) {
|
if w.bool(!n.Implicit()) {
|
||||||
w.expr(n.Right())
|
w.expr(n.Right())
|
||||||
@ -1122,7 +1123,7 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
// unreachable - generated by compiler for trampolin routines
|
// unreachable - generated by compiler for trampolin routines
|
||||||
|
|
||||||
case ir.OGO, ir.ODEFER:
|
case ir.OGO, ir.ODEFER:
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
|
|
||||||
@ -1148,8 +1149,15 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
w.expr(n.Right())
|
w.expr(n.Right())
|
||||||
w.stmtList(n.Body())
|
w.stmtList(n.Body())
|
||||||
|
|
||||||
case ir.OSELECT, ir.OSWITCH:
|
case ir.OSELECT:
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
|
w.pos(n.Pos())
|
||||||
|
w.stmtList(n.Init())
|
||||||
|
w.exprsOrNil(nil, nil) // TODO(rsc): Delete (and fix importer).
|
||||||
|
w.caseList(n)
|
||||||
|
|
||||||
|
case ir.OSWITCH:
|
||||||
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.stmtList(n.Init())
|
w.stmtList(n.Init())
|
||||||
w.exprsOrNil(n.Left(), nil)
|
w.exprsOrNil(n.Left(), nil)
|
||||||
@ -1163,7 +1171,7 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
|
|
||||||
case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL:
|
case ir.OBREAK, ir.OCONTINUE, ir.OGOTO, ir.OLABEL:
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
label := ""
|
label := ""
|
||||||
if sym := n.Sym(); sym != nil {
|
if sym := n.Sym(); sym != nil {
|
||||||
@ -1176,19 +1184,34 @@ func (w *exportWriter) stmt(n ir.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) caseList(sw ir.Node) {
|
func isNamedTypeSwitch(n ir.Node) bool {
|
||||||
namedTypeSwitch := sw.Op() == ir.OSWITCH && sw.Left() != nil && sw.Left().Op() == ir.OTYPESW && sw.Left().Left() != nil
|
if n.Op() != ir.OSWITCH {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
sw := n.(*ir.SwitchStmt)
|
||||||
|
if sw.Left() == nil || sw.Left().Op() != ir.OTYPESW {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
guard := sw.Left().(*ir.TypeSwitchGuard)
|
||||||
|
return guard.Left() != nil
|
||||||
|
}
|
||||||
|
|
||||||
cases := sw.List().Slice()
|
func (w *exportWriter) caseList(sw ir.Node) {
|
||||||
|
namedTypeSwitch := isNamedTypeSwitch(sw)
|
||||||
|
|
||||||
|
var cases []ir.Node
|
||||||
|
if sw.Op() == ir.OSWITCH {
|
||||||
|
cases = sw.(*ir.SwitchStmt).List().Slice()
|
||||||
|
} else {
|
||||||
|
cases = sw.(*ir.SelectStmt).List().Slice()
|
||||||
|
}
|
||||||
w.uint64(uint64(len(cases)))
|
w.uint64(uint64(len(cases)))
|
||||||
for _, cas := range cases {
|
for _, cas := range cases {
|
||||||
if cas.Op() != ir.OCASE {
|
cas := cas.(*ir.CaseStmt)
|
||||||
base.Fatalf("expected OCASE, got %v", cas)
|
|
||||||
}
|
|
||||||
w.pos(cas.Pos())
|
w.pos(cas.Pos())
|
||||||
w.stmtList(cas.List())
|
w.stmtList(cas.List())
|
||||||
if namedTypeSwitch {
|
if namedTypeSwitch {
|
||||||
w.localName(cas.Rlist().First())
|
w.localName(cas.Rlist().First().(*ir.Name))
|
||||||
}
|
}
|
||||||
w.stmtList(cas.Body())
|
w.stmtList(cas.Body())
|
||||||
}
|
}
|
||||||
@ -1201,22 +1224,29 @@ func (w *exportWriter) exprList(list ir.Nodes) {
|
|||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) expr(n ir.Node) {
|
func simplifyForExport(n ir.Node) ir.Node {
|
||||||
// from nodefmt (fmt.go)
|
switch n.Op() {
|
||||||
//
|
case ir.OPAREN:
|
||||||
// nodefmt reverts nodes back to their original - we don't need to do
|
return simplifyForExport(n.Left())
|
||||||
// it because we are not bound to produce valid Go syntax when exporting
|
case ir.ODEREF:
|
||||||
//
|
if n.Implicit() {
|
||||||
// if (fmtmode != FExp || n.Op != OLITERAL) && n.Orig != nil {
|
return simplifyForExport(n.Left())
|
||||||
// n = n.Orig
|
}
|
||||||
// }
|
case ir.OADDR:
|
||||||
|
if n.Implicit() {
|
||||||
// from exprfmt (fmt.go)
|
return simplifyForExport(n.Left())
|
||||||
for n.Op() == ir.OPAREN || n.Implicit() && (n.Op() == ir.ODEREF || n.Op() == ir.OADDR || n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR) {
|
}
|
||||||
n = n.Left()
|
case ir.ODOT, ir.ODOTPTR:
|
||||||
|
if n.Implicit() {
|
||||||
|
return simplifyForExport(n.Left())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
switch op := n.Op(); op {
|
func (w *exportWriter) expr(n ir.Node) {
|
||||||
|
n = simplifyForExport(n)
|
||||||
|
switch n.Op() {
|
||||||
// expressions
|
// expressions
|
||||||
// (somewhat closely following the structure of exprfmt in fmt.go)
|
// (somewhat closely following the structure of exprfmt in fmt.go)
|
||||||
case ir.ONIL:
|
case ir.ONIL:
|
||||||
@ -1243,6 +1273,7 @@ func (w *exportWriter) expr(n ir.Node) {
|
|||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
// Package scope name.
|
// Package scope name.
|
||||||
|
n := n.(*ir.Name)
|
||||||
if (n.Class() == ir.PEXTERN || n.Class() == ir.PFUNC) && !ir.IsBlank(n) {
|
if (n.Class() == ir.PEXTERN || n.Class() == ir.PFUNC) && !ir.IsBlank(n) {
|
||||||
w.op(ir.ONONAME)
|
w.op(ir.ONONAME)
|
||||||
w.qualifiedIdent(n)
|
w.qualifiedIdent(n)
|
||||||
@ -1291,7 +1322,7 @@ func (w *exportWriter) expr(n ir.Node) {
|
|||||||
w.op(ir.OSTRUCTLIT)
|
w.op(ir.OSTRUCTLIT)
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type())
|
w.typ(n.Type())
|
||||||
w.elemList(n.List()) // special handling of field names
|
w.fieldList(n.List()) // special handling of field names
|
||||||
|
|
||||||
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
|
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
|
||||||
w.op(ir.OCOMPLIT)
|
w.op(ir.OCOMPLIT)
|
||||||
@ -1349,7 +1380,7 @@ func (w *exportWriter) expr(n ir.Node) {
|
|||||||
|
|
||||||
case ir.OCOPY, ir.OCOMPLEX:
|
case ir.OCOPY, ir.OCOMPLEX:
|
||||||
// treated like other builtin calls (see e.g., OREAL)
|
// treated like other builtin calls (see e.g., OREAL)
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
w.expr(n.Right())
|
w.expr(n.Right())
|
||||||
@ -1361,20 +1392,21 @@ func (w *exportWriter) expr(n ir.Node) {
|
|||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
w.typ(n.Type())
|
w.typ(n.Type())
|
||||||
|
|
||||||
case 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:
|
case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
if n.Left() != nil {
|
w.expr(n.Left())
|
||||||
w.expr(n.Left())
|
w.op(ir.OEND)
|
||||||
w.op(ir.OEND)
|
|
||||||
} else {
|
case ir.OAPPEND, ir.ODELETE, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
|
||||||
w.exprList(n.List()) // emits terminating OEND
|
w.op(n.Op())
|
||||||
}
|
w.pos(n.Pos())
|
||||||
|
w.exprList(n.List()) // emits terminating OEND
|
||||||
// only append() calls may contain '...' arguments
|
// only append() calls may contain '...' arguments
|
||||||
if op == ir.OAPPEND {
|
if n.Op() == ir.OAPPEND {
|
||||||
w.bool(n.IsDDD())
|
w.bool(n.IsDDD())
|
||||||
} else if n.IsDDD() {
|
} else if n.IsDDD() {
|
||||||
base.Fatalf("exporter: unexpected '...' with %v call", op)
|
base.Fatalf("exporter: unexpected '...' with %v call", n.Op())
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
|
case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
|
||||||
@ -1386,15 +1418,13 @@ func (w *exportWriter) expr(n ir.Node) {
|
|||||||
w.bool(n.IsDDD())
|
w.bool(n.IsDDD())
|
||||||
|
|
||||||
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
||||||
w.op(op) // must keep separate from OMAKE for importer
|
w.op(n.Op()) // must keep separate from OMAKE for importer
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.typ(n.Type())
|
w.typ(n.Type())
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
// empty list
|
// empty list
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
case n.List().Len() != 0: // pre-typecheck
|
|
||||||
w.exprList(n.List()) // emits terminating OEND
|
|
||||||
case n.Right() != nil:
|
case n.Right() != nil:
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
w.expr(n.Right())
|
w.expr(n.Right())
|
||||||
@ -1405,15 +1435,37 @@ func (w *exportWriter) expr(n ir.Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// unary expressions
|
// unary expressions
|
||||||
case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
|
case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.ORECV:
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
|
|
||||||
|
case ir.OADDR:
|
||||||
|
w.op(n.Op())
|
||||||
|
w.pos(n.Pos())
|
||||||
|
w.expr(n.Left())
|
||||||
|
|
||||||
|
case ir.ODEREF:
|
||||||
|
w.op(n.Op())
|
||||||
|
w.pos(n.Pos())
|
||||||
|
w.expr(n.Left())
|
||||||
|
|
||||||
|
case ir.OSEND:
|
||||||
|
w.op(n.Op())
|
||||||
|
w.pos(n.Pos())
|
||||||
|
w.expr(n.Left())
|
||||||
|
w.expr(n.Right())
|
||||||
|
|
||||||
// binary expressions
|
// binary expressions
|
||||||
case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
|
case ir.OADD, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
|
||||||
ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR:
|
ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.ORSH, ir.OSUB, ir.OXOR:
|
||||||
w.op(op)
|
w.op(n.Op())
|
||||||
|
w.pos(n.Pos())
|
||||||
|
w.expr(n.Left())
|
||||||
|
w.expr(n.Right())
|
||||||
|
|
||||||
|
case ir.OANDAND, ir.OOROR:
|
||||||
|
w.op(n.Op())
|
||||||
w.pos(n.Pos())
|
w.pos(n.Pos())
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
w.expr(n.Right())
|
w.expr(n.Right())
|
||||||
@ -1454,15 +1506,16 @@ func (w *exportWriter) exprsOrNil(a, b ir.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) elemList(list ir.Nodes) {
|
func (w *exportWriter) fieldList(list ir.Nodes) {
|
||||||
w.uint64(uint64(list.Len()))
|
w.uint64(uint64(list.Len()))
|
||||||
for _, n := range list.Slice() {
|
for _, n := range list.Slice() {
|
||||||
|
n := n.(*ir.StructKeyExpr)
|
||||||
w.selector(n.Sym())
|
w.selector(n.Sym())
|
||||||
w.expr(n.Left())
|
w.expr(n.Left())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *exportWriter) localName(n ir.Node) {
|
func (w *exportWriter) localName(n *ir.Name) {
|
||||||
// Escape analysis happens after inline bodies are saved, but
|
// Escape analysis happens after inline bodies are saved, but
|
||||||
// we're using the same ONAME nodes, so we might still see
|
// we're using the same ONAME nodes, so we might still see
|
||||||
// PAUTOHEAP here.
|
// PAUTOHEAP here.
|
||||||
|
@ -753,7 +753,7 @@ func (r *importReader) stmtList() []ir.Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *importReader) caseList(sw ir.Node) []ir.Node {
|
func (r *importReader) caseList(sw ir.Node) []ir.Node {
|
||||||
namedTypeSwitch := sw.Op() == ir.OSWITCH && sw.Left() != nil && sw.Left().Op() == ir.OTYPESW && sw.Left().Left() != nil
|
namedTypeSwitch := isNamedTypeSwitch(sw)
|
||||||
|
|
||||||
cases := make([]ir.Node, r.uint64())
|
cases := make([]ir.Node, r.uint64())
|
||||||
for i := range cases {
|
for i := range cases {
|
||||||
@ -766,7 +766,7 @@ func (r *importReader) caseList(sw ir.Node) []ir.Node {
|
|||||||
caseVar := ir.NewNameAt(cas.Pos(), r.ident())
|
caseVar := ir.NewNameAt(cas.Pos(), r.ident())
|
||||||
declare(caseVar, dclcontext)
|
declare(caseVar, dclcontext)
|
||||||
cas.PtrRlist().Set1(caseVar)
|
cas.PtrRlist().Set1(caseVar)
|
||||||
caseVar.Defn = sw.Left()
|
caseVar.Defn = sw.(*ir.SwitchStmt).Left()
|
||||||
}
|
}
|
||||||
cas.PtrBody().Set(r.stmtList())
|
cas.PtrBody().Set(r.stmtList())
|
||||||
cases[i] = cas
|
cases[i] = cas
|
||||||
@ -915,14 +915,14 @@ func (r *importReader) node() ir.Node {
|
|||||||
return n
|
return n
|
||||||
|
|
||||||
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:
|
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:
|
||||||
n := npos(r.pos(), builtinCall(op))
|
n := builtinCall(r.pos(), op)
|
||||||
n.PtrList().Set(r.exprList())
|
n.PtrList().Set(r.exprList())
|
||||||
if op == ir.OAPPEND {
|
if op == ir.OAPPEND {
|
||||||
n.SetIsDDD(r.bool())
|
n.SetIsDDD(r.bool())
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
|
// case OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
|
||||||
// unreachable - mapped to OCALL case below by exporter
|
// unreachable - mapped to OCALL case below by exporter
|
||||||
|
|
||||||
case ir.OCALL:
|
case ir.OCALL:
|
||||||
@ -934,7 +934,7 @@ func (r *importReader) node() ir.Node {
|
|||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
|
||||||
n := npos(r.pos(), builtinCall(ir.OMAKE))
|
n := builtinCall(r.pos(), ir.OMAKE)
|
||||||
n.PtrList().Append(ir.TypeNode(r.typ()))
|
n.PtrList().Append(ir.TypeNode(r.typ()))
|
||||||
n.PtrList().Append(r.exprList()...)
|
n.PtrList().Append(r.exprList()...)
|
||||||
return n
|
return n
|
||||||
@ -1042,8 +1042,7 @@ func (r *importReader) node() ir.Node {
|
|||||||
case ir.OSELECT:
|
case ir.OSELECT:
|
||||||
n := ir.NodAt(r.pos(), ir.OSELECT, nil, nil)
|
n := ir.NodAt(r.pos(), ir.OSELECT, nil, nil)
|
||||||
n.PtrInit().Set(r.stmtList())
|
n.PtrInit().Set(r.stmtList())
|
||||||
left, _ := r.exprsOrNil()
|
r.exprsOrNil() // TODO(rsc): Delete (and fix exporter). These are always nil.
|
||||||
n.SetLeft(left)
|
|
||||||
n.PtrList().Set(r.caseList(n))
|
n.PtrList().Set(r.caseList(n))
|
||||||
return n
|
return n
|
||||||
|
|
||||||
@ -1110,3 +1109,12 @@ func (r *importReader) exprsOrNil() (a, b ir.Node) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func builtinCall(pos src.XPos, op ir.Op) *ir.CallExpr {
|
||||||
|
return ir.NewCallExpr(pos, ir.OCALL, mkname(types.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func npos(pos src.XPos, n ir.Node) ir.Node {
|
||||||
|
n.SetPos(pos)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user