From 0631d65dc525f79991e99b41c745b7c709b6e2a5 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Wed, 9 Sep 2009 17:48:55 -0700 Subject: [PATCH] composit literal under 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 | 31 +++ src/cmd/gc/align.c | 2 + src/cmd/gc/go.h | 1 + src/cmd/gc/sinit.c | 539 +++++++++++++++++++++++++++++++++++++++++++++ src/cmd/gc/walk.c | 485 ---------------------------------------- 5 files changed, 573 insertions(+), 485 deletions(-) diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c index a6c1c6d11f..e94b3e5fdb 100644 --- a/src/cmd/6g/ggen.c +++ b/src/cmd/6g/ggen.c @@ -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); diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c index 703182c0b1..bc963384d2 100644 --- a/src/cmd/gc/align.c +++ b/src/cmd/gc/align.c @@ -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: diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 7b743fd958..93c900db32 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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); diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index 07db731ef0..4ae82ba2ce 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -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; +} diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 18c88867ae..6f5dde3282 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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 -- 2.48.1