case OARRAYLIT:
// Link values to array
- for _, n5 := range n.List.Slice() {
- e.escassign(n, n5.Right, e.stepAssignWhere(n, n5.Right, "array literal element", n))
+ for _, n2 := range n.List.Slice() {
+ if n2.Op == OKEY {
+ n2 = n2.Right
+ }
+ e.escassign(n, n2, e.stepAssignWhere(n, n2, "array literal element", n))
}
case OSLICELIT:
// Slice is not leaked until proven otherwise
e.track(n)
// Link values to slice
- for _, n5 := range n.List.Slice() {
- e.escassign(n, n5.Right, e.stepAssignWhere(n, n5.Right, "slice literal element", n))
+ for _, n2 := range n.List.Slice() {
+ if n2.Op == OKEY {
+ n2 = n2.Right
+ }
+ e.escassign(n, n2, e.stepAssignWhere(n, n2, "slice literal element", n))
}
// Link values to struct.
case OSLICELIT:
for _, n1 := range src.List.Slice() {
- e.escwalk(level.dec(), dst, n1.Right, e.stepWalk(dst, n1.Right, "slice-literal-element", step))
+ if n1.Op == OKEY {
+ n1 = n1.Right
+ }
+ e.escwalk(level.dec(), dst, n1, e.stepWalk(dst, n1, "slice-literal-element", step))
}
fallthrough
var mode initGenType
for _, n1 := range n.List.Slice() {
- value := n1.Right
- if n.Op == OSTRUCTLIT {
- value = n1.Left
+ switch n1.Op {
+ case OKEY:
+ n1 = n1.Right
+ case OSTRUCTKEY:
+ n1 = n1.Left
}
- mode |= getdyn(value, false)
+ mode |= getdyn(n1, false)
if mode == initDynamic|initConst {
break
}
return false
case OARRAYLIT:
for _, r := range n.List.Slice() {
- if r.Op != OKEY {
- Fatalf("isStaticCompositeLiteral: rhs not OKEY: %v", r)
+ if r.Op == OKEY {
+ r = r.Right
}
- if r.Left.Op != OLITERAL || !isStaticCompositeLiteral(r.Right) {
+ if !isStaticCompositeLiteral(r) {
return false
}
}
var splitnode func(*Node) (a *Node, value *Node)
switch n.Op {
case OARRAYLIT, OSLICELIT:
+ var k int64
splitnode = func(r *Node) (*Node, *Node) {
- if r.Op != OKEY {
- Fatalf("fixedlit: rhs not OKEY: %v", r)
+ if r.Op == OKEY {
+ k = nonnegintconst(r.Left)
+ r = r.Right
}
- return nod(OINDEX, var_, r.Left), r.Right
+ a := nod(OINDEX, var_, nodintconst(k))
+ k++
+ return a, r
}
case OSTRUCTLIT:
splitnode = func(r *Node) (*Node, *Node) {
}
islit := isliteral(value)
- if n.Op == OARRAYLIT {
- islit = islit && isliteral(r.Left)
- }
if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
continue
}
}
// put dynamics into array (5)
+ var index int64
for _, r := range n.List.Slice() {
- if r.Op != OKEY {
- Fatalf("slicelit: rhs not OKEY: %v", r)
+ value := r
+ if r.Op == OKEY {
+ index = nonnegintconst(r.Left)
+ value = r.Right
}
- index := r.Left
- value := r.Right
- a := nod(OINDEX, vauto, index)
+ a := nod(OINDEX, vauto, nodintconst(index))
a.Bounded = true
+ index++
// TODO need to check bounds?
continue
}
- if isliteral(index) && isliteral(value) {
+ if isliteral(value) {
continue
}
Fatalf("initplan")
case OARRAYLIT, OSLICELIT:
+ var k int64
for _, a := range n.List.Slice() {
- index := nonnegintconst(a.Left)
- if a.Op != OKEY || index < 0 {
- Fatalf("initplan fixedlit")
+ if a.Op == OKEY {
+ k = nonnegintconst(a.Left)
+ a = a.Right
}
- addvalue(p, index*n.Type.Elem().Width, a.Right)
+ addvalue(p, k*n.Type.Elem().Width, a)
+ k++
}
case OSTRUCTLIT:
case OARRAYLIT:
for _, n1 := range n.List.Slice() {
- if !iszero(n1.Right) {
+ if n1.Op == OKEY {
+ n1 = n1.Right
+ }
+ if !iszero(n1) {
return false
}
}
OIND // *Left
OINDEX // Left[Right] (index of array or slice)
OINDEXMAP // Left[Right] (index of map)
- OKEY // Left:Right (key:value in struct/array/map literal, or slice index pair)
+ OKEY // Left:Right (key:value in struct/array/map literal)
OSTRUCTKEY // Sym:Left (key:value in struct literal, after type checking)
OLEN // len(Left)
OMAKE // make(List) (before type checking converts to one of the following)
t = t.Elem()
}
- var r *Node
switch t.Etype {
default:
yyerror("invalid type for composite literal: %v", t)
var length, i int64
checkBounds := t.IsArray() && !t.isDDDArray()
- for i2, n2 := range n.List.Slice() {
- l := n2
+ nl := n.List.Slice()
+ for i2, l := range nl {
setlineno(l)
- if l.Op != OKEY {
- l = nod(OKEY, nodintconst(int64(i)), l)
- l.Left.Type = Types[TINT]
- l.Left.Typecheck = 1
- n.List.SetIndex(i2, l)
- }
-
- l.Left = typecheck(l.Left, Erv)
- evconst(l.Left)
-
- i = nonnegintconst(l.Left)
- if i < 0 && l.Left.Diag == 0 {
- yyerror("index must be non-negative integer constant")
- l.Left.Diag = 1
- i = -(1 << 30) // stay negative for a while
+ vp := &nl[i2]
+ if l.Op == OKEY {
+ l.Left = typecheck(l.Left, Erv)
+ evconst(l.Left)
+ i = nonnegintconst(l.Left)
+ if i < 0 && l.Left.Diag == 0 {
+ yyerror("index must be non-negative integer constant")
+ l.Left.Diag = 1
+ i = -(1 << 30) // stay negative for a while
+ }
+ vp = &l.Right
}
if i >= 0 && indices != nil {
}
}
+ r := *vp
+ pushtype(r, t.Elem())
+ r = typecheck(r, Erv)
+ r = defaultlit(r, t.Elem())
+ *vp = assignconv(r, t.Elem(), "array or slice literal")
+
i++
if i > length {
length = i
checkBounds = false
}
}
-
- r = l.Right
- pushtype(r, t.Elem())
- r = typecheck(r, Erv)
- r = defaultlit(r, t.Elem())
- l.Right = assignconv(r, t.Elem(), "array or slice literal")
}
if t.isDDDArray() {
case TMAP:
hash := make(map[uint32][]*Node)
- var l *Node
- for i3, n3 := range n.List.Slice() {
- l = n3
+ for i3, l := range n.List.Slice() {
setlineno(l)
if l.Op != OKEY {
n.List.SetIndex(i3, typecheck(n.List.Index(i3), Erv))
continue
}
- r = l.Left
+ r := l.Left
pushtype(r, t.Key())
r = typecheck(r, Erv)
r = defaultlit(r, t.Key())
// simple list of variables
f, it := iterFields(t)
- var s *Sym
ls := n.List.Slice()
for i1, n1 := range ls {
setlineno(n1)
continue
}
- s = f.Sym
+ s := f.Sym
if s != nil && !exportname(s.Name) && s.Pkg != localpkg {
yyerror("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
}