mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: unify arraylit and structlit
They were almost identical. Merge them and some of their calling code. Passes toolstash -cmp. Change-Id: I9e92a864a6c09c9e18ed52dc247a678467e344ba Reviewed-on: https://go-review.googlesource.com/26754 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
49cce1a62e
commit
cd2d5ee048
2 changed files with 59 additions and 154 deletions
|
|
@ -579,117 +579,56 @@ func isStaticCompositeLiteral(n *Node) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func structlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
|
// fixedlit handles struct, array, and slice literals.
|
||||||
|
// TODO: expand documentation.
|
||||||
|
func fixedlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
|
||||||
|
var indexnode func(*Node) *Node
|
||||||
|
switch n.Op {
|
||||||
|
case OARRAYLIT, OSLICELIT:
|
||||||
|
indexnode = func(index *Node) *Node { return Nod(OINDEX, var_, index) }
|
||||||
|
case OSTRUCTLIT:
|
||||||
|
indexnode = func(index *Node) *Node { return NodSym(ODOT, var_, index.Sym) }
|
||||||
|
default:
|
||||||
|
Fatalf("fixedlit bad op: %v", n.Op)
|
||||||
|
}
|
||||||
|
|
||||||
for _, r := range n.List.Slice() {
|
for _, r := range n.List.Slice() {
|
||||||
if r.Op != OKEY {
|
if r.Op != OKEY {
|
||||||
Fatalf("structlit: rhs not OKEY: %v", r)
|
Fatalf("fixedlit: rhs not OKEY: %v", r)
|
||||||
}
|
}
|
||||||
index := r.Left
|
index := r.Left
|
||||||
value := r.Right
|
value := r.Right
|
||||||
|
|
||||||
switch value.Op {
|
switch value.Op {
|
||||||
case OSLICELIT:
|
case OSLICELIT:
|
||||||
if pass == 1 && ctxt != 0 {
|
if (pass == 1 && ctxt != 0) || (pass == 2 && ctxt == 0) {
|
||||||
a := NodSym(ODOT, var_, index.Sym)
|
a := indexnode(index)
|
||||||
slicelit(ctxt, value, a, init)
|
slicelit(ctxt, value, a, init)
|
||||||
} else if pass == 2 && ctxt == 0 {
|
|
||||||
a := NodSym(ODOT, var_, index.Sym)
|
|
||||||
slicelit(ctxt, value, a, init)
|
|
||||||
} else if pass == 3 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
|
|
||||||
case OARRAYLIT:
|
|
||||||
a := NodSym(ODOT, var_, index.Sym)
|
|
||||||
arraylit(ctxt, pass, value, a, init)
|
|
||||||
continue
|
|
||||||
|
|
||||||
case OSTRUCTLIT:
|
|
||||||
a := NodSym(ODOT, var_, index.Sym)
|
|
||||||
structlit(ctxt, pass, value, a, init)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if isliteral(value) {
|
|
||||||
if pass == 2 {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else if pass == 1 {
|
|
||||||
|
case OARRAYLIT, OSTRUCTLIT:
|
||||||
|
a := indexnode(index)
|
||||||
|
fixedlit(ctxt, pass, value, a, init)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// build list of var.field = expr
|
islit := isliteral(value)
|
||||||
setlineno(value)
|
if n.Op == OARRAYLIT {
|
||||||
a := NodSym(ODOT, var_, index.Sym)
|
islit = islit && isliteral(index)
|
||||||
|
}
|
||||||
|
if (pass == 1 && !islit) || (pass == 2 && islit) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
a = Nod(OAS, a, value)
|
// build list of assignments: var[index] = expr
|
||||||
|
setlineno(value)
|
||||||
|
a := Nod(OAS, indexnode(index), value)
|
||||||
a = typecheck(a, Etop)
|
a = typecheck(a, Etop)
|
||||||
if pass == 1 {
|
if pass == 1 {
|
||||||
a = walkexpr(a, init) // add any assignments in r to top
|
a = walkexpr(a, init) // add any assignments in r to top
|
||||||
if a.Op != OAS {
|
if a.Op != OAS {
|
||||||
Fatalf("structlit: not as")
|
Fatalf("fixedlit: not as")
|
||||||
}
|
|
||||||
a.IsStatic = true
|
|
||||||
} else {
|
|
||||||
a = orderstmtinplace(a)
|
|
||||||
a = walkstmt(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
init.Append(a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func arraylit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
|
|
||||||
for _, r := range n.List.Slice() {
|
|
||||||
if r.Op != OKEY {
|
|
||||||
Fatalf("arraylit: rhs not OKEY: %v", r)
|
|
||||||
}
|
|
||||||
index := r.Left
|
|
||||||
value := r.Right
|
|
||||||
|
|
||||||
switch value.Op {
|
|
||||||
case OSLICELIT:
|
|
||||||
if pass == 1 && ctxt != 0 {
|
|
||||||
a := Nod(OINDEX, var_, index)
|
|
||||||
slicelit(ctxt, value, a, init)
|
|
||||||
} else if pass == 2 && ctxt == 0 {
|
|
||||||
a := Nod(OINDEX, var_, index)
|
|
||||||
slicelit(ctxt, value, a, init)
|
|
||||||
} else if pass == 3 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
|
|
||||||
case OARRAYLIT:
|
|
||||||
a := Nod(OINDEX, var_, index)
|
|
||||||
arraylit(ctxt, pass, value, a, init)
|
|
||||||
continue
|
|
||||||
|
|
||||||
case OSTRUCTLIT:
|
|
||||||
a := Nod(OINDEX, var_, index)
|
|
||||||
structlit(ctxt, pass, value, a, init)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if isliteral(index) && isliteral(value) {
|
|
||||||
if pass == 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else if pass == 1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// build list of var[index] = value
|
|
||||||
setlineno(value)
|
|
||||||
a := Nod(OINDEX, var_, index)
|
|
||||||
|
|
||||||
a = Nod(OAS, a, value)
|
|
||||||
a = typecheck(a, Etop)
|
|
||||||
if pass == 1 {
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
if a.Op != OAS {
|
|
||||||
Fatalf("arraylit: not as")
|
|
||||||
}
|
}
|
||||||
a.IsStatic = true
|
a.IsStatic = true
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -710,8 +649,8 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||||
// put everything into static array
|
// put everything into static array
|
||||||
vstat := staticname(t, ctxt)
|
vstat := staticname(t, ctxt)
|
||||||
|
|
||||||
arraylit(ctxt, 1, n, vstat, init)
|
fixedlit(ctxt, 1, n, vstat, init)
|
||||||
arraylit(ctxt, 2, n, vstat, init)
|
fixedlit(ctxt, 2, n, vstat, init)
|
||||||
|
|
||||||
// copy static to slice
|
// copy static to slice
|
||||||
a := Nod(OSLICE, vstat, nil)
|
a := Nod(OSLICE, vstat, nil)
|
||||||
|
|
@ -749,7 +688,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||||
mode := getdyn(n, true)
|
mode := getdyn(n, true)
|
||||||
if mode&initConst != 0 {
|
if mode&initConst != 0 {
|
||||||
vstat = staticname(t, ctxt)
|
vstat = staticname(t, ctxt)
|
||||||
arraylit(ctxt, 1, n, vstat, init)
|
fixedlit(ctxt, 1, n, vstat, init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make new auto *array (3 declare)
|
// make new auto *array (3 declare)
|
||||||
|
|
@ -814,12 +753,8 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||||
case OSLICELIT:
|
case OSLICELIT:
|
||||||
break
|
break
|
||||||
|
|
||||||
case OARRAYLIT:
|
case OARRAYLIT, OSTRUCTLIT:
|
||||||
arraylit(ctxt, 2, value, a, init)
|
fixedlit(ctxt, 2, value, a, init)
|
||||||
continue
|
|
||||||
|
|
||||||
case OSTRUCTLIT:
|
|
||||||
structlit(ctxt, 2, value, a, init)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1025,9 +960,9 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||||
var_ = typecheck(var_, Erv|Easgn)
|
var_ = typecheck(var_, Erv|Easgn)
|
||||||
anylit(ctxt, n.Left, var_, init)
|
anylit(ctxt, n.Left, var_, init)
|
||||||
|
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT, OARRAYLIT:
|
||||||
if !t.IsStruct() {
|
if !t.IsStruct() && !t.IsArray() {
|
||||||
Fatalf("anylit: not struct")
|
Fatalf("anylit: not struct/array")
|
||||||
}
|
}
|
||||||
|
|
||||||
if var_.isSimpleName() && n.List.Len() > 4 {
|
if var_.isSimpleName() && n.List.Len() > 4 {
|
||||||
|
|
@ -1035,7 +970,11 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||||
// lay out static data
|
// lay out static data
|
||||||
vstat := staticname(t, ctxt)
|
vstat := staticname(t, ctxt)
|
||||||
|
|
||||||
structlit(ctxt, 1, n, vstat, init)
|
pass1ctxt := ctxt
|
||||||
|
if n.Op == OARRAYLIT {
|
||||||
|
pass1ctxt = 1
|
||||||
|
}
|
||||||
|
fixedlit(pass1ctxt, 1, n, vstat, init)
|
||||||
|
|
||||||
// copy static to var
|
// copy static to var
|
||||||
a := Nod(OAS, var_, vstat)
|
a := Nod(OAS, var_, vstat)
|
||||||
|
|
@ -1045,65 +984,35 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||||
init.Append(a)
|
init.Append(a)
|
||||||
|
|
||||||
// add expressions to automatic
|
// add expressions to automatic
|
||||||
structlit(ctxt, 2, n, var_, init)
|
fixedlit(ctxt, 2, n, var_, init)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
structlit(ctxt, 1, n, var_, init)
|
fixedlit(ctxt, 1, n, var_, init)
|
||||||
structlit(ctxt, 2, n, var_, init)
|
fixedlit(ctxt, 2, n, var_, init)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize of not completely specified
|
var components int64
|
||||||
if var_.isSimpleName() || n.List.Len() < t.NumFields() {
|
if n.Op == OARRAYLIT {
|
||||||
|
components = t.NumElem()
|
||||||
|
} else {
|
||||||
|
components = int64(t.NumFields())
|
||||||
|
}
|
||||||
|
// initialization of an array or struct with unspecified components (missing fields or arrays)
|
||||||
|
if var_.isSimpleName() || int64(n.List.Len()) < components {
|
||||||
a := Nod(OAS, var_, nil)
|
a := Nod(OAS, var_, nil)
|
||||||
a = typecheck(a, Etop)
|
a = typecheck(a, Etop)
|
||||||
a = walkexpr(a, init)
|
a = walkexpr(a, init)
|
||||||
init.Append(a)
|
init.Append(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
structlit(ctxt, 3, n, var_, init)
|
fixedlit(ctxt, 3, n, var_, init)
|
||||||
|
|
||||||
case OSLICELIT:
|
case OSLICELIT:
|
||||||
slicelit(ctxt, n, var_, init)
|
slicelit(ctxt, n, var_, init)
|
||||||
|
|
||||||
case OARRAYLIT:
|
|
||||||
if var_.isSimpleName() && n.List.Len() > 4 {
|
|
||||||
if ctxt == 0 {
|
|
||||||
// lay out static data
|
|
||||||
vstat := staticname(t, ctxt)
|
|
||||||
|
|
||||||
arraylit(1, 1, n, vstat, init)
|
|
||||||
|
|
||||||
// copy static to automatic
|
|
||||||
a := Nod(OAS, var_, vstat)
|
|
||||||
|
|
||||||
a = typecheck(a, Etop)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
// add expressions to automatic
|
|
||||||
arraylit(ctxt, 2, n, var_, init)
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
arraylit(ctxt, 1, n, var_, init)
|
|
||||||
arraylit(ctxt, 2, n, var_, init)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize of not completely specified
|
|
||||||
if var_.isSimpleName() || int64(n.List.Len()) < t.NumElem() {
|
|
||||||
a := Nod(OAS, var_, nil)
|
|
||||||
a = typecheck(a, Etop)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
arraylit(ctxt, 3, n, var_, init)
|
|
||||||
|
|
||||||
case OMAPLIT:
|
case OMAPLIT:
|
||||||
if !t.IsMap() {
|
if !t.IsMap() {
|
||||||
Fatalf("anylit: not map")
|
Fatalf("anylit: not map")
|
||||||
|
|
@ -1219,7 +1128,7 @@ func initplan(n *Node) {
|
||||||
case OARRAYLIT, OSLICELIT:
|
case OARRAYLIT, OSLICELIT:
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List.Slice() {
|
||||||
if a.Op != OKEY || !Smallintconst(a.Left) {
|
if a.Op != OKEY || !Smallintconst(a.Left) {
|
||||||
Fatalf("initplan arraylit")
|
Fatalf("initplan fixedlit")
|
||||||
}
|
}
|
||||||
addvalue(p, n.Type.Elem().Width*a.Left.Int64(), a.Right)
|
addvalue(p, n.Type.Elem().Width*a.Left.Int64(), a.Right)
|
||||||
}
|
}
|
||||||
|
|
@ -1227,7 +1136,7 @@ func initplan(n *Node) {
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
for _, a := range n.List.Slice() {
|
for _, a := range n.List.Slice() {
|
||||||
if a.Op != OKEY || a.Left.Type != structkey {
|
if a.Op != OKEY || a.Left.Type != structkey {
|
||||||
Fatalf("initplan structlit")
|
Fatalf("initplan fixedlit")
|
||||||
}
|
}
|
||||||
addvalue(p, a.Left.Xoffset, a.Right)
|
addvalue(p, a.Left.Xoffset, a.Right)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1637,11 +1637,7 @@ opswitch:
|
||||||
// n can be directly represented in the read-only data section.
|
// n can be directly represented in the read-only data section.
|
||||||
// Make direct reference to the static data. See issue 12841.
|
// Make direct reference to the static data. See issue 12841.
|
||||||
vstat := staticname(n.Type, 0)
|
vstat := staticname(n.Type, 0)
|
||||||
if n.Op == OSTRUCTLIT {
|
fixedlit(0, 1, n, vstat, init)
|
||||||
structlit(0, 1, n, vstat, init)
|
|
||||||
} else {
|
|
||||||
arraylit(0, 1, n, vstat, init)
|
|
||||||
}
|
|
||||||
n = vstat
|
n = vstat
|
||||||
n = typecheck(n, Erv)
|
n = typecheck(n, Erv)
|
||||||
break
|
break
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue