Commit 11779362 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile/internal/syntax: expose additional information for gc

gc needs access to line offsets for Nodes. It also needs access to the
end line offset for function bodies so it knows what line number to
use for things like implicit returns and defer executions.

Lastly, include an extra bool to distinguish between simple and full
slice expressions. This is redundant in valid parse trees, but needed
by gc for producing complete warnings in invalid inputs.

Change-Id: I64baf334a35c72336d26fa6755c67eb9d6f4e93c
Reviewed-on: https://go-review.googlesource.com/27196Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 4e8c1137
...@@ -8,6 +8,7 @@ package syntax ...@@ -8,6 +8,7 @@ package syntax
// Nodes // Nodes
type Node interface { type Node interface {
Line() uint32
aNode() aNode()
} }
...@@ -19,6 +20,10 @@ type node struct { ...@@ -19,6 +20,10 @@ type node struct {
func (*node) aNode() {} func (*node) aNode() {}
func (n *node) Line() uint32 {
return n.line
}
func (n *node) init(p *parser) { func (n *node) init(p *parser) {
n.pos = uint32(p.pos) n.pos = uint32(p.pos)
n.line = uint32(p.line) n.line = uint32(p.line)
...@@ -80,11 +85,12 @@ type ( ...@@ -80,11 +85,12 @@ type (
} }
FuncDecl struct { FuncDecl struct {
Attr map[string]bool // go:attr map Attr map[string]bool // go:attr map
Recv *Field // nil means regular function Recv *Field // nil means regular function
Name *Name Name *Name
Type *FuncType Type *FuncType
Body []Stmt // nil means no body (forward declaration) Body []Stmt // nil means no body (forward declaration)
EndLine uint32 // TODO(mdempsky): Cleaner solution.
decl decl
} }
) )
...@@ -136,8 +142,9 @@ type ( ...@@ -136,8 +142,9 @@ type (
// func Type { Body } // func Type { Body }
FuncLit struct { FuncLit struct {
Type *FuncType Type *FuncType
Body []Stmt Body []Stmt
EndLine uint32 // TODO(mdempsky): Cleaner solution.
expr expr
} }
...@@ -165,6 +172,11 @@ type ( ...@@ -165,6 +172,11 @@ type (
SliceExpr struct { SliceExpr struct {
X Expr X Expr
Index [3]Expr Index [3]Expr
// Full indicates whether this is a simple or full slice expression.
// In a valid AST, this is equivalent to Index[2] != nil.
// TODO(mdempsky): This is only needed to report the "3-index
// slice of string" error when Index[2] is missing.
Full bool
expr expr
} }
......
...@@ -422,6 +422,8 @@ func (p *parser) funcDecl() *FuncDecl { ...@@ -422,6 +422,8 @@ func (p *parser) funcDecl() *FuncDecl {
f.Type = p.funcType() f.Type = p.funcType()
f.Body = p.funcBody() f.Body = p.funcBody()
f.EndLine = uint32(p.line)
// TODO(gri) deal with function properties // TODO(gri) deal with function properties
// if noescape && body != nil { // if noescape && body != nil {
// p.error("can only use //go:noescape with external func implementations") // p.error("can only use //go:noescape with external func implementations")
...@@ -624,6 +626,7 @@ func (p *parser) operand(keep_parens bool) Expr { ...@@ -624,6 +626,7 @@ func (p *parser) operand(keep_parens bool) Expr {
f.init(p) f.init(p)
f.Type = t f.Type = t
f.Body = p.funcBody() f.Body = p.funcBody()
f.EndLine = uint32(p.line)
p.xnest-- p.xnest--
p.fnest-- p.fnest--
return f return f
...@@ -739,6 +742,7 @@ loop: ...@@ -739,6 +742,7 @@ loop:
t.Index[1] = p.expr() t.Index[1] = p.expr()
} }
if p.got(_Colon) { if p.got(_Colon) {
t.Full = true
// x[i:j:...] // x[i:j:...]
if t.Index[1] == nil { if t.Index[1] == nil {
p.error("middle index required in 3-index slice") p.error("middle index required in 3-index slice")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment