]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: stop storing TFIELD types in Node.Type
authorMatthew Dempsky <mdempsky@google.com>
Mon, 14 Mar 2016 07:24:43 +0000 (00:24 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 14 Mar 2016 21:12:29 +0000 (21:12 +0000)
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/20676
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/typecheck.go

index ec256e1ccb3cd7f7f3f0ad3a4be307330492c433..7f7b7577a1c67abdaeb62504fc4428ccbc70f3d9 100644 (file)
@@ -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.
index 3363d4993c686b6dc4c8614ba8139f6c4296a6f1..e6db3d18e0345b8209d55df15d210cdcb1483c79 100644 (file)
@@ -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 {
index e54f7e1c971625ab56e6c84b84a7f727f72b258f..631427c0d3cecd1957030b53e3c68cd716141ca6 100644 (file)
@@ -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:
index 2ddc8cbbab40933592694b604452fffde484eeaa..c363df88221731b4e29abdb696819db632eccbca 100644 (file)
@@ -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
index e19e161a7a4f8f93f09f9f17866e73e99f0c912f..97e268466e7f6d62b5084a43e49d04a3fc8e5a01 100644 (file)
@@ -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