]> Cypherpunks repositories - gostls13.git/commitdiff
composit literal under
authorKen Thompson <ken@golang.org>
Thu, 10 Sep 2009 00:48:55 +0000 (17:48 -0700)
committerKen Thompson <ken@golang.org>
Thu, 10 Sep 2009 00:48:55 +0000 (17:48 -0700)
init function context.
also moved composit literal
code from walk.c to sinit.c

R=rsc
OCL=34503
CL=34503

src/cmd/6g/ggen.c
src/cmd/gc/align.c
src/cmd/gc/go.h
src/cmd/gc/sinit.c
src/cmd/gc/walk.c

index a6c1c6d11f653d0e2107eb55a656daab0c079841..e94b3e5fdb25583de0ff82c0f55d37ecc8d2d076 100644 (file)
@@ -1093,6 +1093,9 @@ gen_as_init(Node *n)
        default:
                goto no;
 
+       case OCONVSLICE:
+               goto slice;
+
        case OLITERAL:
                break;
        }
@@ -1143,6 +1146,34 @@ gen_as_init(Node *n)
 yes:
        return 1;
 
+slice:
+       p = gins(ANOP, N, N); // in case the data is the dest of a goto
+       nr = n->right->left;
+       if(nr == N || nr->op != OADDR)
+               goto no;
+       nr = nr->left;
+       if(nr == N || nr->op != ONAME)
+               goto no;
+
+       // nr is the array being converted to a slice
+       if(nr->type == T || nr->type->etype != TARRAY || nr->type->bound < 0)
+               goto no;
+
+       nam.xoffset += Array_array;
+       p = gins(ADATA, &nam, n->right->left);
+       p->from.scale = types[tptr]->width;
+
+       nam.xoffset += Array_nel-Array_array;
+       nodconst(&nod1, types[TINT32], nr->type->bound);
+       p = gins(ADATA, &nam, &nod1);
+       p->from.scale = types[TINT32]->width;
+
+       nam.xoffset += Array_cap-Array_nel;
+       p = gins(ADATA, &nam, &nod1);
+       p->from.scale = types[TINT32]->width;
+
+       goto yes;
+
 no:
        if(n->dodata == 2) {
                dump("\ngen_as_init", n);
index 703182c0b1091de10109fb215dd78244c25e2c5c..bc963384d21bbbd46717e43240247b497d0abb15 100644 (file)
@@ -205,6 +205,8 @@ dowidth(Type *t)
                        w = sizeof_Array;
                else
                        fatal("dowidth %T", t); // probably [...]T
+               if(w == 0)
+                       w = maxround;
                break;
 
        case TSTRUCT:
index 7b743fd958af6e5ac4a1d3ae9ab9091f5954c80d..93c900db3218c1e17ce8d3fe1d0e32d3e63242d6 100644 (file)
@@ -1020,6 +1020,7 @@ void      colasdefn(NodeList*, Node*);
 NodeList*      reorder1(NodeList*);
 NodeList*      reorder3(NodeList*);
 NodeList*      reorder4(NodeList*);
+int    vmatch1(Node*, Node*);
 void   anylit(Node*, Node*, NodeList**);
 int    oaslit(Node*, NodeList**);
 void   heapmoves(void);
index 07db731ef013c332d43306aef2d1f6391cc1abcc..4ae82ba2ce75e8e84a17565bb2909cd0ce4b3bd8 100644 (file)
@@ -95,3 +95,542 @@ initfix(NodeList *l)
        initreorder(l, &lout);
        return lout;
 }
+
+/*
+ * from here down is the walk analysis
+ * of composit literals.
+ * most of the work is to generate
+ * data statements for the constant
+ * part of the composit literal.
+ */
+
+static int
+isliteral(Node *n)
+{
+       if(n->op == OLITERAL)
+               if(n->val.ctype != CTNIL)
+                       return 1;
+       return 0;
+}
+
+static int
+simplename(Node *n)
+{
+       if(n->op != ONAME)
+               goto no;
+       if(!n->addable)
+               goto no;
+       if(n->class & PHEAP)
+               goto no;
+       if(n->class == PPARAMREF)
+               goto no;
+       return 1;
+
+no:
+       return 0;
+}
+
+static void    arraylit(Node *n, Node *var, int pass, NodeList **init);
+
+static void
+structlit(Node *n, Node *var, int pass, NodeList **init)
+{
+       Node *r, *a;
+       NodeList *nl;
+       Node *index, *value;
+
+       for(nl=n->list; nl; nl=nl->next) {
+               r = nl->n;
+               if(r->op != OKEY)
+                       fatal("structlit: rhs not OKEY: %N", r);
+               index = r->left;
+               value = r->right;
+
+               switch(value->op) {
+               case OARRAYLIT:
+                       if(value->type->bound < 0)
+                               break;
+                       a = nod(ODOT, var, newname(index->sym));
+                       arraylit(value, a, pass, init);
+                       continue;
+
+               case OSTRUCTLIT:
+                       a = nod(ODOT, var, newname(index->sym));
+                       structlit(value, a, pass, init);
+                       continue;
+               }
+
+               if(isliteral(value)) {
+                       if(pass == 2)
+                               continue;
+               } else
+                       if(pass == 1)
+                               continue;
+
+               // build list of var.field = expr
+               a = nod(ODOT, var, newname(index->sym));
+               a = nod(OAS, a, value);
+               typecheck(&a, Etop);
+               walkexpr(&a, init);
+               if(pass == 1) {
+                       if(a->op != OAS)
+                               fatal("structlit: not as");
+                       a->dodata = 2;
+               }
+               *init = list(*init, a);
+       }
+}
+
+static void
+arraylit(Node *n, Node *var, int pass, NodeList **init)
+{
+       Node *r, *a;
+       NodeList *l;
+       Node *index, *value;
+
+       for(l=n->list; l; l=l->next) {
+               r = l->n;
+               if(r->op != OKEY)
+                       fatal("arraylit: rhs not OKEY: %N", r);
+               index = r->left;
+               value = r->right;
+
+               switch(value->op) {
+               case OARRAYLIT:
+                       if(value->type->bound < 0)
+                               break;
+                       a = nod(OINDEX, var, index);
+                       arraylit(value, a, pass, init);
+                       continue;
+
+               case OSTRUCTLIT:
+                       a = nod(OINDEX, var, index);
+                       structlit(value, a, pass, init);
+                       continue;
+               }
+
+               if(isliteral(index) && isliteral(value)) {
+                       if(pass == 2)
+                               continue;
+               } else
+                       if(pass == 1)
+                               continue;
+
+               // build list of var[index] = value
+               a = nod(OINDEX, var, index);
+               a = nod(OAS, a, value);
+               typecheck(&a, Etop);
+               walkexpr(&a, init);     // add any assignments in r to top
+               if(pass == 1) {
+                       if(a->op != OAS)
+                               fatal("structlit: not as");
+                       a->dodata = 2;
+               }
+               *init = list(*init, a);
+       }
+}
+
+static void
+slicelit(Node *n, Node *var, NodeList **init)
+{
+       Node *r, *a;
+       NodeList *l;
+       Type *t;
+       Node *vstat, *vheap;
+       Node *index, *value;
+
+       // make an array type
+       t = shallow(n->type);
+       t->bound = mpgetfix(n->right->val.u.xval);
+       t->width = 0;
+       dowidth(t);
+
+       // make static initialized array
+       vstat = staticname(t);
+       arraylit(n, vstat, 1, init);
+
+       // make new *array heap
+       vheap = nod(OXXX, N, N);
+       tempname(vheap, ptrto(t));
+
+       a = nod(ONEW, N, N);
+       a->list = list1(typenod(t));
+       a = nod(OAS, vheap, a);
+       typecheck(&a, Etop);
+       walkexpr(&a, init);
+       *init = list(*init, a);
+
+       // copy static to heap
+       a = nod(OIND, vheap, N);
+       a = nod(OAS, a, vstat);
+       typecheck(&a, Etop);
+       walkexpr(&a, init);
+       *init = list(*init, a);
+
+       // make slice out of heap
+       a = nod(OAS, var, vheap);
+       typecheck(&a, Etop);
+       walkexpr(&a, init);
+       *init = list(*init, a);
+
+       // put dynamics into slice
+       for(l=n->list; l; l=l->next) {
+               r = l->n;
+               if(r->op != OKEY)
+                       fatal("slicelit: rhs not OKEY: %N", r);
+               index = r->left;
+               value = r->right;
+
+               switch(value->op) {
+               case OARRAYLIT:
+                       if(value->type->bound < 0)
+                               break;
+                       a = nod(OINDEX, var, index);
+                       arraylit(value, a, 2, init);
+                       continue;
+
+               case OSTRUCTLIT:
+                       a = nod(OINDEX, var, index);
+                       structlit(value, a, 2, init);
+                       continue;
+               }
+
+               if(isliteral(index) && isliteral(value))
+                       continue;
+
+               // build list of var[c] = expr
+               a = nod(OINDEX, var, index);
+               a = nod(OAS, a, value);
+               typecheck(&a, Etop);
+               walkexpr(&a, init);     // add any assignments in r to top
+               *init = list(*init, a);
+       }
+}
+
+static void
+maplit(Node *n, Node *var, NodeList **init)
+{
+       Node *r, *a;
+       NodeList *l;
+       int nerr, b;
+       Type *t, *tk, *tv, *t1;
+       Node *vstat, *index, *value;
+       Sym *syma, *symb;
+
+       // make the map var
+       nerr = nerrors;
+
+       a = nod(OMAKE, N, N);
+       a->list = list1(typenod(n->type));
+       a = nod(OAS, var, a);
+       typecheck(&a, Etop);
+       walkexpr(&a, init);
+       *init = list(*init, a);
+
+       // count the initializers
+       b = 0;
+       for(l=n->list; l; l=l->next) {
+               r = l->n;
+
+               if(r->op != OKEY)
+                       fatal("slicelit: rhs not OKEY: %N", r);
+               index = r->left;
+               value = r->right;
+
+               if(isliteral(index) && isliteral(value))
+                       b++;
+       }
+
+       t = T;
+       if(b != 0) {
+               // build type [count]struct { a Tindex, b Tvalue }
+               t = n->type;
+               tk = t->down;
+               tv = t->type;
+
+               symb = lookup("b");
+               t = typ(TFIELD);
+               t->type = tv;
+               t->sym = symb;
+
+               syma = lookup("a");
+               t1 = t;
+               t = typ(TFIELD);
+               t->type = tk;
+               t->sym = syma;
+               t->down = t1;
+
+               t1 = t;
+               t = typ(TSTRUCT);
+               t->type = t1;
+
+               t1 = t;
+               t = typ(TARRAY);
+               t->bound = b;
+               t->type = t1;
+
+               dowidth(t);
+
+               // make and initialize static array
+               vstat = staticname(t);
+               b = 0;
+               for(l=n->list; l; l=l->next) {
+                       r = l->n;
+
+                       if(r->op != OKEY)
+                               fatal("slicelit: rhs not OKEY: %N", r);
+                       index = r->left;
+                       value = r->right;
+
+                       if(isliteral(index) && isliteral(value)) {
+                               // build vstat[b].a = key;
+                               a = nodintconst(b);
+                               a = nod(OINDEX, vstat, a);
+                               a = nod(ODOT, a, newname(syma));
+                               a = nod(OAS, a, index);
+                               typecheck(&a, Etop);
+                               walkexpr(&a, init);
+                               a->dodata = 2;
+                               *init = list(*init, a);
+
+                               // build vstat[b].b = value;
+                               a = nodintconst(b);
+                               a = nod(OINDEX, vstat, a);
+                               a = nod(ODOT, a, newname(symb));
+                               a = nod(OAS, a, value);
+                               typecheck(&a, Etop);
+                               walkexpr(&a, init);
+                               a->dodata = 2;
+                               *init = list(*init, a);
+
+                               b++;
+                       }
+               }
+
+               // loop adding structure elements to map
+               // for i = 0; i < len(vstat); i++ {
+               //      map[vstat[i].a] = vstat[i].b
+               // }
+               index = nod(OXXX, N, N);
+               tempname(index, types[TINT]);
+
+               a = nod(OINDEX, vstat, index);
+               a = nod(ODOT, a, newname(symb));
+
+               r = nod(OINDEX, vstat, index);
+               r = nod(ODOT, r, newname(syma));
+               r = nod(OINDEX, var, r);
+
+               r = nod(OAS, r, a);
+
+               a = nod(OFOR, N, N);
+               a->nbody = list1(r);
+
+               a->ninit = list1(nod(OAS, index, nodintconst(0)));
+               a->ntest = nod(OLT, index, nodintconst(t->bound));
+               a->nincr = nod(OASOP, index, nodintconst(1));
+               a->nincr->etype = OADD;
+
+               typecheck(&a, Etop);
+               walkstmt(&a);
+               *init = list(*init, a);
+       }
+
+       // put in dynamic entries one-at-a-time
+       for(l=n->list; l; l=l->next) {
+               r = l->n;
+
+               if(r->op != OKEY)
+                       fatal("slicelit: rhs not OKEY: %N", r);
+               index = r->left;
+               value = r->right;
+
+               if(isliteral(index) && isliteral(value))
+                       continue;
+
+               // build list of var[c] = expr
+               a = nod(OINDEX, var, r->left);
+               a = nod(OAS, a, r->right);
+               typecheck(&a, Etop);
+               walkexpr(&a, init);
+               if(nerr != nerrors)
+                       break;
+
+               *init = list(*init, a);
+       }
+}
+
+void
+anylit(Node *n, Node *var, NodeList **init)
+{
+       Type *t;
+       Node *a, *vstat;
+
+       t = n->type;
+       switch(n->op) {
+       default:
+               fatal("anylit: not lit");
+
+       case OSTRUCTLIT:
+               if(t->etype != TSTRUCT)
+                       fatal("anylit: not struct");
+
+               if(simplename(var)) {
+
+                       // lay out static data
+                       vstat = staticname(t);
+                       structlit(n, vstat, 1, init);
+
+                       // copy static to automatic
+                       a = nod(OAS, var, vstat);
+                       typecheck(&a, Etop);
+                       walkexpr(&a, init);
+                       *init = list(*init, a);
+
+                       // add expressions to automatic
+                       structlit(n, var, 2, init);
+                       break;
+               }
+
+               // initialize of not completely specified
+               if(count(n->list) < structcount(t)) {
+                       a = nod(OAS, var, N);
+                       typecheck(&a, Etop);
+                       walkexpr(&a, init);
+                       *init = list(*init, a);
+               }
+               structlit(n, var, 3, init);
+               break;
+
+       case OARRAYLIT:
+               if(t->etype != TARRAY)
+                       fatal("anylit: not array");
+               if(t->bound < 0) {
+                       slicelit(n, var, init);
+                       break;
+               }
+
+               if(simplename(var)) {
+
+                       // lay out static data
+                       vstat = staticname(t);
+                       arraylit(n, vstat, 1, init);
+
+                       // copy static to automatic
+                       a = nod(OAS, var, vstat);
+                       typecheck(&a, Etop);
+                       walkexpr(&a, init);
+                       *init = list(*init, a);
+
+                       // add expressions to automatic
+                       arraylit(n, var, 2, init);
+                       break;
+               }
+
+               // initialize of not completely specified
+               if(count(n->list) < t->bound) {
+                       a = nod(OAS, var, N);
+                       typecheck(&a, Etop);
+                       walkexpr(&a, init);
+                       *init = list(*init, a);
+               }
+               arraylit(n, var, 3, init);
+               break;
+
+       case OMAPLIT:
+               if(t->etype != TMAP)
+                       fatal("anylit: not map");
+               maplit(n, var, init);
+               break;
+       }
+}
+
+int
+oaslit(Node *n, NodeList **init)
+{
+       Type *t;
+       Node *vstat, *a;
+
+       if(n->left == N || n->right == N)
+               goto no;
+       if(n->left->type == T || n->right->type == T)
+               goto no;
+       if(!simplename(n->left))
+               goto no;
+       if(!eqtype(n->left->type, n->right->type))
+               goto no;
+       if(n->dodata == 1)
+               goto initctxt;
+
+       switch(n->right->op) {
+       default:
+               goto no;
+
+       case OSTRUCTLIT:
+       case OARRAYLIT:
+       case OMAPLIT:
+               if(vmatch1(n->left, n->right))
+                       goto no;
+               anylit(n->right, n->left, init);
+               break;
+       }
+       n->op = OEMPTY;
+       return 1;
+
+no:
+       // not a special composit literal assignment
+       return 0;
+
+initctxt:
+       // in the initialization context
+       // we are trying to put data statements
+       // right into the initialized variables
+       switch(n->right->op) {
+       default:
+               goto no;
+
+       case OSTRUCTLIT:
+               structlit(n->right, n->left, 1, init);
+               structlit(n->right, n->left, 2, init);
+               break;
+
+       case OARRAYLIT:
+               t = n->right->type;
+               if(t == T)
+                       goto no;
+               if(t->bound >= 0) {
+                       arraylit(n->right, n->left, 1, init);
+                       arraylit(n->right, n->left, 2, init);
+                       break;
+               }
+
+               // make a static slice
+               // make an array type
+               t = shallow(t);
+               t->bound = mpgetfix(n->right->right->val.u.xval);
+               t->width = 0;
+               dowidth(t);
+
+               // make static initialized array
+               vstat = staticname(t);
+               arraylit(n->right, vstat, 1, init);
+               arraylit(n->right, vstat, 2, init);
+
+               // copy static to slice
+               a = nod(OADDR, vstat, N);
+               a = nod(OAS, n->left, a);
+               typecheck(&a, Etop);
+// turns into a function that is hard to parse
+// in ggen where it is turned into DATA statements
+//             walkexpr(&a, init);
+               a->dodata = 2;
+               *init = list(*init, a);
+               break;
+
+       case OMAPLIT:
+               maplit(n->right, n->left, init);
+               break;
+       }
+       n->op = OEMPTY;
+       return 1;
+}
index 18c88867ae78b6a3f7aa94b8a86fc475737fea9a..6f5dde32820470f86084631cdf16c72977b14a89 100644 (file)
@@ -1971,491 +1971,6 @@ reorder4(NodeList *ll)
        return ll;
 }
 
-static int
-isliteral(Node *n)
-{
-       if(n->op == OLITERAL)
-               if(n->val.ctype != CTNIL)
-                       return 1;
-       return 0;
-}
-
-void   arraylit(Node *n, Node *var, int pass, NodeList **init);
-
-void
-structlit(Node *n, Node *var, int pass, NodeList **init)
-{
-       Node *r, *a;
-       NodeList *nl;
-       Node *index, *value;
-
-       for(nl=n->list; nl; nl=nl->next) {
-               r = nl->n;
-               if(r->op != OKEY)
-                       fatal("structlit: rhs not OKEY: %N", r);
-               index = r->left;
-               value = r->right;
-
-               switch(value->op) {
-               case OARRAYLIT:
-                       if(value->type->bound < 0)
-                               break;
-                       a = nod(ODOT, var, newname(index->sym));
-                       arraylit(value, a, pass, init);
-                       continue;
-
-               case OSTRUCTLIT:
-                       a = nod(ODOT, var, newname(index->sym));
-                       structlit(value, a, pass, init);
-                       continue;
-               }
-
-               if(isliteral(value)) {
-                       if(pass == 2)
-                               continue;
-               } else
-                       if(pass == 1)
-                               continue;
-
-               // build list of var.field = expr
-               a = nod(ODOT, var, newname(index->sym));
-               a = nod(OAS, a, value);
-               typecheck(&a, Etop);
-               walkexpr(&a, init);
-               if(pass == 1) {
-                       if(a->op != OAS)
-                               fatal("structlit: not as");
-                       a->dodata = 2;
-               }
-               *init = list(*init, a);
-       }
-}
-
-void
-arraylit(Node *n, Node *var, int pass, NodeList **init)
-{
-       Node *r, *a;
-       NodeList *l;
-       Node *index, *value;
-
-       for(l=n->list; l; l=l->next) {
-               r = l->n;
-               if(r->op != OKEY)
-                       fatal("arraylit: rhs not OKEY: %N", r);
-               index = r->left;
-               value = r->right;
-
-               switch(value->op) {
-               case OARRAYLIT:
-                       if(value->type->bound < 0)
-                               break;
-                       a = nod(OINDEX, var, index);
-                       arraylit(value, a, pass, init);
-                       continue;
-
-               case OSTRUCTLIT:
-                       a = nod(OINDEX, var, index);
-                       structlit(value, a, pass, init);
-                       continue;
-               }
-
-               if(isliteral(index) && isliteral(value)) {
-                       if(pass == 2)
-                               continue;
-               } else
-                       if(pass == 1)
-                               continue;
-
-               // build list of var[index] = value
-               a = nod(OINDEX, var, index);
-               a = nod(OAS, a, value);
-               typecheck(&a, Etop);
-               walkexpr(&a, init);     // add any assignments in r to top
-               if(pass == 1) {
-                       if(a->op != OAS)
-                               fatal("structlit: not as");
-                       a->dodata = 2;
-               }
-               *init = list(*init, a);
-       }
-}
-
-void
-slicelit(Node *n, Node *var, NodeList **init)
-{
-       Node *r, *a;
-       NodeList *l;
-       Type *t;
-       Node *vstat, *vheap;
-       Node *index, *value;
-
-       // make an array type
-       t = shallow(n->type);
-       t->bound = mpgetfix(n->right->val.u.xval);
-       t->width = 0;
-       dowidth(t);
-
-       // make static initialized array
-       vstat = staticname(t);
-       arraylit(n, vstat, 1, init);
-
-       // make new *array heap
-       vheap = nod(OXXX, N, N);
-       tempname(vheap, ptrto(t));
-
-       a = nod(ONEW, N, N);
-       a->list = list1(typenod(t));
-       a = nod(OAS, vheap, a);
-       typecheck(&a, Etop);
-       walkexpr(&a, init);
-       *init = list(*init, a);
-
-       // copy static to heap
-       a = nod(OIND, vheap, N);
-       a = nod(OAS, a, vstat);
-       typecheck(&a, Etop);
-       walkexpr(&a, init);
-       *init = list(*init, a);
-
-       // make slice out of heap
-       a = nod(OAS, var, vheap);
-       typecheck(&a, Etop);
-       walkexpr(&a, init);
-       *init = list(*init, a);
-
-       // put dynamics into slice
-       for(l=n->list; l; l=l->next) {
-               r = l->n;
-               if(r->op != OKEY)
-                       fatal("slicelit: rhs not OKEY: %N", r);
-               index = r->left;
-               value = r->right;
-
-               switch(value->op) {
-               case OARRAYLIT:
-                       if(value->type->bound < 0)
-                               break;
-                       a = nod(OINDEX, var, index);
-                       arraylit(value, a, 2, init);
-                       continue;
-
-               case OSTRUCTLIT:
-                       a = nod(OINDEX, var, index);
-                       structlit(value, a, 2, init);
-                       continue;
-               }
-
-               if(isliteral(index) && isliteral(value))
-                       continue;
-
-               // build list of var[c] = expr
-               a = nod(OINDEX, var, index);
-               a = nod(OAS, a, value);
-               typecheck(&a, Etop);
-               walkexpr(&a, init);     // add any assignments in r to top
-               *init = list(*init, a);
-       }
-}
-
-void
-maplit(Node *n, Node *var, NodeList **init)
-{
-       Node *r, *a;
-       NodeList *l;
-       int nerr, b;
-       Type *t, *tk, *tv, *t1;
-       Node *vstat, *index, *value;
-       Sym *syma, *symb;
-
-       // make the map var
-       nerr = nerrors;
-
-       a = nod(OMAKE, N, N);
-       a->list = list1(typenod(n->type));
-       a = nod(OAS, var, a);
-       typecheck(&a, Etop);
-       walkexpr(&a, init);
-       *init = list(*init, a);
-
-       // count the initializers
-       b = 0;
-       for(l=n->list; l; l=l->next) {
-               r = l->n;
-
-               if(r->op != OKEY)
-                       fatal("slicelit: rhs not OKEY: %N", r);
-               index = r->left;
-               value = r->right;
-
-               if(isliteral(index) && isliteral(value))
-                       b++;
-       }
-
-       t = T;
-       if(b != 0) {
-               // build type [count]struct { a Tindex, b Tvalue }
-               t = n->type;
-               tk = t->down;
-               tv = t->type;
-
-               symb = lookup("b");
-               t = typ(TFIELD);
-               t->type = tv;
-               t->sym = symb;
-
-               syma = lookup("a");
-               t1 = t;
-               t = typ(TFIELD);
-               t->type = tk;
-               t->sym = syma;
-               t->down = t1;
-
-               t1 = t;
-               t = typ(TSTRUCT);
-               t->type = t1;
-
-               t1 = t;
-               t = typ(TARRAY);
-               t->bound = b;
-               t->type = t1;
-
-               dowidth(t);
-
-               // make and initialize static array
-               vstat = staticname(t);
-               b = 0;
-               for(l=n->list; l; l=l->next) {
-                       r = l->n;
-
-                       if(r->op != OKEY)
-                               fatal("slicelit: rhs not OKEY: %N", r);
-                       index = r->left;
-                       value = r->right;
-
-                       if(isliteral(index) && isliteral(value)) {
-                               // build vstat[b].a = key;
-                               a = nodintconst(b);
-                               a = nod(OINDEX, vstat, a);
-                               a = nod(ODOT, a, newname(syma));
-                               a = nod(OAS, a, index);
-                               typecheck(&a, Etop);
-                               walkexpr(&a, init);
-                               a->dodata = 2;
-                               *init = list(*init, a);
-
-                               // build vstat[b].b = value;
-                               a = nodintconst(b);
-                               a = nod(OINDEX, vstat, a);
-                               a = nod(ODOT, a, newname(symb));
-                               a = nod(OAS, a, value);
-                               typecheck(&a, Etop);
-                               walkexpr(&a, init);
-                               a->dodata = 2;
-                               *init = list(*init, a);
-
-                               b++;
-                       }
-               }
-
-               // loop adding structure elements to map
-               // for i = 0; i < len(vstat); i++ {
-               //      map[vstat[i].a] = vstat[i].b
-               // }
-               index = nod(OXXX, N, N);
-               tempname(index, types[TINT]);
-
-               a = nod(OINDEX, vstat, index);
-               a = nod(ODOT, a, newname(symb));
-
-               r = nod(OINDEX, vstat, index);
-               r = nod(ODOT, r, newname(syma));
-               r = nod(OINDEX, var, r);
-
-               r = nod(OAS, r, a);
-
-               a = nod(OFOR, N, N);
-               a->nbody = list1(r);
-
-               a->ninit = list1(nod(OAS, index, nodintconst(0)));
-               a->ntest = nod(OLT, index, nodintconst(t->bound));
-               a->nincr = nod(OASOP, index, nodintconst(1));
-               a->nincr->etype = OADD;
-
-               typecheck(&a, Etop);
-               walkstmt(&a);
-               *init = list(*init, a);
-       }
-
-       // put in dynamic entries one-at-a-time
-       for(l=n->list; l; l=l->next) {
-               r = l->n;
-
-               if(r->op != OKEY)
-                       fatal("slicelit: rhs not OKEY: %N", r);
-               index = r->left;
-               value = r->right;
-
-               if(isliteral(index) && isliteral(value))
-                       continue;
-
-               // build list of var[c] = expr
-               a = nod(OINDEX, var, r->left);
-               a = nod(OAS, a, r->right);
-               typecheck(&a, Etop);
-               walkexpr(&a, init);
-               if(nerr != nerrors)
-                       break;
-
-               *init = list(*init, a);
-       }
-}
-
-static int
-simplename(Node *n)
-{
-       if(n->op != ONAME)
-               goto no;
-       if(!n->addable)
-               goto no;
-       if(n->class & PHEAP)
-               goto no;
-       if(n->class == PPARAMREF)
-               goto no;
-       return 1;
-
-no:
-       return 0;
-}
-
-void
-anylit(Node *n, Node *var, NodeList **init)
-{
-       Type *t;
-       Node *a, *vstat;
-
-       t = n->type;
-       switch(n->op) {
-       default:
-               fatal("anylit: not lit");
-
-       case OSTRUCTLIT:
-               if(t->etype != TSTRUCT)
-                       fatal("anylit: not struct");
-
-               if(simplename(var)) {
-
-                       // lay out static data
-                       vstat = staticname(t);
-                       structlit(n, vstat, 1, init);
-
-                       // copy static to automatic
-                       a = nod(OAS, var, vstat);
-                       typecheck(&a, Etop);
-                       walkexpr(&a, init);
-                       *init = list(*init, a);
-
-                       // add expressions to automatic
-                       structlit(n, var, 2, init);
-                       break;
-               }
-
-               // initialize of not completely specified
-               if(count(n->list) < structcount(t)) {
-                       a = nod(OAS, var, N);
-                       typecheck(&a, Etop);
-                       walkexpr(&a, init);
-                       *init = list(*init, a);
-               }
-               structlit(n, var, 3, init);
-               break;
-
-       case OARRAYLIT:
-               if(t->etype != TARRAY)
-                       fatal("anylit: not array");
-               if(t->bound < 0) {
-                       slicelit(n, var, init);
-                       break;
-               }
-
-               if(simplename(var)) {
-
-                       // lay out static data
-                       vstat = staticname(t);
-                       arraylit(n, vstat, 1, init);
-
-                       // copy static to automatic
-                       a = nod(OAS, var, vstat);
-                       typecheck(&a, Etop);
-                       walkexpr(&a, init);
-                       *init = list(*init, a);
-
-                       // add expressions to automatic
-                       arraylit(n, var, 2, init);
-                       break;
-               }
-
-               // initialize of not completely specified
-               if(count(n->list) < t->bound) {
-                       a = nod(OAS, var, N);
-                       typecheck(&a, Etop);
-                       walkexpr(&a, init);
-                       *init = list(*init, a);
-               }
-               arraylit(n, var, 3, init);
-               break;
-
-       case OMAPLIT:
-               if(t->etype != TMAP)
-                       fatal("anylit: not map");
-               maplit(n, var, init);
-               break;
-       }
-}
-
-int
-oaslit(Node *n, NodeList **init)
-{
-       Type *t;
-
-       if(n->left == N || n->right == N)
-               goto no;
-       if(!simplename(n->left))
-               goto no;
-       if(n->dodata == 1)
-               goto initctxt;
-
-no:
-       // not a special composit literal assignment
-       return 0;
-
-initctxt:
-       switch(n->right->op) {
-       default:
-               goto no;
-
-       case OSTRUCTLIT:
-               structlit(n->right, n->left, 3, init);
-               break;
-
-       case OARRAYLIT:
-               t = n->right->type;
-               if(t == T)
-                       goto no;
-               if(t->bound < 0) {
-                       slicelit(n->right, n->left, init);
-                       break;
-               }
-               arraylit(n->right, n->left, 3, init);
-               break;
-
-       case OMAPLIT:
-               maplit(n->right, n->left, init);
-               break;
-       }
-       n->op = OEMPTY;
-       return 1;
-}
-
 /*
  * walk through argin parameters.
  * generate and return code to allocate