1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 /*
6 * static initialization
7 */
8
9 #include "go.h"
10
11 static NodeList *initlist;
12 static void init2(Node*, NodeList**);
13 static void init2list(NodeList*, NodeList**);
14
15 static void
16 init1(Node *n, NodeList **out)
17 {
18 NodeList *l;
19
20 if(n == N)
21 return;
22 init1(n->left, out);
23 init1(n->right, out);
24 for(l=n->list; l; l=l->next)
25 init1(l->n, out);
26
27 if(n->op != ONAME)
28 return;
29 switch(n->class) {
30 case PEXTERN:
31 case PFUNC:
32 break;
33 default:
34 if(isblank(n) && n->defn != N && !n->defn->initorder) {
35 n->defn->initorder = 1;
36 *out = list(*out, n->defn);
37 }
38 return;
39 }
40
41 if(n->initorder == 1)
42 return;
43 if(n->initorder == 2) {
44 if(n->class == PFUNC)
45 return;
46
47 // if there have already been errors printed,
48 // those errors probably confused us and
49 // there might not be a loop. let the user
50 // fix those first.
51 flusherrors();
52 if(nerrors > 0)
53 errorexit();
54
55 print("initialization loop:\n");
56 for(l=initlist;; l=l->next) {
57 if(l->next == nil)
58 break;
59 l->next->end = l;
60 }
61 for(; l; l=l->end)
62 print("\t%L %S refers to\n", l->n->lineno, l->n->sym);
63 print("\t%L %S\n", n->lineno, n->sym);
64 errorexit();
65 }
66 n->initorder = 2;
67 l = malloc(sizeof *l);
68 l->next = initlist;
69 l->n = n;
70 l->end = nil;
71 initlist = l;
72
73 // make sure that everything n depends on is initialized.
74 // n->defn is an assignment to n
75 if(n->defn != N) {
76 switch(n->defn->op) {
77 default:
78 goto bad;
79
80 case ODCLFUNC:
81 init2list(n->defn->nbody, out);
82 break;
83
84 case OAS:
85 if(n->defn->left != n)
86 goto bad;
87 n->defn->dodata = 1;
88 init1(n->defn->right, out);
89 if(debug['j'])
90 print("%S\n", n->sym);
91 *out = list(*out, n->defn);
92 break;
93
94 case OAS2FUNC:
95 case OAS2MAPR:
96 case OAS2DOTTYPE:
97 case OAS2RECV:
98 if(n->defn->initorder)
99 break;
100 n->defn->initorder = 1;
101 for(l=n->defn->rlist; l; l=l->next)
102 init1(l->n, out);
103 *out = list(*out, n->defn);
104 break;
105 }
106 }
107 l = initlist;
108 initlist = l->next;
109 if(l->n != n)
110 fatal("bad initlist");
111 free(l);
112 n->initorder = 1;
113 return;
114
115 bad:
116 dump("defn", n->defn);
117 fatal("init1: bad defn");
118 }
119
120 // recurse over n, doing init1 everywhere.
121 static void
122 init2(Node *n, NodeList **out)
123 {
124 if(n == N || n->initorder == 1)
125 return;
126 init1(n, out);
127 init2(n->left, out);
128 init2(n->right, out);
129 init2(n->ntest, out);
130 init2list(n->ninit, out);
131 init2list(n->list, out);
132 init2list(n->rlist, out);
133 init2list(n->nbody, out);
134 init2list(n->nelse, out);
135 }
136
137 static void
138 init2list(NodeList *l, NodeList **out)
139 {
140 for(; l; l=l->next)
141 init2(l->n, out);
142 }
143
144
145 static void
146 initreorder(NodeList *l, NodeList **out)
147 {
148 Node *n;
149
150 for(; l; l=l->next) {
151 n = l->n;
152 switch(n->op) {
153 case ODCLFUNC:
154 case ODCLCONST:
155 case ODCLTYPE:
156 continue;
157 }
158 initreorder(n->ninit, out);
159 n->ninit = nil;
160 init1(n, out);
161 }
162 }
163
164 NodeList*
165 initfix(NodeList *l)
166 {
167 NodeList *lout;
168
169 lout = nil;
170 initreorder(l, &lout);
171 return lout;
172 }
173
174 /*
175 * from here down is the walk analysis
176 * of composite literals.
177 * most of the work is to generate
178 * data statements for the constant
179 * part of the composite literal.
180 */
181
182 static void structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init);
183 static void arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init);
184 static void slicelit(int ctxt, Node *n, Node *var, NodeList **init);
185 static void maplit(int ctxt, Node *n, Node *var, NodeList **init);
186
187 static Node*
188 staticname(Type *t, int ctxt)
189 {
190 Node *n;
191
192 snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen);
193 statuniqgen++;
194 n = newname(lookup(namebuf));
195 if(!ctxt)
196 n->readonly = 1;
197 addvar(n, t, PEXTERN);
198 return n;
199 }
200
201 static int
202 isliteral(Node *n)
203 {
204 if(n->op == OLITERAL)
205 if(n->val.ctype != CTNIL)
206 return 1;
207 return 0;
208 }
209
210 static int
211 simplename(Node *n)
212 {
213 if(n->op != ONAME)
214 goto no;
215 if(!n->addable)
216 goto no;
217 if(n->class & PHEAP)
218 goto no;
219 if(n->class == PPARAMREF)
220 goto no;
221 return 1;
222
223 no:
224 return 0;
225 }
226
227 static void
228 litas(Node *l, Node *r, NodeList **init)
229 {
230 Node *a;
231
232 a = nod(OAS, l, r);
233 typecheck(&a, Etop);
234 walkexpr(&a, init);
235 *init = list(*init, a);
236 }
237
238 enum
239 {
240 MODEDYNAM = 1,
241 MODECONST = 2,
242 };
243
244 static int
245 getdyn(Node *n, int top)
246 {
247 NodeList *nl;
248 Node *value;
249 int mode;
250
251 mode = 0;
252 switch(n->op) {
253 default:
254 if(isliteral(n))
255 return MODECONST;
256 return MODEDYNAM;
257 case OARRAYLIT:
258 if(!top && n->type->bound < 0)
259 return MODEDYNAM;
260 case OSTRUCTLIT:
261 break;
262 }
263
264 for(nl=n->list; nl; nl=nl->next) {
265 value = nl->n->right;
266 mode |= getdyn(value, 0);
267 if(mode == (MODEDYNAM|MODECONST))
268 break;
269 }
270 return mode;
271 }
272
273 static void
274 structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
275 {
276 Node *r, *a;
277 NodeList *nl;
278 Node *index, *value;
279
280 for(nl=n->list; nl; nl=nl->next) {
281 r = nl->n;
282 if(r->op != OKEY)
283 fatal("structlit: rhs not OKEY: %N", r);
284 index = r->left;
285 value = r->right;
286
287 switch(value->op) {
288 case OARRAYLIT:
289 if(value->type->bound < 0) {
290 if(pass == 1 && ctxt != 0) {
291 a = nod(ODOT, var, newname(index->sym));
292 slicelit(ctxt, value, a, init);
293 } else
294 if(pass == 2 && ctxt == 0) {
295 a = nod(ODOT, var, newname(index->sym));
296 slicelit(ctxt, value, a, init);
297 } else
298 if(pass == 3)
299 break;
300 continue;
301 }
302 a = nod(ODOT, var, newname(index->sym));
303 arraylit(ctxt, pass, value, a, init);
304 continue;
305
306 case OSTRUCTLIT:
307 a = nod(ODOT, var, newname(index->sym));
308 structlit(ctxt, pass, value, a, init);
309 continue;
310 }
311
312 if(isliteral(value)) {
313 if(pass == 2)
314 continue;
315 } else
316 if(pass == 1)
317 continue;
318
319 // build list of var.field = expr
320 a = nod(ODOT, var, newname(index->sym));
321 a = nod(OAS, a, value);
322 typecheck(&a, Etop);
323 walkexpr(&a, init);
324 if(pass == 1) {
325 if(a->op != OAS)
326 fatal("structlit: not as");
327 a->dodata = 2;
328 }
329 *init = list(*init, a);
330 }
331 }
332
333 static void
334 arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
335 {
336 Node *r, *a;
337 NodeList *l;
338 Node *index, *value;
339
340 for(l=n->list; l; l=l->next) {
341 r = l->n;
342 if(r->op != OKEY)
343 fatal("arraylit: rhs not OKEY: %N", r);
344 index = r->left;
345 value = r->right;
346
347 switch(value->op) {
348 case OARRAYLIT:
349 if(value->type->bound < 0) {
350 if(pass == 1 && ctxt != 0) {
351 a = nod(OINDEX, var, index);
352 slicelit(ctxt, value, a, init);
353 } else
354 if(pass == 2 && ctxt == 0) {
355 a = nod(OINDEX, var, index);
356 slicelit(ctxt, value, a, init);
357 } else
358 if(pass == 3)
359 break;
360 continue;
361 }
362 a = nod(OINDEX, var, index);
363 arraylit(ctxt, pass, value, a, init);
364 continue;
365
366 case OSTRUCTLIT:
367 a = nod(OINDEX, var, index);
368 structlit(ctxt, pass, value, a, init);
369 continue;
370 }
371
372 if(isliteral(index) && isliteral(value)) {
373 if(pass == 2)
374 continue;
375 } else
376 if(pass == 1)
377 continue;
378
379 // build list of var[index] = value
380 a = nod(OINDEX, var, index);
381 a = nod(OAS, a, value);
382 typecheck(&a, Etop);
383 walkexpr(&a, init); // add any assignments in r to top
384 if(pass == 1) {
385 if(a->op != OAS)
386 fatal("structlit: not as");
387 a->dodata = 2;
388 }
389 *init = list(*init, a);
390 }
391 }
392
393 static void
394 slicelit(int ctxt, Node *n, Node *var, NodeList **init)
395 {
396 Node *r, *a;
397 NodeList *l;
398 Type *t;
399 Node *vstat, *vauto;
400 Node *index, *value;
401 int mode;
402
403 // make an array type
404 t = shallow(n->type);
405 t->bound = mpgetfix(n->right->val.u.xval);
406 t->width = 0;
407 t->sym = nil;
408 dowidth(t);
409
410 if(ctxt != 0) {
411
412 // put everything into static array
413 vstat = staticname(t, ctxt);
414 arraylit(ctxt, 1, n, vstat, init);
415 arraylit(ctxt, 2, n, vstat, init);
416
417 // copy static to slice
418 a = nod(OSLICE, vstat, nod(OKEY, N, N));
419 a = nod(OAS, var, a);
420 typecheck(&a, Etop);
421 a->dodata = 2;
422 *init = list(*init, a);
423 return;
424 }
425
426 // recipe for var = []t{...}
427 // 1. make a static array
428 // var vstat [...]t
429 // 2. assign (data statements) the constant part
430 // vstat = constpart{}
431 // 3. make an auto pointer to array and allocate heap to it
432 // var vauto *[...]t = new([...]t)
433 // 4. copy the static array to the auto array
434 // *vauto = vstat
435 // 5. assign slice of allocated heap to var
436 // var = [0:]*auto
437 // 6. for each dynamic part assign to the slice
438 // var[i] = dynamic part
439 //
440 // an optimization is done if there is no constant part
441 // 3. var vauto *[...]t = new([...]t)
442 // 5. var = [0:]*auto
443 // 6. var[i] = dynamic part
444
445 // if the literal contains constants,
446 // make static initialized array (1),(2)
447 vstat = N;
448 mode = getdyn(n, 1);
449 if(mode & MODECONST) {
450 vstat = staticname(t, ctxt);
451 arraylit(ctxt, 1, n, vstat, init);
452 }
453
454 // make new auto *array (3 declare)
455 vauto = nod(OXXX, N, N);
456 tempname(vauto, ptrto(t));
457
458 // set auto to point at new heap (3 assign)
459 a = nod(ONEW, N, N);
460 a->list = list1(typenod(t));
461 a = nod(OAS, vauto, a);
462 typecheck(&a, Etop);
463 walkexpr(&a, init);
464 *init = list(*init, a);
465
466 if(vstat != N) {
467 // copy static to heap (4)
468 a = nod(OIND, vauto, N);
469 a = nod(OAS, a, vstat);
470 typecheck(&a, Etop);
471 walkexpr(&a, init);
472 *init = list(*init, a);
473 }
474
475 // make slice out of heap (5)
476 a = nod(OAS, var, nod(OSLICE, vauto, nod(OKEY, N, N)));
477 typecheck(&a, Etop);
478 walkexpr(&a, init);
479 *init = list(*init, a);
480
481 // put dynamics into slice (6)
482 for(l=n->list; l; l=l->next) {
483 r = l->n;
484 if(r->op != OKEY)
485 fatal("slicelit: rhs not OKEY: %N", r);
486 index = r->left;
487 value = r->right;
488 a = nod(OINDEX, var, index);
489 a->etype = 1; // no bounds checking
490 // TODO need to check bounds?
491
492 switch(value->op) {
493 case OARRAYLIT:
494 if(value->type->bound < 0)
495 break;
496 arraylit(ctxt, 2, value, a, init);
497 continue;
498
499 case OSTRUCTLIT:
500 structlit(ctxt, 2, value, a, init);
501 continue;
502 }
503
504 if(isliteral(index) && isliteral(value))
505 continue;
506
507 // build list of var[c] = expr
508 a = nod(OAS, a, value);
509 typecheck(&a, Etop);
510 walkexpr(&a, init);
511 *init = list(*init, a);
512 }
513 }
514
515 static void
516 maplit(int ctxt, Node *n, Node *var, NodeList **init)
517 {
518 Node *r, *a;
519 NodeList *l;
520 int nerr, b;
521 Type *t, *tk, *tv, *t1;
522 Node *vstat, *index, *value;
523 Sym *syma, *symb;
524
525 ctxt = 0;
526
527 // make the map var
528 nerr = nerrors;
529
530 a = nod(OMAKE, N, N);
531 a->list = list1(typenod(n->type));
532 litas(var, a, init);
533
534 // count the initializers
535 b = 0;
536 for(l=n->list; l; l=l->next) {
537 r = l->n;
538
539 if(r->op != OKEY)
540 fatal("slicelit: rhs not OKEY: %N", r);
541 index = r->left;
542 value = r->right;
543
544 if(isliteral(index) && isliteral(value))
545 b++;
546 }
547
548 t = T;
549 if(b != 0) {
550 // build type [count]struct { a Tindex, b Tvalue }
551 t = n->type;
552 tk = t->down;
553 tv = t->type;
554
555 symb = lookup("b");
556 t = typ(TFIELD);
557 t->type = tv;
558 t->sym = symb;
559
560 syma = lookup("a");
561 t1 = t;
562 t = typ(TFIELD);
563 t->type = tk;
564 t->sym = syma;
565 t->down = t1;
566
567 t1 = t;
568 t = typ(TSTRUCT);
569 t->type = t1;
570
571 t1 = t;
572 t = typ(TARRAY);
573 t->bound = b;
574 t->type = t1;
575
576 dowidth(t);
577
578 // make and initialize static array
579 vstat = staticname(t, ctxt);
580 b = 0;
581 for(l=n->list; l; l=l->next) {
582 r = l->n;
583
584 if(r->op != OKEY)
585 fatal("slicelit: rhs not OKEY: %N", r);
586 index = r->left;
587 value = r->right;
588
589 if(isliteral(index) && isliteral(value)) {
590 // build vstat[b].a = key;
591 a = nodintconst(b);
592 a = nod(OINDEX, vstat, a);
593 a = nod(ODOT, a, newname(syma));
594 a = nod(OAS, a, index);
595 typecheck(&a, Etop);
596 walkexpr(&a, init);
597 a->dodata = 2;
598 *init = list(*init, a);
599
600 // build vstat[b].b = value;
601 a = nodintconst(b);
602 a = nod(OINDEX, vstat, a);
603 a = nod(ODOT, a, newname(symb));
604 a = nod(OAS, a, value);
605 typecheck(&a, Etop);
606 walkexpr(&a, init);
607 a->dodata = 2;
608 *init = list(*init, a);
609
610 b++;
611 }
612 }
613
614 // loop adding structure elements to map
615 // for i = 0; i < len(vstat); i++ {
616 // map[vstat[i].a] = vstat[i].b
617 // }
618 index = nod(OXXX, N, N);
619 tempname(index, types[TINT]);
620
621 a = nod(OINDEX, vstat, index);
622 a->etype = 1; // no bounds checking
623 a = nod(ODOT, a, newname(symb));
624
625 r = nod(OINDEX, vstat, index);
626 r->etype = 1; // no bounds checking
627 r = nod(ODOT, r, newname(syma));
628 r = nod(OINDEX, var, r);
629
630 r = nod(OAS, r, a);
631
632 a = nod(OFOR, N, N);
633 a->nbody = list1(r);
634
635 a->ninit = list1(nod(OAS, index, nodintconst(0)));
636 a->ntest = nod(OLT, index, nodintconst(t->bound));
637 a->nincr = nod(OASOP, index, nodintconst(1));
638 a->nincr->etype = OADD;
639
640 typecheck(&a, Etop);
641 walkstmt(&a);
642 *init = list(*init, a);
643 }
644
645 // put in dynamic entries one-at-a-time
646 for(l=n->list; l; l=l->next) {
647 r = l->n;
648
649 if(r->op != OKEY)
650 fatal("slicelit: rhs not OKEY: %N", r);
651 index = r->left;
652 value = r->right;
653
654 if(isliteral(index) && isliteral(value))
655 continue;
656
657 // build list of var[c] = expr
658 a = nod(OINDEX, var, r->left);
659 a = nod(OAS, a, r->right);
660 typecheck(&a, Etop);
661 walkexpr(&a, init);
662 if(nerr != nerrors)
663 break;
664
665 *init = list(*init, a);
666 }
667 }
668
669 void
670 anylit(int ctxt, Node *n, Node *var, NodeList **init)
671 {
672 Type *t;
673 Node *a, *vstat;
674
675 t = n->type;
676 switch(n->op) {
677 default:
678 fatal("anylit: not lit");
679
680 case OSTRUCTLIT:
681 if(t->etype != TSTRUCT)
682 fatal("anylit: not struct");
683
684 if(simplename(var)) {
685
686 if(ctxt == 0) {
687 // lay out static data
688 vstat = staticname(t, ctxt);
689 structlit(ctxt, 1, n, vstat, init);
690
691 // copy static to var
692 a = nod(OAS, var, vstat);
693 typecheck(&a, Etop);
694 walkexpr(&a, init);
695 *init = list(*init, a);
696
697 // add expressions to automatic
698 structlit(ctxt, 2, n, var, init);
699 break;
700 }
701 structlit(ctxt, 1, n, var, init);
702 structlit(ctxt, 2, n, var, init);
703 break;
704 }
705
706 // initialize of not completely specified
707 if(count(n->list) < structcount(t)) {
708 a = nod(OAS, var, N);
709 typecheck(&a, Etop);
710 walkexpr(&a, init);
711 *init = list(*init, a);
712 }
713 structlit(ctxt, 3, n, var, init);
714 break;
715
716 case OARRAYLIT:
717 if(t->etype != TARRAY)
718 fatal("anylit: not array");
719 if(t->bound < 0) {
720 slicelit(ctxt, n, var, init);
721 break;
722 }
723
724 if(simplename(var)) {
725
726 if(ctxt == 0) {
727 // lay out static data
728 vstat = staticname(t, ctxt);
729 arraylit(1, 1, n, vstat, init);
730
731 // copy static to automatic
732 a = nod(OAS, var, vstat);
733 typecheck(&a, Etop);
734 walkexpr(&a, init);
735 *init = list(*init, a);
736
737 // add expressions to automatic
738 arraylit(ctxt, 2, n, var, init);
739 break;
740 }
741 arraylit(ctxt, 1, n, var, init);
742 arraylit(ctxt, 2, n, var, init);
743 break;
744 }
745
746 // initialize of not completely specified
747 if(count(n->list) < t->bound) {
748 a = nod(OAS, var, N);
749 typecheck(&a, Etop);
750 walkexpr(&a, init);
751 *init = list(*init, a);
752 }
753 arraylit(ctxt, 3, n, var, init);
754 break;
755
756 case OMAPLIT:
757 if(t->etype != TMAP)
758 fatal("anylit: not map");
759 maplit(ctxt, n, var, init);
760 break;
761 }
762 }
763
764 int
765 oaslit(Node *n, NodeList **init)
766 {
767 int ctxt;
768
769 if(n->left == N || n->right == N)
770 goto no;
771 if(n->left->type == T || n->right->type == T)
772 goto no;
773 if(!simplename(n->left))
774 goto no;
775 if(!eqtype(n->left->type, n->right->type))
776 goto no;
777
778 // context is init() function.
779 // implies generated data executed
780 // exactly once and not subject to races.
781 ctxt = 0;
782 // if(n->dodata == 1)
783 // ctxt = 1;
784
785 switch(n->right->op) {
786 default:
787 goto no;
788
789 case OSTRUCTLIT:
790 case OARRAYLIT:
791 case OMAPLIT:
792 if(vmatch1(n->left, n->right))
793 goto no;
794 anylit(ctxt, n->right, n->left, init);
795 break;
796 }
797 n->op = OEMPTY;
798 return 1;
799
800 no:
801 // not a special composit literal assignment
802 return 0;
803 }
804
805 static int
806 getlit(Node *lit)
807 {
808 if(smallintconst(lit))
809 return mpgetfix(lit->val.u.xval);
810 return -1;
811 }
812
813 int
814 stataddr(Node *nam, Node *n)
815 {
816 int l;
817
818 if(n == N)
819 goto no;
820
821 switch(n->op) {
822
823 case ONAME:
824 *nam = *n;
825 return n->addable;
826
827 case ODOT:
828 if(!stataddr(nam, n->left))
829 break;
830 nam->xoffset += n->xoffset;
831 nam->type = n->type;
832 return 1;
833
834 case OINDEX:
835 if(n->left->type->bound < 0)
836 break;
837 if(!stataddr(nam, n->left))
838 break;
839 l = getlit(n->right);
840 if(l < 0)
841 break;
842 nam->xoffset += l*n->type->width;
843 nam->type = n->type;
844 return 1;
845 }
846
847 no:
848 return 0;
849 }
850
851 int
852 gen_as_init(Node *n)
853 {
854 Node *nr, *nl;
855 Node nam, nod1;
856
857 if(n->dodata == 0)
858 goto no;
859
860 nr = n->right;
861 nl = n->left;
862 if(nr == N) {
863 if(!stataddr(&nam, nl))
864 goto no;
865 if(nam.class != PEXTERN)
866 goto no;
867 goto yes;
868 }
869
870 if(nr->type == T || !eqtype(nl->type, nr->type))
871 goto no;
872
873 if(!stataddr(&nam, nl))
874 goto no;
875
876 if(nam.class != PEXTERN)
877 goto no;
878
879 switch(nr->op) {
880 default:
881 goto no;
882
883 case OCONVNOP:
884 nr = nr->left;
885 if(nr == N || nr->op != OSLICEARR)
886 goto no;
887 // fall through
888
889 case OSLICEARR:
890 if(nr->right->op == OKEY && nr->right->left == N && nr->right->right == N) {
891 nr = nr->left;
892 goto slice;
893 }
894 goto no;
895
896 case OLITERAL:
897 break;
898 }
899
900 switch(nr->type->etype) {
901 default:
902 goto no;
903
904 case TBOOL:
905 case TINT8:
906 case TUINT8:
907 case TINT16:
908 case TUINT16:
909 case TINT32:
910 case TUINT32:
911 case TINT64:
912 case TUINT64:
913 case TINT:
914 case TUINT:
915 case TUINTPTR:
916 case TPTR32:
917 case TPTR64:
918 case TFLOAT32:
919 case TFLOAT64:
920 gused(N); // in case the data is the dest of a goto
921 gdata(&nam, nr, nr->type->width);
922 break;
923
924 case TCOMPLEX64:
925 case TCOMPLEX128:
926 gused(N); // in case the data is the dest of a goto
927 gdatacomplex(&nam, nr->val.u.cval);
928 break;
929
930 case TSTRING:
931 gused(N); // in case the data is the dest of a goto
932 gdatastring(&nam, nr->val.u.sval);
933 break;
934 }
935
936 yes:
937 return 1;
938
939 slice:
940 gused(N); // in case the data is the dest of a goto
941 nl = nr;
942 if(nr == N || nr->op != OADDR)
943 goto no;
944 nr = nr->left;
945 if(nr == N || nr->op != ONAME)
946 goto no;
947
948 // nr is the array being converted to a slice
949 if(nr->type == T || nr->type->etype != TARRAY || nr->type->bound < 0)
950 goto no;
951
952 nam.xoffset += Array_array;
953 gdata(&nam, nl, types[tptr]->width);
954
955 nam.xoffset += Array_nel-Array_array;
956 nodconst(&nod1, types[TINT32], nr->type->bound);
957 gdata(&nam, &nod1, types[TINT32]->width);
958
959 nam.xoffset += Array_cap-Array_nel;
960 gdata(&nam, &nod1, types[TINT32]->width);
961
962 goto yes;
963
964 no:
965 if(n->dodata == 2) {
966 dump("\ngen_as_init", n);
967 fatal("gen_as_init couldnt make data statement");
968 }
969 return 0;
970 }
971