root/trunk/src/todt.c

Revision 823, 27.2 kB (checked in by walter, 1 year ago)

bugzilla 5090 ICE(todt.c) struct literal initializing zero length array

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 /* A dt_t is a simple structure representing data to be added
11  * to the data segment of the output object file. As such,
12  * it is a list of initialized bytes, 0 data, and offsets from
13  * other symbols.
14  * Each D symbol and type can be converted into a dt_t so it can
15  * be written to the data segment.
16  */
17
18 #include        <stdio.h>
19 #include        <string.h>
20 #include        <time.h>
21 #include        <assert.h>
22 #include        <complex.h>
23
24 #include        "lexer.h"
25 #include        "mtype.h"
26 #include        "expression.h"
27 #include        "init.h"
28 #include        "enum.h"
29 #include        "aggregate.h"
30 #include        "declaration.h"
31
32
33 // Back end
34 #include        "cc.h"
35 #include        "el.h"
36 #include        "oper.h"
37 #include        "global.h"
38 #include        "code.h"
39 #include        "type.h"
40 #include        "dt.h"
41
42 extern Symbol *static_sym();
43
44 /* ================================================================ */
45
46 dt_t *Initializer::toDt()
47 {
48     assert(0);
49     return NULL;
50 }
51
52
53 dt_t *VoidInitializer::toDt()
54 {   /* Void initializers are set to 0, just because we need something
55      * to set them to in the static data segment.
56      */
57     dt_t *dt = NULL;
58
59     dtnzeros(&dt, type->size());
60     return dt;
61 }
62
63
64 dt_t *StructInitializer::toDt()
65 {
66     Array dts;
67     unsigned i;
68     unsigned j;
69     dt_t *dt;
70     dt_t *d;
71     dt_t **pdtend;
72     unsigned offset;
73
74     //printf("StructInitializer::toDt('%s')\n", toChars());
75     dts.setDim(ad->fields.dim);
76     dts.zero();
77
78     for (i = 0; i < vars.dim; i++)
79     {
80         VarDeclaration *v = (VarDeclaration *)vars.data[i];
81         Initializer *val = (Initializer *)value.data[i];
82
83         //printf("vars[%d] = %s\n", i, v->toChars());
84
85         for (j = 0; 1; j++)
86         {
87             assert(j < dts.dim);
88             //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad->fields.data[j])->toChars());
89             if ((VarDeclaration *)ad->fields.data[j] == v)
90             {
91                 if (dts.data[j])
92                     error(loc, "field %s of %s already initialized", v->toChars(), ad->toChars());
93                 dts.data[j] = (void *)val->toDt();
94                 break;
95             }
96         }
97     }
98
99     dt = NULL;
100     pdtend = &dt;
101     offset = 0;
102     for (j = 0; j < dts.dim; j++)
103     {
104         VarDeclaration *v = (VarDeclaration *)ad->fields.data[j];
105
106         d = (dt_t *)dts.data[j];
107         if (!d)
108         {   // An instance specific initializer was not provided.
109             // Look to see if there's a default initializer from the
110             // struct definition
111             VarDeclaration *v = (VarDeclaration *)ad->fields.data[j];
112
113             if (v->init)
114             {
115                 d = v->init->toDt();
116             }
117             else if (v->offset >= offset)
118             {
119                 unsigned k;
120                 unsigned offset2 = v->offset + v->type->size();
121                 // Make sure this field does not overlap any explicitly
122                 // initialized field.
123                 for (k = j + 1; 1; k++)
124                 {
125                     if (k == dts.dim)           // didn't find any overlap
126                     {
127                         v->type->toDt(&d);
128                         break;
129                     }
130                     VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k];
131
132                     if (v2->offset < offset2 && dts.data[k])
133                         break;                  // overlap
134                 }
135             }
136         }
137         if (d)
138         {
139             if (v->offset < offset)
140                 error(loc, "duplicate union initialization for %s", v->toChars());
141             else
142             {   unsigned sz = dt_size(d);
143                 unsigned vsz = v->type->size();
144                 unsigned voffset = v->offset;
145
146                 if (sz > vsz)
147                 {   assert(v->type->ty == Tsarray && vsz == 0);
148                     error(loc, "zero length array %s has non-zero length initializer", v->toChars());
149                 }
150
151                 unsigned dim = 1;
152                 for (Type *vt = v->type->toBasetype();
153                      vt->ty == Tsarray;
154                      vt = vt->nextOf()->toBasetype())
155                 {   TypeSArray *tsa = (TypeSArray *)vt;
156                     dim *= tsa->dim->toInteger();
157                 }
158                 //printf("sz = %d, dim = %d, vsz = %d\n", sz, dim, vsz);
159                 assert(sz == vsz || sz * dim <= vsz);
160
161                 for (size_t i = 0; i < dim; i++)
162                 {
163                     if (offset < voffset)
164                         pdtend = dtnzeros(pdtend, voffset - offset);
165                     if (!d)
166                     {
167                         if (v->init)
168                             d = v->init->toDt();
169                         else
170                             v->type->toDt(&d);
171                     }
172                     pdtend = dtcat(pdtend, d);
173                     d = NULL;
174                     offset = voffset + sz;
175                     voffset += vsz / dim;
176                     if (sz == vsz)
177                         break;
178                 }
179             }
180         }
181     }
182     if (offset < ad->structsize)
183         dtnzeros(pdtend, ad->structsize - offset);
184
185     return dt;
186 }
187
188
189 dt_t *ArrayInitializer::toDt()
190 {
191     //printf("ArrayInitializer::toDt('%s')\n", toChars());
192     Type *tb = type->toBasetype();
193     Type *tn = tb->nextOf()->toBasetype();
194
195     Array dts;
196     unsigned size;
197     unsigned length;
198     unsigned i;
199     dt_t *dt;
200     dt_t *d;
201     dt_t **pdtend;
202
203     //printf("\tdim = %d\n", dim);
204     dts.setDim(dim);
205     dts.zero();
206
207     size = tn->size();
208
209     length = 0;
210     for (i = 0; i < index.dim; i++)
211     {   Expression *idx;
212         Initializer *val;
213
214         idx = (Expression *)index.data[i];
215         if (idx)
216             length = idx->toInteger();
217         //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);
218
219         assert(length < dim);
220         val = (Initializer *)value.data[i];
221         dt = val->toDt();
222         if (dts.data[length])
223             error(loc, "duplicate initializations for index %d", length);
224         dts.data[length] = (void *)dt;
225         length++;
226     }
227
228     Expression *edefault = tb->nextOf()->defaultInit();
229
230     unsigned n = 1;
231     for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->nextOf()->toBasetype())
232     {   TypeSArray *tsa = (TypeSArray *)tbn;
233
234         n *= tsa->dim->toInteger();
235     }
236
237     d = NULL;
238     pdtend = &d;
239     for (i = 0; i < dim; i++)
240     {
241         dt = (dt_t *)dts.data[i];
242         if (dt)
243             pdtend = dtcat(pdtend, dt);
244         else
245         {
246             for (int j = 0; j < n; j++)
247                 pdtend = edefault->toDt(pdtend);
248         }
249     }
250     switch (tb->ty)
251     {
252         case Tsarray:
253         {   unsigned tadim;
254             TypeSArray *ta = (TypeSArray *)tb;
255
256             tadim = ta->dim->toInteger();
257             if (dim < tadim)
258             {
259                 if (edefault->isBool(FALSE))
260                     // pad out end of array
261                     pdtend = dtnzeros(pdtend, size * (tadim - dim));
262                 else
263                 {
264                     for (i = dim; i < tadim; i++)
265                     {   for (int j = 0; j < n; j++)
266                             pdtend = edefault->toDt(pdtend);
267                     }
268                 }
269             }
270             else if (dim > tadim)
271             {
272 #ifdef DEBUG
273                 printf("1: ");
274 #endif
275                 error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
276             }
277             break;
278         }
279
280         case Tpointer:
281         case Tarray:
282             // Create symbol, and then refer to it
283             Symbol *s;
284             s = static_sym();
285             s->Sdt = d;
286             outdata(s);
287
288             d = NULL;
289             if (tb->ty == Tarray)
290                 dtsize_t(&d, dim);
291             dtxoff(&d, s, 0, TYnptr);
292             break;
293
294         default:
295             assert(0);
296     }
297     return d;
298 }
299
300
301 dt_t *ArrayInitializer::toDtBit()
302 {
303 #if DMDV1
304     unsigned size;
305     unsigned length;
306     unsigned i;
307     unsigned tadim;
308     dt_t *d;
309     dt_t **pdtend;
310     Type *tb = type->toBasetype();
311
312     //printf("ArrayInitializer::toDtBit('%s')\n", toChars());
313
314     Bits databits;
315     Bits initbits;
316
317     if (tb->ty == Tsarray)
318     {
319         /* The 'dim' for ArrayInitializer is only the maximum dimension
320          * seen in the initializer, not the type. So, for static arrays,
321          * use instead the dimension of the type in order
322          * to get the whole thing.
323          */
324         dinteger_t value = ((TypeSArray*)tb)->dim->toInteger();
325         tadim = value;
326         assert(tadim == value);  // truncation overflow should already be checked
327         databits.resize(tadim);
328         initbits.resize(tadim);
329     }
330     else
331     {
332         databits.resize(dim);
333         initbits.resize(dim);
334     }
335
336     /* The default initializer may be something other than zero.
337      */
338     if (tb->nextOf()->defaultInit()->toInteger())
339        databits.set();
340
341     size = sizeof(databits.data[0]);
342
343     length = 0;
344     for (i = 0; i < index.dim; i++)
345     {   Expression *idx;
346         Initializer *val;
347         Expression *eval;
348
349         idx = (Expression *)index.data[i];
350         if (idx)
351         {   dinteger_t value;
352             value = idx->toInteger();
353             length = value;
354             if (length != value)
355             {   error(loc, "index overflow %llu", value);
356                 length = 0;
357             }
358         }
359         assert(length < dim);
360
361         val = (Initializer *)value.data[i];
362         eval = val->toExpression();
363         if (initbits.test(length))
364             error(loc, "duplicate initializations for index %d", length);
365         initbits.set(length);
366         if (eval->toInteger())          // any non-zero value is boolean 'true'
367             databits.set(length);
368         else
369             databits.clear(length);     // boolean 'false'
370         length++;
371     }
372
373     d = NULL;
374     pdtend = dtnbytes(&d, databits.allocdim * size, (char *)databits.data);
375     switch (tb->ty)
376     {
377         case Tsarray:
378         {
379             if (dim > tadim)
380             {
381 #ifdef DEBUG
382                 printf("2: ");
383 #endif
384                 error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
385             }
386             else
387             {
388                 tadim = (tadim + 31) / 32;
389                 if (databits.allocdim < tadim)
390                     pdtend = dtnzeros(pdtend, size * (tadim - databits.allocdim));      // pad out end of array
391             }
392             break;
393         }
394
395         case Tpointer:
396         case Tarray:
397             // Create symbol, and then refer to it
398             Symbol *s;
399             s = static_sym();
400             s->Sdt = d;
401             outdata(s);
402
403             d = NULL;
404             if (tb->ty == Tarray)
405                 dtsize_t(&d, dim);
406             dtxoff(&d, s, 0, TYnptr);
407             break;
408
409         default:
410             assert(0);
411     }
412     return d;
413 #else
414     return NULL;
415 #endif
416 }
417
418
419 dt_t *ExpInitializer::toDt()
420 {
421     dt_t *dt = NULL;
422
423     exp = exp->optimize(WANTvalue);
424     exp->toDt(&dt);
425     return dt;
426 }
427
428 /* ================================================================ */
429
430 dt_t **Expression::toDt(dt_t **pdt)
431 {
432 #ifdef DEBUG
433     printf("Expression::toDt() %d\n", op);
434     dump(0);
435 #endif
436     error("non-constant expression %s", toChars());
437     pdt = dtnzeros(pdt, 1);
438     return pdt;
439 }
440
441 dt_t **IntegerExp::toDt(dt_t **pdt)
442 {   unsigned sz;
443
444     //printf("IntegerExp::toDt() %d\n", op);
445     sz = type->size();
446     if (value == 0)
447         pdt = dtnzeros(pdt, sz);
448     else
449         pdt = dtnbytes(pdt, sz, (char *)&value);
450     return pdt;
451 }
452
453 static char zeropad[6];
454
455 dt_t **RealExp::toDt(dt_t **pdt)
456 {
457     d_float32 fvalue;
458     d_float64 dvalue;
459     d_float80 evalue;
460
461     //printf("RealExp::toDt(%Lg)\n", value);
462     switch (type->toBasetype()->ty)
463     {
464         case Tfloat32:
465         case Timaginary32:
466             fvalue = value;
467             pdt = dtnbytes(pdt,4,(char *)&fvalue);
468             break;
469
470         case Tfloat64:
471         case Timaginary64:
472             dvalue = value;
473             pdt = dtnbytes(pdt,8,(char *)&dvalue);
474             break;
475
476         case Tfloat80:
477         case Timaginary80:
478             evalue = value;
479             pdt = dtnbytes(pdt,REALSIZE - REALPAD,(char *)&evalue);
480             pdt = dtnbytes(pdt,REALPAD,zeropad);
481             assert(REALPAD <= sizeof(zeropad));
482             break;
483
484         default:
485             printf("%s\n", toChars());
486             type->print();
487             assert(0);
488             break;
489     }
490     return pdt;
491 }
492
493 dt_t **ComplexExp::toDt(dt_t **pdt)
494 {
495     //printf("ComplexExp::toDt() '%s'\n", toChars());
496     d_float32 fvalue;
497     d_float64 dvalue;
498     d_float80 evalue;
499
500     switch (type->toBasetype()->ty)
501     {
502         case Tcomplex32:
503             fvalue = creall(value);
504             pdt = dtnbytes(pdt,4,(char *)&fvalue);
505             fvalue = cimagl(value);
506             pdt = dtnbytes(pdt,4,(char *)&fvalue);
507             break;
508
509         case Tcomplex64:
510             dvalue = creall(value);
511             pdt = dtnbytes(pdt,8,(char *)&dvalue);
512             dvalue = cimagl(value);
513             pdt = dtnbytes(pdt,8,(char *)&dvalue);
514             break;
515
516         case Tcomplex80:
517             evalue = creall(value);
518             pdt = dtnbytes(pdt,REALSIZE - REALPAD,(char *)&evalue);
519             pdt = dtnbytes(pdt,REALPAD,zeropad);
520             evalue = cimagl(value);
521             pdt = dtnbytes(pdt,REALSIZE - REALPAD,(char *)&evalue);
522             pdt = dtnbytes(pdt,REALPAD,zeropad);
523             break;
524
525         default:
526             assert(0);
527             break;
528     }
529     return pdt;
530 }
531
532 dt_t **NullExp::toDt(dt_t **pdt)
533 {
534     assert(type);
535     return dtnzeros(pdt, type->size());
536 }
537
538 dt_t **StringExp::toDt(dt_t **pdt)
539 {
540     //printf("StringExp::toDt() '%s', type = %s\n", toChars(), type->toChars());
541     Type *t = type->toBasetype();
542
543     // BUG: should implement some form of static string pooling
544     switch (t->ty)
545     {
546         case Tarray:
547             dtsize_t(pdt, len);
548             pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string);
549             break;
550
551         case Tsarray:
552         {   TypeSArray *tsa = (TypeSArray *)type;
553             dinteger_t dim;
554
555             pdt = dtnbytes(pdt, len * sz, (const char *)string);
556             if (tsa->dim)
557             {
558                 dim = tsa->dim->toInteger();
559                 if (len < dim)
560                 {
561                     // Pad remainder with 0
562                     pdt = dtnzeros(pdt, (dim - len) * tsa->next->size());
563                 }
564             }
565             break;
566         }
567         case Tpointer:
568             pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string);
569             break;
570
571         default:
572             printf("StringExp::toDt(type = %s)\n", type->toChars());
573             assert(0);
574     }
575     return pdt;
576 }
577
578 dt_t **ArrayLiteralExp::toDt(dt_t **pdt)
579 {
580     //printf("ArrayLiteralExp::toDt() '%s', type = %s\n", toChars(), type->toChars());
581
582     dt_t *d;
583     dt_t **pdtend;
584
585     d = NULL;
586     pdtend = &d;
587     for (int i = 0; i < elements->dim; i++)
588     {   Expression *e = (Expression *)elements->data[i];
589
590         pdtend = e->toDt(pdtend);
591     }
592     Type *t = type->toBasetype();
593
594     switch (t->ty)
595     {
596         case Tsarray:
597             pdt = dtcat(pdt, d);
598             break;
599
600         case Tpointer:
601         case Tarray:
602             if (t->ty == Tarray)
603                 dtsize_t(pdt, elements->dim);
604             if (d)
605             {
606                 // Create symbol, and then refer to it
607                 Symbol *s;
608                 s = static_sym();
609                 s->Sdt = d;
610                 outdata(s);
611
612                 dtxoff(pdt, s, 0, TYnptr);
613             }
614             else
615                 dtsize_t(pdt, 0);
616
617             break;
618
619         default:
620             assert(0);
621     }
622     return pdt;
623 }
624
625 dt_t **StructLiteralExp::toDt(dt_t **pdt)
626 {
627     Array dts;
628     unsigned i;
629     unsigned j;
630     dt_t *dt;
631     dt_t *d;
632     unsigned offset;
633
634     //printf("StructLiteralExp::toDt() %s)\n", toChars());
635     dts.setDim(sd->fields.dim);
636     dts.zero();
637     assert(elements->dim <= sd->fields.dim);
638
639     for (i = 0; i < elements->dim; i++)
640     {
641         Expression *e = (Expression *)elements->data[i];
642         if (!e)
643             continue;
644         dt = NULL;
645         e->toDt(&dt);
646         dts.data[i] = (void *)dt;
647     }
648
649     offset = 0;
650     for (j = 0; j < dts.dim; j++)
651     {
652         VarDeclaration *v = (VarDeclaration *)sd->fields.data[j];
653
654         d = (dt_t *)dts.data[j];
655         if (!d)
656         {   // An instance specific initializer was not provided.
657             // Look to see if there's a default initializer from the
658             // struct definition
659             VarDeclaration *v = (VarDeclaration *)sd->fields.data[j];
660
661             if (v->init)
662             {
663                 d = v->init->toDt();
664             }
665             else if (v->offset >= offset)
666             {
667                 unsigned k;
668                 unsigned offset2 = v->offset + v->type->size();
669                 // Make sure this field (v) does not overlap any explicitly
670                 // initialized field.
671                 for (k = j + 1; 1; k++)
672                 {
673                     if (k == dts.dim)           // didn't find any overlap
674                     {
675                         v->type->toDt(&d);
676                         break;
677                     }
678                     VarDeclaration *v2 = (VarDeclaration *)sd->fields.data[k];
679
680                     if (v2->offset < offset2 && dts.data[k])
681                         break;                  // overlap
682                 }
683             }
684         }
685         if (d)
686         {
687             if (v->offset < offset)
688                 error("duplicate union initialization for %s", v->toChars());
689             else
690             {   unsigned sz = dt_size(d);
691                 unsigned vsz = v->type->size();
692                 unsigned voffset = v->offset;
693
694                 if (sz > vsz)
695                 {   assert(v->type->ty == Tsarray && vsz == 0);
696                     error("zero length array %s has non-zero length initializer", v->toChars());
697                 }
698
699                 unsigned dim = 1;
700                 Type *vt;
701                 for (vt = v->type->toBasetype();
702                      vt->ty == Tsarray;
703                      vt = vt->nextOf()->toBasetype())
704                 {   TypeSArray *tsa = (TypeSArray *)vt;
705                     dim *= tsa->dim->toInteger();
706                 }
707                 //printf("sz = %d, dim = %d, vsz = %d\n", sz, dim, vsz);
708                 assert(sz == vsz || sz * dim <= vsz);
709
710                 for (size_t i = 0; i < dim; i++)
711                 {
712                     if (offset < voffset)
713                         pdt = dtnzeros(pdt, voffset - offset);
714                     if (!d)
715                     {
716                         if (v->init)
717                             d = v->init->toDt();
718                         else
719                             vt->toDt(&d);
720                     }
721                     pdt = dtcat(pdt, d);
722                     d = NULL;
723                     offset = voffset + sz;
724                     voffset += vsz / dim;
725                     if (sz == vsz)
726                         break;
727                 }
728             }
729         }
730     }
731     if (offset < sd->structsize)
732         pdt = dtnzeros(pdt, sd->structsize - offset);
733
734     return pdt;
735 }
736
737
738 dt_t **SymOffExp::toDt(dt_t **pdt)
739 {
740     Symbol *s;
741
742     //printf("SymOffExp::toDt('%s')\n", var->toChars());
743     assert(var);
744     if (!(var->isDataseg() || var->isCodeseg()) ||
745         var->needThis() ||
746         var->isThreadlocal())
747     {
748 #ifdef DEBUG
749         printf("SymOffExp::toDt()\n");
750 #endif
751         error("non-constant expression %s", toChars());
752         return pdt;
753     }
754     s = var->toSymbol();
755     return dtxoff(pdt, s, offset, TYnptr);
756 }
757
758 dt_t **VarExp::toDt(dt_t **pdt)
759 {
760     //printf("VarExp::toDt() %d\n", op);
761     for (; *pdt; pdt = &((*pdt)->DTnext))
762         ;
763
764     VarDeclaration *v = var->isVarDeclaration();
765     if (v && (v->isConst() || v->isImmutable()) &&
766         type->toBasetype()->ty != Tsarray && v->init)
767     {
768         if (v->inuse)
769         {
770             error("recursive reference %s", toChars());
771             return pdt;
772         }
773         v->inuse++;
774         *pdt = v->init->toDt();
775         v->inuse--;
776         return pdt;
777     }
778     SymbolDeclaration *sd = var->isSymbolDeclaration();
779     if (sd && sd->dsym)
780     {
781         sd->dsym->toDt(pdt);
782         return pdt;
783     }
784 #ifdef DEBUG
785     printf("VarExp::toDt(), kind = %s\n", var->kind());
786 #endif
787     error("non-constant expression %s", toChars());
788     pdt = dtnzeros(pdt, 1);
789     return pdt;
790 }
791
792 /* ================================================================= */
793
794 // Generate the data for the static initializer.
795
796 void ClassDeclaration::toDt(dt_t **pdt)
797 {
798     //printf("ClassDeclaration::toDt(this = '%s')\n", toChars());
799
800     // Put in first two members, the vtbl[] and the monitor
801     dtxoff(pdt, toVtblSymbol(), 0, TYnptr);
802     dtsize_t(pdt, 0);                    // monitor
803
804     // Put in the rest
805     toDt2(pdt, this);
806
807     //printf("-ClassDeclaration::toDt(this = '%s')\n", toChars());
808 }
809
810 void ClassDeclaration::toDt2(dt_t **pdt, ClassDeclaration *cd)
811 {
812     unsigned offset;
813     unsigned i;
814     dt_t *dt;
815     unsigned csymoffset;
816
817 #define LOG 0
818
819 #if LOG
820     printf("ClassDeclaration::toDt2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
821 #endif
822     if (baseClass)
823     {
824         baseClass->toDt2(pdt, cd);
825         offset = baseClass->structsize;
826     }
827     else
828     {
829         offset = PTRSIZE * 2;
830     }
831
832     // Note equivalence of this loop to struct's
833     for (i = 0; i < fields.dim; i++)
834     {
835         VarDeclaration *v = (VarDeclaration *)fields.data[i];
836         Initializer *init;
837
838         //printf("\t\tv = '%s' v->offset = %2d, offset = %2d\n", v->toChars(), v->offset, offset);
839         dt = NULL;
840         init = v->init;
841         if (init)
842         {   //printf("\t\t%s has initializer %s\n", v->toChars(), init->toChars());
843             ExpInitializer *ei = init->isExpInitializer();
844             Type *tb = v->type->toBasetype();
845             if (ei && tb->ty == Tsarray)
846                 ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
847             else
848                 dt = init->toDt();
849         }
850         else if (v->offset >= offset)
851         {   //printf("\t\tdefault initializer\n");
852             v->type->toDt(&dt);
853         }
854         if (dt)
855         {
856             if (v->offset < offset)
857                 error("duplicated union initialization for %s", v->toChars());
858             else
859             {
860                 if (offset < v->offset)
861                     dtnzeros(pdt, v->offset - offset);
862                 dtcat(pdt, dt);
863                 offset = v->offset + v->type->size();
864             }
865         }
866     }
867
868     // Interface vptr initializations
869     toSymbol();                                         // define csym
870
871     for (i = 0; i < vtblInterfaces->dim; i++)
872     {   BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
873
874 #if 1 || INTERFACE_VIRTUAL
875         for (ClassDeclaration *cd2 = cd; 1; cd2 = cd2->baseClass)
876         {
877             assert(cd2);
878             csymoffset = cd2->baseVtblOffset(b);
879             if (csymoffset != ~0)
880             {
881                 if (offset < b->offset)
882                     dtnzeros(pdt, b->offset - offset);
883                 dtxoff(pdt, cd2->toSymbol(), csymoffset, TYnptr);
884                 break;
885             }
886         }
887 #else
888         csymoffset = baseVtblOffset(b);
889         assert(csymoffset != ~0);
890         dtxoff(pdt, csym, csymoffset, TYnptr);
891 #endif
892         offset = b->offset + PTRSIZE;
893     }
894
895     if (offset < structsize)
896         dtnzeros(pdt, structsize - offset);
897
898 #undef LOG
899 }
900
901 void StructDeclaration::toDt(dt_t **pdt)
902 {
903     unsigned offset;
904     unsigned i;
905     dt_t *dt;
906
907     //printf("StructDeclaration::toDt(), this='%s'\n", toChars());
908     offset = 0;
909
910     // Note equivalence of this loop to class's
911     for (i = 0; i < fields.dim; i++)
912     {
913         VarDeclaration *v = (VarDeclaration *)fields.data[i];
914         //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset);
915         dt = NULL;
916         int sz;
917
918         if (v->storage_class & STCref)
919         {
920             sz = PTRSIZE;
921             if (v->offset >= offset)
922                 dtnzeros(&dt, sz);
923         }
924         else
925         {
926             sz = v->type->size();
927             Initializer *init = v->init;
928             if (init)
929             {   //printf("\t\thas initializer %s\n", init->toChars());
930                 ExpInitializer *ei = init->isExpInitializer();
931                 Type *tb = v->type->toBasetype();
932                 if (ei && tb->ty == Tsarray)
933                     ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
934                 else
935                     dt = init->toDt();
936             }
937             else if (v->offset >= offset)
938                 v->type->toDt(&dt);
939         }
940         if (dt)
941         {
942             if (v->offset < offset)
943                 error("overlapping initialization for struct %s.%s", toChars(), v->toChars());
944             else
945             {
946                 if (offset < v->offset)
947                     dtnzeros(pdt, v->offset - offset);
948                 dtcat(pdt, dt);
949                 offset = v->offset + sz;
950             }
951         }
952     }
953
954     if (offset < structsize)
955         dtnzeros(pdt, structsize - offset);
956
957     dt_optimize(*pdt);
958 }
959
960 /* ================================================================= */
961
962 dt_t **Type::toDt(dt_t **pdt)
963 {
964     //printf("Type::toDt()\n");
965     Expression *e = defaultInit();
966     return e->toDt(pdt);
967 }
968
969 dt_t **TypeSArray::toDt(dt_t **pdt)
970 {
971     return toDtElem(pdt, NULL);
972 }
973
974 dt_t **TypeSArray::toDtElem(dt_t **pdt, Expression *e)
975 {
976     int i;
977     unsigned len;
978
979     //printf("TypeSArray::toDtElem()\n");
980     len = dim->toInteger();
981     if (len)
982     {
983         while (*pdt)
984             pdt = &((*pdt)->DTnext);
985         Type *tnext = next;
986         Type *tbn = tnext->toBasetype();
987         while (tbn->ty == Tsarray)
988         {   TypeSArray *tsa = (TypeSArray *)tbn;
989
990             len *= tsa->dim->toInteger();
991             tnext = tbn->nextOf();
992             tbn = tnext->toBasetype();
993         }
994         if (!e)                         // if not already supplied
995             e = tnext->defaultInit();   // use default initializer
996         if (tbn->ty == Tstruct)
997             tnext->toDt(pdt);
998         else
999             e->toDt(pdt);
1000         dt_optimize(*pdt);
1001         if ((*pdt)->dt == DT_azeros && !(*pdt)->DTnext)
1002         {
1003             (*pdt)->DTazeros *= len;
1004             pdt = &((*pdt)->DTnext);
1005         }
1006         else if ((*pdt)->dt == DT_1byte && (*pdt)->DTonebyte == 0 && !(*pdt)->DTnext)
1007         {
1008             (*pdt)->dt = DT_azeros;
1009             (*pdt)->DTazeros = len;
1010             pdt = &((*pdt)->DTnext);
1011         }
1012         else if (e->op != TOKstring && e->op != TOKarrayliteral)
1013         {
1014             for (i = 1; i < len; i++)
1015             {
1016                 if (tbn->ty == Tstruct)
1017                 {   pdt = tnext->toDt(pdt);
1018                     while (*pdt)
1019                         pdt = &((*pdt)->DTnext);
1020                 }
1021                 else
1022                     pdt = e->toDt(pdt);
1023             }
1024         }
1025     }
1026     return pdt;
1027 }
1028
1029 dt_t **TypeStruct::toDt(dt_t **pdt)
1030 {
1031     sym->toDt(pdt);
1032     return pdt;
1033 }
1034
1035 dt_t **TypeTypedef::toDt(dt_t **pdt)
1036 {
1037     if (sym->init)
1038     {
1039         dt_t *dt = sym->init->toDt();
1040
1041         while (*pdt)
1042             pdt = &((*pdt)->DTnext);
1043         *pdt = dt;
1044         return pdt;
1045     }
1046     sym->basetype->toDt(pdt);
1047     return pdt;
1048 }
Note: See TracBrowser for help on using the browser.