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.
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 {
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:
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
}
}
+// 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
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
// 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()
}
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