Cope with Main not being a class.
[delight/core.git] / dmd2 / todt.c
blob48a9bb149229ad0d121b91c366b9be84ff5d4d75
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, July 2007
17 /* A dt_t is a simple structure representing data to be added
18 * to the data segment of the output object file. As such,
19 * it is a list of initialized bytes, 0 data, and offsets from
20 * other symbols.
21 * Each D symbol and type can be converted into a dt_t so it can
22 * be written to the data segment.
25 #undef integer_t
26 #include <stdio.h>
27 #include <string.h>
28 #include <time.h>
29 #include <assert.h>
30 #include <complex.h>
32 #ifdef __APPLE__
33 #define integer_t dmd_integer_t
34 #endif
36 #include "lexer.h"
37 #include "mtype.h"
38 #include "expression.h"
39 #include "init.h"
40 #include "enum.h"
41 #include "aggregate.h"
42 #include "declaration.h"
45 // Back end
46 #ifndef IN_GCC
47 #include "cc.h"
48 #include "el.h"
49 #include "oper.h"
50 #include "global.h"
51 #include "code.h"
52 #include "type.h"
53 #endif
54 #include "dt.h"
56 extern Symbol *static_sym();
58 /* ================================================================ */
60 #ifdef IN_GCC
61 static dt_t *createTsarrayDt(dt_t * elem_or_all, Type *t)
63 assert(elem_or_all != NULL);
64 target_size_t eoa_size = dt_size(elem_or_all);
65 if (eoa_size == t->size())
67 return elem_or_all;
69 else
71 TypeSArray * tsa = (TypeSArray *) t->toBasetype();
72 assert(tsa->ty == Tsarray);
74 target_size_t dim = tsa->dim->toInteger();
75 dt_t * adt = NULL;
76 dt_t ** padt = & adt;
78 if (eoa_size * dim == eoa_size)
80 for (target_size_t i = 0; i < dim; i++)
81 padt = dtcontainer(padt, NULL, elem_or_all);
83 else
85 assert(tsa->size(0) % eoa_size == 0);
86 for (target_size_t i = 0; i < dim; i++)
87 padt = dtcontainer(padt, NULL,
88 createTsarrayDt(elem_or_all, tsa->next));
90 dt_t * fdt = NULL;
91 dtcontainer(& fdt, t, adt);
92 return fdt;
95 #endif
98 dt_t *Initializer::toDt()
100 assert(0);
101 return NULL;
105 dt_t *VoidInitializer::toDt()
106 { /* Void initializers are set to 0, just because we need something
107 * to set them to in the static data segment.
109 dt_t *dt = NULL;
111 dtnzeros(&dt, type->size());
112 return dt;
116 dt_t *StructInitializer::toDt()
118 Array dts;
119 unsigned i;
120 unsigned j;
121 dt_t *dt;
122 dt_t *d;
123 dt_t **pdtend;
124 target_size_t offset;
126 //printf("StructInitializer::toDt('%s')\n", toChars());
127 dts.setDim(ad->fields.dim);
128 dts.zero();
130 for (i = 0; i < vars.dim; i++)
132 VarDeclaration *v = (VarDeclaration *)vars.data[i];
133 Initializer *val = (Initializer *)value.data[i];
135 //printf("vars[%d] = %s\n", i, v->toChars());
137 for (j = 0; 1; j++)
139 assert(j < dts.dim);
140 //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad->fields.data[j])->toChars());
141 if ((VarDeclaration *)ad->fields.data[j] == v)
143 if (dts.data[j])
144 error(loc, "field %s of %s already initialized", v->toChars(), ad->toChars());
145 dts.data[j] = (void *)val->toDt();
146 break;
151 dt = NULL;
152 pdtend = &dt;
153 offset = 0;
154 for (j = 0; j < dts.dim; j++)
156 VarDeclaration *v = (VarDeclaration *)ad->fields.data[j];
158 d = (dt_t *)dts.data[j];
159 if (!d)
160 { // An instance specific initializer was not provided.
161 // Look to see if there's a default initializer from the
162 // struct definition
163 VarDeclaration *v = (VarDeclaration *)ad->fields.data[j];
165 if (v->init)
167 d = v->init->toDt();
169 else if (v->offset >= offset)
171 target_size_t k;
172 target_size_t offset2 = v->offset + v->type->size();
173 // Make sure this field does not overlap any explicitly
174 // initialized field.
175 for (k = j + 1; 1; k++)
177 if (k == dts.dim) // didn't find any overlap
179 v->type->toDt(&d);
180 break;
182 VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k];
184 if (v2->offset < offset2 && dts.data[k])
185 break; // overlap
189 if (d)
191 if (v->offset < offset)
192 error(loc, "duplicate union initialization for %s", v->toChars());
193 else
194 { target_size_t sz = dt_size(d);
195 target_size_t vsz = v->type->size();
196 target_size_t voffset = v->offset;
197 assert(sz <= vsz);
199 #ifdef IN_GCC
200 if (offset < voffset)
201 pdtend = dtnzeros(pdtend, voffset - offset);
202 if (v->type->toBasetype()->ty == Tsarray)
204 d = createTsarrayDt(d, v->type);
205 sz = dt_size(d);
206 assert(sz <= vsz);
208 pdtend = dtcat(pdtend, d);
209 offset = voffset + sz;
210 #else
211 target_size_t dim = 1;
212 for (Type *vt = v->type->toBasetype();
213 vt->ty == Tsarray;
214 vt = vt->nextOf()->toBasetype())
215 { TypeSArray *tsa = (TypeSArray *)vt;
216 dim *= tsa->dim->toInteger();
219 for (target_size_t i = 0; i < dim; i++)
221 if (offset < voffset)
222 pdtend = dtnzeros(pdtend, voffset - offset);
223 if (!d)
225 if (v->init)
226 d = v->init->toDt();
227 else
228 v->type->toDt(&d);
230 pdtend = dtcat(pdtend, d);
231 d = NULL;
232 offset = voffset + sz;
233 voffset += vsz / dim;
234 if (sz == vsz)
235 break;
237 #endif
241 if (offset < ad->structsize)
242 dtnzeros(pdtend, ad->structsize - offset);
244 #ifdef IN_GCC
245 dt_t * cdt = NULL;
246 dtcontainer(& cdt, ad->type, dt);
247 dt = cdt;
248 #endif
249 return dt;
253 dt_t *ArrayInitializer::toDt()
255 //printf("ArrayInitializer::toDt('%s')\n", toChars());
256 Type *tb = type->toBasetype();
257 Type *tn = tb->nextOf()->toBasetype();
259 Array dts;
260 unsigned size;
261 unsigned length;
262 unsigned i;
263 dt_t *dt;
264 dt_t *d;
265 dt_t **pdtend;
267 //printf("\tdim = %d\n", dim);
268 dts.setDim(dim);
269 dts.zero();
271 size = tn->size();
273 length = 0;
274 for (i = 0; i < index.dim; i++)
275 { Expression *idx;
276 Initializer *val;
278 idx = (Expression *)index.data[i];
279 if (idx)
280 length = idx->toInteger();
281 //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);
283 assert(length < dim);
284 val = (Initializer *)value.data[i];
285 dt = val->toDt();
286 if (dts.data[length])
287 error(loc, "duplicate initializations for index %d", length);
288 if (tn->ty == Tsarray)
289 dt = createTsarrayDt(dt, tb->nextOf());
290 dts.data[length] = (void *)dt;
291 length++;
294 Expression *edefault = tb->nextOf()->defaultInit();
295 #ifdef IN_GCC
296 dt_t * sadefault = NULL;
298 if (tn->ty == Tsarray)
299 tn->toDt(& sadefault);
300 else
301 edefault->toDt(& sadefault);
302 #else
303 unsigned n = 1;
304 for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->nextOf()->toBasetype())
305 { TypeSArray *tsa = (TypeSArray *)tbn;
307 n *= tsa->dim->toInteger();
309 #endif
311 d = NULL;
312 pdtend = &d;
313 for (i = 0; i < dim; i++)
315 dt = (dt_t *)dts.data[i];
316 #ifdef IN_GCC
317 pdtend = dtcontainer(pdtend, NULL, dt ? dt : sadefault);
318 #else
319 if (dt)
320 pdtend = dtcat(pdtend, dt);
321 else
323 for (int j = 0; j < n; j++)
324 pdtend = edefault->toDt(pdtend);
326 #endif
328 switch (tb->ty)
330 case Tsarray:
331 { unsigned tadim;
332 TypeSArray *ta = (TypeSArray *)tb;
334 tadim = ta->dim->toInteger();
335 if (dim < tadim)
337 if (edefault->isBool(FALSE))
338 // pad out end of array
339 // (ok for GDC as well)
340 pdtend = dtnzeros(pdtend, size * (tadim - dim));
341 else
343 for (i = dim; i < tadim; i++)
344 #ifdef IN_GCC
345 pdtend = dtcontainer(pdtend, NULL, sadefault);
346 #else
347 { for (int j = 0; j < n; j++)
348 pdtend = edefault->toDt(pdtend);
350 #endif
353 else if (dim > tadim)
355 #ifdef DEBUG
356 printf("1: ");
357 #endif
358 error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
360 #ifdef IN_GCC
361 dt_t * cdt = NULL;
362 dtcontainer(& cdt, type, d);
363 d = cdt;
364 #endif
365 break;
368 case Tpointer:
369 case Tarray:
370 // Create symbol, and then refer to it
371 Symbol *s;
372 s = static_sym();
373 s->Sdt = d;
374 outdata(s);
376 d = NULL;
377 if (tb->ty == Tarray)
378 dtdword(&d, dim);
379 dtxoff(&d, s, 0, TYnptr);
380 #ifdef IN_GCC
381 dt_t * cdt;
382 cdt = NULL;
383 if (tb->ty == Tarray)
384 dtcontainer(& cdt, type, d);
385 d = cdt;
386 #endif
387 break;
389 default:
390 assert(0);
392 return d;
396 dt_t *ArrayInitializer::toDtBit()
398 #if 0
399 unsigned size;
400 unsigned length;
401 unsigned i;
402 unsigned tadim;
403 dt_t *d;
404 dt_t **pdtend;
405 Type *tb = type->toBasetype();
407 Bits databits;
408 Bits initbits;
410 if (tb->ty == Tsarray)
412 /* The 'dim' for ArrayInitializer is only the maximum dimension
413 * seen in the initializer, not the type. So, for static arrays,
414 * use instead the dimension of the type in order
415 * to get the whole thing.
417 integer_t value = ((TypeSArray*)tb)->dim->toInteger();
418 tadim = value;
419 assert(tadim == value); // truncation overflow should already be checked
420 databits.resize(tadim);
421 initbits.resize(tadim);
423 else
425 databits.resize(dim);
426 initbits.resize(dim);
429 /* The default initializer may be something other than zero.
431 if (tb->nextOf()->defaultInit()->toInteger())
432 databits.set();
434 size = sizeof(databits.data[0]);
436 length = 0;
437 for (i = 0; i < index.dim; i++)
438 { Expression *idx;
439 Initializer *val;
440 Expression *eval;
442 idx = (Expression *)index.data[i];
443 if (idx)
444 { integer_t value;
445 value = idx->toInteger();
446 length = value;
447 if (length != value)
448 { error(loc, "index overflow %llu", value);
449 length = 0;
452 assert(length < dim);
454 val = (Initializer *)value.data[i];
455 eval = val->toExpression();
456 if (initbits.test(length))
457 error(loc, "duplicate initializations for index %d", length);
458 initbits.set(length);
459 if (eval->toInteger()) // any non-zero value is boolean 'true'
460 databits.set(length);
461 else
462 databits.clear(length); // boolean 'false'
463 length++;
466 d = NULL;
467 #ifdef IN_GCC
468 pdtend = dtnbits(&d, databits.allocdim * size, (char *)databits.data, sizeof(databits.data[0]));
469 #else
470 pdtend = dtnbytes(&d, databits.allocdim * size, (char *)databits.data);
471 #endif
472 switch (tb->ty)
474 case Tsarray:
476 if (dim > tadim)
478 #ifdef DEBUG
479 printf("3: ");
480 #endif
481 error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
483 else
485 tadim = (tadim + 31) / 32;
486 if (databits.allocdim < tadim)
487 pdtend = dtnzeros(pdtend, size * (tadim - databits.allocdim)); // pad out end of array
489 break;
492 case Tpointer:
493 case Tarray:
494 // Create symbol, and then refer to it
495 Symbol *s;
496 s = static_sym();
497 s->Sdt = d;
498 outdata(s);
500 d = NULL;
501 if (tb->ty == Tarray)
502 dtdword(&d, dim);
503 dtxoff(&d, s, 0, TYnptr);
504 break;
506 default:
507 assert(0);
509 return d;
510 #else
511 return NULL;
512 #endif
516 dt_t *ExpInitializer::toDt()
518 dt_t *dt = NULL;
520 exp = exp->optimize(WANTvalue);
521 exp->toDt(&dt);
522 return dt;
525 /* ================================================================ */
527 dt_t **Expression::toDt(dt_t **pdt)
529 #ifdef DEBUG
530 printf("Expression::toDt() %d\n", op);
531 dump(0);
532 #endif
533 error("non-constant expression %s", toChars());
534 pdt = dtnzeros(pdt, 1);
535 return pdt;
538 #ifndef IN_GCC
540 dt_t **IntegerExp::toDt(dt_t **pdt)
541 { unsigned sz;
543 //printf("IntegerExp::toDt() %d\n", op);
544 sz = type->size();
545 if (value == 0)
546 pdt = dtnzeros(pdt, sz);
547 else
548 pdt = dtnbytes(pdt, sz, (char *)&value);
549 return pdt;
552 static char zeropad[2];
554 dt_t **RealExp::toDt(dt_t **pdt)
556 d_float32 fvalue;
557 d_float64 dvalue;
558 d_float80 evalue;
560 //printf("RealExp::toDt(%Lg)\n", value);
561 switch (type->toBasetype()->ty)
563 case Tfloat32:
564 case Timaginary32:
565 fvalue = value;
566 pdt = dtnbytes(pdt,4,(char *)&fvalue);
567 break;
569 case Tfloat64:
570 case Timaginary64:
571 dvalue = value;
572 pdt = dtnbytes(pdt,8,(char *)&dvalue);
573 break;
575 case Tfloat80:
576 case Timaginary80:
577 evalue = value;
578 pdt = dtnbytes(pdt,REALSIZE - REALPAD,(char *)&evalue);
579 pdt = dtnbytes(pdt,REALPAD,zeropad);
580 break;
582 default:
583 fprintf(stderr, "%s\n", toChars());
584 type->print();
585 assert(0);
586 break;
588 return pdt;
591 dt_t **ComplexExp::toDt(dt_t **pdt)
593 //printf("ComplexExp::toDt() '%s'\n", toChars());
594 d_float32 fvalue;
595 d_float64 dvalue;
596 d_float80 evalue;
598 switch (type->toBasetype()->ty)
600 case Tcomplex32:
601 fvalue = creall(value);
602 pdt = dtnbytes(pdt,4,(char *)&fvalue);
603 fvalue = cimagl(value);
604 pdt = dtnbytes(pdt,4,(char *)&fvalue);
605 break;
607 case Tcomplex64:
608 dvalue = creall(value);
609 pdt = dtnbytes(pdt,8,(char *)&dvalue);
610 dvalue = cimagl(value);
611 pdt = dtnbytes(pdt,8,(char *)&dvalue);
612 break;
614 case Tcomplex80:
615 evalue = creall(value);
616 pdt = dtnbytes(pdt,REALSIZE - REALPAD,(char *)&evalue);
617 pdt = dtnbytes(pdt,REALPAD,zeropad);
618 evalue = cimagl(value);
619 pdt = dtnbytes(pdt,REALSIZE - REALPAD,(char *)&evalue);
620 pdt = dtnbytes(pdt,REALPAD,zeropad);
621 break;
623 default:
624 assert(0);
625 break;
627 return pdt;
631 #endif
633 dt_t **NullExp::toDt(dt_t **pdt)
635 assert(type);
636 return dtnzeros(pdt, type->size());
639 dt_t **StringExp::toDt(dt_t **pdt)
641 //printf("StringExp::toDt() '%s', type = %s\n", toChars(), type->toChars());
642 Type *t = type->toBasetype();
644 // BUG: should implement some form of static string pooling
645 switch (t->ty)
647 case Tarray:
648 dt_t * adt; adt = NULL;
649 dtdword(& adt, len);
650 #ifndef IN_GCC
651 dtabytes(& adt, TYnptr, 0, (len + 1) * sz, (char *)string);
652 pdt = dcat(pdt, adt);
653 #else
654 dtawords(& adt, len + 1, string, sz);
655 pdt = dtcontainer(pdt, type, adt);
656 #endif
658 break;
660 case Tsarray:
661 { TypeSArray *tsa = (TypeSArray *)type;
662 integer_t dim;
664 #ifndef IN_GCC
665 pdt = dtnbytes(pdt, len * sz, (const char *)string);
666 #else
667 pdt = dtnwords(pdt, len, string, sz);
668 #endif
669 if (tsa->dim)
671 dim = tsa->dim->toInteger();
672 if (len < dim)
674 // Pad remainder with 0
675 pdt = dtnzeros(pdt, (dim - len) * tsa->next->size());
678 break;
680 case Tpointer:
681 #ifndef IN_GCC
682 pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string);
683 #else
684 pdt = dtawords(pdt, len + 1, string, sz);
685 #endif
686 break;
688 default:
689 fprintf(stderr, "StringExp::toDt(type = %s)\n", type->toChars());
690 assert(0);
692 return pdt;
695 dt_t **ArrayLiteralExp::toDt(dt_t **pdt)
697 //printf("ArrayLiteralExp::toDt() '%s', type = %s\n", toChars(), type->toChars());
699 dt_t *d;
700 dt_t **pdtend;
702 d = NULL;
703 pdtend = &d;
704 for (int i = 0; i < elements->dim; i++)
705 { Expression *e = (Expression *)elements->data[i];
707 pdtend = e->toDt(pdtend);
709 #ifdef IN_GCC
710 dt_t * cdt = NULL;
711 dtcontainer(& cdt, type, d);
712 d = cdt;
713 #endif
714 Type *t = type->toBasetype();
716 switch (t->ty)
718 case Tsarray:
719 pdt = dtcat(pdt, d);
720 break;
722 case Tpointer:
723 case Tarray:
724 dt_t * adt; adt = NULL;
725 if (t->ty == Tarray)
726 dtdword(& adt, elements->dim);
727 if (d)
729 // Create symbol, and then refer to it
730 Symbol *s;
731 s = static_sym();
732 s->Sdt = d;
733 outdata(s);
735 dtxoff(& adt, s, 0, TYnptr);
737 else
738 dtdword(& adt, 0);
739 #ifdef IN_GCC
740 if (t->ty == Tarray)
741 dtcontainer(pdt, type, adt);
742 else
743 #endif
744 dtcat(pdt, adt);
746 break;
748 default:
749 assert(0);
751 return pdt;
754 dt_t **StructLiteralExp::toDt(dt_t **pdt)
756 Array dts;
757 unsigned i;
758 unsigned j;
759 dt_t *dt;
760 dt_t *d;
761 dt_t *sdt = NULL;
762 target_size_t offset;
764 //printf("StructLiteralExp::toDt() %s)\n", toChars());
765 dts.setDim(sd->fields.dim);
766 dts.zero();
767 assert(elements->dim <= sd->fields.dim);
769 for (i = 0; i < elements->dim; i++)
771 Expression *e = (Expression *)elements->data[i];
772 if (!e)
773 continue;
774 dt = NULL;
775 e->toDt(&dt);
776 dts.data[i] = (void *)dt;
779 offset = 0;
780 for (j = 0; j < dts.dim; j++)
782 VarDeclaration *v = (VarDeclaration *)sd->fields.data[j];
784 d = (dt_t *)dts.data[j];
785 if (!d)
786 { // An instance specific initializer was not provided.
787 // Look to see if there's a default initializer from the
788 // struct definition
789 VarDeclaration *v = (VarDeclaration *)sd->fields.data[j];
791 if (v->init)
793 d = v->init->toDt();
795 else if (v->offset >= offset)
797 target_size_t k;
798 target_size_t offset2 = v->offset + v->type->size();
799 // Make sure this field (v) does not overlap any explicitly
800 // initialized field.
801 for (k = j + 1; 1; k++)
803 if (k == dts.dim) // didn't find any overlap
805 v->type->toDt(&d);
806 break;
808 VarDeclaration *v2 = (VarDeclaration *)sd->fields.data[k];
810 if (v2->offset < offset2 && dts.data[k])
811 break; // overlap
815 if (d)
817 if (v->offset < offset)
818 error("duplicate union initialization for %s", v->toChars());
819 else
820 { target_size_t sz = dt_size(d);
821 target_size_t vsz = v->type->size();
822 target_size_t voffset = v->offset;
823 assert(sz <= vsz);
825 #ifdef IN_GCC
826 if (offset < voffset)
827 dtnzeros(& sdt, voffset - offset);
828 if (v->type->toBasetype()->ty == Tsarray)
830 d = createTsarrayDt(d, v->type);
831 sz = dt_size(d);
832 assert(sz <= vsz);
834 dtcat(& sdt, d);
835 offset = voffset + sz;
836 #else
837 target_size_t dim = 1;
838 for (Type *vt = v->type->toBasetype();
839 vt->ty == Tsarray;
840 vt = vt->nextOf()->toBasetype())
841 { TypeSArray *tsa = (TypeSArray *)vt;
842 dim *= tsa->dim->toInteger();
845 for (target_size_t i = 0; i < dim; i++)
847 if (offset < voffset)
848 dtnzeros(& sdt, voffset - offset);
849 if (!d)
851 if (v->init)
852 d = v->init->toDt();
853 else
854 v->type->toDt(&d);
856 dtcat(& sdt, d);
857 d = NULL;
858 offset = voffset + sz;
859 voffset += vsz / dim;
860 if (sz == vsz)
861 break;
863 #endif
867 if (offset < sd->structsize)
868 dtnzeros(& sdt, sd->structsize - offset);
869 #ifdef IN_GCC
870 dtcontainer(pdt, type, sdt);
871 #else
872 pdt = dtcat(pdt, sdt);
873 #endif
875 return pdt;
879 dt_t **SymOffExp::toDt(dt_t **pdt)
881 Symbol *s;
883 //printf("SymOffExp::toDt('%s')\n", var->toChars());
884 assert(var);
885 if (!(var->isDataseg() || var->isCodeseg()) ||
886 var->needThis() ||
887 var->storage_class & STCtls)
889 #ifdef DEBUG
890 printf("SymOffExp::toDt()\n");
891 #endif
892 error("non-constant expression %s", toChars());
893 return pdt;
895 s = var->toSymbol();
896 return dtxoff(pdt, s, offset, TYnptr);
899 dt_t **VarExp::toDt(dt_t **pdt)
901 //printf("VarExp::toDt() %d\n", op);
902 for (; *pdt; pdt = &((*pdt)->DTnext))
905 VarDeclaration *v = var->isVarDeclaration();
906 if (v && (v->isConst() || v->isInvariant()) &&
907 type->toBasetype()->ty != Tsarray && v->init)
909 *pdt = v->init->toDt();
910 return pdt;
912 SymbolDeclaration *sd = var->isSymbolDeclaration();
913 if (sd && sd->dsym)
915 sd->dsym->toDt(pdt);
916 return pdt;
918 #ifdef DEBUG
919 printf("VarExp::toDt(), kind = %s\n", var->kind());
920 #endif
921 error("non-constant expression %s", toChars());
922 pdt = dtnzeros(pdt, 1);
923 return pdt;
926 /* ================================================================= */
928 // Generate the data for the static initializer.
930 void ClassDeclaration::toDt(dt_t **pdt)
932 //printf("ClassDeclaration::toDt(this = '%s')\n", toChars());
934 // Put in first two members, the vtbl[] and the monitor
935 dtxoff(pdt, toVtblSymbol(), 0, TYnptr);
936 dtdword(pdt, 0); // monitor
938 // Put in the rest
939 toDt2(pdt, this);
941 //printf("-ClassDeclaration::toDt(this = '%s')\n", toChars());
944 void ClassDeclaration::toDt2(dt_t **pdt, ClassDeclaration *cd)
946 unsigned offset;
947 unsigned i;
948 dt_t *dt;
949 unsigned csymoffset;
951 #define LOG 0
953 #if LOG
954 printf("ClassDeclaration::toDt2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
955 #endif
956 if (baseClass)
958 baseClass->toDt2(pdt, cd);
959 offset = baseClass->structsize;
961 else
963 offset = PTRSIZE * 2;
966 // Note equivalence of this loop to struct's
967 for (i = 0; i < fields.dim; i++)
969 VarDeclaration *v = (VarDeclaration *)fields.data[i];
970 Initializer *init;
972 //printf("\t\tv = '%s' v->offset = %2d, offset = %2d\n", v->toChars(), v->offset, offset);
973 dt = NULL;
974 init = v->init;
975 if (init)
976 { //printf("\t\t%s has initializer %s\n", v->toChars(), init->toChars());
977 ExpInitializer *ei = init->isExpInitializer();
978 Type *tb = v->type->toBasetype();
979 if (ei && tb->ty == Tsarray)
981 #ifdef IN_GCC
982 dt = init->toDt();
983 dt = createTsarrayDt(dt, v->type);
984 #else
985 ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
986 #endif
988 else
989 dt = init->toDt();
991 else if (v->offset >= offset)
992 { //printf("\t\tdefault initializer\n");
993 v->type->toDt(&dt);
995 if (dt)
997 if (v->offset < offset)
998 error("2duplicate union initialization for %s", v->toChars());
999 else
1001 if (offset < v->offset)
1002 dtnzeros(pdt, v->offset - offset);
1003 dtcat(pdt, dt);
1004 offset = v->offset + v->type->size();
1009 // Interface vptr initializations
1010 toSymbol(); // define csym
1012 for (i = 0; i < vtblInterfaces->dim; i++)
1013 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
1015 #if 1 || INTERFACE_VIRTUAL
1016 for (ClassDeclaration *cd2 = cd; 1; cd2 = cd2->baseClass)
1018 assert(cd2);
1019 csymoffset = cd2->baseVtblOffset(b);
1020 if (csymoffset != ~0)
1022 if (offset < b->offset)
1023 dtnzeros(pdt, b->offset - offset);
1024 dtxoff(pdt, cd2->toSymbol(), csymoffset, TYnptr);
1025 break;
1028 #else
1029 csymoffset = baseVtblOffset(b);
1030 assert(csymoffset != ~0);
1031 dtxoff(pdt, csym, csymoffset, TYnptr);
1032 #endif
1033 offset = b->offset + PTRSIZE;
1036 if (offset < structsize)
1037 dtnzeros(pdt, structsize - offset);
1039 #undef LOG
1042 void StructDeclaration::toDt(dt_t **pdt)
1044 if (zeroInit)
1046 dtnzeros(pdt, structsize);
1047 return;
1050 unsigned offset;
1051 unsigned i;
1052 dt_t *dt;
1053 dt_t *sdt = NULL;
1055 //printf("StructDeclaration::toDt(), this='%s'\n", toChars());
1056 offset = 0;
1058 // Note equivalence of this loop to class's
1059 for (i = 0; i < fields.dim; i++)
1061 VarDeclaration *v = (VarDeclaration *)fields.data[i];
1062 Initializer *init;
1064 //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset);
1065 dt = NULL;
1066 init = v->init;
1067 if (init)
1068 { //printf("\t\thas initializer %s\n", init->toChars());
1069 ExpInitializer *ei = init->isExpInitializer();
1070 Type *tb = v->type->toBasetype();
1071 if (ei && tb->ty == Tsarray)
1073 #ifdef IN_GCC
1074 dt = init->toDt();
1075 dt = createTsarrayDt(dt, v->type);
1076 #else
1077 ((TypeSArray *)tb)->toDtElem(&dt, ei->exp);
1078 #endif
1080 else
1081 dt = init->toDt();
1083 else if (v->offset >= offset)
1084 v->type->toDt(&dt);
1085 if (dt)
1087 if (v->offset < offset)
1088 error("overlapping initialization for struct %s.%s", toChars(), v->toChars());
1089 else
1091 if (offset < v->offset)
1092 dtnzeros(& sdt, v->offset - offset);
1093 dtcat(& sdt, dt);
1094 offset = v->offset + v->type->size();
1099 if (offset < structsize)
1100 dtnzeros(& sdt, structsize - offset);
1101 #ifdef IN_GCC
1102 dtcontainer(pdt, type, sdt);
1103 #else
1104 dtcat(pdt, sdt);
1105 #endif
1107 dt_optimize(*pdt);
1110 /* ================================================================= */
1112 dt_t **Type::toDt(dt_t **pdt)
1114 //printf("Type::toDt()\n");
1115 Expression *e = defaultInit();
1116 return e->toDt(pdt);
1119 dt_t **TypeSArray::toDt(dt_t **pdt)
1121 return toDtElem(pdt, NULL);
1124 dt_t **TypeSArray::toDtElem(dt_t **pdt, Expression *e)
1126 int i;
1127 unsigned len;
1129 //printf("TypeSArray::toDtElem()\n");
1130 len = dim->toInteger();
1131 if (len)
1133 while (*pdt)
1134 pdt = &((*pdt)->DTnext);
1135 Type *tnext = next;
1136 Type *tbn = tnext->toBasetype();
1137 while (tbn->ty == Tsarray)
1138 { TypeSArray *tsa = (TypeSArray *)tbn;
1140 len *= tsa->dim->toInteger();
1141 tnext = tbn->nextOf();
1142 tbn = tnext->toBasetype();
1144 if (!e) // if not already supplied
1145 e = tnext->defaultInit(); // use default initializer
1146 dt_t *adt = NULL;
1147 dt_t **padt = & adt;
1148 /* problem...?
1149 if (tbn->ty == Tstruct)
1150 tnext->toDt(pdt);
1151 else
1152 e->toDt(pdt);
1154 e->toDt(padt);
1155 dt_optimize(*padt);
1157 // These first two cases are okay for GDC too
1158 if ((*padt)->dt == DT_azeros && !(*padt)->DTnext)
1160 (*padt)->DTazeros *= len;
1161 pdt = dtcat(pdt, adt);
1163 else if ((*padt)->dt == DT_1byte && (*padt)->DTonebyte == 0 && !(*padt)->DTnext)
1165 (*padt)->dt = DT_azeros;
1166 (*padt)->DTazeros = len;
1167 pdt = dtcat(pdt, adt);
1169 else if (e->op != TOKstring)
1171 #ifdef IN_GCC
1172 pdt = dtcat(pdt, createTsarrayDt(adt, this));
1173 #else
1174 for (i = 1; i < len; i++)
1176 if (tbn->ty == Tstruct)
1177 { padt = tnext->toDt(padt);
1178 while (*padt)
1179 pdt = &((*padt)->DTnext);
1181 else
1182 padt = e->toDt(padt);
1184 pdt = dtcat(pdt, adt);
1185 #endif
1188 return pdt;
1191 dt_t **TypeStruct::toDt(dt_t **pdt)
1193 sym->toDt(pdt);
1194 return pdt;
1197 dt_t **TypeTypedef::toDt(dt_t **pdt)
1199 if (sym->init)
1201 dt_t *dt = sym->init->toDt();
1203 while (*pdt)
1204 pdt = &((*pdt)->DTnext);
1205 *pdt = dt;
1206 return pdt;
1208 sym->basetype->toDt(pdt);
1209 return pdt;