2016-03-04 17:09:08 -08:00
|
|
|
// Copyright 2016 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 syntax
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
2016-12-01 22:04:49 -08:00
|
|
|
"strconv"
|
2016-03-04 17:09:08 -08:00
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const debug = false
|
|
|
|
|
const trace = false
|
|
|
|
|
|
|
|
|
|
type parser struct {
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
file *PosBase
|
|
|
|
|
errh ErrorHandler
|
|
|
|
|
mode Mode
|
2016-03-04 17:09:08 -08:00
|
|
|
scanner
|
|
|
|
|
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
base *PosBase // current position base
|
|
|
|
|
first error // first error encountered
|
|
|
|
|
errcnt int // number of errors encountered
|
|
|
|
|
pragma Pragma // pragma flags
|
2016-12-01 22:04:49 -08:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
fnest int // function nesting level (for error handling)
|
|
|
|
|
xnest int // expression nesting level (for complit ambiguity resolution)
|
|
|
|
|
indent []byte // tracing support
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) init(file *PosBase, r io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) {
|
2018-02-20 20:14:51 -08:00
|
|
|
p.file = file
|
2016-12-01 22:04:49 -08:00
|
|
|
p.errh = errh
|
2017-04-07 15:41:45 -07:00
|
|
|
p.mode = mode
|
2016-12-02 10:44:34 -08:00
|
|
|
p.scanner.init(
|
2016-12-09 17:15:05 -08:00
|
|
|
r,
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
// Error and directive handler for scanner.
|
|
|
|
|
// Because the (line, col) positions passed to the
|
|
|
|
|
// handler is always at or after the current reading
|
|
|
|
|
// position, it is safe to use the most recent position
|
2016-12-02 10:44:34 -08:00
|
|
|
// base to compute the corresponding Pos value.
|
|
|
|
|
func(line, col uint, msg string) {
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
if msg[0] != '/' {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(p.posAt(line, col), msg)
|
2016-12-09 17:15:05 -08:00
|
|
|
return
|
2016-12-02 10:44:34 -08:00
|
|
|
}
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
|
|
|
|
|
// otherwise it must be a comment containing a line or go: directive
|
|
|
|
|
text := commentText(msg)
|
|
|
|
|
if strings.HasPrefix(text, "line ") {
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
var pos Pos // position immediately following the comment
|
|
|
|
|
if msg[1] == '/' {
|
2018-02-22 15:50:14 -08:00
|
|
|
// line comment (newline is part of the comment)
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
pos = MakePos(p.file, line+1, colbase)
|
|
|
|
|
} else {
|
|
|
|
|
// regular comment
|
|
|
|
|
// (if the comment spans multiple lines it's not
|
|
|
|
|
// a valid line directive and will be discarded
|
|
|
|
|
// by updateBase)
|
|
|
|
|
pos = MakePos(p.file, line, col+uint(len(msg)))
|
|
|
|
|
}
|
|
|
|
|
p.updateBase(pos, line, col+2+5, text[5:]) // +2 to skip over // or /*
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// go: directive (but be conservative and test)
|
|
|
|
|
if pragh != nil && strings.HasPrefix(text, "go:") {
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
p.pragma |= pragh(p.posAt(line, col+2), text) // +2 to skip over // or /*
|
2016-12-02 10:44:34 -08:00
|
|
|
}
|
|
|
|
|
},
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
directives,
|
2016-12-02 10:44:34 -08:00
|
|
|
)
|
2016-12-01 22:04:49 -08:00
|
|
|
|
2018-02-20 20:14:51 -08:00
|
|
|
p.base = file
|
2016-12-01 22:04:49 -08:00
|
|
|
p.first = nil
|
2017-10-10 16:56:56 -07:00
|
|
|
p.errcnt = 0
|
2016-12-01 22:04:49 -08:00
|
|
|
p.pragma = 0
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
p.fnest = 0
|
|
|
|
|
p.xnest = 0
|
|
|
|
|
p.indent = nil
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 15:50:14 -08:00
|
|
|
// updateBase sets the current position base to a new line base at pos.
|
|
|
|
|
// The base's filename, line, and column values are extracted from text
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
// which is positioned at (tline, tcol) (only needed for error messages).
|
|
|
|
|
func (p *parser) updateBase(pos Pos, tline, tcol uint, text string) {
|
2018-01-03 15:52:22 -08:00
|
|
|
i, n, ok := trailingDigits(text)
|
|
|
|
|
if i == 0 {
|
2016-12-09 14:28:49 -08:00
|
|
|
return // ignore (not a line directive)
|
2016-12-01 22:04:49 -08:00
|
|
|
}
|
2018-01-03 15:52:22 -08:00
|
|
|
// i > 0
|
|
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
|
// text has a suffix :xxx but xxx is not a number
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
p.errorAt(p.posAt(tline, tcol+i), "invalid line number: "+text[i:])
|
2018-01-03 15:52:22 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
var line, col uint
|
2018-01-03 15:52:22 -08:00
|
|
|
i2, n2, ok2 := trailingDigits(text[:i-1])
|
|
|
|
|
if ok2 {
|
|
|
|
|
//line filename:line:col
|
|
|
|
|
i, i2 = i2, i
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
line, col = n2, n
|
|
|
|
|
if col == 0 || col > PosMax {
|
|
|
|
|
p.errorAt(p.posAt(tline, tcol+i2), "invalid column number: "+text[i2:])
|
2018-01-03 15:52:22 -08:00
|
|
|
return
|
|
|
|
|
}
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
text = text[:i2-1] // lop off ":col"
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
} else {
|
|
|
|
|
//line filename:line
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
line = n
|
2018-01-03 15:52:22 -08:00
|
|
|
}
|
|
|
|
|
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
if line == 0 || line > PosMax {
|
|
|
|
|
p.errorAt(p.posAt(tline, tcol+i), "invalid line number: "+text[i:])
|
2016-12-01 22:04:49 -08:00
|
|
|
return
|
|
|
|
|
}
|
2018-01-03 15:52:22 -08:00
|
|
|
|
2018-02-22 15:50:14 -08:00
|
|
|
// If we have a column (//line filename:line:col form),
|
|
|
|
|
// an empty filename means to use the previous filename.
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
filename := text[:i-1] // lop off ":line"
|
2018-02-22 15:50:14 -08:00
|
|
|
if filename == "" && ok2 {
|
|
|
|
|
filename = p.base.Filename()
|
|
|
|
|
}
|
2018-01-03 15:52:22 -08:00
|
|
|
|
cmd/compile, cmd/compile/internal/syntax: print relative column info
This change enables printing of relative column information if a
prior line directive specified a valid column. If there was no
line directive, or the line directive didn't specify a column
(or the -C flag is specified), no column information is shown in
file positions.
Implementation: Column values (and line values, for that matter)
that are zero are interpreted as "unknown". A line directive that
doesn't specify a column records that as a zero column in the
respective PosBase data structure. When computing relative columns,
a relative value is zero of the base's column value is zero.
When formatting a position, a zero column value is not printed.
To make this work without special cases, the PosBase for a file
is given a concrete (non-0:0) position 1:1 with the PosBase's
line and column also being 1:1. In other words, at the position
1:1 of a file, it's relative positions are starting with 1:1 as
one would expect.
In the package syntax, this requires self-recursive PosBases for
file bases, matching what cmd/internal/src.PosBase was already
doing. In src.PosBase, file and inlining bases also need to be
based at 1:1 to indicate "known" positions.
This change completes the cmd/compiler part of the issue below.
Fixes #22662.
Change-Id: I6c3d2dee26709581fba0d0261b1d12e93f1cba1a
Reviewed-on: https://go-review.googlesource.com/97375
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-02-26 17:35:29 -08:00
|
|
|
p.base = NewLineBase(pos, filename, line, col)
|
2018-01-03 15:52:22 -08:00
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
func commentText(s string) string {
|
|
|
|
|
if s[:2] == "/*" {
|
|
|
|
|
return s[2 : len(s)-2] // lop off /* and */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// line comment (does not include newline)
|
|
|
|
|
// (on Windows, the line comment may end in \r\n)
|
|
|
|
|
i := len(s)
|
|
|
|
|
if s[i-1] == '\r' {
|
|
|
|
|
i--
|
|
|
|
|
}
|
2018-02-22 15:50:14 -08:00
|
|
|
return s[2:i] // lop off //, and \r at end, if any
|
cmd/compile/internal/syntax: implement comment reporting in scanner
R=go1.11
In order to collect comments in the AST and for error testing purposes,
the scanner needs to not only recognize and skip comments, but also be
able to report them if so desired. This change adds a mode flag to the
scanner's init function which controls the scanner behavior around
comments.
In the common case where comments are not needed, there must be no
significant overhead. Thus, comments are reported via a handler upcall
rather than being returned as a _Comment token (which the parser would
have to filter out with every scanner.next() call).
Because the handlers for error messages, directives, and comments all
look the same (they take a position and text), and because directives
look like comments, and errors never start with a '/', this change
simplifies the scanner's init call to only take one (error) handler
instead of 2 or 3 different handlers with identical signature. It is
trivial in the handler to determine if we have an error, directive,
or general comment.
Finally, because directives are comments, when reporting directives
the full comment text is returned now rather than just the directive
text. This simplifies the implementation and makes the scanner API
more regular. Furthermore, it provides important information about
the comment style used by a directive, which may matter eventually
when we fully implement /*line file:line:col*/ directives.
Change-Id: I2adbfcebecd615e4237ed3a832b6ceb9518bf09c
Reviewed-on: https://go-review.googlesource.com/88215
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-17 21:42:51 -08:00
|
|
|
}
|
|
|
|
|
|
2018-01-03 15:52:22 -08:00
|
|
|
func trailingDigits(text string) (uint, uint, bool) {
|
|
|
|
|
// Want to use LastIndexByte below but it's not defined in Go1.4 and bootstrap fails.
|
|
|
|
|
i := strings.LastIndex(text, ":") // look from right (Windows filenames may contain ':')
|
|
|
|
|
if i < 0 {
|
|
|
|
|
return 0, 0, false // no ":"
|
|
|
|
|
}
|
|
|
|
|
// i >= 0
|
|
|
|
|
n, err := strconv.ParseUint(text[i+1:], 10, 0)
|
|
|
|
|
return uint(i + 1), uint(n), err == nil
|
2016-12-01 22:04:49 -08:00
|
|
|
}
|
|
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) got(tok token) bool {
|
|
|
|
|
if p.tok == tok {
|
|
|
|
|
p.next()
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) want(tok token) {
|
|
|
|
|
if !p.got(tok) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting " + tokstring(tok))
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Error handling
|
|
|
|
|
|
2018-02-14 15:22:44 -08:00
|
|
|
// posAt returns the Pos value for (line, col) and the current position base.
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) posAt(line, col uint) Pos {
|
|
|
|
|
return MakePos(p.base, line, col)
|
2016-06-06 17:59:05 -07:00
|
|
|
}
|
|
|
|
|
|
2016-12-01 22:04:49 -08:00
|
|
|
// error reports an error at the given position.
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) errorAt(pos Pos, msg string) {
|
2016-12-02 10:44:34 -08:00
|
|
|
err := Error{pos, msg}
|
2016-12-01 22:04:49 -08:00
|
|
|
if p.first == nil {
|
|
|
|
|
p.first = err
|
|
|
|
|
}
|
2017-10-10 16:56:56 -07:00
|
|
|
p.errcnt++
|
2016-12-01 22:04:49 -08:00
|
|
|
if p.errh == nil {
|
|
|
|
|
panic(p.first)
|
|
|
|
|
}
|
|
|
|
|
p.errh(err)
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-14 15:22:44 -08:00
|
|
|
// syntaxErrorAt reports a syntax error at the given position.
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) syntaxErrorAt(pos Pos, msg string) {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
2017-10-11 11:14:30 -07:00
|
|
|
p.print("syntax error: " + msg)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-08 16:01:56 -08:00
|
|
|
if p.tok == _EOF && p.first != nil {
|
2016-03-04 17:09:08 -08:00
|
|
|
return // avoid meaningless follow-up errors
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add punctuation etc. as needed to msg
|
|
|
|
|
switch {
|
|
|
|
|
case msg == "":
|
|
|
|
|
// nothing to do
|
2018-01-10 16:05:12 -08:00
|
|
|
case strings.HasPrefix(msg, "in "), strings.HasPrefix(msg, "at "), strings.HasPrefix(msg, "after "):
|
2016-03-04 17:09:08 -08:00
|
|
|
msg = " " + msg
|
2018-01-10 16:05:12 -08:00
|
|
|
case strings.HasPrefix(msg, "expecting "):
|
2016-03-04 17:09:08 -08:00
|
|
|
msg = ", " + msg
|
|
|
|
|
default:
|
|
|
|
|
// plain error - we don't care about current token
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(pos, "syntax error: "+msg)
|
2016-03-04 17:09:08 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// determine token string
|
|
|
|
|
var tok string
|
|
|
|
|
switch p.tok {
|
2017-02-08 17:30:45 -08:00
|
|
|
case _Name, _Semi:
|
2016-03-04 17:09:08 -08:00
|
|
|
tok = p.lit
|
2016-06-06 17:59:05 -07:00
|
|
|
case _Literal:
|
|
|
|
|
tok = "literal " + p.lit
|
2016-03-04 17:09:08 -08:00
|
|
|
case _Operator:
|
|
|
|
|
tok = p.op.String()
|
|
|
|
|
case _AssignOp:
|
|
|
|
|
tok = p.op.String() + "="
|
|
|
|
|
case _IncOp:
|
|
|
|
|
tok = p.op.String()
|
|
|
|
|
tok += tok
|
|
|
|
|
default:
|
|
|
|
|
tok = tokstring(p.tok)
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(pos, "syntax error: unexpected "+tok+msg)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-10-11 11:14:30 -07:00
|
|
|
// tokstring returns the English word for selected punctuation tokens
|
|
|
|
|
// for more readable error messages.
|
|
|
|
|
func tokstring(tok token) string {
|
|
|
|
|
switch tok {
|
|
|
|
|
case _Comma:
|
|
|
|
|
return "comma"
|
|
|
|
|
case _Semi:
|
2017-10-11 16:57:39 -07:00
|
|
|
return "semicolon or newline"
|
2017-10-11 11:14:30 -07:00
|
|
|
}
|
|
|
|
|
return tok.String()
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-02 10:44:34 -08:00
|
|
|
// Convenience methods using the current token position.
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) pos() Pos { return p.posAt(p.line, p.col) }
|
2018-02-14 15:22:44 -08:00
|
|
|
func (p *parser) syntaxError(msg string) { p.syntaxErrorAt(p.pos(), msg) }
|
2016-12-01 22:04:49 -08:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
// The stopset contains keywords that start a statement.
|
|
|
|
|
// They are good synchronization points in case of syntax
|
|
|
|
|
// errors and (usually) shouldn't be skipped over.
|
|
|
|
|
const stopset uint64 = 1<<_Break |
|
|
|
|
|
1<<_Const |
|
|
|
|
|
1<<_Continue |
|
|
|
|
|
1<<_Defer |
|
|
|
|
|
1<<_Fallthrough |
|
|
|
|
|
1<<_For |
|
|
|
|
|
1<<_Go |
|
|
|
|
|
1<<_Goto |
|
|
|
|
|
1<<_If |
|
|
|
|
|
1<<_Return |
|
|
|
|
|
1<<_Select |
|
|
|
|
|
1<<_Switch |
|
|
|
|
|
1<<_Type |
|
|
|
|
|
1<<_Var
|
|
|
|
|
|
|
|
|
|
// Advance consumes tokens until it finds a token of the stopset or followlist.
|
|
|
|
|
// The stopset is only considered if we are inside a function (p.fnest > 0).
|
|
|
|
|
// The followlist is the list of valid tokens that can follow a production;
|
2017-10-11 11:14:30 -07:00
|
|
|
// if it is empty, exactly one (non-EOF) token is consumed to ensure progress.
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) advance(followlist ...token) {
|
2017-10-11 11:14:30 -07:00
|
|
|
if trace {
|
|
|
|
|
p.print(fmt.Sprintf("advance %s", followlist))
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// compute follow set
|
2017-03-24 11:43:08 -07:00
|
|
|
// (not speed critical, advance is only called in error situations)
|
2017-10-11 11:14:30 -07:00
|
|
|
var followset uint64 = 1 << _EOF // don't skip over EOF
|
|
|
|
|
if len(followlist) > 0 {
|
|
|
|
|
if p.fnest > 0 {
|
|
|
|
|
followset |= stopset
|
|
|
|
|
}
|
|
|
|
|
for _, tok := range followlist {
|
|
|
|
|
followset |= 1 << tok
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-10-11 11:14:30 -07:00
|
|
|
for !contains(followset, p.tok) {
|
|
|
|
|
if trace {
|
|
|
|
|
p.print("skip " + p.tok.String())
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
2017-10-11 11:14:30 -07:00
|
|
|
if len(followlist) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-10-11 11:14:30 -07:00
|
|
|
if trace {
|
|
|
|
|
p.print("next " + p.tok.String())
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// usage: defer p.trace(msg)()
|
|
|
|
|
func (p *parser) trace(msg string) func() {
|
2017-10-11 11:14:30 -07:00
|
|
|
p.print(msg + " (")
|
2016-03-04 17:09:08 -08:00
|
|
|
const tab = ". "
|
|
|
|
|
p.indent = append(p.indent, tab...)
|
|
|
|
|
return func() {
|
|
|
|
|
p.indent = p.indent[:len(p.indent)-len(tab)]
|
|
|
|
|
if x := recover(); x != nil {
|
|
|
|
|
panic(x) // skip print_trace
|
|
|
|
|
}
|
2017-10-11 11:14:30 -07:00
|
|
|
p.print(")")
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-11 11:14:30 -07:00
|
|
|
func (p *parser) print(msg string) {
|
|
|
|
|
fmt.Printf("%5d: %s%s\n", p.line, p.indent, msg)
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Package files
|
|
|
|
|
//
|
|
|
|
|
// Parse methods are annotated with matching Go productions as appropriate.
|
|
|
|
|
// The annotations are intended as guidelines only since a single Go grammar
|
|
|
|
|
// rule may be covered by multiple parse methods and vice versa.
|
2017-03-24 16:23:21 -07:00
|
|
|
//
|
|
|
|
|
// Excluding methods returning slices, parse methods named xOrNil may return
|
|
|
|
|
// nil; all others are expected to return a valid non-nil node.
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
// SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) fileOrNil() *File {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
|
|
|
|
defer p.trace("file")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f := new(File)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
// PackageClause
|
2016-06-06 17:59:05 -07:00
|
|
|
if !p.got(_Package) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("package statement must be first")
|
2016-06-06 17:59:05 -07:00
|
|
|
return nil
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
f.PkgName = p.name()
|
|
|
|
|
p.want(_Semi)
|
|
|
|
|
|
|
|
|
|
// don't bother continuing if package clause has errors
|
2016-11-08 16:01:56 -08:00
|
|
|
if p.first != nil {
|
2016-03-04 17:09:08 -08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// { ImportDecl ";" }
|
|
|
|
|
for p.got(_Import) {
|
|
|
|
|
f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
|
|
|
|
|
p.want(_Semi)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// { TopLevelDecl ";" }
|
|
|
|
|
for p.tok != _EOF {
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Const:
|
|
|
|
|
p.next()
|
|
|
|
|
f.DeclList = p.appendGroup(f.DeclList, p.constDecl)
|
|
|
|
|
|
|
|
|
|
case _Type:
|
|
|
|
|
p.next()
|
|
|
|
|
f.DeclList = p.appendGroup(f.DeclList, p.typeDecl)
|
|
|
|
|
|
|
|
|
|
case _Var:
|
|
|
|
|
p.next()
|
|
|
|
|
f.DeclList = p.appendGroup(f.DeclList, p.varDecl)
|
|
|
|
|
|
|
|
|
|
case _Func:
|
|
|
|
|
p.next()
|
2017-03-24 16:23:21 -07:00
|
|
|
if d := p.funcDeclOrNil(); d != nil {
|
|
|
|
|
f.DeclList = append(f.DeclList, d)
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
default:
|
2017-03-24 16:23:21 -07:00
|
|
|
if p.tok == _Lbrace && len(f.DeclList) > 0 && isEmptyFuncDecl(f.DeclList[len(f.DeclList)-1]) {
|
2016-03-04 17:09:08 -08:00
|
|
|
// opening { of function declaration on next line
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("unexpected semicolon or newline before {")
|
2016-03-04 17:09:08 -08:00
|
|
|
} else {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("non-declaration statement outside function body")
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
p.advance(_Const, _Type, _Var, _Func)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 16:31:53 -07:00
|
|
|
// Reset p.pragma BEFORE advancing to the next token (consuming ';')
|
|
|
|
|
// since comments before may set pragmas for the next function decl.
|
|
|
|
|
p.pragma = 0
|
|
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok != _EOF && !p.got(_Semi) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("after top level declaration")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Const, _Type, _Var, _Func)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// p.tok == _EOF
|
|
|
|
|
|
|
|
|
|
f.Lines = p.source.line
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
func isEmptyFuncDecl(dcl Decl) bool {
|
2016-03-04 17:09:08 -08:00
|
|
|
f, ok := dcl.(*FuncDecl)
|
|
|
|
|
return ok && f.Body == nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Declarations
|
|
|
|
|
|
2017-10-11 16:57:39 -07:00
|
|
|
// list parses a possibly empty, sep-separated list, optionally
|
|
|
|
|
// followed by sep and enclosed by ( and ) or { and }. open is
|
|
|
|
|
// one of _Lparen, or _Lbrace, sep is one of _Comma or _Semi,
|
|
|
|
|
// and close is expected to be the (closing) opposite of open.
|
|
|
|
|
// For each list element, f is called. After f returns true, no
|
|
|
|
|
// more list elements are accepted. list returns the position
|
|
|
|
|
// of the closing token.
|
|
|
|
|
//
|
|
|
|
|
// list = "(" { f sep } ")" |
|
|
|
|
|
// "{" { f sep } "}" . // sep is optional before ")" or "}"
|
|
|
|
|
//
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) list(open, sep, close token, f func() bool) Pos {
|
2017-10-11 16:57:39 -07:00
|
|
|
p.want(open)
|
|
|
|
|
|
|
|
|
|
var done bool
|
|
|
|
|
for p.tok != _EOF && p.tok != close && !done {
|
|
|
|
|
done = f()
|
2017-10-16 18:01:47 -07:00
|
|
|
// sep is optional before close
|
|
|
|
|
if !p.got(sep) && p.tok != close {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError(fmt.Sprintf("expecting %s or %s", tokstring(sep), tokstring(close)))
|
2017-10-16 17:17:40 -07:00
|
|
|
p.advance(_Rparen, _Rbrack, _Rbrace)
|
|
|
|
|
if p.tok != close {
|
2017-10-16 18:01:47 -07:00
|
|
|
// position could be better but we had an error so we don't care
|
2017-10-16 17:17:40 -07:00
|
|
|
return p.pos()
|
|
|
|
|
}
|
2017-10-11 16:57:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pos := p.pos()
|
|
|
|
|
p.want(close)
|
|
|
|
|
return pos
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// appendGroup(f) = f | "(" { f ";" } ")" . // ";" is optional before ")"
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) appendGroup(list []Decl, f func(*Group) Decl) []Decl {
|
2017-10-11 16:57:39 -07:00
|
|
|
if p.tok == _Lparen {
|
2016-03-04 17:09:08 -08:00
|
|
|
g := new(Group)
|
2017-10-11 16:57:39 -07:00
|
|
|
p.list(_Lparen, _Semi, _Rparen, func() bool {
|
2017-03-24 16:23:21 -07:00
|
|
|
list = append(list, f(g))
|
2017-10-11 16:57:39 -07:00
|
|
|
return false
|
|
|
|
|
})
|
2017-03-24 16:23:21 -07:00
|
|
|
} else {
|
|
|
|
|
list = append(list, f(nil))
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
if debug {
|
|
|
|
|
for _, d := range list {
|
|
|
|
|
if d == nil {
|
|
|
|
|
panic("nil list entry")
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-24 11:43:08 -07:00
|
|
|
}
|
2017-03-24 16:23:21 -07:00
|
|
|
|
2017-03-24 11:43:08 -07:00
|
|
|
return list
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
// ImportSpec = [ "." | PackageName ] ImportPath .
|
|
|
|
|
// ImportPath = string_lit .
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) importDecl(group *Group) Decl {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("importDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d := new(ImportDecl)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
d.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Name:
|
|
|
|
|
d.LocalPkgName = p.name()
|
|
|
|
|
case _Dot:
|
2017-03-24 16:23:21 -07:00
|
|
|
d.LocalPkgName = p.newName(".")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
|
|
|
|
}
|
2017-03-24 11:43:08 -07:00
|
|
|
d.Path = p.oliteral()
|
|
|
|
|
if d.Path == nil {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("missing import path")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Semi, _Rparen)
|
2017-03-24 11:43:08 -07:00
|
|
|
return nil
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
d.Group = group
|
|
|
|
|
|
|
|
|
|
return d
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
// ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) constDecl(group *Group) Decl {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("constDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d := new(ConstDecl)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
d.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
d.NameList = p.nameList(p.name())
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok != _EOF && p.tok != _Semi && p.tok != _Rparen {
|
2017-03-24 16:23:21 -07:00
|
|
|
d.Type = p.typeOrNil()
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.got(_Assign) {
|
|
|
|
|
d.Values = p.exprList()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
d.Group = group
|
|
|
|
|
|
|
|
|
|
return d
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-16 16:28:30 -08:00
|
|
|
// TypeSpec = identifier [ "=" ] Type .
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) typeDecl(group *Group) Decl {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("typeDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d := new(TypeDecl)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
d.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
d.Name = p.name()
|
2016-12-16 16:28:30 -08:00
|
|
|
d.Alias = p.got(_Assign)
|
2017-03-24 16:23:21 -07:00
|
|
|
d.Type = p.typeOrNil()
|
2016-03-04 17:09:08 -08:00
|
|
|
if d.Type == nil {
|
2017-03-24 16:23:21 -07:00
|
|
|
d.Type = p.bad()
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("in type declaration")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Semi, _Rparen)
|
|
|
|
|
}
|
|
|
|
|
d.Group = group
|
cmd/compile: add go:notinheap type pragma
This adds a //go:notinheap pragma for declarations of types that must
not be heap allocated. We ensure these rules by disallowing new(T),
make([]T), append([]T), or implicit allocation of T, by disallowing
conversions to notinheap types, and by propagating notinheap to any
struct or array that contains notinheap elements.
The utility of this pragma is that we can eliminate write barriers for
writes to pointers to go:notinheap types, since the write barrier is
guaranteed to be a no-op. This will let us mark several scheduler and
memory allocator structures as go:notinheap, which will let us
disallow write barriers in the scheduler and memory allocator much
more thoroughly and also eliminate some problematic hybrid write
barriers.
This also makes go:nowritebarrierrec and go:yeswritebarrierrec much
more powerful. Currently we use go:nowritebarrier all over the place,
but it's almost never what you actually want: when write barriers are
illegal, they're typically illegal for a whole dynamic scope. Partly
this is because go:nowritebarrier has been around longer, but it's
also because go:nowritebarrierrec couldn't be used in situations that
had no-op write barriers or where some nested scope did allow write
barriers. go:notinheap eliminates many no-op write barriers and
go:yeswritebarrierrec makes it possible to opt back in to write
barriers, so these two changes will let us use go:nowritebarrierrec
far more liberally.
This updates #13386, which is about controlling pointers from non-GC'd
memory to GC'd memory. That would require some additional pragma (or
pragmas), but could build on this pragma.
Change-Id: I6314f8f4181535dd166887c9ec239977b54940bd
Reviewed-on: https://go-review.googlesource.com/30939
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2016-10-11 22:53:27 -04:00
|
|
|
d.Pragma = p.pragma
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
return d
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
// VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
|
2016-03-04 17:09:08 -08:00
|
|
|
func (p *parser) varDecl(group *Group) Decl {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("varDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d := new(VarDecl)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
d.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
d.NameList = p.nameList(p.name())
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.got(_Assign) {
|
|
|
|
|
d.Values = p.exprList()
|
|
|
|
|
} else {
|
|
|
|
|
d.Type = p.type_()
|
|
|
|
|
if p.got(_Assign) {
|
|
|
|
|
d.Values = p.exprList()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
d.Group = group
|
|
|
|
|
|
|
|
|
|
return d
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
// FunctionDecl = "func" FunctionName ( Function | Signature ) .
|
2016-03-04 17:09:08 -08:00
|
|
|
// FunctionName = identifier .
|
|
|
|
|
// Function = Signature FunctionBody .
|
|
|
|
|
// MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
|
|
|
|
|
// Receiver = Parameters .
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) funcDeclOrNil() *FuncDecl {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
|
|
|
|
defer p.trace("funcDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
f := new(FuncDecl)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = p.pos()
|
2016-11-04 16:27:31 -07:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok == _Lparen {
|
2016-11-04 16:27:31 -07:00
|
|
|
rcvr := p.paramList()
|
|
|
|
|
switch len(rcvr) {
|
2016-03-04 17:09:08 -08:00
|
|
|
case 0:
|
|
|
|
|
p.error("method has no receiver")
|
|
|
|
|
default:
|
|
|
|
|
p.error("method has multiple receivers")
|
2017-03-24 11:43:08 -07:00
|
|
|
fallthrough
|
|
|
|
|
case 1:
|
|
|
|
|
f.Recv = rcvr[0]
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.tok != _Name {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting name or (")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Lbrace, _Semi)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
f.Name = p.name()
|
2016-03-04 17:09:08 -08:00
|
|
|
f.Type = p.funcType()
|
2017-03-21 22:23:15 -07:00
|
|
|
if p.tok == _Lbrace {
|
2017-10-10 16:12:52 -07:00
|
|
|
f.Body = p.funcBody()
|
2017-03-16 10:43:54 -07:00
|
|
|
}
|
2016-08-30 16:31:53 -07:00
|
|
|
f.Pragma = p.pragma
|
2016-08-16 13:33:29 -07:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-10 16:12:52 -07:00
|
|
|
func (p *parser) funcBody() *BlockStmt {
|
2017-10-10 16:56:56 -07:00
|
|
|
p.fnest++
|
|
|
|
|
errcnt := p.errcnt
|
2017-10-10 16:12:52 -07:00
|
|
|
body := p.blockStmt("")
|
2017-10-10 16:56:56 -07:00
|
|
|
p.fnest--
|
|
|
|
|
|
|
|
|
|
// Don't check branches if there were syntax errors in the function
|
|
|
|
|
// as it may lead to spurious errors (e.g., see test/switch2.go) or
|
|
|
|
|
// possibly crashes due to incomplete syntax trees.
|
|
|
|
|
if p.mode&CheckBranches != 0 && errcnt == p.errcnt {
|
2017-10-10 16:12:52 -07:00
|
|
|
checkBranches(body, p.errh)
|
|
|
|
|
}
|
2017-10-10 16:56:56 -07:00
|
|
|
|
2017-10-10 16:12:52 -07:00
|
|
|
return body
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Expressions
|
|
|
|
|
|
|
|
|
|
func (p *parser) expr() Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("expr")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p.binaryExpr(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Expression = UnaryExpr | Expression binary_op Expression .
|
|
|
|
|
func (p *parser) binaryExpr(prec int) Expr {
|
|
|
|
|
// don't trace binaryExpr - only leads to overly nested trace output
|
|
|
|
|
|
|
|
|
|
x := p.unaryExpr()
|
|
|
|
|
for (p.tok == _Operator || p.tok == _Star) && p.prec > prec {
|
|
|
|
|
t := new(Operation)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
t.Op = p.op
|
|
|
|
|
t.X = x
|
|
|
|
|
tprec := p.prec
|
|
|
|
|
p.next()
|
|
|
|
|
t.Y = p.binaryExpr(tprec)
|
|
|
|
|
x = t
|
|
|
|
|
}
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
|
|
|
|
|
func (p *parser) unaryExpr() Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("unaryExpr")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Operator, _Star:
|
|
|
|
|
switch p.op {
|
|
|
|
|
case Mul, Add, Sub, Not, Xor:
|
|
|
|
|
x := new(Operation)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
x.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
x.Op = p.op
|
|
|
|
|
p.next()
|
|
|
|
|
x.X = p.unaryExpr()
|
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
case And:
|
|
|
|
|
x := new(Operation)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
x.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
x.Op = And
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
// unaryExpr may have returned a parenthesized composite literal
|
|
|
|
|
// (see comment in operand) - remove parentheses if any
|
|
|
|
|
x.X = unparen(p.unaryExpr())
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
case _Arrow:
|
2016-03-04 17:09:08 -08:00
|
|
|
// receive op (<-x) or receive-only channel (<-chan E)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
|
|
|
|
|
|
|
|
|
// If the next token is _Chan we still don't know if it is
|
|
|
|
|
// a channel (<-chan int) or a receive op (<-chan int(ch)).
|
|
|
|
|
// We only know once we have found the end of the unaryExpr.
|
|
|
|
|
|
|
|
|
|
x := p.unaryExpr()
|
|
|
|
|
|
|
|
|
|
// There are two cases:
|
|
|
|
|
//
|
|
|
|
|
// <-chan... => <-x is a channel type
|
|
|
|
|
// <-x => <-x is a receive operation
|
|
|
|
|
//
|
|
|
|
|
// In the first case, <- must be re-associated with
|
|
|
|
|
// the channel type parsed already:
|
|
|
|
|
//
|
|
|
|
|
// <-(chan E) => (<-chan E)
|
|
|
|
|
// <-(chan<-E) => (<-chan (<-E))
|
|
|
|
|
|
2016-06-06 17:59:05 -07:00
|
|
|
if _, ok := x.(*ChanType); ok {
|
2016-03-04 17:09:08 -08:00
|
|
|
// x is a channel type => re-associate <-
|
|
|
|
|
dir := SendOnly
|
|
|
|
|
t := x
|
2016-06-06 17:59:05 -07:00
|
|
|
for dir == SendOnly {
|
|
|
|
|
c, ok := t.(*ChanType)
|
|
|
|
|
if !ok {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
dir = c.Dir
|
2016-03-04 17:09:08 -08:00
|
|
|
if dir == RecvOnly {
|
|
|
|
|
// t is type <-chan E but <-<-chan E is not permitted
|
|
|
|
|
// (report same error as for "type _ <-<-chan E")
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("unexpected <-, expecting chan")
|
2016-03-04 17:09:08 -08:00
|
|
|
// already progressed, no need to advance
|
|
|
|
|
}
|
2016-06-06 17:59:05 -07:00
|
|
|
c.Dir = RecvOnly
|
|
|
|
|
t = c.Elem
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
if dir == SendOnly {
|
|
|
|
|
// channel dir is <- but channel element E is not a channel
|
|
|
|
|
// (report same error as for "type _ <-chan<-E")
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError(fmt.Sprintf("unexpected %s, expecting chan", String(t)))
|
2016-03-04 17:09:08 -08:00
|
|
|
// already progressed, no need to advance
|
|
|
|
|
}
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// x is not a channel type => we have a receive op
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
o := new(Operation)
|
|
|
|
|
o.pos = pos
|
|
|
|
|
o.Op = Recv
|
|
|
|
|
o.X = x
|
|
|
|
|
return o
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2016-06-06 17:59:05 -07:00
|
|
|
// TODO(mdempsky): We need parens here so we can report an
|
|
|
|
|
// error for "(x) := true". It should be possible to detect
|
|
|
|
|
// and reject that more efficiently though.
|
|
|
|
|
return p.pexpr(true)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// callStmt parses call-like statements that can be preceded by 'defer' and 'go'.
|
|
|
|
|
func (p *parser) callStmt() *CallStmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("callStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(CallStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2017-02-09 16:00:23 -08:00
|
|
|
s.Tok = p.tok // _Defer or _Go
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
|
|
|
|
|
|
|
|
|
x := p.pexpr(p.tok == _Lparen) // keep_parens so we can report error below
|
2017-03-24 16:23:21 -07:00
|
|
|
if t := unparen(x); t != x {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(x.Pos(), fmt.Sprintf("expression in %s must not be parenthesized", s.Tok))
|
2016-03-04 17:09:08 -08:00
|
|
|
// already progressed, no need to advance
|
2017-03-24 16:23:21 -07:00
|
|
|
x = t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cx, ok := x.(*CallExpr)
|
|
|
|
|
if !ok {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(x.Pos(), fmt.Sprintf("expression in %s must be function call", s.Tok))
|
2016-03-04 17:09:08 -08:00
|
|
|
// already progressed, no need to advance
|
2017-06-26 11:12:43 -07:00
|
|
|
cx = new(CallExpr)
|
2017-03-24 16:23:21 -07:00
|
|
|
cx.pos = x.Pos()
|
2018-02-14 16:57:28 -08:00
|
|
|
cx.Fun = x // assume common error of missing parentheses (function invocation)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
s.Call = cx
|
|
|
|
|
return s
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Operand = Literal | OperandName | MethodExpr | "(" Expression ")" .
|
|
|
|
|
// Literal = BasicLit | CompositeLit | FunctionLit .
|
|
|
|
|
// BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
|
|
|
|
|
// OperandName = identifier | QualifiedIdent.
|
|
|
|
|
func (p *parser) operand(keep_parens bool) Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("operand " + p.tok.String())()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Name:
|
|
|
|
|
return p.name()
|
|
|
|
|
|
|
|
|
|
case _Literal:
|
|
|
|
|
return p.oliteral()
|
|
|
|
|
|
|
|
|
|
case _Lparen:
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
|
|
|
|
p.xnest++
|
2017-02-22 13:43:23 -08:00
|
|
|
x := p.expr()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.xnest--
|
|
|
|
|
p.want(_Rparen)
|
|
|
|
|
|
|
|
|
|
// Optimization: Record presence of ()'s only where needed
|
|
|
|
|
// for error reporting. Don't bother in other cases; it is
|
|
|
|
|
// just a waste of memory and time.
|
|
|
|
|
|
|
|
|
|
// Parentheses are not permitted on lhs of := .
|
|
|
|
|
// switch x.Op {
|
|
|
|
|
// case ONAME, ONONAME, OPACK, OTYPE, OLITERAL, OTYPESW:
|
|
|
|
|
// keep_parens = true
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// Parentheses are not permitted around T in a composite
|
|
|
|
|
// literal T{}. If the next token is a {, assume x is a
|
|
|
|
|
// composite literal type T (it may not be, { could be
|
|
|
|
|
// the opening brace of a block, but we don't know yet).
|
|
|
|
|
if p.tok == _Lbrace {
|
|
|
|
|
keep_parens = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parentheses are also not permitted around the expression
|
|
|
|
|
// in a go/defer statement. In that case, operand is called
|
|
|
|
|
// with keep_parens set.
|
|
|
|
|
if keep_parens {
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
px := new(ParenExpr)
|
|
|
|
|
px.pos = pos
|
|
|
|
|
px.X = x
|
|
|
|
|
x = px
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
case _Func:
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
|
|
|
|
t := p.funcType()
|
2017-03-21 22:23:15 -07:00
|
|
|
if p.tok == _Lbrace {
|
2016-03-04 17:09:08 -08:00
|
|
|
p.xnest++
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
f := new(FuncLit)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
f.Type = t
|
2017-10-10 16:12:52 -07:00
|
|
|
f.Body = p.funcBody()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
p.xnest--
|
|
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
case _Lbrack, _Chan, _Map, _Struct, _Interface:
|
|
|
|
|
return p.type_() // othertype
|
|
|
|
|
|
|
|
|
|
default:
|
2017-03-24 16:23:21 -07:00
|
|
|
x := p.bad()
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting expression")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance()
|
2017-03-24 16:23:21 -07:00
|
|
|
return x
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Syntactically, composite literals are operands. Because a complit
|
|
|
|
|
// type may be a qualified identifier which is handled by pexpr
|
|
|
|
|
// (together with selector expressions), complits are parsed there
|
|
|
|
|
// as well (operand is only called from pexpr).
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PrimaryExpr =
|
|
|
|
|
// Operand |
|
|
|
|
|
// Conversion |
|
|
|
|
|
// PrimaryExpr Selector |
|
|
|
|
|
// PrimaryExpr Index |
|
|
|
|
|
// PrimaryExpr Slice |
|
|
|
|
|
// PrimaryExpr TypeAssertion |
|
|
|
|
|
// PrimaryExpr Arguments .
|
|
|
|
|
//
|
|
|
|
|
// Selector = "." identifier .
|
|
|
|
|
// Index = "[" Expression "]" .
|
|
|
|
|
// Slice = "[" ( [ Expression ] ":" [ Expression ] ) |
|
|
|
|
|
// ( [ Expression ] ":" Expression ":" Expression )
|
|
|
|
|
// "]" .
|
|
|
|
|
// TypeAssertion = "." "(" Type ")" .
|
|
|
|
|
// Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
|
|
|
|
|
func (p *parser) pexpr(keep_parens bool) Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("pexpr")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x := p.operand(keep_parens)
|
|
|
|
|
|
|
|
|
|
loop:
|
|
|
|
|
for {
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
switch p.tok {
|
|
|
|
|
case _Dot:
|
|
|
|
|
p.next()
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Name:
|
|
|
|
|
// pexpr '.' sym
|
|
|
|
|
t := new(SelectorExpr)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.X = x
|
|
|
|
|
t.Sel = p.name()
|
|
|
|
|
x = t
|
|
|
|
|
|
|
|
|
|
case _Lparen:
|
|
|
|
|
p.next()
|
|
|
|
|
if p.got(_Type) {
|
|
|
|
|
t := new(TypeSwitchGuard)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.X = x
|
|
|
|
|
x = t
|
|
|
|
|
} else {
|
|
|
|
|
t := new(AssertExpr)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.X = x
|
|
|
|
|
t.Type = p.expr()
|
|
|
|
|
x = t
|
|
|
|
|
}
|
|
|
|
|
p.want(_Rparen)
|
|
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting name or (")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Semi, _Rparen)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case _Lbrack:
|
|
|
|
|
p.next()
|
|
|
|
|
p.xnest++
|
|
|
|
|
|
|
|
|
|
var i Expr
|
|
|
|
|
if p.tok != _Colon {
|
|
|
|
|
i = p.expr()
|
|
|
|
|
if p.got(_Rbrack) {
|
|
|
|
|
// x[i]
|
|
|
|
|
t := new(IndexExpr)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.X = x
|
|
|
|
|
t.Index = i
|
|
|
|
|
x = t
|
|
|
|
|
p.xnest--
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// x[i:...
|
|
|
|
|
t := new(SliceExpr)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.X = x
|
|
|
|
|
t.Index[0] = i
|
|
|
|
|
p.want(_Colon)
|
|
|
|
|
if p.tok != _Colon && p.tok != _Rbrack {
|
|
|
|
|
// x[i:j...
|
|
|
|
|
t.Index[1] = p.expr()
|
|
|
|
|
}
|
|
|
|
|
if p.got(_Colon) {
|
2016-08-16 13:33:29 -07:00
|
|
|
t.Full = true
|
2016-03-04 17:09:08 -08:00
|
|
|
// x[i:j:...]
|
|
|
|
|
if t.Index[1] == nil {
|
|
|
|
|
p.error("middle index required in 3-index slice")
|
|
|
|
|
}
|
|
|
|
|
if p.tok != _Rbrack {
|
|
|
|
|
// x[i:j:k...
|
|
|
|
|
t.Index[2] = p.expr()
|
|
|
|
|
} else {
|
|
|
|
|
p.error("final index required in 3-index slice")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
p.want(_Rbrack)
|
|
|
|
|
|
|
|
|
|
x = t
|
|
|
|
|
p.xnest--
|
|
|
|
|
|
|
|
|
|
case _Lparen:
|
2017-10-11 15:02:10 -07:00
|
|
|
t := new(CallExpr)
|
|
|
|
|
t.pos = pos
|
|
|
|
|
t.Fun = x
|
|
|
|
|
t.ArgList, t.HasDots = p.argList()
|
|
|
|
|
x = t
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
case _Lbrace:
|
|
|
|
|
// operand may have returned a parenthesized complit
|
|
|
|
|
// type; accept it but complain if we have a complit
|
|
|
|
|
t := unparen(x)
|
2017-02-22 13:43:23 -08:00
|
|
|
// determine if '{' belongs to a composite literal or a block statement
|
2016-03-04 17:09:08 -08:00
|
|
|
complit_ok := false
|
|
|
|
|
switch t.(type) {
|
|
|
|
|
case *Name, *SelectorExpr:
|
|
|
|
|
if p.xnest >= 0 {
|
2017-02-22 13:43:23 -08:00
|
|
|
// x is considered a composite literal type
|
2016-03-04 17:09:08 -08:00
|
|
|
complit_ok = true
|
|
|
|
|
}
|
|
|
|
|
case *ArrayType, *SliceType, *StructType, *MapType:
|
|
|
|
|
// x is a comptype
|
|
|
|
|
complit_ok = true
|
|
|
|
|
}
|
|
|
|
|
if !complit_ok {
|
|
|
|
|
break loop
|
|
|
|
|
}
|
|
|
|
|
if t != x {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("cannot parenthesize type in composite literal")
|
2016-03-04 17:09:08 -08:00
|
|
|
// already progressed, no need to advance
|
|
|
|
|
}
|
|
|
|
|
n := p.complitexpr()
|
|
|
|
|
n.Type = x
|
|
|
|
|
x = n
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break loop
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Element = Expression | LiteralValue .
|
|
|
|
|
func (p *parser) bare_complitexpr() Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("bare_complitexpr")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.tok == _Lbrace {
|
|
|
|
|
// '{' start_complit braced_keyval_list '}'
|
|
|
|
|
return p.complitexpr()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p.expr()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// LiteralValue = "{" [ ElementList [ "," ] ] "}" .
|
|
|
|
|
func (p *parser) complitexpr() *CompositeLit {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("complitexpr")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x := new(CompositeLit)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
x.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
p.xnest++
|
2017-10-11 16:57:39 -07:00
|
|
|
x.Rbrace = p.list(_Lbrace, _Comma, _Rbrace, func() bool {
|
2016-03-04 17:09:08 -08:00
|
|
|
// value
|
|
|
|
|
e := p.bare_complitexpr()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
if p.tok == _Colon {
|
2016-03-04 17:09:08 -08:00
|
|
|
// key ':' value
|
|
|
|
|
l := new(KeyValueExpr)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
l.pos = p.pos()
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
l.Key = e
|
|
|
|
|
l.Value = p.bare_complitexpr()
|
|
|
|
|
e = l
|
|
|
|
|
x.NKeys++
|
|
|
|
|
}
|
|
|
|
|
x.ElemList = append(x.ElemList, e)
|
2017-10-11 16:57:39 -07:00
|
|
|
return false
|
|
|
|
|
})
|
2016-03-04 17:09:08 -08:00
|
|
|
p.xnest--
|
|
|
|
|
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Types
|
|
|
|
|
|
|
|
|
|
func (p *parser) type_() Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("type_")()
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
typ := p.typeOrNil()
|
|
|
|
|
if typ == nil {
|
|
|
|
|
typ = p.bad()
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting type")
|
2018-01-16 17:00:51 -08:00
|
|
|
p.advance(_Comma, _Colon, _Semi, _Rparen, _Rbrack, _Rbrace)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
return typ
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func newIndirect(pos Pos, typ Expr) Expr {
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
o := new(Operation)
|
|
|
|
|
o.pos = pos
|
|
|
|
|
o.Op = Mul
|
|
|
|
|
o.X = typ
|
|
|
|
|
return o
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
// typeOrNil is like type_ but it returns nil if there was no type
|
2016-03-04 17:09:08 -08:00
|
|
|
// instead of reporting an error.
|
|
|
|
|
//
|
|
|
|
|
// Type = TypeName | TypeLit | "(" Type ")" .
|
|
|
|
|
// TypeName = identifier | QualifiedIdent .
|
|
|
|
|
// TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
|
|
|
|
|
// SliceType | MapType | Channel_Type .
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) typeOrNil() Expr {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
2017-03-24 16:23:21 -07:00
|
|
|
defer p.trace("typeOrNil")()
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
switch p.tok {
|
|
|
|
|
case _Star:
|
|
|
|
|
// ptrtype
|
|
|
|
|
p.next()
|
2017-03-24 16:23:21 -07:00
|
|
|
return newIndirect(pos, p.type_())
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
case _Arrow:
|
2016-03-04 17:09:08 -08:00
|
|
|
// recvchantype
|
|
|
|
|
p.next()
|
|
|
|
|
p.want(_Chan)
|
|
|
|
|
t := new(ChanType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.Dir = RecvOnly
|
|
|
|
|
t.Elem = p.chanElem()
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
case _Func:
|
|
|
|
|
// fntype
|
|
|
|
|
p.next()
|
|
|
|
|
return p.funcType()
|
|
|
|
|
|
|
|
|
|
case _Lbrack:
|
|
|
|
|
// '[' oexpr ']' ntype
|
|
|
|
|
// '[' _DotDotDot ']' ntype
|
|
|
|
|
p.next()
|
|
|
|
|
p.xnest++
|
|
|
|
|
if p.got(_Rbrack) {
|
|
|
|
|
// []T
|
|
|
|
|
p.xnest--
|
|
|
|
|
t := new(SliceType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.Elem = p.type_()
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// [n]T
|
|
|
|
|
t := new(ArrayType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
if !p.got(_DotDotDot) {
|
|
|
|
|
t.Len = p.expr()
|
|
|
|
|
}
|
|
|
|
|
p.want(_Rbrack)
|
|
|
|
|
p.xnest--
|
|
|
|
|
t.Elem = p.type_()
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
case _Chan:
|
|
|
|
|
// _Chan non_recvchantype
|
|
|
|
|
// _Chan _Comm ntype
|
|
|
|
|
p.next()
|
|
|
|
|
t := new(ChanType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-11-04 16:27:31 -07:00
|
|
|
if p.got(_Arrow) {
|
2016-03-04 17:09:08 -08:00
|
|
|
t.Dir = SendOnly
|
|
|
|
|
}
|
|
|
|
|
t.Elem = p.chanElem()
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
case _Map:
|
|
|
|
|
// _Map '[' ntype ']' ntype
|
|
|
|
|
p.next()
|
|
|
|
|
p.want(_Lbrack)
|
|
|
|
|
t := new(MapType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
t.Key = p.type_()
|
|
|
|
|
p.want(_Rbrack)
|
|
|
|
|
t.Value = p.type_()
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
case _Struct:
|
|
|
|
|
return p.structType()
|
|
|
|
|
|
|
|
|
|
case _Interface:
|
|
|
|
|
return p.interfaceType()
|
|
|
|
|
|
|
|
|
|
case _Name:
|
|
|
|
|
return p.dotname(p.name())
|
|
|
|
|
|
|
|
|
|
case _Lparen:
|
|
|
|
|
p.next()
|
|
|
|
|
t := p.type_()
|
|
|
|
|
p.want(_Rparen)
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) funcType() *FuncType {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("funcType")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typ := new(FuncType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
typ.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
typ.ParamList = p.paramList()
|
|
|
|
|
typ.ResultList = p.funcResult()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
return typ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) chanElem() Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("chanElem")()
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
typ := p.typeOrNil()
|
|
|
|
|
if typ == nil {
|
|
|
|
|
typ = p.bad()
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("missing channel element type")
|
2017-03-24 16:23:21 -07:00
|
|
|
// assume element type is simply absent - don't advance
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
return typ
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) dotname(name *Name) Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("dotname")()
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
if p.tok == _Dot {
|
2016-03-04 17:09:08 -08:00
|
|
|
s := new(SelectorExpr)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
s.X = name
|
|
|
|
|
s.Sel = p.name()
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
return name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StructType = "struct" "{" { FieldDecl ";" } "}" .
|
|
|
|
|
func (p *parser) structType() *StructType {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("structType")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typ := new(StructType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
typ.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
p.want(_Struct)
|
2017-10-11 16:57:39 -07:00
|
|
|
p.list(_Lbrace, _Semi, _Rbrace, func() bool {
|
2016-03-04 17:09:08 -08:00
|
|
|
p.fieldDecl(typ)
|
2017-10-11 16:57:39 -07:00
|
|
|
return false
|
|
|
|
|
})
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
return typ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
|
|
|
|
|
func (p *parser) interfaceType() *InterfaceType {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("interfaceType")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typ := new(InterfaceType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
typ.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
p.want(_Interface)
|
2017-10-11 16:57:39 -07:00
|
|
|
p.list(_Lbrace, _Semi, _Rbrace, func() bool {
|
2016-03-04 17:09:08 -08:00
|
|
|
if m := p.methodDecl(); m != nil {
|
|
|
|
|
typ.MethodList = append(typ.MethodList, m)
|
|
|
|
|
}
|
2017-10-11 16:57:39 -07:00
|
|
|
return false
|
|
|
|
|
})
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
return typ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Result = Parameters | Type .
|
|
|
|
|
func (p *parser) funcResult() []*Field {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("funcResult")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.tok == _Lparen {
|
|
|
|
|
return p.paramList()
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2017-03-24 16:23:21 -07:00
|
|
|
if typ := p.typeOrNil(); typ != nil {
|
2016-03-04 17:09:08 -08:00
|
|
|
f := new(Field)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = pos
|
2017-03-24 16:23:21 -07:00
|
|
|
f.Type = typ
|
2016-03-04 17:09:08 -08:00
|
|
|
return []*Field{f}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) addField(styp *StructType, pos Pos, name *Name, typ Expr, tag *BasicLit) {
|
2016-03-04 17:09:08 -08:00
|
|
|
if tag != nil {
|
|
|
|
|
for i := len(styp.FieldList) - len(styp.TagList); i > 0; i-- {
|
|
|
|
|
styp.TagList = append(styp.TagList, nil)
|
|
|
|
|
}
|
|
|
|
|
styp.TagList = append(styp.TagList, tag)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f := new(Field)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
f.Name = name
|
|
|
|
|
f.Type = typ
|
|
|
|
|
styp.FieldList = append(styp.FieldList, f)
|
|
|
|
|
|
|
|
|
|
if debug && tag != nil && len(styp.FieldList) != len(styp.TagList) {
|
|
|
|
|
panic("inconsistent struct field list")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] .
|
|
|
|
|
// AnonymousField = [ "*" ] TypeName .
|
|
|
|
|
// Tag = string_lit .
|
|
|
|
|
func (p *parser) fieldDecl(styp *StructType) {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("fieldDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
switch p.tok {
|
|
|
|
|
case _Name:
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
name := p.name()
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok == _Dot || p.tok == _Literal || p.tok == _Semi || p.tok == _Rbrace {
|
|
|
|
|
// embed oliteral
|
|
|
|
|
typ := p.qualifiedName(name)
|
|
|
|
|
tag := p.oliteral()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.addField(styp, pos, nil, typ, tag)
|
2016-03-04 17:09:08 -08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// new_name_list ntype oliteral
|
|
|
|
|
names := p.nameList(name)
|
|
|
|
|
typ := p.type_()
|
|
|
|
|
tag := p.oliteral()
|
|
|
|
|
|
|
|
|
|
for _, name := range names {
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.addField(styp, name.Pos(), name, typ, tag)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case _Lparen:
|
|
|
|
|
p.next()
|
|
|
|
|
if p.tok == _Star {
|
|
|
|
|
// '(' '*' embed ')' oliteral
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
2017-03-24 16:23:21 -07:00
|
|
|
typ := newIndirect(pos, p.qualifiedName(nil))
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Rparen)
|
|
|
|
|
tag := p.oliteral()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.addField(styp, pos, nil, typ, tag)
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("cannot parenthesize embedded type")
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// '(' embed ')' oliteral
|
|
|
|
|
typ := p.qualifiedName(nil)
|
|
|
|
|
p.want(_Rparen)
|
|
|
|
|
tag := p.oliteral()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.addField(styp, pos, nil, typ, tag)
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("cannot parenthesize embedded type")
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case _Star:
|
|
|
|
|
p.next()
|
|
|
|
|
if p.got(_Lparen) {
|
|
|
|
|
// '*' '(' embed ')' oliteral
|
2017-03-24 16:23:21 -07:00
|
|
|
typ := newIndirect(pos, p.qualifiedName(nil))
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Rparen)
|
|
|
|
|
tag := p.oliteral()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.addField(styp, pos, nil, typ, tag)
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("cannot parenthesize embedded type")
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// '*' embed oliteral
|
2017-03-24 16:23:21 -07:00
|
|
|
typ := newIndirect(pos, p.qualifiedName(nil))
|
2016-03-04 17:09:08 -08:00
|
|
|
tag := p.oliteral()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.addField(styp, pos, nil, typ, tag)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting field name or embedded type")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Semi, _Rbrace)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) oliteral() *BasicLit {
|
|
|
|
|
if p.tok == _Literal {
|
|
|
|
|
b := new(BasicLit)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
b.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
b.Value = p.lit
|
|
|
|
|
b.Kind = p.kind
|
|
|
|
|
p.next()
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MethodSpec = MethodName Signature | InterfaceTypeName .
|
|
|
|
|
// MethodName = identifier .
|
|
|
|
|
// InterfaceTypeName = TypeName .
|
|
|
|
|
func (p *parser) methodDecl() *Field {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("methodDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Name:
|
|
|
|
|
name := p.name()
|
|
|
|
|
|
|
|
|
|
// accept potential name list but complain
|
|
|
|
|
hasNameList := false
|
|
|
|
|
for p.got(_Comma) {
|
|
|
|
|
p.name()
|
|
|
|
|
hasNameList = true
|
|
|
|
|
}
|
|
|
|
|
if hasNameList {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("name list not allowed in interface type")
|
2016-03-04 17:09:08 -08:00
|
|
|
// already progressed, no need to advance
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f := new(Field)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = name.Pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok != _Lparen {
|
|
|
|
|
// packname
|
|
|
|
|
f.Type = p.qualifiedName(name)
|
|
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f.Name = name
|
|
|
|
|
f.Type = p.funcType()
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
case _Lparen:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("cannot parenthesize embedded type")
|
2016-03-04 17:09:08 -08:00
|
|
|
f := new(Field)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = p.pos()
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
f.Type = p.qualifiedName(nil)
|
|
|
|
|
p.want(_Rparen)
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting method or interface name")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Semi, _Rbrace)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParameterDecl = [ IdentifierList ] [ "..." ] Type .
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) paramDeclOrNil() *Field {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
|
|
|
|
defer p.trace("paramDecl")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f := new(Field)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
f.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Name:
|
|
|
|
|
f.Name = p.name()
|
|
|
|
|
switch p.tok {
|
2016-11-04 16:27:31 -07:00
|
|
|
case _Name, _Star, _Arrow, _Func, _Lbrack, _Chan, _Map, _Struct, _Interface, _Lparen:
|
2016-03-04 17:09:08 -08:00
|
|
|
// sym name_or_type
|
|
|
|
|
f.Type = p.type_()
|
|
|
|
|
|
|
|
|
|
case _DotDotDot:
|
|
|
|
|
// sym dotdotdot
|
|
|
|
|
f.Type = p.dotsType()
|
|
|
|
|
|
|
|
|
|
case _Dot:
|
|
|
|
|
// name_or_type
|
|
|
|
|
// from dotname
|
|
|
|
|
f.Type = p.dotname(f.Name)
|
|
|
|
|
f.Name = nil
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
case _Arrow, _Star, _Func, _Lbrack, _Chan, _Map, _Struct, _Interface, _Lparen:
|
2016-03-04 17:09:08 -08:00
|
|
|
// name_or_type
|
|
|
|
|
f.Type = p.type_()
|
|
|
|
|
|
|
|
|
|
case _DotDotDot:
|
|
|
|
|
// dotdotdot
|
|
|
|
|
f.Type = p.dotsType()
|
|
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting )")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Comma, _Rparen)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ...Type
|
|
|
|
|
func (p *parser) dotsType() *DotsType {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("dotsType")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t := new(DotsType)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
t.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
p.want(_DotDotDot)
|
2017-03-24 16:23:21 -07:00
|
|
|
t.Elem = p.typeOrNil()
|
2016-03-04 17:09:08 -08:00
|
|
|
if t.Elem == nil {
|
2017-03-24 16:23:21 -07:00
|
|
|
t.Elem = p.bad()
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("final argument in variadic function missing type")
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parameters = "(" [ ParameterList [ "," ] ] ")" .
|
|
|
|
|
// ParameterList = ParameterDecl { "," ParameterDecl } .
|
|
|
|
|
func (p *parser) paramList() (list []*Field) {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("paramList")()
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
var named int // number of parameters that have an explicit name and type
|
2017-10-11 16:57:39 -07:00
|
|
|
p.list(_Lparen, _Comma, _Rparen, func() bool {
|
2017-03-24 16:23:21 -07:00
|
|
|
if par := p.paramDeclOrNil(); par != nil {
|
2016-03-04 17:09:08 -08:00
|
|
|
if debug && par.Name == nil && par.Type == nil {
|
|
|
|
|
panic("parameter without name or type")
|
|
|
|
|
}
|
|
|
|
|
if par.Name != nil && par.Type != nil {
|
|
|
|
|
named++
|
|
|
|
|
}
|
|
|
|
|
list = append(list, par)
|
|
|
|
|
}
|
2017-10-11 16:57:39 -07:00
|
|
|
return false
|
|
|
|
|
})
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
// distribute parameter types
|
|
|
|
|
if named == 0 {
|
|
|
|
|
// all unnamed => found names are named types
|
|
|
|
|
for _, par := range list {
|
|
|
|
|
if typ := par.Name; typ != nil {
|
|
|
|
|
par.Type = typ
|
|
|
|
|
par.Name = nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if named != len(list) {
|
|
|
|
|
// some named => all must be named
|
2017-03-24 16:23:21 -07:00
|
|
|
ok := true
|
2016-03-04 17:09:08 -08:00
|
|
|
var typ Expr
|
|
|
|
|
for i := len(list) - 1; i >= 0; i-- {
|
|
|
|
|
if par := list[i]; par.Type != nil {
|
|
|
|
|
typ = par.Type
|
|
|
|
|
if par.Name == nil {
|
2017-03-24 16:23:21 -07:00
|
|
|
ok = false
|
|
|
|
|
n := p.newName("_")
|
|
|
|
|
n.pos = typ.Pos() // correct position
|
|
|
|
|
par.Name = n
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
2017-03-24 16:23:21 -07:00
|
|
|
} else if typ != nil {
|
2016-03-04 17:09:08 -08:00
|
|
|
par.Type = typ
|
2017-03-24 16:23:21 -07:00
|
|
|
} else {
|
|
|
|
|
// par.Type == nil && typ == nil => we only have a par.Name
|
|
|
|
|
ok = false
|
|
|
|
|
t := p.bad()
|
|
|
|
|
t.pos = par.Name.Pos() // correct position
|
|
|
|
|
par.Type = t
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
2017-03-24 16:23:21 -07:00
|
|
|
if !ok {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxErrorAt(pos, "mixed named and unnamed function parameters")
|
2017-03-24 16:23:21 -07:00
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) bad() *BadExpr {
|
|
|
|
|
b := new(BadExpr)
|
|
|
|
|
b.pos = p.pos()
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Statements
|
|
|
|
|
|
|
|
|
|
// We represent x++, x-- as assignments x += ImplicitOne, x -= ImplicitOne.
|
|
|
|
|
// ImplicitOne should not be used elsewhere.
|
|
|
|
|
var ImplicitOne = &BasicLit{Value: "1"}
|
|
|
|
|
|
|
|
|
|
// SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
|
|
|
|
|
func (p *parser) simpleStmt(lhs Expr, rangeOk bool) SimpleStmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("simpleStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
if rangeOk && p.tok == _Range {
|
2016-03-04 17:09:08 -08:00
|
|
|
// _Range expr
|
|
|
|
|
if debug && lhs != nil {
|
|
|
|
|
panic("invalid call of simpleStmt")
|
|
|
|
|
}
|
2017-03-24 16:23:21 -07:00
|
|
|
return p.newRangeClause(nil, false)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if lhs == nil {
|
|
|
|
|
lhs = p.exprList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, ok := lhs.(*ListExpr); !ok && p.tok != _Assign && p.tok != _Define {
|
|
|
|
|
// expr
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
switch p.tok {
|
|
|
|
|
case _AssignOp:
|
|
|
|
|
// lhs op= rhs
|
|
|
|
|
op := p.op
|
|
|
|
|
p.next()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
return p.newAssignStmt(pos, op, lhs, p.expr())
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
case _IncOp:
|
|
|
|
|
// lhs++ or lhs--
|
|
|
|
|
op := p.op
|
|
|
|
|
p.next()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
return p.newAssignStmt(pos, op, lhs, ImplicitOne)
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2016-11-04 16:27:31 -07:00
|
|
|
case _Arrow:
|
2016-03-04 17:09:08 -08:00
|
|
|
// lhs <- rhs
|
|
|
|
|
s := new(SendStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = pos
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
s.Chan = lhs
|
|
|
|
|
s.Value = p.expr()
|
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
// expr
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s := new(ExprStmt)
|
2017-03-24 16:23:21 -07:00
|
|
|
s.pos = lhs.Pos()
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.X = lhs
|
|
|
|
|
return s
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// expr_list
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
pos := p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
switch p.tok {
|
|
|
|
|
case _Assign:
|
|
|
|
|
p.next()
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
if rangeOk && p.tok == _Range {
|
2016-03-04 17:09:08 -08:00
|
|
|
// expr_list '=' _Range expr
|
2017-03-24 16:23:21 -07:00
|
|
|
return p.newRangeClause(lhs, false)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// expr_list '=' expr_list
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
return p.newAssignStmt(pos, 0, lhs, p.exprList())
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
case _Define:
|
|
|
|
|
p.next()
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
if rangeOk && p.tok == _Range {
|
2016-03-04 17:09:08 -08:00
|
|
|
// expr_list ':=' range expr
|
2017-03-24 16:23:21 -07:00
|
|
|
return p.newRangeClause(lhs, true)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// expr_list ':=' expr_list
|
|
|
|
|
rhs := p.exprList()
|
|
|
|
|
|
|
|
|
|
if x, ok := rhs.(*TypeSwitchGuard); ok {
|
|
|
|
|
switch lhs := lhs.(type) {
|
|
|
|
|
case *Name:
|
|
|
|
|
x.Lhs = lhs
|
|
|
|
|
case *ListExpr:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(lhs.Pos(), fmt.Sprintf("cannot assign 1 value to %d variables", len(lhs.ElemList)))
|
2017-03-24 16:23:21 -07:00
|
|
|
// make the best of what we have
|
|
|
|
|
if lhs, ok := lhs.ElemList[0].(*Name); ok {
|
|
|
|
|
x.Lhs = lhs
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.errorAt(lhs.Pos(), fmt.Sprintf("invalid variable name %s in type switch", String(lhs)))
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s := new(ExprStmt)
|
|
|
|
|
s.pos = x.Pos()
|
|
|
|
|
s.X = x
|
|
|
|
|
return s
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
as := p.newAssignStmt(pos, Def, lhs, rhs)
|
2016-06-06 17:59:05 -07:00
|
|
|
return as
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting := or = or comma")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Semi, _Rbrace)
|
2017-03-24 16:23:21 -07:00
|
|
|
// make the best of what we have
|
|
|
|
|
if x, ok := lhs.(*ListExpr); ok {
|
|
|
|
|
lhs = x.ElemList[0]
|
|
|
|
|
}
|
|
|
|
|
s := new(ExprStmt)
|
|
|
|
|
s.pos = lhs.Pos()
|
|
|
|
|
s.X = lhs
|
|
|
|
|
return s
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) newRangeClause(lhs Expr, def bool) *RangeClause {
|
2016-03-04 17:09:08 -08:00
|
|
|
r := new(RangeClause)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
r.pos = p.pos()
|
|
|
|
|
p.next() // consume _Range
|
2016-03-04 17:09:08 -08:00
|
|
|
r.Lhs = lhs
|
|
|
|
|
r.Def = def
|
|
|
|
|
r.X = p.expr()
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
func (p *parser) newAssignStmt(pos Pos, op Operator, lhs, rhs Expr) *AssignStmt {
|
2016-03-04 17:09:08 -08:00
|
|
|
a := new(AssignStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
a.pos = pos
|
2016-03-04 17:09:08 -08:00
|
|
|
a.Op = op
|
|
|
|
|
a.Lhs = lhs
|
|
|
|
|
a.Rhs = rhs
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 18:03:17 -07:00
|
|
|
func (p *parser) labeledStmtOrNil(label *Name) Stmt {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
|
|
|
|
defer p.trace("labeledStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-06 17:59:05 -07:00
|
|
|
s := new(LabeledStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-06-06 17:59:05 -07:00
|
|
|
s.Label = label
|
|
|
|
|
|
|
|
|
|
p.want(_Colon)
|
|
|
|
|
|
2017-03-24 18:03:17 -07:00
|
|
|
if p.tok == _Rbrace {
|
|
|
|
|
// We expect a statement (incl. an empty statement), which must be
|
|
|
|
|
// terminated by a semicolon. Because semicolons may be omitted before
|
|
|
|
|
// an _Rbrace, seeing an _Rbrace implies an empty statement.
|
|
|
|
|
e := new(EmptyStmt)
|
|
|
|
|
e.pos = p.pos()
|
|
|
|
|
s.Stmt = e
|
|
|
|
|
return s
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 18:03:17 -07:00
|
|
|
s.Stmt = p.stmtOrNil()
|
|
|
|
|
if s.Stmt != nil {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// report error at line of ':' token
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxErrorAt(s.pos, "missing statement after label")
|
2017-03-24 18:03:17 -07:00
|
|
|
// we are already at the end of the labeled statement - no need to advance
|
|
|
|
|
return nil // avoids follow-on errors (see e.g., fixedbugs/bug274.go)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-10-10 16:12:52 -07:00
|
|
|
// context must be a non-empty string unless we know that p.tok == _Lbrace.
|
2017-03-21 22:23:15 -07:00
|
|
|
func (p *parser) blockStmt(context string) *BlockStmt {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
|
|
|
|
defer p.trace("blockStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(BlockStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2017-03-21 22:23:15 -07:00
|
|
|
|
2017-10-16 21:52:34 -07:00
|
|
|
// people coming from C may forget that braces are mandatory in Go
|
2017-03-21 22:23:15 -07:00
|
|
|
if !p.got(_Lbrace) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting { after " + context)
|
2017-03-21 22:23:15 -07:00
|
|
|
p.advance(_Name, _Rbrace)
|
2017-10-16 21:52:34 -07:00
|
|
|
s.Rbrace = p.pos() // in case we found "}"
|
|
|
|
|
if p.got(_Rbrace) {
|
|
|
|
|
return s
|
|
|
|
|
}
|
2017-03-21 22:23:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.List = p.stmtList()
|
2017-03-21 15:22:13 -07:00
|
|
|
s.Rbrace = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Rbrace)
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) declStmt(f func(*Group) Decl) *DeclStmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("declStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(DeclStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
p.next() // _Const, _Type, or _Var
|
|
|
|
|
s.DeclList = p.appendGroup(nil, f)
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) forStmt() Stmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("forStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(ForStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2017-02-13 12:48:39 -08:00
|
|
|
s.Init, s.Cond, s.Post = p.header(_For)
|
2017-03-21 22:23:15 -07:00
|
|
|
s.Body = p.blockStmt("for clause")
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-13 12:48:39 -08:00
|
|
|
func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleStmt) {
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.want(keyword)
|
2017-02-06 22:01:07 -08:00
|
|
|
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok == _Lbrace {
|
2017-02-13 12:48:39 -08:00
|
|
|
if keyword == _If {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("missing condition in if statement")
|
2017-02-13 12:48:39 -08:00
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
return
|
|
|
|
|
}
|
2017-02-22 13:43:23 -08:00
|
|
|
// p.tok != _Lbrace
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
outer := p.xnest
|
|
|
|
|
p.xnest = -1
|
|
|
|
|
|
|
|
|
|
if p.tok != _Semi {
|
|
|
|
|
// accept potential varDecl but complain
|
2017-02-13 15:08:04 -08:00
|
|
|
if p.got(_Var) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError(fmt.Sprintf("var declaration not allowed in %s initializer", keyword.String()))
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
2017-02-13 12:48:39 -08:00
|
|
|
init = p.simpleStmt(nil, keyword == _For)
|
|
|
|
|
// If we have a range clause, we are done (can only happen for keyword == _For).
|
2016-03-04 17:09:08 -08:00
|
|
|
if _, ok := init.(*RangeClause); ok {
|
|
|
|
|
p.xnest = outer
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var condStmt SimpleStmt
|
2017-02-13 12:48:39 -08:00
|
|
|
var semi struct {
|
cmd/compile/internal/syntax: remove dependency on cmd/internal/src
For dependency reasons, the data structure implementing source
positions in the compiler is in cmd/internal/src. It contains
highly compiler specific details (e.g. inlining index).
This change introduces a parallel but simpler position
representation, defined in the syntax package, which removes
that package's dependency on cmd/internal/src, and also removes
the need to deal with certain filename-specific operations
(defined by the needs of the compiler) in the syntax package.
As a result, the syntax package becomes again a compiler-
independent, stand-alone package that at some point might
replace (or augment) the existing top-level go/* syntax-related
packages.
Additionally, line directives that update column numbers
are now correctly tracked through the syntax package, with
additional tests added. (The respective changes also need to
be made in cmd/internal/src; i.e., the compiler accepts but
still ignores column numbers in line directives.)
This change comes at the cost of a new position translation
step, but that step is cheap because it only needs to do real
work if the position base changed (i.e., if there is a new file,
or new line directive).
There is no noticeable impact on overall compiler performance
measured with `compilebench -count 5 -alloc`:
name old time/op new time/op delta
Template 220ms ± 8% 228ms ±18% ~ (p=0.548 n=5+5)
Unicode 119ms ±11% 113ms ± 5% ~ (p=0.056 n=5+5)
GoTypes 684ms ± 6% 677ms ± 3% ~ (p=0.841 n=5+5)
Compiler 3.19s ± 7% 3.01s ± 1% ~ (p=0.095 n=5+5)
SSA 7.92s ± 8% 7.79s ± 1% ~ (p=0.690 n=5+5)
Flate 141ms ± 7% 139ms ± 4% ~ (p=0.548 n=5+5)
GoParser 173ms ±12% 171ms ± 4% ~ (p=1.000 n=5+5)
Reflect 417ms ± 5% 411ms ± 3% ~ (p=0.548 n=5+5)
Tar 205ms ± 5% 198ms ± 2% ~ (p=0.690 n=5+5)
XML 232ms ± 4% 229ms ± 4% ~ (p=0.690 n=5+5)
StdCmd 28.7s ± 5% 28.2s ± 2% ~ (p=0.421 n=5+5)
name old user-time/op new user-time/op delta
Template 269ms ± 4% 265ms ± 5% ~ (p=0.421 n=5+5)
Unicode 153ms ± 7% 149ms ± 3% ~ (p=0.841 n=5+5)
GoTypes 850ms ± 7% 862ms ± 4% ~ (p=0.841 n=5+5)
Compiler 4.01s ± 5% 3.86s ± 0% ~ (p=0.190 n=5+4)
SSA 10.9s ± 4% 10.8s ± 2% ~ (p=0.548 n=5+5)
Flate 166ms ± 7% 167ms ± 6% ~ (p=1.000 n=5+5)
GoParser 204ms ± 8% 206ms ± 7% ~ (p=0.841 n=5+5)
Reflect 514ms ± 5% 508ms ± 4% ~ (p=0.548 n=5+5)
Tar 245ms ± 6% 244ms ± 3% ~ (p=0.690 n=5+5)
XML 280ms ± 4% 278ms ± 4% ~ (p=0.841 n=5+5)
name old alloc/op new alloc/op delta
Template 37.9MB ± 0% 37.9MB ± 0% ~ (p=0.841 n=5+5)
Unicode 28.8MB ± 0% 28.8MB ± 0% ~ (p=0.841 n=5+5)
GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.151 n=5+5)
Compiler 468MB ± 0% 468MB ± 0% -0.01% (p=0.032 n=5+5)
SSA 1.50GB ± 0% 1.50GB ± 0% ~ (p=0.548 n=5+5)
Flate 24.4MB ± 0% 24.4MB ± 0% ~ (p=1.000 n=5+5)
GoParser 30.7MB ± 0% 30.7MB ± 0% ~ (p=1.000 n=5+5)
Reflect 76.5MB ± 0% 76.5MB ± 0% ~ (p=0.548 n=5+5)
Tar 38.9MB ± 0% 38.9MB ± 0% ~ (p=0.222 n=5+5)
XML 41.6MB ± 0% 41.6MB ± 0% ~ (p=0.548 n=5+5)
name old allocs/op new allocs/op delta
Template 382k ± 0% 382k ± 0% +0.01% (p=0.008 n=5+5)
Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5)
GoTypes 1.19M ± 0% 1.19M ± 0% +0.01% (p=0.008 n=5+5)
Compiler 4.53M ± 0% 4.53M ± 0% +0.03% (p=0.008 n=5+5)
SSA 12.4M ± 0% 12.4M ± 0% +0.00% (p=0.008 n=5+5)
Flate 235k ± 0% 235k ± 0% ~ (p=0.079 n=5+5)
GoParser 318k ± 0% 318k ± 0% ~ (p=0.730 n=5+5)
Reflect 978k ± 0% 978k ± 0% ~ (p=1.000 n=5+5)
Tar 393k ± 0% 393k ± 0% ~ (p=0.056 n=5+5)
XML 405k ± 0% 405k ± 0% ~ (p=0.548 n=5+5)
name old text-bytes new text-bytes delta
HelloSize 672kB ± 0% 672kB ± 0% ~ (all equal)
CmdGoSize 7.12MB ± 0% 7.12MB ± 0% ~ (all equal)
name old data-bytes new data-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
CmdGoSize 390kB ± 0% 390kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.07MB ± 0% 1.07MB ± 0% ~ (all equal)
CmdGoSize 11.2MB ± 0% 11.2MB ± 0% ~ (all equal)
Passes toolstash compare.
For #22662.
Change-Id: I19edb53dd9675af57f7122cb7dba2a6d8bdcc3da
Reviewed-on: https://go-review.googlesource.com/94515
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2018-01-02 16:58:37 -08:00
|
|
|
pos Pos
|
2017-02-22 13:43:23 -08:00
|
|
|
lit string // valid if pos.IsKnown()
|
2017-02-13 12:48:39 -08:00
|
|
|
}
|
2017-11-06 15:01:33 -08:00
|
|
|
if p.tok != _Lbrace {
|
2018-01-10 17:14:20 -08:00
|
|
|
if p.tok == _Semi {
|
|
|
|
|
semi.pos = p.pos()
|
|
|
|
|
semi.lit = p.lit
|
|
|
|
|
p.next()
|
|
|
|
|
} else {
|
|
|
|
|
p.want(_Semi)
|
|
|
|
|
}
|
2017-02-13 12:48:39 -08:00
|
|
|
if keyword == _For {
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok != _Semi {
|
2017-02-22 13:43:23 -08:00
|
|
|
if p.tok == _Lbrace {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting for loop condition")
|
2017-02-22 13:43:23 -08:00
|
|
|
goto done
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
condStmt = p.simpleStmt(nil, false)
|
|
|
|
|
}
|
|
|
|
|
p.want(_Semi)
|
|
|
|
|
if p.tok != _Lbrace {
|
|
|
|
|
post = p.simpleStmt(nil, false)
|
2017-03-20 11:36:15 -07:00
|
|
|
if a, _ := post.(*AssignStmt); a != nil && a.Op == Def {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxErrorAt(a.Pos(), "cannot declare in post statement of for loop")
|
2017-03-20 11:36:15 -07:00
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
} else if p.tok != _Lbrace {
|
|
|
|
|
condStmt = p.simpleStmt(nil, false)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
condStmt = init
|
|
|
|
|
init = nil
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-22 13:43:23 -08:00
|
|
|
done:
|
2016-03-04 17:09:08 -08:00
|
|
|
// unpack condStmt
|
|
|
|
|
switch s := condStmt.(type) {
|
|
|
|
|
case nil:
|
2017-02-22 13:43:23 -08:00
|
|
|
if keyword == _If && semi.pos.IsKnown() {
|
2017-02-13 12:48:39 -08:00
|
|
|
if semi.lit != "semicolon" {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxErrorAt(semi.pos, fmt.Sprintf("unexpected %s, expecting { after if clause", semi.lit))
|
2017-02-13 12:48:39 -08:00
|
|
|
} else {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxErrorAt(semi.pos, "missing condition in if statement")
|
2017-02-13 12:48:39 -08:00
|
|
|
}
|
|
|
|
|
}
|
2016-03-04 17:09:08 -08:00
|
|
|
case *ExprStmt:
|
|
|
|
|
cond = s.X
|
|
|
|
|
default:
|
2018-01-10 16:05:12 -08:00
|
|
|
// A common syntax error is to write '=' instead of '==',
|
|
|
|
|
// which turns an expression into an assignment. Provide
|
|
|
|
|
// a more explicit error message in that case to prevent
|
|
|
|
|
// further confusion.
|
|
|
|
|
str := String(s)
|
|
|
|
|
if as, ok := s.(*AssignStmt); ok && as.Op == 0 {
|
|
|
|
|
str = "assignment " + str
|
|
|
|
|
}
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError(fmt.Sprintf("%s used as value", str))
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p.xnest = outer
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) ifStmt() *IfStmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("ifStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(IfStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2017-02-13 12:48:39 -08:00
|
|
|
s.Init, s.Cond, _ = p.header(_If)
|
2017-03-21 22:23:15 -07:00
|
|
|
s.Then = p.blockStmt("if clause")
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
if p.got(_Else) {
|
2016-06-06 17:59:05 -07:00
|
|
|
switch p.tok {
|
|
|
|
|
case _If:
|
2016-03-04 17:09:08 -08:00
|
|
|
s.Else = p.ifStmt()
|
2016-06-06 17:59:05 -07:00
|
|
|
case _Lbrace:
|
2017-03-21 22:23:15 -07:00
|
|
|
s.Else = p.blockStmt("")
|
2016-06-06 17:59:05 -07:00
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("else must be followed by if or statement block")
|
2016-06-06 17:59:05 -07:00
|
|
|
p.advance(_Name, _Rbrace)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) switchStmt() *SwitchStmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("switchStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(SwitchStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2017-02-13 12:48:39 -08:00
|
|
|
s.Init, s.Tag, _ = p.header(_Switch)
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
if !p.got(_Lbrace) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("missing { after switch clause")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Case, _Default, _Rbrace)
|
|
|
|
|
}
|
|
|
|
|
for p.tok != _EOF && p.tok != _Rbrace {
|
|
|
|
|
s.Body = append(s.Body, p.caseClause())
|
|
|
|
|
}
|
2017-03-21 15:22:13 -07:00
|
|
|
s.Rbrace = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Rbrace)
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) selectStmt() *SelectStmt {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("selectStmt")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s := new(SelectStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.want(_Select)
|
2016-03-04 17:09:08 -08:00
|
|
|
if !p.got(_Lbrace) {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("missing { after select clause")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Case, _Default, _Rbrace)
|
|
|
|
|
}
|
|
|
|
|
for p.tok != _EOF && p.tok != _Rbrace {
|
|
|
|
|
s.Body = append(s.Body, p.commClause())
|
|
|
|
|
}
|
2017-03-21 15:22:13 -07:00
|
|
|
s.Rbrace = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Rbrace)
|
|
|
|
|
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) caseClause() *CaseClause {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("caseClause")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c := new(CaseClause)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
c.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Case:
|
|
|
|
|
p.next()
|
|
|
|
|
c.Cases = p.exprList()
|
|
|
|
|
|
|
|
|
|
case _Default:
|
|
|
|
|
p.next()
|
|
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting case or default or }")
|
2017-03-21 22:23:15 -07:00
|
|
|
p.advance(_Colon, _Case, _Default, _Rbrace)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-21 15:22:13 -07:00
|
|
|
c.Colon = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Colon)
|
|
|
|
|
c.Body = p.stmtList()
|
|
|
|
|
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) commClause() *CommClause {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("commClause")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c := new(CommClause)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
c.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Case:
|
|
|
|
|
p.next()
|
2016-11-28 22:34:50 -08:00
|
|
|
c.Comm = p.simpleStmt(nil, false)
|
2016-03-04 17:09:08 -08:00
|
|
|
|
2016-11-28 22:34:50 -08:00
|
|
|
// The syntax restricts the possible simple statements here to:
|
|
|
|
|
//
|
|
|
|
|
// lhs <- x (send statement)
|
|
|
|
|
// <-x
|
|
|
|
|
// lhs = <-x
|
|
|
|
|
// lhs := <-x
|
|
|
|
|
//
|
|
|
|
|
// All these (and more) are recognized by simpleStmt and invalid
|
|
|
|
|
// syntax trees are flagged later, during type checking.
|
|
|
|
|
// TODO(gri) eventually may want to restrict valid syntax trees
|
|
|
|
|
// here.
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
case _Default:
|
|
|
|
|
p.next()
|
|
|
|
|
|
|
|
|
|
default:
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting case or default or }")
|
2017-03-21 22:23:15 -07:00
|
|
|
p.advance(_Colon, _Case, _Default, _Rbrace)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-21 15:22:13 -07:00
|
|
|
c.Colon = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
p.want(_Colon)
|
|
|
|
|
c.Body = p.stmtList()
|
|
|
|
|
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Statement =
|
|
|
|
|
// Declaration | LabeledStmt | SimpleStmt |
|
|
|
|
|
// GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
|
|
|
|
|
// FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
|
|
|
|
|
// DeferStmt .
|
2017-03-24 18:03:17 -07:00
|
|
|
func (p *parser) stmtOrNil() Stmt {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
|
|
|
|
defer p.trace("stmt " + p.tok.String())()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Most statements (assignments) start with an identifier;
|
|
|
|
|
// look for it first before doing anything more expensive.
|
|
|
|
|
if p.tok == _Name {
|
|
|
|
|
lhs := p.exprList()
|
2016-06-06 17:59:05 -07:00
|
|
|
if label, ok := lhs.(*Name); ok && p.tok == _Colon {
|
2017-03-24 18:03:17 -07:00
|
|
|
return p.labeledStmtOrNil(label)
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
return p.simpleStmt(lhs, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch p.tok {
|
|
|
|
|
case _Lbrace:
|
2017-03-21 22:23:15 -07:00
|
|
|
return p.blockStmt("")
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
case _Var:
|
|
|
|
|
return p.declStmt(p.varDecl)
|
|
|
|
|
|
|
|
|
|
case _Const:
|
|
|
|
|
return p.declStmt(p.constDecl)
|
|
|
|
|
|
|
|
|
|
case _Type:
|
|
|
|
|
return p.declStmt(p.typeDecl)
|
|
|
|
|
|
|
|
|
|
case _Operator, _Star:
|
|
|
|
|
switch p.op {
|
|
|
|
|
case Add, Sub, Mul, And, Xor, Not:
|
|
|
|
|
return p.simpleStmt(nil, false) // unary operators
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case _Literal, _Func, _Lparen, // operands
|
|
|
|
|
_Lbrack, _Struct, _Map, _Chan, _Interface, // composite types
|
2016-11-04 16:27:31 -07:00
|
|
|
_Arrow: // receive operator
|
2016-03-04 17:09:08 -08:00
|
|
|
return p.simpleStmt(nil, false)
|
|
|
|
|
|
|
|
|
|
case _For:
|
|
|
|
|
return p.forStmt()
|
|
|
|
|
|
|
|
|
|
case _Switch:
|
|
|
|
|
return p.switchStmt()
|
|
|
|
|
|
|
|
|
|
case _Select:
|
|
|
|
|
return p.selectStmt()
|
|
|
|
|
|
|
|
|
|
case _If:
|
|
|
|
|
return p.ifStmt()
|
|
|
|
|
|
|
|
|
|
case _Fallthrough:
|
|
|
|
|
s := new(BranchStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
s.Tok = _Fallthrough
|
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
case _Break, _Continue:
|
|
|
|
|
s := new(BranchStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
|
|
|
|
s.Tok = p.tok
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok == _Name {
|
|
|
|
|
s.Label = p.name()
|
|
|
|
|
}
|
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
case _Go, _Defer:
|
|
|
|
|
return p.callStmt()
|
|
|
|
|
|
|
|
|
|
case _Goto:
|
|
|
|
|
s := new(BranchStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
s.Tok = _Goto
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
s.Label = p.name()
|
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
case _Return:
|
|
|
|
|
s := new(ReturnStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
|
|
|
|
p.next()
|
2016-03-04 17:09:08 -08:00
|
|
|
if p.tok != _Semi && p.tok != _Rbrace {
|
|
|
|
|
s.Results = p.exprList()
|
|
|
|
|
}
|
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
case _Semi:
|
|
|
|
|
s := new(EmptyStmt)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
s.pos = p.pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-24 18:03:17 -07:00
|
|
|
return nil
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StatementList = { Statement ";" } .
|
|
|
|
|
func (p *parser) stmtList() (l []Stmt) {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("stmtList")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for p.tok != _EOF && p.tok != _Rbrace && p.tok != _Case && p.tok != _Default {
|
2017-03-24 18:03:17 -07:00
|
|
|
s := p.stmtOrNil()
|
|
|
|
|
if s == nil {
|
2016-03-04 17:09:08 -08:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
l = append(l, s)
|
2017-10-16 21:24:27 -07:00
|
|
|
// ";" is optional before "}"
|
|
|
|
|
if !p.got(_Semi) && p.tok != _Rbrace {
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("at end of statement")
|
2017-10-16 21:24:27 -07:00
|
|
|
p.advance(_Semi, _Rbrace, _Case, _Default)
|
|
|
|
|
p.got(_Semi) // avoid spurious empty statement
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
|
2017-10-11 15:02:10 -07:00
|
|
|
func (p *parser) argList() (list []Expr, hasDots bool) {
|
2016-03-04 17:09:08 -08:00
|
|
|
if trace {
|
2017-10-11 15:02:10 -07:00
|
|
|
defer p.trace("argList")()
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p.xnest++
|
2017-10-11 16:57:39 -07:00
|
|
|
p.list(_Lparen, _Comma, _Rparen, func() bool {
|
2017-10-11 15:02:10 -07:00
|
|
|
list = append(list, p.expr())
|
|
|
|
|
hasDots = p.got(_DotDotDot)
|
2017-10-11 16:57:39 -07:00
|
|
|
return hasDots
|
|
|
|
|
})
|
2016-03-04 17:09:08 -08:00
|
|
|
p.xnest--
|
|
|
|
|
|
2017-10-11 15:02:10 -07:00
|
|
|
return
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// Common productions
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
func (p *parser) newName(value string) *Name {
|
2016-03-04 17:09:08 -08:00
|
|
|
n := new(Name)
|
cmd/compile/internal/syntax: establish principled position information
Until now, the parser set the position for each Node to the position of
the first token belonging to that node. For compatibility with the now
defunct gc parser, in many places that position information was modified
when the gcCompat flag was set (which it was, by default). Furthermore,
in some places, position information was not set at all.
This change removes the gcCompat flag and all associated code, and sets
position information for all nodes in a more principled way, as proposed
by mdempsky (see #16943 for details). Specifically, the position of a
node may not be at the very beginning of the respective production. For
instance for an Operation `a + b`, the position associated with the node
is the position of the `+`. Thus, for `a + b + c` we now get different
positions for the two additions.
This change does not pass toolstash -cmp because position information
recorded in export data and pcline tables is different. There are no
other functional changes.
Added test suite testing the position of all nodes.
Fixes #16943.
Change-Id: I3fc02bf096bc3b3d7d2fa655dfd4714a1a0eb90c
Reviewed-on: https://go-review.googlesource.com/37017
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-02-13 16:00:53 -08:00
|
|
|
n.pos = p.pos()
|
2017-03-24 16:23:21 -07:00
|
|
|
n.Value = value
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *parser) name() *Name {
|
|
|
|
|
// no tracing to avoid overly verbose output
|
2016-03-04 17:09:08 -08:00
|
|
|
|
|
|
|
|
if p.tok == _Name {
|
2017-03-24 16:23:21 -07:00
|
|
|
n := p.newName(p.lit)
|
2016-03-04 17:09:08 -08:00
|
|
|
p.next()
|
2017-03-24 16:23:21 -07:00
|
|
|
return n
|
2016-03-04 17:09:08 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-24 16:23:21 -07:00
|
|
|
n := p.newName("_")
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting name")
|
2017-03-24 16:23:21 -07:00
|
|
|
p.advance()
|
2016-03-04 17:09:08 -08:00
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IdentifierList = identifier { "," identifier } .
|
|
|
|
|
// The first name must be provided.
|
|
|
|
|
func (p *parser) nameList(first *Name) []*Name {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("nameList")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if debug && first == nil {
|
|
|
|
|
panic("first name not provided")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
l := []*Name{first}
|
|
|
|
|
for p.got(_Comma) {
|
|
|
|
|
l = append(l, p.name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return l
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The first name may be provided, or nil.
|
|
|
|
|
func (p *parser) qualifiedName(name *Name) Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("qualifiedName")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch {
|
|
|
|
|
case name != nil:
|
|
|
|
|
// name is provided
|
|
|
|
|
case p.tok == _Name:
|
|
|
|
|
name = p.name()
|
|
|
|
|
default:
|
2017-03-24 16:23:21 -07:00
|
|
|
name = p.newName("_")
|
2018-02-14 15:22:44 -08:00
|
|
|
p.syntaxError("expecting name")
|
2016-03-04 17:09:08 -08:00
|
|
|
p.advance(_Dot, _Semi, _Rbrace)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p.dotname(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ExpressionList = Expression { "," Expression } .
|
|
|
|
|
func (p *parser) exprList() Expr {
|
|
|
|
|
if trace {
|
|
|
|
|
defer p.trace("exprList")()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x := p.expr()
|
|
|
|
|
if p.got(_Comma) {
|
|
|
|
|
list := []Expr{x, p.expr()}
|
|
|
|
|
for p.got(_Comma) {
|
|
|
|
|
list = append(list, p.expr())
|
|
|
|
|
}
|
|
|
|
|
t := new(ListExpr)
|
2016-12-02 10:44:34 -08:00
|
|
|
t.pos = x.Pos()
|
2016-03-04 17:09:08 -08:00
|
|
|
t.ElemList = list
|
|
|
|
|
x = t
|
|
|
|
|
}
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// unparen removes all parentheses around an expression.
|
|
|
|
|
func unparen(x Expr) Expr {
|
|
|
|
|
for {
|
|
|
|
|
p, ok := x.(*ParenExpr)
|
|
|
|
|
if !ok {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
x = p.X
|
|
|
|
|
}
|
|
|
|
|
return x
|
|
|
|
|
}
|