mirror of
https://github.com/golang/go
synced 2024-11-05 11:56:12 -07:00
cmd/compile: include position info in exported function bodies
This gives accurate line numbers to inlined functions from another package. Previously AST nodes from another package would get the line number of the import statement for that package. The following benchmark results show how the size of package export data is impacted by this change. These benchmarks were created by compiling the go1 benchmark and running `go tool pack x` to extract the export data from the resulting .a files. name old bytes new bytes delta bufio 3.59k ± 0% 4.17k ± 0% +16.25% bytes 5.51k ± 0% 6.40k ± 0% +16.21% compress/bzip2 2.69k ± 0% 3.21k ± 0% +19.74% compress/flate 5.14k ± 0% 5.57k ± 0% +8.43% compress/gzip 8.91k ± 0% 10.46k ± 0% +17.32% container/list 1.76k ± 0% 2.13k ± 0% +21.51% context 4.51k ± 0% 5.47k ± 0% +21.43% crypto 1.11k ± 0% 1.13k ± 0% +1.90% crypto/aes 475 ± 0% 475 ± 0% +0.00% crypto/cipher 1.18k ± 0% 1.18k ± 0% +0.00% crypto/des 502 ± 0% 502 ± 0% +0.00% crypto/dsa 5.96k ± 0% 6.54k ± 0% +9.82% crypto/ecdsa 6.93k ± 0% 7.69k ± 0% +10.91% crypto/elliptic 6.53k ± 0% 7.17k ± 0% +9.72% crypto/hmac 464 ± 0% 464 ± 0% +0.00% crypto/internal/cipherhw 313 ± 0% 313 ± 0% +0.00% crypto/md5 695 ± 0% 711 ± 0% +2.30% crypto/rand 5.62k ± 0% 6.21k ± 0% +10.44% crypto/rc4 512 ± 0% 512 ± 0% +0.00% crypto/rsa 7.31k ± 0% 8.10k ± 0% +10.86% crypto/sha1 760 ± 0% 777 ± 0% +2.24% crypto/sha256 523 ± 0% 523 ± 0% +0.00% crypto/sha512 663 ± 0% 663 ± 0% +0.00% crypto/subtle 873 ± 0% 1007 ± 0% +15.35% crypto/tls 29.6k ± 0% 33.8k ± 0% +14.03% crypto/x509 18.7k ± 0% 21.0k ± 0% +12.56% crypto/x509/pkix 10.6k ± 0% 12.2k ± 0% +15.22% encoding 473 ± 0% 473 ± 0% +0.00% encoding/asn1 1.42k ± 0% 1.50k ± 0% +5.99% encoding/base64 1.69k ± 0% 1.80k ± 0% +6.88% encoding/binary 2.76k ± 0% 3.51k ± 0% +27.09% encoding/gob 13.5k ± 0% 15.2k ± 0% +12.98% encoding/hex 857 ± 0% 881 ± 0% +2.80% encoding/json 12.5k ± 0% 14.9k ± 0% +19.37% encoding/pem 484 ± 0% 484 ± 0% +0.00% errors 361 ± 0% 370 ± 0% +2.49% flag 10.5k ± 0% 12.1k ± 0% +14.92% fmt 1.42k ± 0% 1.42k ± 0% +0.00% go/ast 15.8k ± 0% 17.5k ± 0% +10.31% go/parser 8.13k ± 0% 9.86k ± 0% +21.28% go/scanner 3.94k ± 0% 4.53k ± 0% +14.73% go/token 3.53k ± 0% 3.75k ± 0% +6.11% hash 507 ± 0% 507 ± 0% +0.00% hash/crc32 685 ± 0% 685 ± 0% +0.00% internal/nettrace 474 ± 0% 474 ± 0% +0.00% internal/poll 7.23k ± 0% 8.38k ± 0% +15.90% internal/race 511 ± 0% 515 ± 0% +0.78% internal/singleflight 969 ± 0% 1075 ± 0% +10.94% internal/syscall/unix 427 ± 0% 427 ± 0% +0.00% io 3.52k ± 0% 3.69k ± 0% +4.82% io/ioutil 8.48k ± 0% 9.90k ± 0% +16.72% log 5.06k ± 0% 5.98k ± 0% +18.15% math 4.02k ± 0% 4.35k ± 0% +8.26% math/big 9.28k ± 0% 9.94k ± 0% +7.13% math/bits 3.47k ± 0% 4.33k ± 0% +24.83% math/rand 1.30k ± 0% 1.32k ± 0% +2.00% mime 2.98k ± 0% 3.70k ± 0% +24.21% mime/multipart 3.68k ± 0% 4.22k ± 0% +14.65% mime/quotedprintable 2.26k ± 0% 2.65k ± 0% +17.60% net 23.0k ± 0% 25.7k ± 0% +11.74% net/http 59.1k ± 0% 66.7k ± 0% +13.00% net/http/httptest 35.3k ± 0% 40.9k ± 0% +15.80% net/http/httptrace 15.3k ± 0% 17.6k ± 0% +15.26% net/http/internal 2.77k ± 0% 3.27k ± 0% +17.89% net/textproto 4.60k ± 0% 5.25k ± 0% +14.22% net/url 1.73k ± 0% 1.84k ± 0% +6.59% os 14.3k ± 0% 16.4k ± 0% +14.86% path 589 ± 0% 606 ± 0% +2.89% path/filepath 5.07k ± 0% 6.17k ± 0% +21.79% reflect 6.43k ± 0% 6.81k ± 0% +5.90% regexp 5.88k ± 0% 6.46k ± 0% +9.77% regexp/syntax 3.24k ± 0% 3.29k ± 0% +1.73% runtime 13.1k ± 0% 14.9k ± 0% +13.73% runtime/cgo 229 ± 0% 229 ± 0% +0.00% runtime/debug 4.23k ± 0% 5.15k ± 0% +21.79% runtime/internal/atomic 905 ± 0% 905 ± 0% +0.00% runtime/internal/sys 2.04k ± 0% 2.20k ± 0% +7.64% runtime/pprof 4.73k ± 0% 5.65k ± 0% +19.41% runtime/trace 354 ± 0% 354 ± 0% +0.00% sort 1.68k ± 0% 1.85k ± 0% +10.17% strconv 1.85k ± 0% 1.95k ± 0% +5.51% strings 3.98k ± 0% 4.53k ± 0% +13.91% sync 1.52k ± 0% 1.58k ± 0% +4.28% sync/atomic 1.60k ± 0% 1.74k ± 0% +8.50% syscall 53.3k ± 0% 54.3k ± 0% +1.84% testing 8.77k ± 0% 10.09k ± 0% +14.96% testing/internal/testdeps 598 ± 0% 600 ± 0% +0.33% text/tabwriter 3.63k ± 0% 4.41k ± 0% +21.64% text/template 15.7k ± 0% 18.1k ± 0% +15.67% text/template/parse 9.12k ± 0% 10.35k ± 0% +13.48% time 6.38k ± 0% 7.14k ± 0% +11.81% unicode 4.62k ± 0% 4.66k ± 0% +0.98% unicode/utf16 707 ± 0% 791 ± 0% +11.88% unicode/utf8 1.06k ± 0% 1.20k ± 0% +12.63% vendor/golang_org/x/crypto/chacha20poly1305 1.26k ± 0% 1.43k ± 0% +13.54% vendor/golang_org/x/crypto/curve25519 392 ± 0% 392 ± 0% +0.00% vendor/golang_org/x/crypto/poly1305 426 ± 0% 426 ± 0% +0.00% vendor/golang_org/x/net/http2/hpack 4.75k ± 0% 5.77k ± 0% +21.42% vendor/golang_org/x/net/idna 355 ± 0% 355 ± 0% +0.00% vendor/golang_org/x/net/lex/httplex 616 ± 0% 644 ± 0% +4.55% vendor/golang_org/x/net/proxy 7.76k ± 0% 9.58k ± 0% +23.37% vendor/golang_org/x/text/transform 1.31k ± 0% 1.32k ± 0% +0.46% vendor/golang_org/x/text/unicode/norm 5.89k ± 0% 6.84k ± 0% +16.06% vendor/golang_org/x/text/width 1.24k ± 0% 1.27k ± 0% +2.66% [Geo mean] 2.51k 2.74k +9.14% Change-Id: I9ded911bb0ff63c530795fc85253d76b56d8abbc Reviewed-on: https://go-review.googlesource.com/37239 Run-TryBot: David Lazar <lazard@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
0824ae6dc1
commit
9fd359a29a
@ -1202,6 +1202,7 @@ func (p *exporter) expr(n *Node) {
|
||||
break
|
||||
}
|
||||
p.op(OLITERAL)
|
||||
p.pos(n)
|
||||
p.typ(unidealType(n.Type, n.Val()))
|
||||
p.value(n.Val())
|
||||
|
||||
@ -1210,12 +1211,14 @@ func (p *exporter) expr(n *Node) {
|
||||
// _ becomes ~b%d internally; print as _ for export
|
||||
if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
|
||||
p.op(ONAME)
|
||||
p.pos(n)
|
||||
p.string("_") // inlined and customized version of p.sym(n)
|
||||
break
|
||||
}
|
||||
|
||||
if n.Sym != nil && !isblank(n) && n.Name.Vargen > 0 {
|
||||
p.op(ONAME)
|
||||
p.pos(n)
|
||||
p.sym(n)
|
||||
break
|
||||
}
|
||||
@ -1225,12 +1228,14 @@ func (p *exporter) expr(n *Node) {
|
||||
// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
|
||||
if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
|
||||
p.op(OXDOT)
|
||||
p.pos(n)
|
||||
p.expr(n.Left) // n.Left.Op == OTYPE
|
||||
p.fieldSym(n.Right.Sym, true)
|
||||
break
|
||||
}
|
||||
|
||||
p.op(ONAME)
|
||||
p.pos(n)
|
||||
p.sym(n)
|
||||
|
||||
// case OPACK, ONONAME:
|
||||
@ -1238,6 +1243,7 @@ func (p *exporter) expr(n *Node) {
|
||||
|
||||
case OTYPE:
|
||||
p.op(OTYPE)
|
||||
p.pos(n)
|
||||
if p.bool(n.Type == nil) {
|
||||
p.sym(n)
|
||||
} else {
|
||||
@ -1255,21 +1261,25 @@ func (p *exporter) expr(n *Node) {
|
||||
|
||||
case OPTRLIT:
|
||||
p.op(OPTRLIT)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.bool(n.Implicit())
|
||||
|
||||
case OSTRUCTLIT:
|
||||
p.op(OSTRUCTLIT)
|
||||
p.pos(n)
|
||||
p.typ(n.Type)
|
||||
p.elemList(n.List) // special handling of field names
|
||||
|
||||
case OARRAYLIT, OSLICELIT, OMAPLIT:
|
||||
p.op(OCOMPLIT)
|
||||
p.pos(n)
|
||||
p.typ(n.Type)
|
||||
p.exprList(n.List)
|
||||
|
||||
case OKEY:
|
||||
p.op(OKEY)
|
||||
p.pos(n)
|
||||
p.exprsOrNil(n.Left, n.Right)
|
||||
|
||||
// case OSTRUCTKEY:
|
||||
@ -1280,11 +1290,13 @@ func (p *exporter) expr(n *Node) {
|
||||
|
||||
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
||||
p.op(OXDOT)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.fieldSym(n.Sym, true)
|
||||
|
||||
case ODOTTYPE, ODOTTYPE2:
|
||||
p.op(ODOTTYPE)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
if p.bool(n.Right != nil) {
|
||||
p.expr(n.Right)
|
||||
@ -1294,17 +1306,20 @@ func (p *exporter) expr(n *Node) {
|
||||
|
||||
case OINDEX, OINDEXMAP:
|
||||
p.op(OINDEX)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.expr(n.Right)
|
||||
|
||||
case OSLICE, OSLICESTR, OSLICEARR:
|
||||
p.op(OSLICE)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
low, high, _ := n.SliceBounds()
|
||||
p.exprsOrNil(low, high)
|
||||
|
||||
case OSLICE3, OSLICE3ARR:
|
||||
p.op(OSLICE3)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
low, high, max := n.SliceBounds()
|
||||
p.exprsOrNil(low, high)
|
||||
@ -1313,12 +1328,14 @@ func (p *exporter) expr(n *Node) {
|
||||
case OCOPY, OCOMPLEX:
|
||||
// treated like other builtin calls (see e.g., OREAL)
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.expr(n.Right)
|
||||
p.op(OEND)
|
||||
|
||||
case OCONV, OCONVIFACE, OCONVNOP, OARRAYBYTESTR, OARRAYRUNESTR, OSTRARRAYBYTE, OSTRARRAYRUNE, ORUNESTR:
|
||||
p.op(OCONV)
|
||||
p.pos(n)
|
||||
p.typ(n.Type)
|
||||
if n.Left != nil {
|
||||
p.expr(n.Left)
|
||||
@ -1329,6 +1346,7 @@ func (p *exporter) expr(n *Node) {
|
||||
|
||||
case OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
if n.Left != nil {
|
||||
p.expr(n.Left)
|
||||
p.op(OEND)
|
||||
@ -1344,12 +1362,14 @@ func (p *exporter) expr(n *Node) {
|
||||
|
||||
case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
|
||||
p.op(OCALL)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.exprList(n.List)
|
||||
p.bool(n.Isddd())
|
||||
|
||||
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
||||
p.op(op) // must keep separate from OMAKE for importer
|
||||
p.pos(n)
|
||||
p.typ(n.Type)
|
||||
switch {
|
||||
default:
|
||||
@ -1369,21 +1389,25 @@ func (p *exporter) expr(n *Node) {
|
||||
// unary expressions
|
||||
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
|
||||
// binary expressions
|
||||
case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
|
||||
OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.expr(n.Right)
|
||||
|
||||
case OADDSTR:
|
||||
p.op(OADDSTR)
|
||||
p.pos(n)
|
||||
p.exprList(n.List)
|
||||
|
||||
case OCMPSTR, OCMPIFACE:
|
||||
p.op(Op(n.Etype))
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.expr(n.Right)
|
||||
|
||||
@ -1393,6 +1417,7 @@ func (p *exporter) expr(n *Node) {
|
||||
// TODO(gri) these should not be exported in the first place
|
||||
// TODO(gri) why is this considered an expression in fmt.go?
|
||||
p.op(ODCLCONST)
|
||||
p.pos(n)
|
||||
|
||||
default:
|
||||
Fatalf("cannot export %v (%d) node\n"+
|
||||
@ -1426,6 +1451,7 @@ func (p *exporter) stmt(n *Node) {
|
||||
switch op := n.Op; op {
|
||||
case ODCL:
|
||||
p.op(ODCL)
|
||||
p.pos(n)
|
||||
p.sym(n.Left)
|
||||
p.typ(n.Left.Type)
|
||||
|
||||
@ -1438,12 +1464,14 @@ func (p *exporter) stmt(n *Node) {
|
||||
// the "v = <N>" again.
|
||||
if n.Right != nil {
|
||||
p.op(OAS)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
p.expr(n.Right)
|
||||
}
|
||||
|
||||
case OASOP:
|
||||
p.op(OASOP)
|
||||
p.pos(n)
|
||||
p.int(int(n.Etype))
|
||||
p.expr(n.Left)
|
||||
if p.bool(!n.Implicit()) {
|
||||
@ -1452,11 +1480,13 @@ func (p *exporter) stmt(n *Node) {
|
||||
|
||||
case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
|
||||
p.op(OAS2)
|
||||
p.pos(n)
|
||||
p.exprList(n.List)
|
||||
p.exprList(n.Rlist)
|
||||
|
||||
case ORETURN:
|
||||
p.op(ORETURN)
|
||||
p.pos(n)
|
||||
p.exprList(n.List)
|
||||
|
||||
// case ORETJMP:
|
||||
@ -1464,10 +1494,12 @@ func (p *exporter) stmt(n *Node) {
|
||||
|
||||
case OPROC, ODEFER:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
|
||||
case OIF:
|
||||
p.op(OIF)
|
||||
p.pos(n)
|
||||
p.stmtList(n.Ninit)
|
||||
p.expr(n.Left)
|
||||
p.stmtList(n.Nbody)
|
||||
@ -1475,32 +1507,38 @@ func (p *exporter) stmt(n *Node) {
|
||||
|
||||
case OFOR:
|
||||
p.op(OFOR)
|
||||
p.pos(n)
|
||||
p.stmtList(n.Ninit)
|
||||
p.exprsOrNil(n.Left, n.Right)
|
||||
p.stmtList(n.Nbody)
|
||||
|
||||
case ORANGE:
|
||||
p.op(ORANGE)
|
||||
p.pos(n)
|
||||
p.stmtList(n.List)
|
||||
p.expr(n.Right)
|
||||
p.stmtList(n.Nbody)
|
||||
|
||||
case OSELECT, OSWITCH:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.stmtList(n.Ninit)
|
||||
p.exprsOrNil(n.Left, nil)
|
||||
p.stmtList(n.List)
|
||||
|
||||
case OCASE, OXCASE:
|
||||
p.op(OXCASE)
|
||||
p.pos(n)
|
||||
p.stmtList(n.List)
|
||||
p.stmtList(n.Nbody)
|
||||
|
||||
case OFALL, OXFALL:
|
||||
p.op(OXFALL)
|
||||
p.pos(n)
|
||||
|
||||
case OBREAK, OCONTINUE:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.exprsOrNil(n.Left, nil)
|
||||
|
||||
case OEMPTY:
|
||||
@ -1508,6 +1546,7 @@ func (p *exporter) stmt(n *Node) {
|
||||
|
||||
case OGOTO, OLABEL:
|
||||
p.op(op)
|
||||
p.pos(n)
|
||||
p.expr(n.Left)
|
||||
|
||||
default:
|
||||
|
@ -10,6 +10,7 @@ package gc
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"cmd/internal/src"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@ -41,6 +42,7 @@ type importer struct {
|
||||
posInfoFormat bool
|
||||
prevFile string
|
||||
prevLine int
|
||||
posBase *src.PosBase
|
||||
|
||||
// debugging support
|
||||
debugFormat bool
|
||||
@ -367,9 +369,9 @@ func (p *importer) obj(tag int) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *importer) pos() {
|
||||
func (p *importer) pos() src.XPos {
|
||||
if !p.posInfoFormat {
|
||||
return
|
||||
return src.NoXPos
|
||||
}
|
||||
|
||||
file := p.prevFile
|
||||
@ -382,10 +384,13 @@ func (p *importer) pos() {
|
||||
file = p.prevFile[:n] + p.string()
|
||||
p.prevFile = file
|
||||
line = p.int()
|
||||
p.posBase = src.NewFileBase(file, file)
|
||||
}
|
||||
p.prevLine = line
|
||||
|
||||
// TODO(gri) register new position
|
||||
pos := src.MakePos(p.posBase, uint(line), 0)
|
||||
xpos := Ctxt.PosTable.XPos(pos)
|
||||
return xpos
|
||||
}
|
||||
|
||||
func (p *importer) newtyp(etype EType) *Type {
|
||||
@ -845,6 +850,11 @@ func (p *importer) expr() *Node {
|
||||
return n
|
||||
}
|
||||
|
||||
func npos(pos src.XPos, n *Node) *Node {
|
||||
n.Pos = pos
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO(gri) split into expr and stmt
|
||||
func (p *importer) node() *Node {
|
||||
switch op := p.op(); op {
|
||||
@ -856,8 +866,9 @@ func (p *importer) node() *Node {
|
||||
// unimplemented
|
||||
|
||||
case OLITERAL:
|
||||
pos := p.pos()
|
||||
typ := p.typ()
|
||||
n := nodlit(p.value(typ))
|
||||
n := npos(pos, nodlit(p.value(typ)))
|
||||
if !typ.IsUntyped() {
|
||||
// Type-checking simplifies unsafe.Pointer(uintptr(c))
|
||||
// to unsafe.Pointer(c) which then cannot type-checked
|
||||
@ -875,16 +886,17 @@ func (p *importer) node() *Node {
|
||||
return n
|
||||
|
||||
case ONAME:
|
||||
return mkname(p.sym())
|
||||
return npos(p.pos(), mkname(p.sym()))
|
||||
|
||||
// case OPACK, ONONAME:
|
||||
// unreachable - should have been resolved by typechecking
|
||||
|
||||
case OTYPE:
|
||||
pos := p.pos()
|
||||
if p.bool() {
|
||||
return mkname(p.sym())
|
||||
return npos(pos, mkname(p.sym()))
|
||||
}
|
||||
return typenod(p.typ())
|
||||
return npos(pos, typenod(p.typ()))
|
||||
|
||||
// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
|
||||
// unreachable - should have been resolved by typechecking
|
||||
@ -893,7 +905,7 @@ func (p *importer) node() *Node {
|
||||
// unimplemented
|
||||
|
||||
case OPTRLIT:
|
||||
n := p.expr()
|
||||
n := npos(p.pos(), p.expr())
|
||||
if !p.bool() /* !implicit, i.e. '&' operator */ {
|
||||
if n.Op == OCOMPLIT {
|
||||
// Special case for &T{...}: turn into (*T){...}.
|
||||
@ -906,7 +918,7 @@ func (p *importer) node() *Node {
|
||||
return n
|
||||
|
||||
case OSTRUCTLIT:
|
||||
n := nod(OCOMPLIT, nil, typenod(p.typ()))
|
||||
n := npos(p.pos(), nod(OCOMPLIT, nil, typenod(p.typ())))
|
||||
n.List.Set(p.elemList()) // special handling of field names
|
||||
return n
|
||||
|
||||
@ -914,13 +926,14 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to case OCOMPLIT below by exporter
|
||||
|
||||
case OCOMPLIT:
|
||||
n := nod(OCOMPLIT, nil, typenod(p.typ()))
|
||||
n := npos(p.pos(), nod(OCOMPLIT, nil, typenod(p.typ())))
|
||||
n.List.Set(p.exprList())
|
||||
return n
|
||||
|
||||
case OKEY:
|
||||
pos := p.pos()
|
||||
left, right := p.exprsOrNil()
|
||||
return nod(OKEY, left, right)
|
||||
return npos(pos, nod(OKEY, left, right))
|
||||
|
||||
// case OSTRUCTKEY:
|
||||
// unreachable - handled in case OSTRUCTLIT by elemList
|
||||
@ -933,13 +946,13 @@ func (p *importer) node() *Node {
|
||||
|
||||
case OXDOT:
|
||||
// see parser.new_dotname
|
||||
return nodSym(OXDOT, p.expr(), p.fieldSym())
|
||||
return npos(p.pos(), nodSym(OXDOT, p.expr(), p.fieldSym()))
|
||||
|
||||
// case ODOTTYPE, ODOTTYPE2:
|
||||
// unreachable - mapped to case ODOTTYPE below by exporter
|
||||
|
||||
case ODOTTYPE:
|
||||
n := nod(ODOTTYPE, p.expr(), nil)
|
||||
n := npos(p.pos(), nod(ODOTTYPE, p.expr(), nil))
|
||||
if p.bool() {
|
||||
n.Right = p.expr()
|
||||
} else {
|
||||
@ -951,10 +964,10 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to cases below by exporter
|
||||
|
||||
case OINDEX:
|
||||
return nod(op, p.expr(), p.expr())
|
||||
return npos(p.pos(), nod(op, p.expr(), p.expr()))
|
||||
|
||||
case OSLICE, OSLICE3:
|
||||
n := nod(op, p.expr(), nil)
|
||||
n := npos(p.pos(), nod(op, p.expr(), nil))
|
||||
low, high := p.exprsOrNil()
|
||||
var max *Node
|
||||
if n.Op.IsSlice3() {
|
||||
@ -967,12 +980,12 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to OCONV case below by exporter
|
||||
|
||||
case OCONV:
|
||||
n := nod(OCALL, typenod(p.typ()), nil)
|
||||
n := npos(p.pos(), nod(OCALL, typenod(p.typ()), nil))
|
||||
n.List.Set(p.exprList())
|
||||
return n
|
||||
|
||||
case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
|
||||
n := builtinCall(op)
|
||||
n := npos(p.pos(), builtinCall(op))
|
||||
n.List.Set(p.exprList())
|
||||
if op == OAPPEND {
|
||||
n.SetIsddd(p.bool())
|
||||
@ -983,31 +996,32 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to OCALL case below by exporter
|
||||
|
||||
case OCALL:
|
||||
n := nod(OCALL, p.expr(), nil)
|
||||
n := npos(p.pos(), nod(OCALL, p.expr(), nil))
|
||||
n.List.Set(p.exprList())
|
||||
n.SetIsddd(p.bool())
|
||||
return n
|
||||
|
||||
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
||||
n := builtinCall(OMAKE)
|
||||
n := npos(p.pos(), builtinCall(OMAKE))
|
||||
n.List.Append(typenod(p.typ()))
|
||||
n.List.Append(p.exprList()...)
|
||||
return n
|
||||
|
||||
// unary expressions
|
||||
case OPLUS, OMINUS, OADDR, OCOM, OIND, ONOT, ORECV:
|
||||
return nod(op, p.expr(), nil)
|
||||
return npos(p.pos(), nod(op, p.expr(), nil))
|
||||
|
||||
// binary expressions
|
||||
case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
|
||||
OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
|
||||
return nod(op, p.expr(), p.expr())
|
||||
return npos(p.pos(), nod(op, p.expr(), p.expr()))
|
||||
|
||||
case OADDSTR:
|
||||
pos := p.pos()
|
||||
list := p.exprList()
|
||||
x := list[0]
|
||||
x := npos(pos, list[0])
|
||||
for _, y := range list[1:] {
|
||||
x = nod(OADD, x, y)
|
||||
x = npos(pos, nod(OADD, x, y))
|
||||
}
|
||||
return x
|
||||
|
||||
@ -1016,7 +1030,7 @@ func (p *importer) node() *Node {
|
||||
|
||||
case ODCLCONST:
|
||||
// TODO(gri) these should not be exported in the first place
|
||||
return nod(OEMPTY, nil, nil)
|
||||
return npos(p.pos(), nod(OEMPTY, nil, nil))
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// statements
|
||||
@ -1026,9 +1040,10 @@ func (p *importer) node() *Node {
|
||||
// was always false - simply ignore in this case
|
||||
p.bool()
|
||||
}
|
||||
pos := p.pos()
|
||||
lhs := dclname(p.sym())
|
||||
typ := typenod(p.typ())
|
||||
return liststmt(variter([]*Node{lhs}, typ, nil)) // TODO(gri) avoid list creation
|
||||
return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
|
||||
|
||||
// case ODCLFIELD:
|
||||
// unimplemented
|
||||
@ -1037,10 +1052,10 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to OAS case below by exporter
|
||||
|
||||
case OAS:
|
||||
return nod(OAS, p.expr(), p.expr())
|
||||
return npos(p.pos(), nod(OAS, p.expr(), p.expr()))
|
||||
|
||||
case OASOP:
|
||||
n := nod(OASOP, nil, nil)
|
||||
n := npos(p.pos(), nod(OASOP, nil, nil))
|
||||
n.Etype = EType(p.int())
|
||||
n.Left = p.expr()
|
||||
if !p.bool() {
|
||||
@ -1055,13 +1070,13 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to OAS2 case below by exporter
|
||||
|
||||
case OAS2:
|
||||
n := nod(OAS2, nil, nil)
|
||||
n := npos(p.pos(), nod(OAS2, nil, nil))
|
||||
n.List.Set(p.exprList())
|
||||
n.Rlist.Set(p.exprList())
|
||||
return n
|
||||
|
||||
case ORETURN:
|
||||
n := nod(ORETURN, nil, nil)
|
||||
n := npos(p.pos(), nod(ORETURN, nil, nil))
|
||||
n.List.Set(p.exprList())
|
||||
return n
|
||||
|
||||
@ -1069,11 +1084,11 @@ func (p *importer) node() *Node {
|
||||
// unreachable - generated by compiler for trampolin routines (not exported)
|
||||
|
||||
case OPROC, ODEFER:
|
||||
return nod(op, p.expr(), nil)
|
||||
return npos(p.pos(), nod(op, p.expr(), nil))
|
||||
|
||||
case OIF:
|
||||
markdcl()
|
||||
n := nod(OIF, nil, nil)
|
||||
n := npos(p.pos(), nod(OIF, nil, nil))
|
||||
n.Ninit.Set(p.stmtList())
|
||||
n.Left = p.expr()
|
||||
n.Nbody.Set(p.stmtList())
|
||||
@ -1083,7 +1098,7 @@ func (p *importer) node() *Node {
|
||||
|
||||
case OFOR:
|
||||
markdcl()
|
||||
n := nod(OFOR, nil, nil)
|
||||
n := npos(p.pos(), nod(OFOR, nil, nil))
|
||||
n.Ninit.Set(p.stmtList())
|
||||
n.Left, n.Right = p.exprsOrNil()
|
||||
n.Nbody.Set(p.stmtList())
|
||||
@ -1092,7 +1107,7 @@ func (p *importer) node() *Node {
|
||||
|
||||
case ORANGE:
|
||||
markdcl()
|
||||
n := nod(ORANGE, nil, nil)
|
||||
n := npos(p.pos(), nod(ORANGE, nil, nil))
|
||||
n.List.Set(p.stmtList())
|
||||
n.Right = p.expr()
|
||||
n.Nbody.Set(p.stmtList())
|
||||
@ -1101,7 +1116,7 @@ func (p *importer) node() *Node {
|
||||
|
||||
case OSELECT, OSWITCH:
|
||||
markdcl()
|
||||
n := nod(op, nil, nil)
|
||||
n := npos(p.pos(), nod(op, nil, nil))
|
||||
n.Ninit.Set(p.stmtList())
|
||||
n.Left, _ = p.exprsOrNil()
|
||||
n.List.Set(p.stmtList())
|
||||
@ -1113,7 +1128,7 @@ func (p *importer) node() *Node {
|
||||
|
||||
case OXCASE:
|
||||
markdcl()
|
||||
n := nod(OXCASE, nil, nil)
|
||||
n := npos(p.pos(), nod(OXCASE, nil, nil))
|
||||
n.Xoffset = int64(block)
|
||||
n.List.Set(p.exprList())
|
||||
// TODO(gri) eventually we must declare variables for type switch
|
||||
@ -1126,22 +1141,23 @@ func (p *importer) node() *Node {
|
||||
// unreachable - mapped to OXFALL case below by exporter
|
||||
|
||||
case OXFALL:
|
||||
n := nod(OXFALL, nil, nil)
|
||||
n := npos(p.pos(), nod(OXFALL, nil, nil))
|
||||
n.Xoffset = int64(block)
|
||||
return n
|
||||
|
||||
case OBREAK, OCONTINUE:
|
||||
pos := p.pos()
|
||||
left, _ := p.exprsOrNil()
|
||||
if left != nil {
|
||||
left = newname(left.Sym)
|
||||
}
|
||||
return nod(op, left, nil)
|
||||
return npos(pos, nod(op, left, nil))
|
||||
|
||||
// case OEMPTY:
|
||||
// unreachable - not emitted by exporter
|
||||
|
||||
case OGOTO, OLABEL:
|
||||
n := nod(op, newname(p.expr().Sym), nil)
|
||||
n := npos(p.pos(), nod(op, newname(p.expr().Sym), nil))
|
||||
n.Sym = dclstack // context, for goto restrictions
|
||||
return n
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user