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