mirror of
https://github.com/golang/go
synced 2024-11-19 12:34:47 -07:00
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/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>
This commit is contained in:
parent
9bffcf382b
commit
c278f9302e
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user