Commit c278f930 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: stop storing TFIELD types in Node.Type

Currently, the only use for this is on the Left side of OKEY nodes
within struct literals.  esc and fmt only care so they can recognize
that the ONAME nodes are actually field names, which need special
handling.

sinit additionally needs to know the field's offset within the struct,
which we can provide via Xoffset.

Passes toolstash/buildall.

Change-Id: I362d965e161f4d80fcd9c9bae0dfacc657dc0b29
Reviewed-on: https://go-review.googlesource.com/20676Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarRobert Griesemer <gri@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 9bffcf38
......@@ -576,7 +576,7 @@ func esc(e *EscState, n *Node, up *Node) {
if n == nil {
return
}
if n.Type != nil && n.Type.Etype == TFIELD {
if n.Type == structkey {
// This is the left side of x:y in a struct literal.
// x is syntax, not an expression.
// See #14405.
......
......@@ -1287,7 +1287,7 @@ func exprfmt(n *Node, prec int) string {
case OKEY:
if n.Left != nil && n.Right != nil {
if fmtmode == FExp && n.Left.Type != nil && n.Left.Type.Etype == TFIELD {
if fmtmode == FExp && n.Left.Type == structkey {
// requires special handling of field names
return fmt.Sprintf("%v:%v", Sconv(n.Left.Sym, obj.FmtShort|obj.FmtByte), n.Right)
} else {
......
......@@ -1246,10 +1246,10 @@ func initplan(n *Node) {
case OSTRUCTLIT:
for _, a := range n.List.Slice() {
if a.Op != OKEY || a.Left.Type == nil {
if a.Op != OKEY || a.Left.Type != structkey {
Fatalf("initplan structlit")
}
addvalue(p, a.Left.Type.Width, a.Right)
addvalue(p, a.Left.Xoffset, a.Right)
}
case OMAPLIT:
......
......@@ -33,6 +33,13 @@ type Node struct {
Sym *Sym // various
E interface{} // Opt or Val, see methods below
// Various. Usually an offset into a struct. For example, ONAME nodes
// that refer to local variables use it to identify their stack frame
// position. ODOT, ODOTPTR, and OINDREG use it to indicate offset
// relative to their base address. ONAME nodes on the left side of an
// OKEY within an OSTRUCTLIT use it to store the named field's offset.
// OXCASE and OXFALL use it to validate the use of fallthrough.
// Possibly still more uses. If you find any, document them.
Xoffset int64
Lineno int32
......
......@@ -2893,6 +2893,11 @@ func pushtype(n *Node, t *Type) {
}
}
// Marker type so esc, fmt, and sinit can recognize the LHS of an OKEY node
// in a struct literal.
// TODO(mdempsky): Find a nicer solution.
var structkey = typ(Txxx)
func typecheckcomplit(np **Node) {
n := *np
lno := lineno
......@@ -3039,6 +3044,9 @@ func typecheckcomplit(np **Node) {
n.Op = OMAPLIT
case TSTRUCT:
// Need valid field offsets for Xoffset below.
dowidth(t)
bad := 0
if n.List.Len() != 0 && nokeys(n.List) {
// simple list of variables
......@@ -3065,7 +3073,8 @@ func typecheckcomplit(np **Node) {
// No pushtype allowed here. Must name fields for that.
n1 = assignconv(n1, f.Type, "field value")
n1 = Nod(OKEY, newname(f.Sym), n1)
n1.Left.Type = f
n1.Left.Type = structkey
n1.Left.Xoffset = f.Width
n1.Left.Typecheck = 1
ls[i1] = n1
f = it.Next()
......@@ -3114,8 +3123,9 @@ func typecheckcomplit(np **Node) {
}
l.Left = newname(s)
l.Left.Type = structkey
l.Left.Xoffset = f.Width
l.Left.Typecheck = 1
l.Left.Type = f
s = f.Sym
fielddup(newname(s), hash)
r = l.Right
......
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