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: