diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 2a678dc2c0..6d8e609186 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -286,47 +286,6 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node { return init } -// declare constants from grammar -// new_name_list [[type] = expr_list] -func constiter(vl []*Node, t *Node, cl []*Node, iotaVal int64) []*Node { - var lno src.XPos // default is to leave line number alone in listtreecopy - if len(cl) == 0 { - if t != nil { - yyerror("const declaration cannot have type without expression") - } - cl = lastconst - t = lasttype - lno = vl[0].Pos - } else { - lastconst = cl - lasttype = t - } - - var vv []*Node - for i, v := range vl { - if i >= len(cl) { - yyerror("missing value in const declaration") - break - } - - c := treecopy(cl[i], lno) - - v.Op = OLITERAL - declare(v, dclcontext) - - v.Name.Param.Ntype = t - v.Name.Defn = c - v.SetIota(iotaVal) - - vv = append(vv, nod(ODCLCONST, v, nil)) - } - - if len(cl) > len(vl) { - yyerror("extra expression in const declaration") - } - return vv -} - // newname returns a new ONAME Node associated with symbol s. func newname(s *Sym) *Node { if s == nil { diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index a460b415d8..312c252feb 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -223,10 +223,6 @@ var dclcontext Class // PEXTERN/PAUTO var statuniqgen int // name generator for static temps -var lastconst []*Node - -var lasttype *Node - var Maxarg int64 var Stksize int64 // stack size for current frame diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index 2de5b18f7c..14dc1a1d87 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -117,9 +117,7 @@ func (p *noder) node() { } func (p *noder) decls(decls []syntax.Decl) (l []*Node) { - var lastConstGroup *syntax.Group - var lastConstRHS []*Node - var iotaVal int64 + var cs constState for _, decl := range decls { p.lineno(decl) @@ -131,23 +129,7 @@ func (p *noder) decls(decls []syntax.Decl) (l []*Node) { l = append(l, p.varDecl(decl)...) case *syntax.ConstDecl: - // Tricky to handle golang.org/issue/15550 correctly. - - if decl.Group == nil || decl.Group != lastConstGroup { - iotaVal = 0 - lastConstRHS = nil - } - - lastconst = lastConstRHS - - l = append(l, p.constDecl(decl, iotaVal)...) - - lastConstRHS = lastconst - lastconst = nil - - iotaVal++ - - lastConstGroup = decl.Group + l = append(l, p.constDecl(decl, &cs)...) case *syntax.TypeDecl: l = append(l, p.typeDecl(decl)) @@ -222,16 +204,62 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []*Node { return variter(names, typ, exprs) } -func (p *noder) constDecl(decl *syntax.ConstDecl, iotaVal int64) []*Node { +type constState struct { + group *syntax.Group + typ *Node + values []*Node + iota int64 +} + +func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node { + if decl.Group == nil || decl.Group != cs.group { + *cs = constState{ + group: decl.Group, + } + } + names := p.declNames(decl.NameList) typ := p.typeExprOrNil(decl.Type) - var exprs []*Node + var values []*Node if decl.Values != nil { - exprs = p.exprList(decl.Values) + values = p.exprList(decl.Values) + cs.typ, cs.values = typ, values + } else { + if typ != nil { + yyerror("const declaration cannot have type without expression") + } + typ, values = cs.typ, cs.values } - return constiter(names, typ, exprs, iotaVal) + var nn []*Node + for i, n := range names { + if i >= len(values) { + yyerror("missing value in const declaration") + break + } + v := values[i] + if decl.Values == nil { + v = treecopy(v, n.Pos) + } + + n.Op = OLITERAL + declare(n, dclcontext) + + n.Name.Param.Ntype = typ + n.Name.Defn = v + n.SetIota(cs.iota) + + nn = append(nn, p.nod(decl, ODCLCONST, n, nil)) + } + + if len(values) > len(names) { + yyerror("extra expression in const declaration") + } + + cs.iota++ + + return nn } func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {