/src/constfold.c

https://bitbucket.org/olioengr/dmd · C · 1714 lines · 1454 code · 173 blank · 87 comment · 465 complexity · 37d38272cfbdcf434d936a147d80a464 MD5 · raw file

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