]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: unify arraylit and structlit
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 19 Jun 2016 19:11:47 +0000 (12:11 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Sun, 4 Sep 2016 16:18:39 +0000 (16:18 +0000)
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>
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/walk.go

index 668e311cbfa5e05e6b61ad9e67b71fcbed1fef3c..fa5d951cab92dc68de2769b5897379e2f4499cab 100644 (file)
@@ -579,117 +579,56 @@ func isStaticCompositeLiteral(n *Node) bool {
        return false
 }
 
-func structlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
-       for _, r := range n.List.Slice() {
-               if r.Op != OKEY {
-                       Fatalf("structlit: rhs not OKEY: %v", r)
-               }
-               index := r.Left
-               value := r.Right
-
-               switch value.Op {
-               case OSLICELIT:
-                       if pass == 1 && ctxt != 0 {
-                               a := NodSym(ODOT, var_, index.Sym)
-                               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
-                       }
-               } else if pass == 1 {
-                       continue
-               }
-
-               // build list of var.field = expr
-               setlineno(value)
-               a := NodSym(ODOT, var_, index.Sym)
-
-               a = Nod(OAS, a, value)
-               a = typecheck(a, Etop)
-               if pass == 1 {
-                       a = walkexpr(a, init) // add any assignments in r to top
-                       if a.Op != OAS {
-                               Fatalf("structlit: not as")
-                       }
-                       a.IsStatic = true
-               } else {
-                       a = orderstmtinplace(a)
-                       a = walkstmt(a)
-               }
-
-               init.Append(a)
+// 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)
        }
-}
 
-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)
+                       Fatalf("fixedlit: 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)
+                       if (pass == 1 && ctxt != 0) || (pass == 2 && ctxt == 0) {
+                               a := indexnode(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
                        }
-                       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)
+               case OARRAYLIT, OSTRUCTLIT:
+                       a := indexnode(index)
+                       fixedlit(ctxt, pass, value, a, init)
                        continue
                }
 
-               if isliteral(index) && isliteral(value) {
-                       if pass == 2 {
-                               continue
-                       }
-               } else if pass == 1 {
+               islit := isliteral(value)
+               if n.Op == OARRAYLIT {
+                       islit = islit && isliteral(index)
+               }
+               if (pass == 1 && !islit) || (pass == 2 && islit) {
                        continue
                }
 
-               // build list of var[index] = value
+               // build list of assignments: var[index] = expr
                setlineno(value)
-               a := Nod(OINDEX, var_, index)
-
-               a = Nod(OAS, a, value)
+               a := Nod(OAS, indexnode(index), value)
                a = typecheck(a, Etop)
                if pass == 1 {
-                       a = walkexpr(a, init)
+                       a = walkexpr(a, init) // add any assignments in r to top
                        if a.Op != OAS {
-                               Fatalf("arraylit: not as")
+                               Fatalf("fixedlit: not as")
                        }
                        a.IsStatic = true
                } else {
@@ -710,8 +649,8 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
                // put everything into static array
                vstat := staticname(t, ctxt)
 
-               arraylit(ctxt, 1, n, vstat, init)
-               arraylit(ctxt, 2, n, vstat, init)
+               fixedlit(ctxt, 1, n, vstat, init)
+               fixedlit(ctxt, 2, n, vstat, init)
 
                // copy static to slice
                a := Nod(OSLICE, vstat, nil)
@@ -749,7 +688,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
        mode := getdyn(n, true)
        if mode&initConst != 0 {
                vstat = staticname(t, ctxt)
-               arraylit(ctxt, 1, n, vstat, init)
+               fixedlit(ctxt, 1, n, vstat, init)
        }
 
        // make new auto *array (3 declare)
@@ -814,12 +753,8 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
                case OSLICELIT:
                        break
 
-               case OARRAYLIT:
-                       arraylit(ctxt, 2, value, a, init)
-                       continue
-
-               case OSTRUCTLIT:
-                       structlit(ctxt, 2, value, a, init)
+               case OARRAYLIT, OSTRUCTLIT:
+                       fixedlit(ctxt, 2, value, a, init)
                        continue
                }
 
@@ -1025,9 +960,9 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
                var_ = typecheck(var_, Erv|Easgn)
                anylit(ctxt, n.Left, var_, init)
 
-       case OSTRUCTLIT:
-               if !t.IsStruct() {
-                       Fatalf("anylit: not struct")
+       case OSTRUCTLIT, OARRAYLIT:
+               if !t.IsStruct() && !t.IsArray() {
+                       Fatalf("anylit: not struct/array")
                }
 
                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
                                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
                                a := Nod(OAS, var_, vstat)
@@ -1045,65 +984,35 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
                                init.Append(a)
 
                                // add expressions to automatic
-                               structlit(ctxt, 2, n, var_, init)
+                               fixedlit(ctxt, 2, n, var_, init)
 
                                break
                        }
 
-                       structlit(ctxt, 1, n, var_, init)
-                       structlit(ctxt, 2, n, var_, init)
+                       fixedlit(ctxt, 1, n, var_, init)
+                       fixedlit(ctxt, 2, n, var_, init)
                        break
                }
 
-               // initialize of not completely specified
-               if var_.isSimpleName() || n.List.Len() < t.NumFields() {
+               var components int64
+               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 = typecheck(a, Etop)
                        a = walkexpr(a, init)
                        init.Append(a)
                }
 
-               structlit(ctxt, 3, n, var_, init)
+               fixedlit(ctxt, 3, n, var_, init)
 
        case OSLICELIT:
                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:
                if !t.IsMap() {
                        Fatalf("anylit: not map")
@@ -1219,7 +1128,7 @@ func initplan(n *Node) {
        case OARRAYLIT, OSLICELIT:
                for _, a := range n.List.Slice() {
                        if a.Op != OKEY || !Smallintconst(a.Left) {
-                               Fatalf("initplan arraylit")
+                               Fatalf("initplan fixedlit")
                        }
                        addvalue(p, n.Type.Elem().Width*a.Left.Int64(), a.Right)
                }
@@ -1227,7 +1136,7 @@ func initplan(n *Node) {
        case OSTRUCTLIT:
                for _, a := range n.List.Slice() {
                        if a.Op != OKEY || a.Left.Type != structkey {
-                               Fatalf("initplan structlit")
+                               Fatalf("initplan fixedlit")
                        }
                        addvalue(p, a.Left.Xoffset, a.Right)
                }
index 5674dbee89658483e5204bf2ad48308915fd10b5..e528dc2b76f202312efdf49f29404901894c2418 100644 (file)
@@ -1637,11 +1637,7 @@ opswitch:
                        // n can be directly represented in the read-only data section.
                        // Make direct reference to the static data. See issue 12841.
                        vstat := staticname(n.Type, 0)
-                       if n.Op == OSTRUCTLIT {
-                               structlit(0, 1, n, vstat, init)
-                       } else {
-                               arraylit(0, 1, n, vstat, init)
-                       }
+                       fixedlit(0, 1, n, vstat, init)
                        n = vstat
                        n = typecheck(n, Erv)
                        break