1: 
   2: // Compiler implementation of the D programming language
   3: // Copyright (c) 1999-2011 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: #include <stdio.h>
  12: #include <stdlib.h>
  13: #include <math.h>
  14: static char __file__[] = __FILE__;      /* for tassert.h                */
  15: #include        "tassert.h"
  16: 
  17: #if __DMC__
  18: #include <complex.h>
  19: #endif
  20: 
  21: #include "cdef.h"
  22: #include "rmem.h"
  23: #include "root.h"
  24: #include "port.h"
  25: 
  26: #include "mtype.h"
  27: #include "expression.h"
  28: #include "aggregate.h"
  29: #include "declaration.h"
  30: #include "utf.h"
  31: 
  32: #define LOG 0
  33: 
  34: int RealEquals(real_t x1, real_t x2);
  35: 
  36: Expression *expType(Type *type, Expression *e)
  37: {
  38:     if (type != e->type)
  39:     {
  40:         e = e->copy();
  41:         e->type = type;
  42:     }
  43:     return e;
  44: }
  45: 
  46: /* ================================== isConst() ============================== */
  47: 
  48: int Expression::isConst()
  49: {
  50:     //printf("Expression::isConst(): %s\n", toChars());
  51:     return 0;
  52: }
  53: 
  54: int IntegerExp::isConst()
  55: {
  56:     return 1;
  57: }
  58: 
  59: int RealExp::isConst()
  60: {
  61:     return 1;
  62: }
  63: 
  64: int ComplexExp::isConst()
  65: {
  66:     return 1;
  67: }
  68: 
  69: int NullExp::isConst()
  70: {
  71:     return 0;
  72: }
  73: 
  74: int SymOffExp::isConst()
  75: {
  76:     return 2;
  77: }
  78: 
  79: /* =============================== constFold() ============================== */
  80: 
  81: /* The constFold() functions were redundant with the optimize() ones,
  82:  * and so have been folded in with them.
  83:  */
  84: 
  85: /* ========================================================================== */
  86: 
  87: Expression *Neg(Type *type, Expression *e1)
  88: {   Expression *e;
  89:     Loc loc = e1->loc;
  90: 
  91:     if (e1->type->isreal())
  92:     {
  93:         e = new RealExp(loc, -e1->toReal(), type);
  94:     }
  95:     else if (e1->type->isimaginary())
  96:     {
  97:         e = new RealExp(loc, -e1->toImaginary(), type);
  98:     }
  99:     else if (e1->type->iscomplex())
 100:     {
 101:         e = new ComplexExp(loc, -e1->toComplex(), type);
 102:     }
 103:     else
 104:         e = new IntegerExp(loc, -e1->toInteger(), type);
warning C4146: unary minus operator applied to unsigned type, result still unsigned
105: return e; 106: } 107: 108: Expression *Com(Type *type, Expression *e1) 109: { Expression *e; 110: Loc loc = e1->loc; 111: 112: e = new IntegerExp(loc, ~e1->toInteger(), type); 113: return e; 114: } 115: 116: Expression *Not(Type *type, Expression *e1) 117: { Expression *e; 118: Loc loc = e1->loc; 119: 120: e = new IntegerExp(loc, e1->isBool(0), type); 121: return e; 122: } 123: 124: Expression *Bool(Type *type, Expression *e1) 125: { Expression *e; 126: Loc loc = e1->loc; 127: 128: e = new IntegerExp(loc, e1->isBool(1), type); 129: return e; 130: } 131: 132: Expression *Add(Type *type, Expression *e1, Expression *e2) 133: { Expression *e; 134: Loc loc = e1->loc; 135: 136: #if LOG 137: printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 138: #endif 139: if (type->isreal()) 140: { 141: e = new RealExp(loc, e1->toReal() + e2->toReal(), type); 142: } 143: else if (type->isimaginary()) 144: { 145: e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type); 146: } 147: else if (type->iscomplex()) 148: { 149: // This rigamarole is necessary so that -0.0 doesn't get 150: // converted to +0.0 by doing an extraneous add with +0.0 151: complex_t c1; 152: real_t r1; 153: real_t i1; 154: 155: complex_t c2; 156: real_t r2; 157: real_t i2; 158: 159: complex_t v; 160: int x; 161: 162: if (e1->type->isreal()) 163: { r1 = e1->toReal(); 164: x = 0; 165: } 166: else if (e1->type->isimaginary()) 167: { i1 = e1->toImaginary(); 168: x = 3; 169: } 170: else 171: { c1 = e1->toComplex(); 172: x = 6; 173: } 174: 175: if (e2->type->isreal()) 176: { r2 = e2->toReal(); 177: } 178: else if (e2->type->isimaginary()) 179: { i2 = e2->toImaginary(); 180: x += 1; 181: } 182: else 183: { c2 = e2->toComplex(); 184: x += 2; 185: } 186: 187: switch (x) 188: { 189: #if __DMC__ 190: case 0+0: v = (complex_t) (r1 + r2); break; 191: case 0+1: v = r1 + i2 * I; break; 192: case 0+2: v = r1 + c2; break; 193: case 3+0: v = i1 * I + r2; break; 194: case 3+1: v = (complex_t) ((i1 + i2) * I); break; 195: case 3+2: v = i1 * I + c2; break; 196: case 6+0: v = c1 + r2; break; 197: case 6+1: v = c1 + i2 * I; break; 198: case 6+2: v = c1 + c2; break; 199: #else 200: case 0+0: v = complex_t(r1 + r2, 0); break; 201: case 0+1: v = complex_t(r1, i2); break; 202: case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break; 203: case 3+0: v = complex_t(r2, i1); break; 204: case 3+1: v = complex_t(0, i1 + i2); break; 205: case 3+2: v = complex_t(creall(c2), i1 + cimagl(c2)); break; 206: case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break; 207: case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break; 208: case 6+2: v = c1 + c2; break; 209: #endif 210: default: assert(0); 211: } 212: e = new ComplexExp(loc, v, type); 213: } 214: else if (e1->op == TOKsymoff) 215: { 216: SymOffExp *soe = (SymOffExp *)e1; 217: e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger());
warning C4244: 'argument' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
218: e->type = type; 219: } 220: else if (e2->op == TOKsymoff) 221: { 222: SymOffExp *soe = (SymOffExp *)e2; 223: e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger());
warning C4244: 'argument' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
224: e->type = type; 225: } 226: else 227: e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type); 228: return e; 229: } 230: 231: 232: Expression *Min(Type *type, Expression *e1, Expression *e2) 233: { Expression *e; 234: Loc loc = e1->loc; 235: 236: if (type->isreal()) 237: { 238: e = new RealExp(loc, e1->toReal() - e2->toReal(), type); 239: } 240: else if (type->isimaginary()) 241: { 242: e = new RealExp(loc, e1->toImaginary() - e2->toImaginary(), type); 243: } 244: else if (type->iscomplex()) 245: { 246: // This rigamarole is necessary so that -0.0 doesn't get 247: // converted to +0.0 by doing an extraneous add with +0.0 248: complex_t c1; 249: real_t r1; 250: real_t i1; 251: 252: complex_t c2; 253: real_t r2; 254: real_t i2; 255: 256: complex_t v; 257: int x; 258: 259: if (e1->type->isreal()) 260: { r1 = e1->toReal(); 261: x = 0; 262: } 263: else if (e1->type->isimaginary()) 264: { i1 = e1->toImaginary(); 265: x = 3; 266: } 267: else 268: { c1 = e1->toComplex(); 269: x = 6; 270: } 271: 272: if (e2->type->isreal()) 273: { r2 = e2->toReal(); 274: } 275: else if (e2->type->isimaginary()) 276: { i2 = e2->toImaginary(); 277: x += 1; 278: } 279: else 280: { c2 = e2->toComplex(); 281: x += 2; 282: } 283: 284: switch (x) 285: { 286: #if __DMC__ 287: case 0+0: v = (complex_t) (r1 - r2); break; 288: case 0+1: v = r1 - i2 * I; break; 289: case 0+2: v = r1 - c2; break; 290: case 3+0: v = i1 * I - r2; break; 291: case 3+1: v = (complex_t) ((i1 - i2) * I); break; 292: case 3+2: v = i1 * I - c2; break; 293: case 6+0: v = c1 - r2; break; 294: case 6+1: v = c1 - i2 * I; break; 295: case 6+2: v = c1 - c2; break; 296: #else 297: case 0+0: v = complex_t(r1 - r2, 0); break; 298: case 0+1: v = complex_t(r1, -i2); break; 299: case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break; 300: case 3+0: v = complex_t(-r2, i1); break; 301: case 3+1: v = complex_t(0, i1 - i2); break; 302: case 3+2: v = complex_t(-creall(c2), i1 - cimagl(c2)); break; 303: case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break; 304: case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break; 305: case 6+2: v = c1 - c2; break; 306: #endif 307: default: assert(0); 308: } 309: e = new ComplexExp(loc, v, type); 310: } 311: else if (e1->op == TOKsymoff) 312: { 313: SymOffExp *soe = (SymOffExp *)e1; 314: e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger());
warning C4244: 'argument' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
315: e->type = type; 316: } 317: else 318: { 319: e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type); 320: } 321: return e; 322: } 323: 324: Expression *Mul(Type *type, Expression *e1, Expression *e2) 325: { Expression *e; 326: Loc loc = e1->loc; 327: 328: if (type->isfloating()) 329: { complex_t c; 330: #ifdef IN_GCC 331: real_t r; 332: #else 333: d_float80 r; 334: #endif 335: 336: if (e1->type->isreal()) 337: { 338: #if __DMC__ 339: c = e1->toReal() * e2->toComplex(); 340: #else 341: r = e1->toReal(); 342: c = e2->toComplex(); 343: c = complex_t(r * creall(c), r * cimagl(c)); 344: #endif 345: } 346: else if (e1->type->isimaginary()) 347: { 348: #if __DMC__ 349: c = e1->toImaginary() * I * e2->toComplex(); 350: #else 351: r = e1->toImaginary(); 352: c = e2->toComplex(); 353: c = complex_t(-r * cimagl(c), r * creall(c)); 354: #endif 355: } 356: else if (e2->type->isreal()) 357: { 358: #if __DMC__ 359: c = e2->toReal() * e1->toComplex(); 360: #else 361: r = e2->toReal(); 362: c = e1->toComplex(); 363: c = complex_t(r * creall(c), r * cimagl(c)); 364: #endif 365: } 366: else if (e2->type->isimaginary()) 367: { 368: #if __DMC__ 369: c = e1->toComplex() * e2->toImaginary() * I; 370: #else 371: r = e2->toImaginary(); 372: c = e1->toComplex(); 373: c = complex_t(-r * cimagl(c), r * creall(c)); 374: #endif 375: } 376: else 377: c = e1->toComplex() * e2->toComplex(); 378: 379: if (type->isreal()) 380: e = new RealExp(loc, creall(c), type); 381: else if (type->isimaginary()) 382: e = new RealExp(loc, cimagl(c), type); 383: else if (type->iscomplex()) 384: e = new ComplexExp(loc, c, type); 385: else 386: assert(0); 387: } 388: else 389: { 390: e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type); 391: } 392: return e; 393: } 394: 395: Expression *Div(Type *type, Expression *e1, Expression *e2) 396: { Expression *e; 397: Loc loc = e1->loc; 398: 399: if (type->isfloating()) 400: { complex_t c; 401: #ifdef IN_GCC 402: real_t r; 403: #else 404: d_float80 r; 405: #endif 406: 407: //e1->type->print(); 408: //e2->type->print(); 409: if (e2->type->isreal()) 410: { 411: if (e1->type->isreal()) 412: { 413: e = new RealExp(loc, e1->toReal() / e2->toReal(), type); 414: return e; 415: } 416: #if __DMC__ 417: //r = e2->toReal(); 418: //c = e1->toComplex(); 419: //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r); 420: 421: c = e1->toComplex() / e2->toReal(); 422: #else 423: r = e2->toReal(); 424: c = e1->toComplex(); 425: c = complex_t(creall(c) / r, cimagl(c) / r); 426: #endif 427: } 428: else if (e2->type->isimaginary()) 429: { 430: #if __DMC__ 431: //r = e2->toImaginary(); 432: //c = e1->toComplex(); 433: //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r); 434: 435: c = e1->toComplex() / (e2->toImaginary() * I); 436: #else 437: r = e2->toImaginary(); 438: c = e1->toComplex(); 439: c = complex_t(cimagl(c) / r, -creall(c) / r); 440: #endif 441: } 442: else 443: { 444: c = e1->toComplex() / e2->toComplex(); 445: } 446: 447: if (type->isreal()) 448: e = new RealExp(loc, creall(c), type); 449: else if (type->isimaginary()) 450: e = new RealExp(loc, cimagl(c), type); 451: else if (type->iscomplex()) 452: e = new ComplexExp(loc, c, type); 453: else 454: assert(0); 455: } 456: else 457: { sinteger_t n1; 458: sinteger_t n2; 459: sinteger_t n; 460: 461: n1 = e1->toInteger(); 462: n2 = e2->toInteger(); 463: if (n2 == 0) 464: { e2->error("divide by 0"); 465: e2 = new IntegerExp(loc, 1, e2->type);
warning C6211: Leaking memory 'e2' due to an exception. Consider using a local catch block to clean up memory: Lines: 396, 397, 399, 457, 458, 459, 461, 462, 463, 464, 465, 466, 468, 471, 472
466: n2 = 1; 467: } 468: if (e1->type->isunsigned() || e2->type->isunsigned()) 469: n = ((d_uns64) n1) / ((d_uns64) n2); 470: else 471: n = n1 / n2; 472: e = new IntegerExp(loc, n, type); 473: } 474: return e; 475: } 476: 477: Expression *Mod(Type *type, Expression *e1, Expression *e2) 478: { Expression *e; 479: Loc loc = e1->loc; 480: 481: if (type->isfloating()) 482: { 483: complex_t c; 484: 485: if (e2->type->isreal()) 486: { real_t r2 = e2->toReal(); 487: 488: #ifdef __DMC__ 489: c = Port::fmodl(e1->toReal(), r2) + Port::fmodl(e1->toImaginary(), r2) * I; 490: #elif defined(IN_GCC) 491: c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2); 492: #else 493: c = complex_t(Port::fmodl(e1->toReal(), r2), Port::fmodl(e1->toImaginary(), r2)); 494: #endif 495: } 496: else if (e2->type->isimaginary()) 497: { real_t i2 = e2->toImaginary(); 498: 499: #ifdef __DMC__ 500: c = Port::fmodl(e1->toReal(), i2) + Port::fmodl(e1->toImaginary(), i2) * I; 501: #elif defined(IN_GCC) 502: c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2); 503: #else 504: c = complex_t(Port::fmodl(e1->toReal(), i2), Port::fmodl(e1->toImaginary(), i2)); 505: #endif 506: } 507: else 508: assert(0); 509: 510: if (type->isreal()) 511: e = new RealExp(loc, creall(c), type); 512: else if (type->isimaginary()) 513: e = new RealExp(loc, cimagl(c), type); 514: else if (type->iscomplex()) 515: e = new ComplexExp(loc, c, type); 516: else 517: assert(0); 518: } 519: else 520: { sinteger_t n1; 521: sinteger_t n2; 522: sinteger_t n; 523: 524: n1 = e1->toInteger(); 525: n2 = e2->toInteger(); 526: if (n2 == 0) 527: { e2->error("divide by 0"); 528: e2 = new IntegerExp(loc, 1, e2->type);
warning C6211: Leaking memory 'e2' due to an exception. Consider using a local catch block to clean up memory: Lines: 478, 479, 481, 520, 521, 522, 524, 525, 526, 527, 528, 529, 531, 546, 549, 550
529: n2 = 1; 530: } 531: if (n2 == -1 && !type->isunsigned()) 532: { // Check for int.min % -1 533: if (n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64) 534: { 535: e2->error("integer overflow: int.min % -1"); 536: e2 = new IntegerExp(loc, 1, e2->type); 537: n2 = 1; 538: } 539: else if (n1 == 0x8000000000000000LL) // long.min % -1 540: { 541: e2->error("integer overflow: long.min % -1"); 542: e2 = new IntegerExp(loc, 1, e2->type); 543: n2 = 1; 544: } 545: } 546: if (e1->type->isunsigned() || e2->type->isunsigned()) 547: n = ((d_uns64) n1) % ((d_uns64) n2); 548: else 549: n = n1 % n2; 550: e = new IntegerExp(loc, n, type); 551: } 552: return e; 553: } 554: 555: Expression *Shl(Type *type, Expression *e1, Expression *e2) 556: { Expression *e; 557: Loc loc = e1->loc; 558: 559: e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type); 560: return e; 561: } 562: 563: Expression *Shr(Type *type, Expression *e1, Expression *e2) 564: { 565: Loc loc = e1->loc; 566: 567: dinteger_t value = e1->toInteger(); 568: unsigned count = e2->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
569: switch (e1->type->toBasetype()->ty) 570: { 571: case Tint8: 572: value = (d_int8)(value) >> count; 573: break; 574: 575: case Tuns8: 576: value = (d_uns8)(value) >> count; 577: break; 578: 579: case Tint16: 580: value = (d_int16)(value) >> count; 581: break; 582: 583: case Tuns16: 584: value = (d_uns16)(value) >> count; 585: break; 586: 587: case Tint32: 588: value = (d_int32)(value) >> count; 589: break; 590: 591: case Tuns32: 592: value = (d_uns32)(value) >> count; 593: break; 594: 595: case Tint64: 596: value = (d_int64)(value) >> count; 597: break; 598: 599: case Tuns64: 600: value = (d_uns64)(value) >> count; 601: break; 602: 603: case Terror: 604: return e1; 605: 606: default: 607: assert(0); 608: } 609: Expression *e = new IntegerExp(loc, value, type); 610: return e; 611: } 612: 613: Expression *Ushr(Type *type, Expression *e1, Expression *e2) 614: { 615: Loc loc = e1->loc; 616: 617: dinteger_t value = e1->toInteger(); 618: unsigned count = e2->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
619: switch (e1->type->toBasetype()->ty) 620: { 621: case Tint8: 622: case Tuns8: 623: assert(0); // no way to trigger this 624: value = (value & 0xFF) >> count; 625: break; 626: 627: case Tint16: 628: case Tuns16: 629: assert(0); // no way to trigger this 630: value = (value & 0xFFFF) >> count; 631: break; 632: 633: case Tint32: 634: case Tuns32: 635: value = (value & 0xFFFFFFFF) >> count; 636: break; 637: 638: case Tint64: 639: case Tuns64: 640: value = (d_uns64)(value) >> count; 641: break; 642: 643: case Terror: 644: return e1; 645: 646: default: 647: assert(0); 648: } 649: Expression *e = new IntegerExp(loc, value, type); 650: return e; 651: } 652: 653: Expression *And(Type *type, Expression *e1, Expression *e2) 654: { 655: Expression *e; 656: e = new IntegerExp(e1->loc, e1->toInteger() & e2->toInteger(), type); 657: return e; 658: } 659: 660: Expression *Or(Type *type, Expression *e1, Expression *e2) 661: { Expression *e; 662: e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type); 663: return e; 664: } 665: 666: Expression *Xor(Type *type, Expression *e1, Expression *e2) 667: { Expression *e; 668: e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type); 669: return e; 670: } 671: 672: /* Also returns EXP_CANT_INTERPRET if cannot be computed. 673: */ 674: Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) 675: { Expression *e; 676: Loc loc = e1->loc; 677: int cmp; 678: real_t r1; 679: real_t r2; 680: 681: //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 682: 683: assert(op == TOKequal || op == TOKnotequal); 684: 685: if (e1->op == TOKnull) 686: { 687: if (e2->op == TOKnull) 688: cmp = 1; 689: else if (e2->op == TOKstring) 690: { StringExp *es2 = (StringExp *)e2; 691: cmp = (0 == es2->len); 692: } 693: else if (e2->op == TOKarrayliteral) 694: { ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 695: cmp = !es2->elements || (0 == es2->elements->dim); 696: } 697: else 698: return EXP_CANT_INTERPRET; 699: } 700: else if (e2->op == TOKnull) 701: { 702: if (e1->op == TOKstring) 703: { StringExp *es1 = (StringExp *)e1; 704: cmp = (0 == es1->len); 705: } 706: else if (e1->op == TOKarrayliteral) 707: { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; 708: cmp = !es1->elements || (0 == es1->elements->dim); 709: } 710: else 711: return EXP_CANT_INTERPRET; 712: } 713: else if (e1->op == TOKstring && e2->op == TOKstring) 714: { StringExp *es1 = (StringExp *)e1; 715: StringExp *es2 = (StringExp *)e2; 716: 717: if (es1->sz != es2->sz) 718: { 719: assert(global.errors); 720: return EXP_CANT_INTERPRET; 721: } 722: if (es1->len == es2->len && 723: memcmp(es1->string, es2->string, es1->sz * es1->len) == 0) 724: cmp = 1; 725: else 726: cmp = 0; 727: } 728: else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral) 729: { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; 730: ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 731: 732: if ((!es1->elements || !es1->elements->dim) && 733: (!es2->elements || !es2->elements->dim)) 734: cmp = 1; // both arrays are empty 735: else if (!es1->elements || !es2->elements) 736: cmp = 0; 737: else if (es1->elements->dim != es2->elements->dim) 738: cmp = 0; 739: else 740: { 741: for (size_t i = 0; i < es1->elements->dim; i++) 742: { Expression *ee1 = es1->elements->tdata()[i]; 743: Expression *ee2 = es2->elements->tdata()[i]; 744: 745: Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 746: if (v == EXP_CANT_INTERPRET) 747: return EXP_CANT_INTERPRET; 748: cmp = v->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'int', possible loss of data
749: if (cmp == 0) 750: break; 751: } 752: } 753: } 754: else if (e1->op == TOKarrayliteral && e2->op == TOKstring) 755: { // Swap operands and use common code 756: Expression *e = e1;
warning C6246: Local declaration of 'e' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '675' of 'c:\projects\extern\d\dmd\src\constfold.c': Lines: 675
757: e1 = e2; 758: e2 = e; 759: goto Lsa; 760: } 761: else if (e1->op == TOKstring && e2->op == TOKarrayliteral) 762: { 763: Lsa: 764: StringExp *es1 = (StringExp *)e1; 765: ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 766: size_t dim1 = es1->len; 767: size_t dim2 = es2->elements ? es2->elements->dim : 0; 768: if (dim1 != dim2) 769: cmp = 0; 770: else 771: { 772: cmp = 1; // if dim1 winds up being 0 773: for (size_t i = 0; i < dim1; i++) 774: { 775: uinteger_t c = es1->charAt(i); 776: Expression *ee2 = (*es2->elements)[i]; 777: if (ee2->isConst() != 1) 778: return EXP_CANT_INTERPRET; 779: cmp = (c == ee2->toInteger()); 780: if (cmp == 0) 781: break; 782: } 783: } 784: } 785: else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) 786: { StructLiteralExp *es1 = (StructLiteralExp *)e1; 787: StructLiteralExp *es2 = (StructLiteralExp *)e2; 788: 789: if (es1->sd != es2->sd) 790: cmp = 0; 791: else if ((!es1->elements || !es1->elements->dim) && 792: (!es2->elements || !es2->elements->dim)) 793: cmp = 1; // both arrays are empty 794: else if (!es1->elements || !es2->elements) 795: cmp = 0; 796: else if (es1->elements->dim != es2->elements->dim) 797: cmp = 0; 798: else 799: { 800: cmp = 1; 801: for (size_t i = 0; i < es1->elements->dim; i++) 802: { Expression *ee1 = es1->elements->tdata()[i]; 803: Expression *ee2 = es2->elements->tdata()[i]; 804: 805: if (ee1 == ee2) 806: continue; 807: if (!ee1 || !ee2) 808: { cmp = 0; 809: break; 810: } 811: Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); 812: if (v == EXP_CANT_INTERPRET) 813: return EXP_CANT_INTERPRET; 814: cmp = v->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'int', possible loss of data
815: if (cmp == 0) 816: break; 817: } 818: } 819: } 820: #if 0 // Should handle this 821: else if (e1->op == TOKarrayliteral && e2->op == TOKstring) 822: { 823: } 824: #endif 825: else if (e1->isConst() != 1 || e2->isConst() != 1) 826: return EXP_CANT_INTERPRET; 827: else if (e1->type->isreal()) 828: { 829: r1 = e1->toReal(); 830: r2 = e2->toReal(); 831: goto L1; 832: } 833: else if (e1->type->isimaginary()) 834: { 835: r1 = e1->toImaginary(); 836: r2 = e2->toImaginary(); 837: L1: 838: #if __DMC__ 839: cmp = (r1 == r2); 840: #else 841: if (Port::isNan(r1) || Port::isNan(r2)) // if unordered 842: { 843: cmp = 0; 844: } 845: else 846: { 847: cmp = (r1 == r2); 848: } 849: #endif 850: } 851: else if (e1->type->iscomplex()) 852: { 853: cmp = e1->toComplex() == e2->toComplex(); 854: } 855: else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer) 856: { 857: cmp = (e1->toInteger() == e2->toInteger()); 858: } 859: else 860: return EXP_CANT_INTERPRET; 861: if (op == TOKnotequal) 862: cmp ^= 1; 863: e = new IntegerExp(loc, cmp, type); 864: return e; 865: } 866: 867: Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) 868: { 869: Loc loc = e1->loc; 870: int cmp; 871: 872: if (e1->op == TOKnull) 873: { 874: cmp = (e2->op == TOKnull); 875: } 876: else if (e2->op == TOKnull) 877: { 878: cmp = 0; 879: } 880: else if (e1->op == TOKsymoff && e2->op == TOKsymoff) 881: { 882: SymOffExp *es1 = (SymOffExp *)e1; 883: SymOffExp *es2 = (SymOffExp *)e2; 884: 885: cmp = (es1->var == es2->var && es1->offset == es2->offset); 886: } 887: else 888: { 889: if (e1->type->isreal()) 890: { 891: cmp = RealEquals(e1->toReal(), e2->toReal()); 892: } 893: else if (e1->type->isimaginary()) 894: { 895: cmp = RealEquals(e1->toImaginary(), e2->toImaginary()); 896: } 897: else if (e1->type->iscomplex()) 898: { 899: complex_t v1 = e1->toComplex(); 900: complex_t v2 = e2->toComplex(); 901: cmp = RealEquals(creall(v1), creall(v2)) && 902: RealEquals(cimagl(v1), cimagl(v1)); 903: } 904: else 905: return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, 906: type, e1, e2); 907: } 908: if (op == TOKnotidentity) 909: cmp ^= 1; 910: return new IntegerExp(loc, cmp, type); 911: } 912: 913: 914: Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) 915: { Expression *e; 916: Loc loc = e1->loc; 917: dinteger_t n; 918: real_t r1; 919: real_t r2; 920: 921: //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 922: 923: if (e1->op == TOKstring && e2->op == TOKstring) 924: { StringExp *es1 = (StringExp *)e1; 925: StringExp *es2 = (StringExp *)e2; 926: size_t sz = es1->sz; 927: assert(sz == es2->sz); 928: 929: size_t len = es1->len; 930: if (es2->len < len) 931: len = es2->len; 932: 933: int cmp = memcmp(es1->string, es2->string, sz * len); 934: if (cmp == 0) 935: cmp = es1->len - es2->len; 936: 937: switch (op) 938: { 939: case TOKlt: n = cmp < 0; break; 940: case TOKle: n = cmp <= 0; break; 941: case TOKgt: n = cmp > 0; break; 942: case TOKge: n = cmp >= 0; break; 943: 944: case TOKleg: n = 1; break; 945: case TOKlg: n = cmp != 0; break; 946: case TOKunord: n = 0; break; 947: case TOKue: n = cmp == 0; break; 948: case TOKug: n = cmp > 0; break; 949: case TOKuge: n = cmp >= 0; break; 950: case TOKul: n = cmp < 0; break; 951: case TOKule: n = cmp <= 0; break; 952: 953: default: 954: assert(0); 955: } 956: } 957: else if (e1->isConst() != 1 || e2->isConst() != 1) 958: return EXP_CANT_INTERPRET; 959: else if (e1->type->isreal()) 960: { 961: r1 = e1->toReal(); 962: r2 = e2->toReal(); 963: goto L1; 964: } 965: else if (e1->type->isimaginary()) 966: { 967: r1 = e1->toImaginary(); 968: r2 = e2->toImaginary(); 969: L1: 970: #if __DMC__ 971: // DMC is the only compiler I know of that handles NAN arguments 972: // correctly in comparisons. 973: switch (op) 974: { 975: case TOKlt: n = r1 < r2; break; 976: case TOKle: n = r1 <= r2; break; 977: case TOKgt: n = r1 > r2; break; 978: case TOKge: n = r1 >= r2; break; 979: 980: case TOKleg: n = r1 <>= r2; break; 981: case TOKlg: n = r1 <> r2; break; 982: case TOKunord: n = r1 !<>= r2; break; 983: case TOKue: n = r1 !<> r2; break; 984: case TOKug: n = r1 !<= r2; break; 985: case TOKuge: n = r1 !< r2; break; 986: case TOKul: n = r1 !>= r2; break; 987: case TOKule: n = r1 !> r2; break; 988: 989: default: 990: assert(0); 991: } 992: #else 993: // Don't rely on compiler, handle NAN arguments separately 994: if (Port::isNan(r1) || Port::isNan(r2)) // if unordered 995: { 996: switch (op) 997: { 998: case TOKlt: n = 0; break; 999: case TOKle: n = 0; break; 1000: case TOKgt: n = 0; break; 1001: case TOKge: n = 0; break; 1002: 1003: case TOKleg: n = 0; break; 1004: case TOKlg: n = 0; break; 1005: case TOKunord: n = 1; break; 1006: case TOKue: n = 1; break; 1007: case TOKug: n = 1; break; 1008: case TOKuge: n = 1; break; 1009: case TOKul: n = 1; break; 1010: case TOKule: n = 1; break; 1011: 1012: default: 1013: assert(0); 1014: } 1015: } 1016: else 1017: { 1018: switch (op) 1019: { 1020: case TOKlt: n = r1 < r2; break; 1021: case TOKle: n = r1 <= r2; break; 1022: case TOKgt: n = r1 > r2; break; 1023: case TOKge: n = r1 >= r2; break; 1024: 1025: case TOKleg: n = 1; break; 1026: case TOKlg: n = r1 != r2; break; 1027: case TOKunord: n = 0; break; 1028: case TOKue: n = r1 == r2; break; 1029: case TOKug: n = r1 > r2; break; 1030: case TOKuge: n = r1 >= r2; break; 1031: case TOKul: n = r1 < r2; break; 1032: case TOKule: n = r1 <= r2; break; 1033: 1034: default: 1035: assert(0); 1036: } 1037: } 1038: #endif 1039: } 1040: else if (e1->type->iscomplex()) 1041: { 1042: assert(0); 1043: } 1044: else 1045: { sinteger_t n1; 1046: sinteger_t n2; 1047: 1048: n1 = e1->toInteger(); 1049: n2 = e2->toInteger(); 1050: if (e1->type->isunsigned() || e2->type->isunsigned()) 1051: { 1052: switch (op) 1053: { 1054: case TOKlt: n = ((d_uns64) n1) < ((d_uns64) n2); break; 1055: case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2); break; 1056: case TOKgt: n = ((d_uns64) n1) > ((d_uns64) n2); break; 1057: case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2); break; 1058: 1059: case TOKleg: n = 1; break; 1060: case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2); break; 1061: case TOKunord: n = 0; break; 1062: case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2); break; 1063: case TOKug: n = ((d_uns64) n1) > ((d_uns64) n2); break; 1064: case TOKuge: n = ((d_uns64) n1) >= ((d_uns64) n2); break; 1065: case TOKul: n = ((d_uns64) n1) < ((d_uns64) n2); break; 1066: case TOKule: n = ((d_uns64) n1) <= ((d_uns64) n2); break; 1067: 1068: default: 1069: assert(0); 1070: } 1071: } 1072: else 1073: { 1074: switch (op) 1075: { 1076: case TOKlt: n = n1 < n2; break; 1077: case TOKle: n = n1 <= n2; break; 1078: case TOKgt: n = n1 > n2; break; 1079: case TOKge: n = n1 >= n2; break; 1080: 1081: case TOKleg: n = 1; break; 1082: case TOKlg: n = n1 != n2; break; 1083: case TOKunord: n = 0; break; 1084: case TOKue: n = n1 == n2; break; 1085: case TOKug: n = n1 > n2; break; 1086: case TOKuge: n = n1 >= n2; break; 1087: case TOKul: n = n1 < n2; break; 1088: case TOKule: n = n1 <= n2; break; 1089: 1090: default: 1091: assert(0); 1092: } 1093: } 1094: } 1095: e = new IntegerExp(loc, n, type); 1096: return e; 1097: } 1098: 1099: /* Also returns EXP_CANT_INTERPRET if cannot be computed. 1100: * to: type to cast to 1101: * type: type to paint the result 1102: */ 1103: 1104: Expression *Cast(Type *type, Type *to, Expression *e1) 1105: { Expression *e = EXP_CANT_INTERPRET; 1106: Loc loc = e1->loc; 1107: 1108: //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); 1109: //printf("\te1->type = %s\n", e1->type->toChars()); 1110: if (e1->type->equals(type) && type->equals(to)) 1111: return e1; 1112: if (e1->type->implicitConvTo(to) >= MATCHconst || 1113: to->implicitConvTo(e1->type) >= MATCHconst) 1114: return expType(to, e1); 1115: 1116: // Allow covariant converions of delegates 1117: // (Perhaps implicit conversion from pure to impure should be a MATCHconst, 1118: // then we wouldn't need this extra check.) 1119: if (e1->type->toBasetype()->ty == Tdelegate && 1120: e1->type->implicitConvTo(to) == MATCHconvert) 1121: return expType(to, e1); 1122: 1123: Type *tb = to->toBasetype(); 1124: Type *typeb = type->toBasetype(); 1125: 1126: /* Allow casting from one string type to another 1127: */ 1128: if (e1->op == TOKstring) 1129: { 1130: if (tb->ty == Tarray && typeb->ty == Tarray && 1131: tb->nextOf()->size() == typeb->nextOf()->size()) 1132: { 1133: return expType(to, e1); 1134: } 1135: } 1136: 1137: if (e1->op == TOKarrayliteral && typeb == tb) 1138: return e1; 1139: 1140: if (e1->isConst() != 1) 1141: return EXP_CANT_INTERPRET; 1142: 1143: if (tb->ty == Tbool) 1144: e = new IntegerExp(loc, e1->toInteger() != 0, type); 1145: else if (type->isintegral()) 1146: { 1147: if (e1->type->isfloating()) 1148: { dinteger_t result; 1149: real_t r = e1->toReal(); 1150: 1151: switch (typeb->ty) 1152: { 1153: case Tint8: result = (d_int8)r; break; 1154: case Tchar: 1155: case Tuns8: result = (d_uns8)r; break; 1156: case Tint16: result = (d_int16)r; break; 1157: case Twchar: 1158: case Tuns16: result = (d_uns16)r; break; 1159: case Tint32: result = (d_int32)r; break; 1160: case Tdchar: 1161: case Tuns32: result = (d_uns32)r; break; 1162: case Tint64: result = (d_int64)r; break; 1163: case Tuns64: result = (d_uns64)r; break; 1164: default: 1165: assert(0); 1166: } 1167: 1168: e = new IntegerExp(loc, result, type); 1169: } 1170: else if (type->isunsigned()) 1171: e = new IntegerExp(loc, e1->toUInteger(), type); 1172: else 1173: e = new IntegerExp(loc, e1->toInteger(), type); 1174: } 1175: else if (tb->isreal()) 1176: { real_t value = e1->toReal(); 1177: 1178: e = new RealExp(loc, value, type); 1179: } 1180: else if (tb->isimaginary()) 1181: { real_t value = e1->toImaginary(); 1182: 1183: e = new RealExp(loc, value, type); 1184: } 1185: else if (tb->iscomplex()) 1186: { complex_t value = e1->toComplex(); 1187: 1188: e = new ComplexExp(loc, value, type); 1189: } 1190: else if (tb->isscalar()) 1191: e = new IntegerExp(loc, e1->toInteger(), type); 1192: else if (tb->ty == Tvoid) 1193: e = EXP_CANT_INTERPRET; 1194: else if (tb->ty == Tstruct && e1->op == TOKint64) 1195: { // Struct = 0; 1196: StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration(); 1197: assert(sd); 1198: Expressions *elements = new Expressions; 1199: for (size_t i = 0; i < sd->fields.dim; i++) 1200: { Dsymbol *s = sd->fields.tdata()[i]; 1201: VarDeclaration *v = s->isVarDeclaration(); 1202: assert(v); 1203: 1204: Expression *exp = new IntegerExp(0); 1205: exp = Cast(v->type, v->type, exp); 1206: if (exp == EXP_CANT_INTERPRET) 1207: return exp; 1208: elements->push(exp); 1209: } 1210: e = new StructLiteralExp(loc, sd, elements); 1211: e->type = type; 1212: } 1213: else 1214: { 1215: if (type != Type::terror) 1216: error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars()); 1217: e = new ErrorExp(); 1218: } 1219: return e; 1220: } 1221: 1222: 1223: Expression *ArrayLength(Type *type, Expression *e1) 1224: { Expression *e; 1225: Loc loc = e1->loc; 1226: 1227: if (e1->op == TOKstring) 1228: { StringExp *es1 = (StringExp *)e1; 1229: 1230: e = new IntegerExp(loc, es1->len, type); 1231: } 1232: else if (e1->op == TOKarrayliteral) 1233: { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; 1234: size_t dim; 1235: 1236: dim = ale->elements ? ale->elements->dim : 0; 1237: e = new IntegerExp(loc, dim, type); 1238: } 1239: else if (e1->op == TOKassocarrayliteral) 1240: { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1; 1241: size_t dim = ale->keys->dim; 1242: 1243: e = new IntegerExp(loc, dim, type); 1244: } 1245: else 1246: e = EXP_CANT_INTERPRET; 1247: return e; 1248: } 1249: 1250: /* Also return EXP_CANT_INTERPRET if this fails 1251: */ 1252: Expression *Index(Type *type, Expression *e1, Expression *e2) 1253: { Expression *e = EXP_CANT_INTERPRET; 1254: Loc loc = e1->loc; 1255: 1256: //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 1257: assert(e1->type); 1258: if (e1->op == TOKstring && e2->op == TOKint64) 1259: { StringExp *es1 = (StringExp *)e1; 1260: uinteger_t i = e2->toInteger(); 1261: 1262: if (i >= es1->len) 1263: e1->error("string index %ju is out of bounds [0 .. %"SIZE_T_FORMAT"u]", i, es1->len); 1264: else 1265: { unsigned value = es1->charAt(i);
warning C4244: 'argument' : conversion from 'uinteger_t' to 'size_t', possible loss of data
1266: e = new IntegerExp(loc, value, type); 1267: } 1268: } 1269: else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64) 1270: { TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype(); 1271: uinteger_t length = tsa->dim->toInteger(); 1272: uinteger_t i = e2->toInteger(); 1273: 1274: if (i >= length) 1275: { e1->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length); 1276: } 1277: else if (e1->op == TOKarrayliteral) 1278: { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; 1279: e = ale->elements->tdata()[i]; 1280: e->type = type; 1281: if (e->checkSideEffect(2)) 1282: e = EXP_CANT_INTERPRET; 1283: } 1284: } 1285: else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64) 1286: { 1287: uinteger_t i = e2->toInteger(); 1288: 1289: if (e1->op == TOKarrayliteral) 1290: { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; 1291: if (i >= ale->elements->dim) 1292: { e1->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); 1293: } 1294: else 1295: { e = ale->elements->tdata()[i]; 1296: e->type = type; 1297: if (e->checkSideEffect(2)) 1298: e = EXP_CANT_INTERPRET; 1299: } 1300: } 1301: } 1302: else if (e1->op == TOKassocarrayliteral) 1303: { 1304: AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1; 1305: /* Search the keys backwards, in case there are duplicate keys 1306: */ 1307: for (size_t i = ae->keys->dim; i;) 1308: { 1309: i--; 1310: Expression *ekey = ae->keys->tdata()[i]; 1311: Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); 1312: if (ex == EXP_CANT_INTERPRET) 1313: return ex; 1314: if (ex->isBool(TRUE)) 1315: { e = ae->values->tdata()[i]; 1316: e->type = type; 1317: if (e->checkSideEffect(2)) 1318: e = EXP_CANT_INTERPRET; 1319: break; 1320: } 1321: } 1322: } 1323: return e; 1324: } 1325: 1326: /* Also return EXP_CANT_INTERPRET if this fails 1327: */ 1328: Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) 1329: { Expression *e = EXP_CANT_INTERPRET; 1330: Loc loc = e1->loc; 1331: 1332: #if LOG 1333: printf("Slice()\n"); 1334: if (lwr) 1335: { printf("\te1 = %s\n", e1->toChars()); 1336: printf("\tlwr = %s\n", lwr->toChars()); 1337: printf("\tupr = %s\n", upr->toChars()); 1338: } 1339: #endif 1340: if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64) 1341: { StringExp *es1 = (StringExp *)e1; 1342: uinteger_t ilwr = lwr->toInteger(); 1343: uinteger_t iupr = upr->toInteger(); 1344: 1345: if (iupr > es1->len || ilwr > iupr) 1346: e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); 1347: else 1348: { dinteger_t value;
warning C4101: 'value' : unreferenced local variable
1349: void *s; 1350: size_t len = iupr - ilwr;
warning C4244: 'initializing' : conversion from 'uinteger_t' to 'size_t', possible loss of data
1351: int sz = es1->sz; 1352: StringExp *es; 1353: 1354: s = mem.malloc((len + 1) * sz); 1355: memcpy((unsigned char *)s, (unsigned char *)es1->string + ilwr * sz, len * sz); 1356: memset((unsigned char *)s + len * sz, 0, sz); 1357: 1358: es = new StringExp(loc, s, len, es1->postfix); 1359: es->sz = sz; 1360: es->committed = 1; 1361: es->type = type; 1362: e = es; 1363: } 1364: } 1365: else if (e1->op == TOKarrayliteral && 1366: lwr->op == TOKint64 && upr->op == TOKint64 && 1367: !e1->checkSideEffect(2)) 1368: { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; 1369: uinteger_t ilwr = lwr->toInteger(); 1370: uinteger_t iupr = upr->toInteger(); 1371: 1372: if (iupr > es1->elements->dim || ilwr > iupr) 1373: e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); 1374: else 1375: { 1376: Expressions *elements = new Expressions(); 1377: elements->setDim(iupr - ilwr);
warning C4244: 'argument' : conversion from 'uinteger_t' to 'unsigned int', possible loss of data
1378: memcpy(elements->tdata(), 1379: es1->elements->tdata() + ilwr, 1380: (iupr - ilwr) * sizeof(es1->elements->tdata()[0]));
warning C4244: 'argument' : conversion from 'uinteger_t' to 'size_t', possible loss of data
1381: e = new ArrayLiteralExp(e1->loc, elements); 1382: e->type = type; 1383: } 1384: } 1385: return e; 1386: } 1387: 1388: /* Also return EXP_CANT_INTERPRET if this fails 1389: */ 1390: Expression *Cat(Type *type, Expression *e1, Expression *e2) 1391: { Expression *e = EXP_CANT_INTERPRET; 1392: Loc loc = e1->loc; 1393: Type *t; 1394: Type *t1 = e1->type->toBasetype(); 1395: Type *t2 = e2->type->toBasetype(); 1396: 1397: //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 1398: //printf("\tt1 = %s, t2 = %s, type = %s\n", t1->toChars(), t2->toChars(), type->toChars()); 1399: 1400: if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) 1401: { e = e2; 1402: t = t1; 1403: goto L2; 1404: } 1405: else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull) 1406: { e = e1; 1407: t = t2; 1408: L2: 1409: Type *tn = e->type->toBasetype(); 1410: if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) 1411: { 1412: // Create a StringExp 1413: void *s; 1414: StringExp *es; 1415: if (t->nextOf()) 1416: t = t->nextOf()->toBasetype(); 1417: int sz = t->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'int', possible loss of data
1418: 1419: dinteger_t v = e->toInteger(); 1420: 1421: size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, v);
warning C4244: 'argument' : conversion from 'dinteger_t' to 'dchar_t', possible loss of data
1422: s = mem.malloc((len + 1) * sz); 1423: if (t->ty == tn->ty) 1424: memcpy((unsigned char *)s, &v, sz); 1425: else 1426: utf_encode(sz, s, v);
warning C4244: 'argument' : conversion from 'dinteger_t' to 'dchar_t', possible loss of data
1427: 1428: // Add terminating 0 1429: memset((unsigned char *)s + len * sz, 0, sz); 1430: 1431: es = new StringExp(loc, s, len); 1432: es->sz = sz; 1433: es->committed = 1; 1434: e = es; 1435: } 1436: else 1437: { // Create an ArrayLiteralExp 1438: Expressions *elements = new Expressions(); 1439: elements->push(e); 1440: e = new ArrayLiteralExp(e->loc, elements); 1441: } 1442: e->type = type; 1443: return e; 1444: } 1445: else if (e1->op == TOKnull && e2->op == TOKnull) 1446: { 1447: if (type == e1->type) 1448: return e1; 1449: if (type == e2->type) 1450: return e2; 1451: return new NullExp(e1->loc, type); 1452: } 1453: else if (e1->op == TOKstring && e2->op == TOKstring) 1454: { 1455: // Concatenate the strings 1456: void *s; 1457: StringExp *es1 = (StringExp *)e1; 1458: StringExp *es2 = (StringExp *)e2; 1459: StringExp *es; 1460: Type *t;
warning C6246: Local declaration of 't' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '1393' of 'c:\projects\extern\d\dmd\src\constfold.c': Lines: 1393
1461: size_t len = es1->len + es2->len; 1462: int sz = es1->sz; 1463: 1464: if (sz != es2->sz) 1465: { 1466: /* Can happen with: 1467: * auto s = "foo"d ~ "bar"c; 1468: */ 1469: assert(global.errors); 1470: return e; 1471: } 1472: s = mem.malloc((len + 1) * sz); 1473: memcpy(s, es1->string, es1->len * sz); 1474: memcpy((unsigned char *)s + es1->len * sz, es2->string, es2->len * sz); 1475: 1476: // Add terminating 0 1477: memset((unsigned char *)s + len * sz, 0, sz); 1478: 1479: es = new StringExp(loc, s, len); 1480: es->sz = sz; 1481: es->committed = es1->committed | es2->committed; 1482: if (es1->committed) 1483: t = es1->type; 1484: else 1485: t = es2->type; 1486: es->type = type; 1487: e = es; 1488: } 1489: else if (e2->op == TOKstring && e1->op == TOKarrayliteral && 1490: t1->nextOf()->isintegral()) 1491: { 1492: // Concatenate the strings 1493: StringExp *es1 = (StringExp *)e2; 1494: ArrayLiteralExp *es2 = (ArrayLiteralExp *)e1; 1495: size_t len = es1->len + es2->elements->dim; 1496: int sz = es1->sz; 1497: 1498: void *s = mem.malloc((len + 1) * sz); 1499: memcpy((char *)s + sz * es2->elements->dim, es1->string, es1->len * sz); 1500: for (int i = 0; i < es2->elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1501: { Expression *es2e = es2->elements->tdata()[i]; 1502: if (es2e->op != TOKint64) 1503: return EXP_CANT_INTERPRET; 1504: dinteger_t v = es2e->toInteger(); 1505: memcpy((unsigned char *)s + i * sz, &v, sz); 1506: } 1507: 1508: // Add terminating 0 1509: memset((unsigned char *)s + len * sz, 0, sz); 1510: 1511: StringExp *es = new StringExp(loc, s, len); 1512: es->sz = sz; 1513: es->committed = 0; 1514: es->type = type; 1515: e = es; 1516: } 1517: else if (e1->op == TOKstring && e2->op == TOKarrayliteral && 1518: t2->nextOf()->isintegral()) 1519: { 1520: // Concatenate the strings 1521: StringExp *es1 = (StringExp *)e1; 1522: ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 1523: size_t len = es1->len + es2->elements->dim; 1524: int sz = es1->sz; 1525: 1526: void *s = mem.malloc((len + 1) * sz); 1527: memcpy(s, es1->string, es1->len * sz); 1528: for (int i = 0; i < es2->elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1529: { Expression *es2e = es2->elements->tdata()[i]; 1530: if (es2e->op != TOKint64) 1531: return EXP_CANT_INTERPRET; 1532: dinteger_t v = es2e->toInteger(); 1533: memcpy((unsigned char *)s + (es1->len + i) * sz, &v, sz); 1534: } 1535: 1536: // Add terminating 0 1537: memset((unsigned char *)s + len * sz, 0, sz); 1538: 1539: StringExp *es = new StringExp(loc, s, len); 1540: es->sz = sz; 1541: es->committed = 0; //es1->committed; 1542: es->type = type; 1543: e = es; 1544: } 1545: else if (e1->op == TOKstring && e2->op == TOKint64) 1546: { 1547: // Concatenate the strings 1548: void *s; 1549: StringExp *es1 = (StringExp *)e1; 1550: StringExp *es; 1551: Type *t;
warning C6246: Local declaration of 't' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '1393' of 'c:\projects\extern\d\dmd\src\constfold.c': Lines: 1393
1552: int sz = es1->sz; 1553: dinteger_t v = e2->toInteger(); 1554: 1555: // Is it a concatentation of homogenous types? 1556: // (char[] ~ char, wchar[]~wchar, or dchar[]~dchar) 1557: bool homoConcat = (sz == t2->size()); 1558: size_t len = es1->len; 1559: len += homoConcat ? 1 : utf_codeLength(sz, v);
warning C4244: 'argument' : conversion from 'dinteger_t' to 'dchar_t', possible loss of data
1560: 1561: s = mem.malloc((len + 1) * sz); 1562: memcpy(s, es1->string, es1->len * sz); 1563: if (homoConcat) 1564: memcpy((unsigned char *)s + (sz * es1->len), &v, sz); 1565: else 1566: utf_encode(sz, (unsigned char *)s + (sz * es1->len), v);
warning C4244: 'argument' : conversion from 'dinteger_t' to 'dchar_t', possible loss of data
1567: 1568: // Add terminating 0 1569: memset((unsigned char *)s + len * sz, 0, sz); 1570: 1571: es = new StringExp(loc, s, len); 1572: es->sz = sz; 1573: es->committed = es1->committed; 1574: t = es1->type; 1575: es->type = type; 1576: e = es; 1577: } 1578: else if (e1->op == TOKint64 && e2->op == TOKstring) 1579: { 1580: // Concatenate the strings 1581: void *s; 1582: StringExp *es2 = (StringExp *)e2; 1583: StringExp *es; 1584: Type *t;
warning C6246: Local declaration of 't' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '1393' of 'c:\projects\extern\d\dmd\src\constfold.c': Lines: 1393
1585: size_t len = 1 + es2->len; 1586: int sz = es2->sz; 1587: dinteger_t v = e1->toInteger(); 1588: 1589: s = mem.malloc((len + 1) * sz); 1590: memcpy((unsigned char *)s, &v, sz); 1591: memcpy((unsigned char *)s + sz, es2->string, es2->len * sz); 1592: 1593: // Add terminating 0 1594: memset((unsigned char *)s + len * sz, 0, sz); 1595: 1596: es = new StringExp(loc, s, len); 1597: es->sz = sz; 1598: es->committed = es2->committed; 1599: t = es2->type; 1600: es->type = type; 1601: e = es; 1602: } 1603: else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && 1604: t1->nextOf()->equals(t2->nextOf())) 1605: { 1606: // Concatenate the arrays 1607: ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; 1608: ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 1609: 1610: es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); 1611: es1->elements->insert(es1->elements->dim, es2->elements); 1612: e = es1; 1613: 1614: if (type->toBasetype()->ty == Tsarray) 1615: { 1616: e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es1->elements->dim, Type::tindex)); 1617: e->type = e->type->semantic(loc, NULL); 1618: } 1619: else 1620: e->type = type; 1621: } 1622: else if (e1->op == TOKarrayliteral && e2->op == TOKnull && 1623: t1->nextOf()->equals(t2->nextOf())) 1624: { 1625: e = e1; 1626: goto L3; 1627: } 1628: else if (e1->op == TOKnull && e2->op == TOKarrayliteral && 1629: t1->nextOf()->equals(t2->nextOf())) 1630: { 1631: e = e2; 1632: L3: 1633: // Concatenate the array with null 1634: ArrayLiteralExp *es = (ArrayLiteralExp *)e; 1635: 1636: es = new ArrayLiteralExp(es->loc, (Expressions *)es->elements->copy()); 1637: e = es; 1638: 1639: if (type->toBasetype()->ty == Tsarray) 1640: { 1641: e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es->elements->dim, Type::tindex)); 1642: e->type = e->type->semantic(loc, NULL); 1643: } 1644: else 1645: e->type = type; 1646: } 1647: else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) && 1648: e1->type->toBasetype()->nextOf()->equals(e2->type)) 1649: { 1650: ArrayLiteralExp *es1; 1651: if (e1->op == TOKarrayliteral) 1652: { es1 = (ArrayLiteralExp *)e1; 1653: es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); 1654: es1->elements->push(e2); 1655: } 1656: else 1657: { 1658: es1 = new ArrayLiteralExp(e1->loc, e2);
warning C6211: Leaking memory 'return value' due to an exception. Consider using a local catch block to clean up memory: Lines: 1391, 1392, 1393, 1394, 1395, 1400, 1405, 1445, 1453, 1489, 1517, 1545, 1578, 1603, 1622, 1628, 1647, 1650, 1651, 1658, 1660, 1662, 1664
1659: } 1660: e = es1; 1661: 1662: if (type->toBasetype()->ty == Tsarray) 1663: { 1664: e->type = new TypeSArray(e2->type, new IntegerExp(loc, es1->elements->dim, Type::tindex)); 1665: e->type = e->type->semantic(loc, NULL); 1666: } 1667: else 1668: e->type = type; 1669: } 1670: else if (e2->op == TOKarrayliteral && 1671: e2->type->toBasetype()->nextOf()->equals(e1->type)) 1672: { 1673: ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 1674: 1675: es2 = new ArrayLiteralExp(es2->loc, (Expressions *)es2->elements->copy()); 1676: es2->elements->shift(e1); 1677: e = es2; 1678: 1679: if (type->toBasetype()->ty == Tsarray) 1680: { 1681: e->type = new TypeSArray(e1->type, new IntegerExp(loc, es2->elements->dim, Type::tindex)); 1682: e->type = e->type->semantic(loc, NULL); 1683: } 1684: else 1685: e->type = type; 1686: } 1687: else if (e1->op == TOKnull && e2->op == TOKstring) 1688: { 1689: t = e1->type; 1690: e = e2; 1691: goto L1; 1692: } 1693: else if (e1->op == TOKstring && e2->op == TOKnull) 1694: { e = e1; 1695: t = e2->type; 1696: L1: 1697: Type *tb = t->toBasetype(); 1698: if (tb->ty == Tarray && tb->nextOf()->equals(e->type)) 1699: { Expressions *expressions = new Expressions(); 1700: expressions->push(e); 1701: e = new ArrayLiteralExp(loc, expressions); 1702: e->type = t; 1703: } 1704: if (!e->type->equals(type)) 1705: { StringExp *se = (StringExp *)e->copy(); 1706: e = se->castTo(NULL, type); 1707: } 1708: } 1709: return e; 1710: } 1711: 1712: Expression *Ptr(Type *type, Expression *e1) 1713: { 1714: //printf("Ptr(e1 = %s)\n", e1->toChars()); 1715: if (e1->op == TOKadd) 1716: { AddExp *ae = (AddExp *)e1; 1717: if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) 1718: { AddrExp *ade = (AddrExp *)ae->e1; 1719: if (ade->e1->op == TOKstructliteral) 1720: { StructLiteralExp *se = (StructLiteralExp *)ade->e1; 1721: unsigned offset = ae->e2->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
1722: Expression *e = se->getField(type, offset); 1723: if (!e) 1724: e = EXP_CANT_INTERPRET; 1725: return e; 1726: } 1727: } 1728: } 1729: return EXP_CANT_INTERPRET; 1730: } 1731: 1732: