PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/gcc/d/expr.cc

http://github.com/D-Programming-GDC/GDC
C++ | 3125 lines | 2171 code | 525 blank | 429 comment | 614 complexity | ccf9a32e649ddf1cd5a460bac888f711 MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /* expr.cc -- Lower D frontend expressions to GCC trees.
  2. Copyright (C) 2015-2018 Free Software Foundation, Inc.
  3. GCC is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3, or (at your option)
  6. any later version.
  7. GCC is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with GCC; see the file COPYING3. If not see
  13. <http://www.gnu.org/licenses/>. */
  14. #include "config.h"
  15. #include "system.h"
  16. #include "coretypes.h"
  17. #include "dmd/aggregate.h"
  18. #include "dmd/ctfe.h"
  19. #include "dmd/declaration.h"
  20. #include "dmd/expression.h"
  21. #include "dmd/identifier.h"
  22. #include "dmd/init.h"
  23. #include "dmd/module.h"
  24. #include "dmd/mtype.h"
  25. #include "dmd/template.h"
  26. #include "tree.h"
  27. #include "fold-const.h"
  28. #include "diagnostic.h"
  29. #include "langhooks.h"
  30. #include "tm.h"
  31. #include "function.h"
  32. #include "toplev.h"
  33. #include "varasm.h"
  34. #include "predict.h"
  35. #include "stor-layout.h"
  36. #include "d-tree.h"
  37. /* Implements the visitor interface to build the GCC trees of all Expression
  38. AST classes emitted from the D Front-end.
  39. All visit methods accept one parameter E, which holds the frontend AST
  40. of the expression to compile. They also don't return any value, instead
  41. generated code is cached in RESULT_ and returned from the caller. */
  42. class ExprVisitor : public Visitor
  43. {
  44. using Visitor::visit;
  45. tree result_;
  46. bool constp_;
  47. /* Determine if type is a struct that has a postblit. */
  48. bool needs_postblit (Type *t)
  49. {
  50. t = t->baseElemOf ();
  51. if (t->ty == Tstruct)
  52. {
  53. StructDeclaration *sd = ((TypeStruct *) t)->sym;
  54. if (sd->postblit)
  55. return true;
  56. }
  57. return false;
  58. }
  59. /* Determine if type is a struct that has a destructor. */
  60. bool needs_dtor (Type *t)
  61. {
  62. t = t->baseElemOf ();
  63. if (t->ty == Tstruct)
  64. {
  65. StructDeclaration *sd = ((TypeStruct *) t)->sym;
  66. if (sd->dtor)
  67. return true;
  68. }
  69. return false;
  70. }
  71. /* Determine if expression is suitable lvalue. */
  72. bool lvalue_p (Expression *e)
  73. {
  74. return ((e->op != TOKslice && e->isLvalue ())
  75. || (e->op == TOKslice && ((UnaExp *) e)->e1->isLvalue ())
  76. || (e->op == TOKcast && ((UnaExp *) e)->e1->isLvalue ()));
  77. }
  78. /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
  79. ARG1. Perform relevant conversions needed for correct code operations. */
  80. tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
  81. {
  82. tree t0 = TREE_TYPE (arg0);
  83. tree t1 = TREE_TYPE (arg1);
  84. tree ret = NULL_TREE;
  85. bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
  86. /* Deal with float mod expressions immediately. */
  87. if (code == FLOAT_MOD_EXPR)
  88. return build_float_modulus (type, arg0, arg1);
  89. if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
  90. return build_nop (type, build_offset_op (code, arg0, arg1));
  91. if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
  92. return build_nop (type, build_offset_op (code, arg1, arg0));
  93. if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
  94. {
  95. gcc_assert (code == MINUS_EXPR);
  96. tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
  97. /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
  98. pointers. If some platform cannot provide that, or has a larger
  99. ptrdiff_type to support differences larger than half the address
  100. space, cast the pointers to some larger integer type and do the
  101. computations in that type. */
  102. if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
  103. ret = fold_build2 (MINUS_EXPR, ptrtype,
  104. d_convert (ptrtype, arg0),
  105. d_convert (ptrtype, arg1));
  106. else
  107. ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
  108. }
  109. else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
  110. {
  111. tree inttype = (unsignedp)
  112. ? d_unsigned_type (type) : d_signed_type (type);
  113. ret = fold_build2 (code, inttype, arg0, arg1);
  114. }
  115. else
  116. {
  117. /* If the operation needs excess precision. */
  118. tree eptype = excess_precision_type (type);
  119. if (eptype != NULL_TREE)
  120. {
  121. arg0 = d_convert (eptype, arg0);
  122. arg1 = d_convert (eptype, arg1);
  123. }
  124. else
  125. {
  126. /* Front-end does not do this conversion and GCC does not
  127. always do it right. */
  128. if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
  129. arg1 = d_convert (t0, arg1);
  130. else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
  131. arg0 = d_convert (t1, arg0);
  132. eptype = type;
  133. }
  134. ret = fold_build2 (code, eptype, arg0, arg1);
  135. }
  136. return d_convert (type, ret);
  137. }
  138. /* Build a binary expression of code CODE, assigning the result into E1. */
  139. tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
  140. {
  141. /* Skip casts for lhs assignment. */
  142. Expression *e1b = e1;
  143. while (e1b->op == TOKcast)
  144. {
  145. CastExp *ce = (CastExp *) e1b;
  146. gcc_assert (same_type_p (ce->type, ce->to));
  147. e1b = ce->e1;
  148. }
  149. /* Stabilize LHS for assignment. */
  150. tree lhs = build_expr (e1b);
  151. tree lexpr = stabilize_expr (&lhs);
  152. /* The LHS expression could be an assignment, to which its operation gets
  153. lost during gimplification. */
  154. if (TREE_CODE (lhs) == MODIFY_EXPR)
  155. {
  156. /* If LHS has side effects, call stabilize_reference on it, so it can
  157. be evaluated multiple times. */
  158. if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
  159. lhs = build_assign (MODIFY_EXPR,
  160. stabilize_reference (TREE_OPERAND (lhs, 0)),
  161. TREE_OPERAND (lhs, 1));
  162. lexpr = compound_expr (lexpr, lhs);
  163. lhs = TREE_OPERAND (lhs, 0);
  164. }
  165. lhs = stabilize_reference (lhs);
  166. /* Save RHS, to ensure that the expression is evaluated before LHS. */
  167. tree rhs = build_expr (e2);
  168. tree rexpr = d_save_expr (rhs);
  169. rhs = this->binary_op (code, build_ctype (e1->type),
  170. convert_expr (lhs, e1b->type, e1->type), rexpr);
  171. if (TREE_SIDE_EFFECTS (rhs))
  172. rhs = compound_expr (rexpr, rhs);
  173. tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
  174. return compound_expr (lexpr, expr);
  175. }
  176. public:
  177. ExprVisitor (bool constp)
  178. {
  179. this->result_ = NULL_TREE;
  180. this->constp_ = constp;
  181. }
  182. tree result (void)
  183. {
  184. return this->result_;
  185. }
  186. /* Visitor interfaces, each Expression class should have
  187. overridden the default. */
  188. void visit (Expression *)
  189. {
  190. gcc_unreachable ();
  191. }
  192. /* Build a conditional expression. If either the second or third
  193. expression is void, then the resulting type is void. Otherwise
  194. they are implicitly converted to a common type. */
  195. void visit (CondExp *e)
  196. {
  197. tree cond = convert_for_condition (build_expr (e->econd),
  198. e->econd->type);
  199. tree t1 = build_expr (e->e1);
  200. tree t2 = build_expr (e->e2);
  201. if (e->type->ty != Tvoid)
  202. {
  203. t1 = convert_expr (t1, e->e1->type, e->type);
  204. t2 = convert_expr (t2, e->e2->type, e->type);
  205. }
  206. this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
  207. }
  208. /* Build an identity comparison expression. Operands go through the
  209. usual conversions to bring them to a common type before comparison.
  210. The result type is bool. */
  211. void visit (IdentityExp *e)
  212. {
  213. tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;
  214. Type *tb1 = e->e1->type->toBasetype ();
  215. Type *tb2 = e->e2->type->toBasetype ();
  216. if ((tb1->ty == Tsarray || tb1->ty == Tarray)
  217. && (tb2->ty == Tsarray || tb2->ty == Tarray))
  218. {
  219. /* For static and dynamic arrays, identity is defined as referring to
  220. the same array elements and the same number of elements. */
  221. tree t1 = d_array_convert (e->e1);
  222. tree t2 = d_array_convert (e->e2);
  223. this->result_ = d_convert (build_ctype (e->type),
  224. build_boolop (code, t1, t2));
  225. }
  226. else if (tb1->isfloating () && tb1->ty != Tvector)
  227. {
  228. /* For floating-point values, identity is defined as the bits in the
  229. operands being identical. */
  230. tree t1 = d_save_expr (build_expr (e->e1));
  231. tree t2 = d_save_expr (build_expr (e->e2));
  232. tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
  233. tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
  234. tree result = build_call_expr (tmemcmp, 3, build_address (t1),
  235. build_address (t2), size);
  236. this->result_ = build_boolop (code, result, integer_zero_node);
  237. }
  238. else if (tb1->ty == Tstruct)
  239. {
  240. /* For struct objects, identity is defined as bits in operands being
  241. identical also. Alignment holes in structs are ignored. */
  242. StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
  243. tree t1 = build_expr (e->e1);
  244. tree t2 = build_expr (e->e2);
  245. gcc_assert (same_type_p (tb1, tb2));
  246. this->result_ = build_struct_comparison (code, sd, t1, t2);
  247. }
  248. else
  249. {
  250. /* For operands of other types, identity is defined as being the
  251. same as equality expressions. */
  252. tree t1 = build_expr (e->e1);
  253. tree t2 = build_expr (e->e2);
  254. this->result_ = d_convert (build_ctype (e->type),
  255. build_boolop (code, t1, t2));
  256. }
  257. }
  258. /* Build an equality expression, which compare the two operands for either
  259. equality or inequality. Operands go through the usual conversions to bring
  260. them to a common type before comparison. The result type is bool. */
  261. void visit (EqualExp *e)
  262. {
  263. Type *tb1 = e->e1->type->toBasetype ();
  264. Type *tb2 = e->e2->type->toBasetype ();
  265. tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;
  266. if ((tb1->ty == Tsarray || tb1->ty == Tarray)
  267. && (tb2->ty == Tsarray || tb2->ty == Tarray))
  268. {
  269. /* For static and dynamic arrays, equality is defined as the lengths of
  270. the arrays matching, and all the elements are equal. */
  271. Type *t1elem = tb1->nextOf ()->toBasetype ();
  272. Type *t2elem = tb1->nextOf ()->toBasetype ();
  273. /* Check if comparisons of arrays can be optimized using memcmp.
  274. This will inline EQ expressions as:
  275. e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
  276. Or when generating a NE expression:
  277. e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
  278. if ((t1elem->isintegral () || t1elem->ty == Tvoid
  279. || (t1elem->ty == Tstruct && !((TypeStruct *)t1elem)->sym->xeq))
  280. && t1elem->ty == t2elem->ty)
  281. {
  282. tree t1 = d_array_convert (e->e1);
  283. tree t2 = d_array_convert (e->e2);
  284. tree result;
  285. /* Make temporaries to prevent multiple evaluations. */
  286. tree t1saved = d_save_expr (t1);
  287. tree t2saved = d_save_expr (t2);
  288. /* Length of arrays, for comparisons done before calling memcmp. */
  289. tree t1len = d_array_length (t1saved);
  290. tree t2len = d_array_length (t2saved);
  291. /* Reference to array data. */
  292. tree t1ptr = d_array_ptr (t1saved);
  293. tree t2ptr = d_array_ptr (t2saved);
  294. /* Compare arrays using memcmp if possible, otherwise for structs,
  295. each field is compared inline. */
  296. if (t1elem->ty != Tstruct
  297. || identity_compare_p (((TypeStruct *) t1elem)->sym))
  298. {
  299. tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
  300. tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
  301. result = build_call_expr (tmemcmp, 3, t1ptr, t2ptr, size);
  302. result = build_boolop (code, result, integer_zero_node);
  303. }
  304. else
  305. {
  306. StructDeclaration *sd = ((TypeStruct *) t1elem)->sym;
  307. result = build_array_struct_comparison (code, sd, t1len,
  308. t1ptr, t2ptr);
  309. }
  310. /* Check array length first before passing to memcmp.
  311. For equality expressions, this becomes:
  312. (e1.length == 0 || memcmp);
  313. Otherwise for inequality:
  314. (e1.length != 0 && memcmp); */
  315. tree tsizecmp = build_boolop (code, t1len, size_zero_node);
  316. if (e->op == TOKequal)
  317. result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
  318. else
  319. result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
  320. /* Finally, check if lengths of both arrays match if dynamic.
  321. The frontend should have already guaranteed that static arrays
  322. have same size. */
  323. if (tb1->ty == Tsarray && tb2->ty == Tsarray)
  324. gcc_assert (tb1->size () == tb2->size ());
  325. else
  326. {
  327. tree tlencmp = build_boolop (code, t1len, t2len);
  328. if (e->op == TOKequal)
  329. result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
  330. else
  331. result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
  332. }
  333. /* Ensure left-to-right order of evaluation. */
  334. if (TREE_SIDE_EFFECTS (t2))
  335. result = compound_expr (t2saved, result);
  336. if (TREE_SIDE_EFFECTS (t1))
  337. result = compound_expr (t1saved, result);
  338. this->result_ = result;
  339. }
  340. else
  341. {
  342. /* Use _adEq2() to compare each element. */
  343. Type *t1array = t1elem->arrayOf ();
  344. tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
  345. d_array_convert (e->e1),
  346. d_array_convert (e->e2),
  347. build_typeinfo (e->loc, t1array));
  348. if (e->op == TOKnotequal)
  349. result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
  350. this->result_ = result;
  351. }
  352. }
  353. else if (tb1->ty == Tstruct)
  354. {
  355. /* Equality for struct objects means the logical product of all
  356. equality results of the corresponding object fields. */
  357. StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
  358. tree t1 = build_expr (e->e1);
  359. tree t2 = build_expr (e->e2);
  360. gcc_assert (same_type_p (tb1, tb2));
  361. this->result_ = build_struct_comparison (code, sd, t1, t2);
  362. }
  363. else if (tb1->ty == Taarray && tb2->ty == Taarray)
  364. {
  365. /* Use _aaEqual() for associative arrays. */
  366. TypeAArray *taa1 = (TypeAArray *) tb1;
  367. tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
  368. build_typeinfo (e->loc, taa1),
  369. build_expr (e->e1),
  370. build_expr (e->e2));
  371. if (e->op == TOKnotequal)
  372. result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
  373. this->result_ = result;
  374. }
  375. else
  376. {
  377. /* For operands of other types, equality is defined as the bit pattern
  378. of the type matches exactly. */
  379. tree t1 = build_expr (e->e1);
  380. tree t2 = build_expr (e->e2);
  381. this->result_ = d_convert (build_ctype (e->type),
  382. build_boolop (code, t1, t2));
  383. }
  384. }
  385. /* Build an `in' expression. This is a condition to see if an element
  386. exists in an associative array. The result is a pointer to the
  387. element, or null if false. */
  388. void visit (InExp *e)
  389. {
  390. Type *tb2 = e->e2->type->toBasetype ();
  391. gcc_assert (tb2->ty == Taarray);
  392. Type *tkey = ((TypeAArray *) tb2)->index->toBasetype ();
  393. tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
  394. /* Build a call to _aaInX(). */
  395. this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
  396. build_expr (e->e2),
  397. build_typeinfo (e->loc, tkey),
  398. build_address (key));
  399. }
  400. /* Build a relational expression. The result type is bool. */
  401. void visit (CmpExp *e)
  402. {
  403. Type *tb1 = e->e1->type->toBasetype ();
  404. Type *tb2 = e->e2->type->toBasetype ();
  405. tree result;
  406. tree_code code;
  407. switch (e->op)
  408. {
  409. case TOKle:
  410. code = LE_EXPR;
  411. break;
  412. case TOKlt:
  413. code = LT_EXPR;
  414. break;
  415. case TOKge:
  416. code = GE_EXPR;
  417. break;
  418. case TOKgt:
  419. code = GT_EXPR;
  420. break;
  421. default:
  422. gcc_unreachable ();
  423. }
  424. /* For static and dynamic arrays, the relational op is turned into a
  425. library call. It is not lowered during codegen. */
  426. if ((tb1->ty == Tsarray || tb1->ty == Tarray)
  427. && (tb2->ty == Tsarray || tb2->ty == Tarray))
  428. {
  429. error ("cannot handle comparison of type %<%s == %s%>",
  430. tb1->toChars (), tb2->toChars ());
  431. gcc_unreachable ();
  432. }
  433. /* Simple comparison. */
  434. result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
  435. this->result_ = d_convert (build_ctype (e->type), result);
  436. }
  437. /* Build a logical `and if' or `or if' expression. If the right operand
  438. expression is void, then the resulting type is void. Otherwise the
  439. result is bool. */
  440. void visit (LogicalExp *e)
  441. {
  442. tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
  443. if (e->e2->type->toBasetype ()->ty != Tvoid)
  444. {
  445. tree t1 = build_expr (e->e1);
  446. tree t2 = build_expr (e->e2);
  447. t1 = convert_for_condition (t1, e->e1->type);
  448. t2 = convert_for_condition (t2, e->e2->type);
  449. this->result_ = d_convert (build_ctype (e->type),
  450. build_boolop (code, t1, t2));
  451. }
  452. else
  453. {
  454. tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
  455. tree t2 = build_expr_dtor (e->e2);
  456. /* Invert condition for logical or if expression. */
  457. if (e->op == TOKoror)
  458. t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
  459. this->result_ = build_condition (build_ctype (e->type),
  460. t1, t2, void_node);
  461. }
  462. }
  463. /* Build a binary operand expression. Operands go through usual arithmetic
  464. conversions to bring them to a common type before evaluating. */
  465. void visit (BinExp *e)
  466. {
  467. tree_code code;
  468. switch (e->op)
  469. {
  470. case TOKadd:
  471. case TOKmin:
  472. if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
  473. || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
  474. {
  475. /* If the result is complex, then we can shortcut binary_op.
  476. Frontend should have already validated types and sizes. */
  477. tree t1 = build_expr (e->e1);
  478. tree t2 = build_expr (e->e2);
  479. if (e->op == TOKmin)
  480. t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
  481. if (e->e1->type->isreal ())
  482. this->result_ = complex_expr (build_ctype (e->type), t1, t2);
  483. else
  484. this->result_ = complex_expr (build_ctype (e->type), t2, t1);
  485. return;
  486. }
  487. else
  488. code = (e->op == TOKadd)
  489. ? PLUS_EXPR : MINUS_EXPR;
  490. break;
  491. case TOKmul:
  492. code = MULT_EXPR;
  493. break;
  494. case TOKdiv:
  495. code = e->e1->type->isintegral ()
  496. ? TRUNC_DIV_EXPR : RDIV_EXPR;
  497. break;
  498. case TOKmod:
  499. code = e->e1->type->isfloating ()
  500. ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
  501. break;
  502. case TOKand:
  503. code = BIT_AND_EXPR;
  504. break;
  505. case TOKor:
  506. code = BIT_IOR_EXPR;
  507. break;
  508. case TOKxor:
  509. code = BIT_XOR_EXPR;
  510. break;
  511. case TOKshl:
  512. code = LSHIFT_EXPR;
  513. break;
  514. case TOKshr:
  515. code = RSHIFT_EXPR;
  516. break;
  517. case TOKushr:
  518. code = UNSIGNED_RSHIFT_EXPR;
  519. break;
  520. default:
  521. gcc_unreachable ();
  522. }
  523. this->result_ = this->binary_op (code, build_ctype (e->type),
  524. build_expr (e->e1), build_expr (e->e2));
  525. }
  526. /* Build a concat expression, which concatenates two or more arrays of the
  527. same type, producing a dynamic array with the result. If one operand
  528. is an element type, that element is converted to an array of length 1. */
  529. void visit (CatExp *e)
  530. {
  531. Type *tb1 = e->e1->type->toBasetype ();
  532. Type *tb2 = e->e2->type->toBasetype ();
  533. Type *etype;
  534. if (tb1->ty == Tarray || tb1->ty == Tsarray)
  535. etype = tb1->nextOf ();
  536. else
  537. etype = tb2->nextOf ();
  538. vec<tree, va_gc> *elemvars = NULL;
  539. tree result;
  540. if (e->e1->op == TOKcat)
  541. {
  542. /* Flatten multiple concatenations to an array.
  543. So the expression ((a ~ b) ~ c) becomes [a, b, c] */
  544. int ndims = 2;
  545. for (Expression *ex = e->e1; ex->op == TOKcat;)
  546. {
  547. if (ex->op == TOKcat)
  548. {
  549. ex = ((CatExp *) ex)->e1;
  550. ndims++;
  551. }
  552. }
  553. /* Store all concatenation args to a temporary byte[][ndims] array. */
  554. Type *targselem = Type::tint8->arrayOf ();
  555. tree var = create_temporary_var (make_array_type (targselem, ndims));
  556. tree init = build_constructor (TREE_TYPE (var), NULL);
  557. vec_safe_push (elemvars, var);
  558. /* Loop through each concatenation from right to left. */
  559. vec<constructor_elt, va_gc> *elms = NULL;
  560. CatExp *ce = e;
  561. int dim = ndims - 1;
  562. for (Expression *oe = ce->e2; oe != NULL;
  563. (ce->e1->op != TOKcat
  564. ? (oe = ce->e1)
  565. : (ce = (CatExp *)ce->e1, oe = ce->e2)))
  566. {
  567. tree arg = d_array_convert (etype, oe, &elemvars);
  568. tree index = size_int (dim);
  569. CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
  570. /* Finished pushing all arrays. */
  571. if (oe == ce->e1)
  572. break;
  573. dim -= 1;
  574. }
  575. /* Check there is no logic bug in constructing byte[][] of arrays. */
  576. gcc_assert (dim == 0);
  577. CONSTRUCTOR_ELTS (init) = elms;
  578. DECL_INITIAL (var) = init;
  579. tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
  580. size_int (ndims), build_address (var));
  581. result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
  582. build_typeinfo (e->loc, e->type), arrs);
  583. }
  584. else
  585. {
  586. /* Handle single concatenation (a ~ b). */
  587. result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
  588. build_typeinfo (e->loc, e->type),
  589. d_array_convert (etype, e->e1, &elemvars),
  590. d_array_convert (etype, e->e2, &elemvars));
  591. }
  592. for (size_t i = 0; i < vec_safe_length (elemvars); ++i)
  593. result = bind_expr ((*elemvars)[i], result);
  594. this->result_ = result;
  595. }
  596. /* Build an assignment operator expression. The right operand is implicitly
  597. converted to the type of the left operand, and assigned to it. */
  598. void visit (BinAssignExp *e)
  599. {
  600. tree_code code;
  601. Expression *e1b = e->e1;
  602. switch (e->op)
  603. {
  604. case TOKaddass:
  605. code = PLUS_EXPR;
  606. break;
  607. case TOKminass:
  608. code = MINUS_EXPR;
  609. break;
  610. case TOKmulass:
  611. code = MULT_EXPR;
  612. break;
  613. case TOKdivass:
  614. code = e->e1->type->isintegral ()
  615. ? TRUNC_DIV_EXPR : RDIV_EXPR;
  616. break;
  617. case TOKmodass:
  618. code = e->e1->type->isfloating ()
  619. ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
  620. break;
  621. case TOKandass:
  622. code = BIT_AND_EXPR;
  623. break;
  624. case TOKorass:
  625. code = BIT_IOR_EXPR;
  626. break;
  627. case TOKxorass:
  628. code = BIT_XOR_EXPR;
  629. break;
  630. case TOKpowass:
  631. gcc_unreachable ();
  632. case TOKshlass:
  633. code = LSHIFT_EXPR;
  634. break;
  635. case TOKshrass:
  636. case TOKushrass:
  637. /* Use the original lhs type before it was promoted. The left operand
  638. of `>>>=' does not undergo integral promotions before shifting.
  639. Strip off casts just incase anyway. */
  640. while (e1b->op == TOKcast)
  641. {
  642. CastExp *ce = (CastExp *) e1b;
  643. gcc_assert (same_type_p (ce->type, ce->to));
  644. e1b = ce->e1;
  645. }
  646. code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
  647. break;
  648. default:
  649. gcc_unreachable ();
  650. }
  651. tree exp = this->binop_assignment (code, e1b, e->e2);
  652. this->result_ = convert_expr (exp, e1b->type, e->type);
  653. }
  654. /* Build a concat assignment expression. The right operand is appended
  655. to the the left operand. */
  656. void visit (CatAssignExp *e)
  657. {
  658. Type *tb1 = e->e1->type->toBasetype ();
  659. Type *tb2 = e->e2->type->toBasetype ();
  660. Type *etype = tb1->nextOf ()->toBasetype ();
  661. if (tb1->ty == Tarray && tb2->ty == Tdchar
  662. && (etype->ty == Tchar || etype->ty == Twchar))
  663. {
  664. /* Append a dchar to a char[] or wchar[] */
  665. libcall_fn libcall = (etype->ty == Tchar)
  666. ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
  667. this->result_ = build_libcall (libcall, e->type, 2,
  668. build_address (build_expr (e->e1)),
  669. build_expr (e->e2));
  670. }
  671. else
  672. {
  673. gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
  674. tree tinfo = build_typeinfo (e->loc, e->type);
  675. tree ptr = build_address (build_expr (e->e1));
  676. if ((tb2->ty == Tarray || tb2->ty == Tsarray)
  677. && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
  678. {
  679. /* Append an array. */
  680. this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
  681. tinfo, ptr, d_array_convert (e->e2));
  682. }
  683. else if (same_type_p (etype, tb2))
  684. {
  685. /* Append an element. */
  686. tree result = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
  687. tinfo, ptr, size_one_node);
  688. result = d_save_expr (result);
  689. /* Assign e2 to last element. */
  690. tree offexp = d_array_length (result);
  691. offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
  692. offexp, size_one_node);
  693. offexp = d_save_expr (offexp);
  694. tree ptrexp = d_array_ptr (result);
  695. ptrexp = void_okay_p (ptrexp);
  696. ptrexp = build_array_index (ptrexp, offexp);
  697. /* Evaluate expression before appending. */
  698. tree t2 = build_expr (e->e2);
  699. tree expr = stabilize_expr (&t2);
  700. t2 = d_save_expr (t2);
  701. result = modify_expr (build_deref (ptrexp), t2);
  702. result = compound_expr (t2, result);
  703. this->result_ = compound_expr (expr, result);
  704. }
  705. else
  706. gcc_unreachable ();
  707. }
  708. }
  709. /* Build an assignment expression. The right operand is implicitly
  710. converted to the type of the left operand, and assigned to it. */
  711. void visit (AssignExp *e)
  712. {
  713. /* First, handle special assignment semantics. */
  714. /* Look for array.length = n; */
  715. if (e->e1->op == TOKarraylength)
  716. {
  717. /* Assignment to an array's length property; resize the array. */
  718. ArrayLengthExp *ale = (ArrayLengthExp *) e->e1;
  719. tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
  720. Type::tsize_t);
  721. tree ptr = build_address (build_expr (ale->e1));
  722. /* Don't want the basetype for the element type. */
  723. Type *etype = ale->e1->type->toBasetype ()->nextOf ();
  724. libcall_fn libcall = etype->isZeroInit ()
  725. ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
  726. tree result = build_libcall (libcall, ale->e1->type, 3,
  727. build_typeinfo (ale->loc, ale->e1->type),
  728. newlength, ptr);
  729. this->result_ = d_array_length (result);
  730. return;
  731. }
  732. /* Look for array[] = n; */
  733. if (e->e1->op == TOKslice)
  734. {
  735. SliceExp *se = (SliceExp *) e->e1;
  736. Type *stype = se->e1->type->toBasetype ();
  737. Type *etype = stype->nextOf ()->toBasetype ();
  738. /* Determine if we need to run postblit or dtor. */
  739. bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
  740. bool destructor = this->needs_dtor (etype);
  741. if (e->memset & blockAssign)
  742. {
  743. /* Set a range of elements to one value. */
  744. tree t1 = d_save_expr (build_expr (e->e1));
  745. tree t2 = build_expr (e->e2);
  746. tree result;
  747. if ((postblit || destructor) && e->op != TOKblit)
  748. {
  749. libcall_fn libcall = (e->op == TOKconstruct)
  750. ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
  751. /* So we can call postblits on const/immutable objects. */
  752. Type *tm = etype->unSharedOf ()->mutableOf ();
  753. tree ti = build_typeinfo (e->loc, tm);
  754. tree result = build_libcall (libcall, Type::tvoid, 4,
  755. d_array_ptr (t1),
  756. build_address (t2),
  757. d_array_length (t1), ti);
  758. this->result_ = compound_expr (result, t1);
  759. return;
  760. }
  761. if (integer_zerop (t2))
  762. {
  763. tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
  764. tree size = size_mult_expr (d_array_length (t1),
  765. size_int (etype->size ()));
  766. result = build_call_expr (tmemset, 3, d_array_ptr (t1),
  767. integer_zero_node, size);
  768. }
  769. else
  770. result = build_array_set (d_array_ptr (t1),
  771. d_array_length (t1), t2);
  772. this->result_ = compound_expr (result, t1);
  773. }
  774. else
  775. {
  776. /* Perform a memcpy operation. */
  777. gcc_assert (e->e2->type->ty != Tpointer);
  778. if (!postblit && !destructor && !array_bounds_check ())
  779. {
  780. tree t1 = d_save_expr (d_array_convert (e->e1));
  781. tree t2 = d_array_convert (e->e2);
  782. tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
  783. tree size = size_mult_expr (d_array_length (t1),
  784. size_int (etype->size ()));
  785. tree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),
  786. d_array_ptr (t2), size);
  787. this->result_ = compound_expr (result, t1);
  788. }
  789. else if ((postblit || destructor) && e->op != TOKblit)
  790. {
  791. /* Generate: _d_arrayassign(ti, from, to)
  792. or: _d_arrayctor(ti, from, to) */
  793. libcall_fn libcall = (e->op == TOKconstruct)
  794. ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
  795. this->result_ = build_libcall (libcall, e->type, 3,
  796. build_typeinfo (e->loc, etype),
  797. d_array_convert (e->e2),
  798. d_array_convert (e->e1));
  799. }
  800. else
  801. {
  802. /* Generate: _d_arraycopy() */
  803. this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
  804. size_int (etype->size ()),
  805. d_array_convert (e->e2),
  806. d_array_convert (e->e1));
  807. }
  808. }
  809. return;
  810. }
  811. /* Look for reference initializations. */
  812. if (e->memset & referenceInit)
  813. {
  814. gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
  815. gcc_assert (e->e1->op == TOKvar);
  816. Declaration *decl = ((VarExp *) e->e1)->var;
  817. if (decl->storage_class & (STCout | STCref))
  818. {
  819. tree t2 = convert_for_assignment (build_expr (e->e2),
  820. e->e2->type, e->e1->type);
  821. tree t1 = build_expr (e->e1);
  822. /* Want reference to lhs, not indirect ref. */
  823. t1 = TREE_OPERAND (t1, 0);
  824. t2 = build_address (t2);
  825. this->result_ = indirect_ref (build_ctype (e->type),
  826. build_assign (INIT_EXPR, t1, t2));
  827. return;
  828. }
  829. }
  830. /* Other types of assignments that may require post construction. */
  831. Type *tb1 = e->e1->type->toBasetype ();
  832. tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
  833. /* Look for struct assignment. */
  834. if (tb1->ty == Tstruct)
  835. {
  836. tree t1 = build_expr (e->e1);
  837. tree t2 = convert_for_assignment (build_expr (e->e2),
  838. e->e2->type, e->e1->type);
  839. /* Look for struct = 0. */
  840. if (e->e2->op == TOKint64)
  841. {
  842. /* Use memset to fill struct. */
  843. gcc_assert (e->op == TOKblit);
  844. StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
  845. tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
  846. tree result = build_call_expr (tmemset, 3, build_address (t1),
  847. t2, size_int (sd->structsize));
  848. /* Maybe set-up hidden pointer to outer scope context. */
  849. if (sd->isNested ())
  850. {
  851. tree field = get_symbol_decl (sd->vthis);
  852. tree value = build_vthis (sd);
  853. tree vthis_exp = modify_expr (component_ref (t1, field), value);
  854. result = compound_expr (result, vthis_exp);
  855. }
  856. this->result_ = compound_expr (result, t1);
  857. }
  858. else
  859. this->result_ = build_assign (modifycode, t1, t2);
  860. return;
  861. }
  862. /* Look for static array assignment. */
  863. if (tb1->ty == Tsarray)
  864. {
  865. /* Look for array = 0. */
  866. if (e->e2->op == TOKint64)
  867. {
  868. /* Use memset to fill the array. */
  869. gcc_assert (e->op == TOKblit);
  870. tree t1 = build_expr (e->e1);
  871. tree t2 = convert_for_assignment (build_expr (e->e2),
  872. e->e2->type, e->e1->type);
  873. tree size = size_int (e->e1->type->size ());
  874. tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
  875. this->result_ = build_call_expr (tmemset, 3, build_address (t1),
  876. t2, size);
  877. return;
  878. }
  879. Type *etype = tb1->nextOf ();
  880. gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
  881. /* Determine if we need to run postblit. */
  882. bool postblit = this->needs_postblit (etype);
  883. bool destructor = this->needs_dtor (etype);
  884. bool lvalue_p = this->lvalue_p (e->e2);
  885. /* Even if the elements in rhs are all rvalues and don't have
  886. to call postblits, this assignment should call dtors on old
  887. assigned elements. */
  888. if ((!postblit && !destructor)
  889. || (e->op == TOKconstruct && !lvalue_p && postblit)
  890. || (e->op == TOKblit || e->e1->type->size () == 0))
  891. {
  892. tree t1 = build_expr (e->e1);
  893. tree t2 = convert_for_assignment (build_expr (e->e2),
  894. e->e2->type, e->e1->type);
  895. this->result_ = build_assign (modifycode, t1, t2);
  896. return;
  897. }
  898. Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
  899. tree result;
  900. if (e->op == TOKconstruct)
  901. {
  902. /* Generate: _d_arrayctor(ti, from, to) */
  903. result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
  904. build_typeinfo (e->loc, etype),
  905. d_array_convert (e->e2),
  906. d_array_convert (e->e1));
  907. }
  908. else
  909. {
  910. /* Generate: _d_arrayassign_l()
  911. or: _d_arrayassign_r() */
  912. libcall_fn libcall = (lvalue_p)
  913. ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
  914. tree elembuf = build_local_temp (build_ctype (etype));
  915. result = build_libcall (libcall, arrtype, 4,
  916. build_typeinfo (e->loc, etype),
  917. d_array_convert (e->e2),
  918. d_array_convert (e->e1),
  919. build_address (elembuf));
  920. }
  921. /* Cast the libcall result back to a static array. */
  922. if (e->type->ty == Tsarray)
  923. result = indirect_ref (build_ctype (e->type),
  924. d_array_ptr (result));
  925. this->result_ = result;
  926. return;
  927. }
  928. /* Simple assignment. */
  929. tree t1 = build_expr (e->e1);
  930. tree t2 = convert_for_assignment (build_expr (e->e2),
  931. e->e2->type, e->e1->type);
  932. this->result_ = build_assign (modifycode, t1, t2);
  933. }
  934. /* Build a postfix expression. */
  935. void visit (PostExp *e)
  936. {
  937. tree result;
  938. if (e->op == TOKplusplus)
  939. {
  940. result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
  941. build_expr (e->e1), build_expr (e->e2));
  942. }
  943. else if (e->op == TOKminusminus)
  944. {
  945. result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
  946. build_expr (e->e1), build_expr (e->e2));
  947. }
  948. else
  949. gcc_unreachable ();
  950. TREE_SIDE_EFFECTS (result) = 1;
  951. this->result_ = result;
  952. }
  953. /* Build an index expression. */
  954. void visit (IndexExp *e)
  955. {
  956. Type *tb1 = e->e1->type->toBasetype ();
  957. if (tb1->ty == Taarray)
  958. {
  959. /* Get the key for the associative array. */
  960. Type *tkey = ((TypeAArray *) tb1)->index->toBasetype ();
  961. tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
  962. libcall_fn libcall;
  963. tree tinfo, ptr;
  964. if (e->modifiable)
  965. {
  966. libcall = LIBCALL_AAGETY;
  967. ptr = build_address (build_expr (e->e1));
  968. tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
  969. }
  970. else
  971. {
  972. libcall = LIBCALL_AAGETRVALUEX;
  973. ptr = build_expr (e->e1);
  974. tinfo = build_typeinfo (e->loc, tkey);
  975. }
  976. /* Index the associative array. */
  977. tree result = build_libcall (libcall, e->type->pointerTo (), 4,
  978. ptr, tinfo,
  979. size_int (tb1->nextOf ()->size ()),
  980. build_address (key));
  981. if (!e->indexIsInBounds && array_bounds_check ())
  982. {
  983. tree tassert = (global.params.checkAction == CHECKACTION_C)
  984. ? build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0)
  985. : d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS);
  986. result = d_save_expr (result);
  987. result = build_condition (TREE_TYPE (result),
  988. d_truthvalue_conversion (result),
  989. result, tassert);
  990. }
  991. this->result_ = indirect_ref (build_ctype (e->type), result);
  992. }
  993. else
  994. {
  995. /* Get the data pointer and length for static and dynamic arrays. */
  996. tree array = d_save_expr (build_expr (e->e1));
  997. tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
  998. tree length = NULL_TREE;
  999. if (tb1->ty != Tpointer)
  1000. length = get_array_length (array, tb1);
  1001. else
  1002. gcc_assert (e->lengthVar == NULL);
  1003. /* The __dollar variable just becomes a placeholder for the
  1004. actual length. */
  1005. if (e->lengthVar)
  1006. e->lengthVar->csym = length;
  1007. /* Generate the index. */
  1008. tree index = build_expr (e->e2);
  1009. /* If it's a static array and the index is constant, the front end has
  1010. already checked the bounds. */
  1011. if (tb1->ty != Tpointer && !e->indexIsInBounds)
  1012. index = build_bounds_condition (e->e2->loc, index, length, false);
  1013. /* Index the .ptr. */
  1014. ptr = void_okay_p (ptr);
  1015. this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
  1016. build_array_index (ptr, index));
  1017. }
  1018. }
  1019. /* Build a comma expression. The type is the type of the right operand. */
  1020. void visit (CommaExp *e)
  1021. {
  1022. tree t1 = build_expr (e->e1);
  1023. tree t2 = build_expr (e->e2);
  1024. tree type = e->type ? build_ctype (e->type) : void_type_node;
  1025. this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
  1026. }
  1027. /* Build an array length expression. Returns the number of elements
  1028. in the array. The result is of type size_t. */
  1029. void visit (ArrayLengthExp *e)
  1030. {
  1031. if (e->e1->type->toBasetype ()->ty == Tarray)
  1032. this->result_ = d_array_length (build_expr (e->e1));
  1033. else
  1034. {
  1035. /* Static arrays have already been handled by the front-end. */
  1036. error ("unexpected type for array length: %qs", e->type->toChars ());
  1037. this->result_ = error_mark_node;
  1038. }
  1039. }
  1040. /* Build a delegate pointer expression. This will return the frame
  1041. pointer value as a type void*. */
  1042. void visit (DelegatePtrExp *e)
  1043. {
  1044. tree t1 = build_expr (e->e1);
  1045. this->result_ = delegate_object (t1);
  1046. }
  1047. /* Build a delegate function pointer expression. This will return the
  1048. function pointer value as a function type. */
  1049. void visit (DelegateFuncptrExp *e)
  1050. {
  1051. tree t1 = build_expr (e->e1);
  1052. this->result_ = delegate_method (t1);
  1053. }
  1054. /* Build a slice expression. */
  1055. void visit (SliceExp *e)
  1056. {
  1057. Type *tb = e->type->toBasetype ();
  1058. Type *tb1 = e->e1->type->toBasetype ();
  1059. gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
  1060. /* Use convert-to-dynamic-array code if possible. */
  1061. if (!e->lwr)
  1062. {
  1063. tree result = build_expr (e->e1);
  1064. if (e->e1->type->toBasetype ()->ty == Tsarray)
  1065. result = convert_expr (result, e->e1->type, e->type);
  1066. this->result_ = result;
  1067. return;
  1068. }
  1069. else
  1070. gcc_assert (e->upr != NULL);
  1071. /* Get the data pointer and length for static and dynamic arrays. */
  1072. tree array = d_save_expr (build_expr (e->e1));
  1073. tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
  1074. tree length = NULL_TREE;
  1075. /* Our array is already a SAVE_EXPR if necessary, so we don't make length
  1076. a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
  1077. if (tb1->ty != Tpointer)
  1078. length = get_array_length (array, tb1);
  1079. else
  1080. gcc_assert (e->lengthVar == NULL);
  1081. /* The __dollar variable just becomes a placeholder for the
  1082. actual length. */
  1083. if (e->lengthVar)
  1084. e->lengthVar->csym = length;
  1085. /* Generate upper and lower bounds. */
  1086. tree lwr_tree = d_save_expr (build_expr (e->lwr));
  1087. tree upr_tree = d_save_expr (build_expr (e->upr));
  1088. /* If the upper bound has any side effects, then the lower bound should be
  1089. copied to a temporary always. */
  1090. if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
  1091. lwr_tree = save_expr (lwr_tree);
  1092. /* Adjust the .ptr offset. */
  1093. if (!integer_zerop (lwr_tree))
  1094. {
  1095. tree ptrtype = TREE_TYPE (ptr);
  1096. ptr = build_array_index (void_okay_p (ptr), lwr_tree);
  1097. ptr = build_nop (ptrtype, ptr);
  1098. }
  1099. else
  1100. lwr_tree = NULL_TREE;
  1101. /* Nothing more to do for static arrays, their bounds checking has been
  1102. done at compile-time. */
  1103. if (tb->ty == Tsarray)
  1104. {
  1105. this->result_ = indirect_ref (build_ctype (e->type), ptr);
  1106. return;
  1107. }
  1108. else
  1109. gcc_assert (tb->ty == Tarray);
  1110. /* Generate bounds checking code. */
  1111. tree newlength;
  1112. if (!e->upperIsInBounds)
  1113. {
  1114. if (length)
  1115. {
  1116. newlength = build_bounds_condition (e->upr->loc, upr_tree,
  1117. length, true);
  1118. }
  1119. else
  1120. {
  1121. /* Still need to check bounds lwr <= upr for pointers. */
  1122. gcc_assert (tb1->ty == Tpointer);
  1123. newlength = upr_tree;
  1124. }
  1125. }
  1126. else
  1127. newlength = upr_tree;
  1128. if (lwr_tree)
  1129. {
  1130. /* Enforces lwr <= upr. No need to check lwr <= length as
  1131. we've already ensured that upr <= length. */
  1132. if (!e->lowerIsLessThanUpper)
  1133. {
  1134. tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
  1135. upr_tree, true);
  1136. /* When bounds checking is off, the index value is
  1137. returned directly. */
  1138. if (cond != lwr_tree)
  1139. newlength = compound_expr (cond, newlength);
  1140. }
  1141. /* Need to ensure lwr always gets evaluated first, as it may be a
  1142. function call. Generates (lwr, upr) - lwr. */
  1143. newlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),
  1144. compound_expr (lwr_tree, newlength), lwr_tree);
  1145. }
  1146. tree result = d_array_value (build_ctype (e->type), newlength, ptr);
  1147. this->result_ = compound_expr (array, result);
  1148. }
  1149. /* Build a cast expression, which converts the given unary expression to the
  1150. type of result. */
  1151. void visit (CastExp *e)
  1152. {
  1153. Type *ebtype = e->e1->type->toBasetype ();
  1154. Type *tbtype = e->to->toBasetype ();
  1155. tree result = build_expr (e->e1, this->constp_);
  1156. /* Just evaluate e1 if it has any side effects. */
  1157. if (tbtype->ty == Tvoid)
  1158. this->result_ = build_nop (build_ctype (tbtype), result);
  1159. else
  1160. this->result_ = convert_expr (result, ebtype, tbtype);
  1161. }
  1162. /* Build a delete expression. */
  1163. void visit (DeleteExp *e)
  1164. {
  1165. tree t1 = build_expr (e->e1);
  1166. Type *tb1 = e->e1->type->toBasetype ();
  1167. if (tb1->ty == Tclass)
  1168. {
  1169. /* For class object references, if there is a destructor for that class,
  1170. the destructor is called for the object instance. */
  1171. libcall_fn libcall;
  1172. if (e->e1->op == TOKvar)
  1173. {
  1174. VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();
  1175. if (v && v->onstack)
  1176. {
  1177. libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
  1178. ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
  1179. this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
  1180. return;
  1181. }
  1182. }
  1183. /* Otherwise, the garbage collector is called to immediately free the
  1184. memory allocated for the class instance. */
  1185. libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
  1186. ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
  1187. t1 = build_address (t1);
  1188. this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
  1189. }
  1190. else if (tb1->ty == Tarray)
  1191. {
  1192. /* For dynamic arrays, the garbage collector is called to immediately
  1193. release the memory. */
  1194. Type *telem = tb1->nextOf ()->baseElemOf ();
  1195. tree ti = null_pointer_node;
  1196. if (telem->ty == Tstruct)
  1197. {
  1198. /* Might need to run destructor on array contents. */
  1199. TypeStruct *ts = (TypeStruct *) telem;
  1200. if (ts->sym->dtor)
  1201. ti = build_typeinfo (e->loc, tb1->nextOf ());
  1202. }
  1203. /* Generate: _delarray_t (&t1, ti); */
  1204. this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
  1205. build_address (t1), ti);
  1206. }
  1207. else if (tb1->ty == Tpointer)
  1208. {
  1209. /* For pointers to a struct instance, if the struct has overloaded
  1210. operator delete, then that operator is called. */
  1211. t1 = build_address (t1);
  1212. Type *tnext = ((TypePointer *)tb1)->next->toBasetype ();
  1213. if (tnext->ty == Tstruct)
  1214. {
  1215. TypeStruct *ts = (TypeStruct *)tnext;
  1216. if (ts->sym->dtor)
  1217. {
  1218. tree ti = build_typeinfo (e->loc, tnext);
  1219. this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
  1220. 2, t1, ti);
  1221. return;
  1222. }
  1223. }
  1224. /* Otherwise, the garbage collector is called to immediately free the
  1225. memory allocated for the pointer. */
  1226. this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
  1227. }
  1228. else
  1229. {
  1230. error ("don't know how to delete %qs", e->e1->toChars ());
  1231. this->result_ = error_mark_node;
  1232. }
  1233. }
  1234. /* Build a remove expression, which removes a particular key from an
  1235. associative array. */
  1236. void visit (RemoveExp *e)
  1237. {
  1238. /* Check that the array is actually an associative array. */
  1239. if (e->e1->type->toBasetype ()->ty == Taarray)
  1240. {
  1241. Type *tb = e->e1->type->toBasetype ();
  1242. Type *tkey = ((TypeAArray *) tb)->index->toBasetype ();
  1243. tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
  1244. this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
  1245. build_expr (e->e1),
  1246. build_typeinfo (e->loc, tkey),
  1247. build_address (index));
  1248. }
  1249. else
  1250. {
  1251. error ("%qs is not an associative array", e->e1->toChars ());
  1252. this->result_ = error_mark_node;
  1253. }
  1254. }
  1255. /* Build an unary not expression. */
  1256. void visit (NotExp *e)
  1257. {
  1258. tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
  1259. /* Need to convert to boolean type or this will fail. */
  1260. result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
  1261. this->result_ = d_convert (build_ctype (e->type), result);
  1262. }
  1263. /* Build a compliment expression, where all the bits in the value are
  1264. complemented. Note: unlike in C, the usual integral promotions
  1265. are not performed prior to the complement operation. */
  1266. void visit (ComExp *e)
  1267. {
  1268. TY ty1 = e->e1->type->toBasetype ()->ty;
  1269. gcc_assert (ty1 != Tarray && ty1 != Tsarray);
  1270. this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
  1271. build_expr (e->e1));
  1272. }
  1273. /* Build an unary negation expression. */
  1274. void visit (NegExp *e)
  1275. {
  1276. TY ty1 = e->e1->type->toBasetype ()->ty;
  1277. gcc_assert (ty1 != Tarray && ty1 != Tsarray);
  1278. tree type = build_ctype (e->type);
  1279. tree expr = build_expr (e->e1);
  1280. /* If the operation needs excess precision. */
  1281. tree eptype = excess_precision_type (type);
  1282. if (eptype != NULL_TREE)
  1283. expr = d_convert (eptype, expr);
  1284. else
  1285. eptype = type;
  1286. tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
  1287. this->result_ = d_convert (type, ret);
  1288. }
  1289. /* Build a pointer index expression. */
  1290. void visit (PtrExp *e)
  1291. {
  1292. Type *tnext = NULL;
  1293. size_t offset;
  1294. tree result;
  1295. if (e->e1->op == TOKadd)
  1296. {
  1297. BinExp *be = (BinExp *) e->e1;
  1298. if (be->e1->op == TOKaddress
  1299. && be->e2->isConst () && be->e2->type->isintegral ())
  1300. {
  1301. Expression *ae = ((AddrExp *) be->e1)->e1;
  1302. tnext = ae->type->toBasetype ();
  1303. result = build_expr (ae);
  1304. offset = be->e2->toUInteger ();
  1305. }
  1306. }
  1307. else if (e->e1->op == TOKsymoff)
  1308. {
  1309. SymOffExp *se = (SymOffExp *) e->e1;
  1310. if (!declaration_reference_p (se->var))
  1311. {
  1312. tnext = se->var->type->toBasetype ();
  1313. result = get_decl_tree (se->var);
  1314. offset = se->offset;
  1315. }
  1316. }
  1317. /* Produce better code by converting *(#record + n) to
  1318. COMPONENT_REFERENCE. Otherwise, the variable will always be
  1319. allocated in memory because its address is taken. */
  1320. if (tnext && tnext->ty == Tstruct)
  1321. {
  1322. StructDeclaration *sd = ((TypeStruct *) tnext)->sym;
  1323. for (size_t i = 0; i < sd->fields.dim; i++)
  1324. {
  1325. VarDeclaration *field = sd->fields[i];
  1326. if (field->offset == offset
  1327. && same_type_p (field->type, e->type))
  1328. {
  1329. /* Catch errors, backend will ICE otherwise. */
  1330. if (error_operand_p (result))
  1331. this->result_ = result;
  1332. else
  1333. {
  1334. result = component_ref (result, get_symbol_decl (field));
  1335. this->result_ = result;
  1336. }
  1337. return;
  1338. }
  1339. else if (field->offset > offset)
  1340. break;
  1341. }
  1342. }
  1343. this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
  1344. }
  1345. /* Build an unary address expression. */
  1346. void visit (AddrExp *e)
  1347. {
  1348. tree type = build_ctype (e->type);
  1349. tree exp;
  1350. /* The frontend optimizer can convert const symbol into a struct literal.
  1351. Taking the address of a struct literal is otherwise illegal. */
  1352. if (e->e1->op == TOKstructliteral)
  1353. {
  1354. StructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;
  1355. gcc_assert (sle != NULL);
  1356. /* Build the reference symbol, the decl is built first as the
  1357. initializer may have recursive references. */
  1358. if (!sle->sym)
  1359. {
  1360. sle->sym = build_artificial_decl (build_ctype (sle->type),
  1361. NULL_TREE, "S");
  1362. DECL_INITIAL (sle->sym) = build_expr (sle, true);
  1363. d_pushdecl (sle->sym);
  1364. rest_of_decl_compilation (sle->sym, 1, 0);
  1365. }
  1366. exp = sle->sym;
  1367. }
  1368. else
  1369. exp = build_expr (e->e1, this->constp_);
  1370. TREE_CONSTANT (exp) = 0;
  1371. this->result_ = d_convert (type, build_address (exp));
  1372. }
  1373. /* Build a function call expression. */
  1374. void visit (CallExp *e)
  1375. {
  1376. Type *tb = e->e1->type->toBasetype ();
  1377. Expression *e1b = e->e1;
  1378. tree callee = NULL_TREE;
  1379. tree object = NULL_TREE;
  1380. tree cleanup = NULL_TREE;
  1381. TypeFunction *tf = NULL;
  1382. /* Calls to delegates can sometimes look like this. */
  1383. if (e1b->op == TOKcomma)
  1384. {
  1385. e1b = ((CommaExp *) e1b)->e2;
  1386. gcc_assert (e1b->op == TOKvar);
  1387. Declaration *var = ((VarExp *) e1b)->var;
  1388. gcc_assert (var->isFuncDeclaration () && !var->needThis ());
  1389. }
  1390. if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
  1391. {
  1392. DotVarExp *dve = (DotVarExp *) e1b;
  1393. /* Don't modify the static initializer for struct literals. */
  1394. if (dve->e1->op == TOKstructliteral)
  1395. {
  1396. StructLiteralExp *sle = (StructLiteralExp *) dve->e1;
  1397. sle->useStaticInit = false;
  1398. }
  1399. FuncDeclaration *fd = dve->var->isFuncDeclaration ();
  1400. if (fd != NULL)
  1401. {
  1402. /* Get the correct callee from the DotVarExp object. */
  1403. tree fndecl = get_symbol_decl (fd);
  1404. AggregateDeclaration *ad = fd->isThis ();
  1405. /* Static method; ignore the object instance. */
  1406. if (!ad)
  1407. callee = build_address (fndecl);
  1408. else
  1409. {
  1410. tree thisexp = build_expr (dve->e1);
  1411. /* When constructing temporaries, if the constructor throws,
  1412. then the object is destructed even though it is not a fully
  1413. constructed object yet. And so this call will need to be
  1414. moved inside the TARGET_EXPR_INITIAL slot. */
  1415. if (fd->isCtorDeclaration ()
  1416. && TREE_CODE (thisexp) == COMPOUND_EXPR
  1417. && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
  1418. && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
  1419. {
  1420. cleanup = TREE_OPERAND (thisexp, 0);
  1421. thisexp = TREE_OPERAND (thisexp, 1);
  1422. }
  1423. /* Want reference to 'this' object. */
  1424. if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
  1425. thisexp = build_address (thisexp);
  1426. /* Make the callee a virtual call. */
  1427. if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
  1428. {
  1429. tree fntype = build_pointer_type (TREE_TYPE (fndecl));
  1430. tree thistype = build_ctype (ad->handleType ());
  1431. thisexp = build_nop (thistype, d_save_expr (thisexp));
  1432. fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
  1433. }
  1434. else
  1435. fndecl = build_address (fndecl);
  1436. callee = build_method_call (fndecl, thisexp, fd->type);
  1437. }
  1438. }
  1439. }
  1440. if (callee == NULL_TREE)

Large files files are truncated, but you can click here to view the full file