1 /* expr.cc -- Lower D frontend expressions to GCC trees. 2 Copyright (C) 2015-2022 Free Software Foundation, Inc. 3 4 GCC is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 GCC is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with GCC; see the file COPYING3. If not see 16 <http://www.gnu.org/licenses/>. */ 17 18 #include "config.h" 19 #include "system.h" 20 #include "coretypes.h" 21 22 #include "dmd/aggregate.h" 23 #include "dmd/ctfe.h" 24 #include "dmd/declaration.h" 25 #include "dmd/enum.h" 26 #include "dmd/expression.h" 27 #include "dmd/identifier.h" 28 #include "dmd/init.h" 29 #include "dmd/module.h" 30 #include "dmd/mtype.h" 31 #include "dmd/template.h" 32 33 #include "tree.h" 34 #include "fold-const.h" 35 #include "diagnostic.h" 36 #include "langhooks.h" 37 #include "tm.h" 38 #include "function.h" 39 #include "toplev.h" 40 #include "varasm.h" 41 #include "predict.h" 42 #include "stor-layout.h" 43 44 #include "d-tree.h" 45 46 47 /* Determine if type T is a struct that has a postblit. */ 48 49 static bool 50 needs_postblit (Type *t) 51 { 52 t = t->baseElemOf (); 53 54 if (TypeStruct *ts = t->isTypeStruct ()) 55 { 56 if (ts->sym->postblit) 57 return true; 58 } 59 60 return false; 61 } 62 63 /* Determine if type T is a struct that has a destructor. */ 64 65 static bool 66 needs_dtor (Type *t) 67 { 68 t = t->baseElemOf (); 69 70 if (TypeStruct *ts = t->isTypeStruct ()) 71 { 72 if (ts->sym->dtor) 73 return true; 74 } 75 76 return false; 77 } 78 79 /* Determine if expression E is a suitable lvalue. */ 80 81 static bool 82 lvalue_p (Expression *e) 83 { 84 SliceExp *se = e->isSliceExp (); 85 if (se != NULL && se->e1->isLvalue ()) 86 return true; 87 88 CastExp *ce = e->isCastExp (); 89 if (ce != NULL && ce->e1->isLvalue ()) 90 return true; 91 92 return (e->op != EXP::slice && e->isLvalue ()); 93 } 94 95 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and 96 ARG1. Perform relevant conversions needed for correct code operations. */ 97 98 static tree 99 binary_op (tree_code code, tree type, tree arg0, tree arg1) 100 { 101 tree t0 = TREE_TYPE (arg0); 102 tree t1 = TREE_TYPE (arg1); 103 tree ret = NULL_TREE; 104 105 /* Deal with float mod expressions immediately. */ 106 if (code == FLOAT_MOD_EXPR) 107 return build_float_modulus (type, arg0, arg1); 108 109 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1)) 110 return build_nop (type, build_offset_op (code, arg0, arg1)); 111 112 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1)) 113 return build_nop (type, build_offset_op (code, arg1, arg0)); 114 115 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1)) 116 { 117 gcc_assert (code == MINUS_EXPR); 118 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0); 119 120 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as 121 pointers. If some platform cannot provide that, or has a larger 122 ptrdiff_type to support differences larger than half the address 123 space, cast the pointers to some larger integer type and do the 124 computations in that type. */ 125 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0)) 126 ret = fold_build2 (MINUS_EXPR, ptrtype, 127 d_convert (ptrtype, arg0), 128 d_convert (ptrtype, arg1)); 129 else 130 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1); 131 } 132 else 133 { 134 /* If the operation needs excess precision. */ 135 tree eptype = excess_precision_type (type); 136 if (eptype != NULL_TREE) 137 { 138 arg0 = d_convert (eptype, arg0); 139 arg1 = d_convert (eptype, arg1); 140 } 141 else 142 { 143 /* Front-end does not do this conversion and GCC does not 144 always do it right. */ 145 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1)) 146 arg1 = d_convert (t0, arg1); 147 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0)) 148 arg0 = d_convert (t1, arg0); 149 150 eptype = type; 151 } 152 153 ret = build2 (code, eptype, arg0, arg1); 154 } 155 156 return d_convert (type, ret); 157 } 158 159 /* Build a binary expression of code CODE, assigning the result into E1. */ 160 161 static tree 162 binop_assignment (tree_code code, Expression *e1, Expression *e2) 163 { 164 /* Skip casts for lhs assignment. */ 165 Expression *e1b = e1; 166 while (e1b->op == EXP::cast_) 167 { 168 CastExp *ce = e1b->isCastExp (); 169 gcc_assert (same_type_p (ce->type, ce->to)); 170 e1b = ce->e1; 171 } 172 173 /* Stabilize LHS for assignment. */ 174 tree lhs = build_expr (e1b); 175 tree lexpr = stabilize_expr (&lhs); 176 177 /* The LHS expression could be an assignment, to which its operation gets 178 lost during gimplification. */ 179 if (TREE_CODE (lhs) == MODIFY_EXPR) 180 { 181 /* If LHS has side effects, call stabilize_reference on it, so it can 182 be evaluated multiple times. */ 183 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) 184 lhs = build_assign (MODIFY_EXPR, 185 stabilize_reference (TREE_OPERAND (lhs, 0)), 186 TREE_OPERAND (lhs, 1)); 187 188 lexpr = compound_expr (lexpr, lhs); 189 lhs = TREE_OPERAND (lhs, 0); 190 } 191 192 lhs = stabilize_reference (lhs); 193 194 /* Save RHS, to ensure that the expression is evaluated before LHS. */ 195 tree rhs = build_expr (e2); 196 tree rexpr = d_save_expr (rhs); 197 198 rhs = binary_op (code, build_ctype (e1->type), 199 convert_expr (lhs, e1b->type, e1->type), rexpr); 200 if (TREE_SIDE_EFFECTS (rhs)) 201 rhs = compound_expr (rexpr, rhs); 202 203 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type)); 204 return compound_expr (lexpr, expr); 205 } 206 207 /* Implements the visitor interface to build the GCC trees of all Expression 208 AST classes emitted from the D Front-end. 209 All visit methods accept one parameter E, which holds the frontend AST 210 of the expression to compile. They also don't return any value, instead 211 generated code is cached in RESULT_ and returned from the caller. */ 212 213 class ExprVisitor : public Visitor 214 { 215 using Visitor::visit; 216 217 tree result_; 218 bool constp_; 219 bool literalp_; 220 221 public: 222 ExprVisitor (bool constp, bool literalp) 223 { 224 this->result_ = NULL_TREE; 225 this->constp_ = constp; 226 this->literalp_ = literalp; 227 } 228 229 tree result (void) 230 { 231 return this->result_; 232 } 233 234 /* Visitor interfaces, each Expression class should have 235 overridden the default. */ 236 237 void visit (Expression *) 238 { 239 gcc_unreachable (); 240 } 241 242 /* Build a conditional expression. If either the second or third 243 expression is void, then the resulting type is void. Otherwise 244 they are implicitly converted to a common type. */ 245 246 void visit (CondExp *e) 247 { 248 tree cond = convert_for_condition (build_expr (e->econd), 249 e->econd->type); 250 tree t1 = build_expr (e->e1); 251 tree t2 = build_expr (e->e2); 252 253 if (e->type->ty != TY::Tvoid) 254 { 255 t1 = convert_expr (t1, e->e1->type, e->type); 256 t2 = convert_expr (t2, e->e2->type, e->type); 257 } 258 259 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2); 260 } 261 262 /* Build an identity comparison expression. Operands go through the 263 usual conversions to bring them to a common type before comparison. 264 The result type is bool. */ 265 266 void visit (IdentityExp *e) 267 { 268 tree_code code = (e->op == EXP::identity) ? EQ_EXPR : NE_EXPR; 269 Type *tb1 = e->e1->type->toBasetype (); 270 Type *tb2 = e->e2->type->toBasetype (); 271 272 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) 273 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) 274 { 275 /* For static and dynamic arrays, identity is defined as referring to 276 the same array elements and the same number of elements. */ 277 tree t1 = d_array_convert (e->e1); 278 tree t2 = d_array_convert (e->e2); 279 this->result_ = d_convert (build_ctype (e->type), 280 build_boolop (code, t1, t2)); 281 } 282 else if (tb1->isfloating () && tb1->ty != TY::Tvector) 283 { 284 /* For floating-point values, identity is defined as the bits in the 285 operands being identical. */ 286 tree t1 = d_save_expr (build_expr (e->e1)); 287 tree t2 = d_save_expr (build_expr (e->e2)); 288 289 if (!tb1->iscomplex ()) 290 this->result_ = build_float_identity (code, t1, t2); 291 else 292 { 293 /* Compare the real and imaginary parts separately. */ 294 tree req = build_float_identity (code, real_part (t1), 295 real_part (t2)); 296 tree ieq = build_float_identity (code, imaginary_part (t1), 297 imaginary_part (t2)); 298 299 if (code == EQ_EXPR) 300 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq); 301 else 302 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq); 303 } 304 } 305 else if (TypeStruct *ts = tb1->isTypeStruct ()) 306 { 307 /* For struct objects, identity is defined as bits in operands being 308 identical also. Alignment holes in structs are ignored. */ 309 tree t1 = build_expr (e->e1); 310 tree t2 = build_expr (e->e2); 311 312 gcc_assert (same_type_p (tb1, tb2)); 313 314 this->result_ = build_struct_comparison (code, ts->sym, t1, t2); 315 } 316 else 317 { 318 /* For operands of other types, identity is defined as being the 319 same as equality expressions. */ 320 tree t1 = build_expr (e->e1); 321 tree t2 = build_expr (e->e2); 322 this->result_ = d_convert (build_ctype (e->type), 323 build_boolop (code, t1, t2)); 324 } 325 } 326 327 /* Build an equality expression, which compare the two operands for either 328 equality or inequality. Operands go through the usual conversions to bring 329 them to a common type before comparison. The result type is bool. */ 330 331 void visit (EqualExp *e) 332 { 333 Type *tb1 = e->e1->type->toBasetype (); 334 Type *tb2 = e->e2->type->toBasetype (); 335 tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR; 336 337 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) 338 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) 339 { 340 /* For static and dynamic arrays, equality is defined as the lengths of 341 the arrays matching, and all the elements are equal. */ 342 Type *t1elem = tb1->nextOf ()->toBasetype (); 343 Type *t2elem = tb1->nextOf ()->toBasetype (); 344 345 /* Check if comparisons of arrays can be optimized using memcmp. 346 This will inline EQ expressions as: 347 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0; 348 Or when generating a NE expression: 349 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */ 350 if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid 351 || (t1elem->ty == TY::Tstruct 352 && !t1elem->isTypeStruct ()->sym->xeq)) 353 && t1elem->ty == t2elem->ty) 354 { 355 tree t1 = d_array_convert (e->e1); 356 tree t2 = d_array_convert (e->e2); 357 tree result; 358 359 /* Make temporaries to prevent multiple evaluations. */ 360 tree t1saved = d_save_expr (t1); 361 tree t2saved = d_save_expr (t2); 362 363 /* Length of arrays, for comparisons done before calling memcmp. */ 364 tree t1len = d_array_length (t1saved); 365 tree t2len = d_array_length (t2saved); 366 367 /* Reference to array data. */ 368 tree t1ptr = d_array_ptr (t1saved); 369 tree t2ptr = d_array_ptr (t2saved); 370 371 /* Compare arrays using memcmp if possible, otherwise for structs, 372 each field is compared inline. */ 373 if (t1elem->ty != TY::Tstruct 374 || identity_compare_p (t1elem->isTypeStruct ()->sym)) 375 { 376 tree size = size_mult_expr (t1len, size_int (t1elem->size ())); 377 378 result = build_memcmp_call (t1ptr, t2ptr, size); 379 result = build_boolop (code, result, integer_zero_node); 380 } 381 else 382 { 383 StructDeclaration *sd = t1elem->isTypeStruct ()->sym; 384 385 result = build_array_struct_comparison (code, sd, t1len, 386 t1ptr, t2ptr); 387 } 388 389 /* Check array length first before passing to memcmp. 390 For equality expressions, this becomes: 391 (e1.length == 0 || memcmp); 392 Otherwise for inequality: 393 (e1.length != 0 && memcmp); */ 394 tree tsizecmp = build_boolop (code, t1len, size_zero_node); 395 if (e->op == EXP::equal) 396 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result); 397 else 398 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result); 399 400 /* Finally, check if lengths of both arrays match if dynamic. 401 The frontend should have already guaranteed that static arrays 402 have same size. */ 403 if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray) 404 gcc_assert (tb1->size () == tb2->size ()); 405 else 406 { 407 tree tlencmp = build_boolop (code, t1len, t2len); 408 if (e->op == EXP::equal) 409 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result); 410 else 411 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result); 412 } 413 414 /* Ensure left-to-right order of evaluation. */ 415 if (TREE_SIDE_EFFECTS (t2)) 416 result = compound_expr (t2saved, result); 417 418 if (TREE_SIDE_EFFECTS (t1)) 419 result = compound_expr (t1saved, result); 420 421 this->result_ = result; 422 } 423 else 424 { 425 /* Use _adEq2() to compare each element. */ 426 Type *t1array = t1elem->arrayOf (); 427 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3, 428 d_array_convert (e->e1), 429 d_array_convert (e->e2), 430 build_typeinfo (e, t1array)); 431 432 if (e->op == EXP::notEqual) 433 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result); 434 435 this->result_ = result; 436 } 437 } 438 else if (TypeStruct *ts = tb1->isTypeStruct ()) 439 { 440 /* Equality for struct objects means the logical product of all 441 equality results of the corresponding object fields. */ 442 tree t1 = build_expr (e->e1); 443 tree t2 = build_expr (e->e2); 444 445 gcc_assert (same_type_p (tb1, tb2)); 446 447 this->result_ = build_struct_comparison (code, ts->sym, t1, t2); 448 } 449 else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray) 450 { 451 /* Use _aaEqual() for associative arrays. */ 452 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3, 453 build_typeinfo (e, tb1), 454 build_expr (e->e1), 455 build_expr (e->e2)); 456 457 if (e->op == EXP::notEqual) 458 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result); 459 460 this->result_ = result; 461 } 462 else 463 { 464 /* For operands of other types, equality is defined as the bit pattern 465 of the type matches exactly. */ 466 tree t1 = build_expr (e->e1); 467 tree t2 = build_expr (e->e2); 468 469 this->result_ = d_convert (build_ctype (e->type), 470 build_boolop (code, t1, t2)); 471 } 472 } 473 474 /* Build an `in' expression. This is a condition to see if an element 475 exists in an associative array. The result is a pointer to the 476 element, or null if false. */ 477 478 void visit (InExp *e) 479 { 480 Type *tb2 = e->e2->type->toBasetype (); 481 Type *tkey = tb2->isTypeAArray ()->index->toBasetype (); 482 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey); 483 484 /* Build a call to _aaInX(). */ 485 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3, 486 build_expr (e->e2), 487 build_typeinfo (e, tkey), 488 build_address (key)); 489 } 490 491 /* Build a relational expression. The result type is bool. */ 492 493 void visit (CmpExp *e) 494 { 495 Type *tb1 = e->e1->type->toBasetype (); 496 Type *tb2 = e->e2->type->toBasetype (); 497 498 tree result; 499 tree_code code; 500 501 switch (e->op) 502 { 503 case EXP::lessOrEqual: 504 code = LE_EXPR; 505 break; 506 507 case EXP::lessThan: 508 code = LT_EXPR; 509 break; 510 511 case EXP::greaterOrEqual: 512 code = GE_EXPR; 513 break; 514 515 case EXP::greaterThan: 516 code = GT_EXPR; 517 break; 518 519 default: 520 gcc_unreachable (); 521 } 522 523 /* For static and dynamic arrays, the relational op is turned into a 524 library call. It is not lowered during codegen. */ 525 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray) 526 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray)) 527 { 528 error ("cannot handle comparison of type %<%s == %s%>", 529 tb1->toChars (), tb2->toChars ()); 530 gcc_unreachable (); 531 } 532 533 /* Simple comparison. */ 534 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2)); 535 this->result_ = d_convert (build_ctype (e->type), result); 536 } 537 538 /* Build a logical `and if' or `or if' expression. If the right operand 539 expression is void, then the resulting type is void. Otherwise the 540 result is bool. */ 541 542 void visit (LogicalExp *e) 543 { 544 tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR; 545 546 if (e->e2->type->toBasetype ()->ty != TY::Tvoid) 547 { 548 tree t1 = build_expr (e->e1); 549 tree t2 = build_expr (e->e2); 550 551 t1 = convert_for_condition (t1, e->e1->type); 552 t2 = convert_for_condition (t2, e->e2->type); 553 554 this->result_ = d_convert (build_ctype (e->type), 555 build_boolop (code, t1, t2)); 556 } 557 else 558 { 559 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type); 560 tree t2 = build_expr_dtor (e->e2); 561 562 /* Invert condition for logical or if expression. */ 563 if (e->op == EXP::orOr) 564 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1); 565 566 this->result_ = build_condition (build_ctype (e->type), 567 t1, t2, void_node); 568 } 569 } 570 571 /* Build a binary operand expression. Operands go through usual arithmetic 572 conversions to bring them to a common type before evaluating. */ 573 574 void visit (BinExp *e) 575 { 576 tree_code code; 577 578 switch (e->op) 579 { 580 case EXP::add: 581 case EXP::min: 582 if ((e->e1->type->isreal () && e->e2->type->isimaginary ()) 583 || (e->e1->type->isimaginary () && e->e2->type->isreal ())) 584 { 585 /* If the result is complex, then we can shortcut binary_op. 586 Frontend should have already validated types and sizes. */ 587 tree t1 = build_expr (e->e1); 588 tree t2 = build_expr (e->e2); 589 590 if (e->op == EXP::min) 591 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2); 592 593 if (e->e1->type->isreal ()) 594 this->result_ = complex_expr (build_ctype (e->type), t1, t2); 595 else 596 this->result_ = complex_expr (build_ctype (e->type), t2, t1); 597 598 return; 599 } 600 else 601 code = (e->op == EXP::add) 602 ? PLUS_EXPR : MINUS_EXPR; 603 break; 604 605 case EXP::mul: 606 code = MULT_EXPR; 607 break; 608 609 case EXP::div: 610 /* Determine if the div expression is a lowered pointer diff operation. 611 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */ 612 if (MinExp *me = e->e1->isMinExp ()) 613 { 614 if (me->e1->type->ty == TY::Tpointer 615 && me->e2->type->ty == TY::Tpointer 616 && e->e2->op == EXP::int64) 617 { 618 code = EXACT_DIV_EXPR; 619 break; 620 } 621 } 622 623 code = e->e1->type->isintegral () 624 ? TRUNC_DIV_EXPR : RDIV_EXPR; 625 break; 626 627 case EXP::mod: 628 code = e->e1->type->isfloating () 629 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR; 630 break; 631 632 case EXP::and_: 633 code = BIT_AND_EXPR; 634 break; 635 636 case EXP::or_: 637 code = BIT_IOR_EXPR; 638 break; 639 640 case EXP::xor_: 641 code = BIT_XOR_EXPR; 642 break; 643 644 case EXP::leftShift: 645 code = LSHIFT_EXPR; 646 break; 647 648 case EXP::rightShift: 649 code = RSHIFT_EXPR; 650 break; 651 652 case EXP::unsignedRightShift: 653 code = UNSIGNED_RSHIFT_EXPR; 654 break; 655 656 default: 657 gcc_unreachable (); 658 } 659 660 this->result_ = binary_op (code, build_ctype (e->type), 661 build_expr (e->e1), build_expr (e->e2)); 662 } 663 664 665 /* Build a concat expression, which concatenates two or more arrays of the 666 same type, producing a dynamic array with the result. If one operand 667 is an element type, that element is converted to an array of length 1. */ 668 669 void visit (CatExp *e) 670 { 671 Type *tb1 = e->e1->type->toBasetype (); 672 Type *tb2 = e->e2->type->toBasetype (); 673 Type *etype; 674 675 if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray) 676 etype = tb1->nextOf (); 677 else 678 etype = tb2->nextOf (); 679 680 tree result; 681 682 if (e->e1->op == EXP::concatenate) 683 { 684 /* Flatten multiple concatenations to an array. 685 So the expression ((a ~ b) ~ c) becomes [a, b, c] */ 686 int ndims = 2; 687 688 for (Expression *ex = e->e1; ex->op == EXP::concatenate;) 689 { 690 if (ex->op == EXP::concatenate) 691 { 692 ex = ex->isCatExp ()->e1; 693 ndims++; 694 } 695 } 696 697 /* Store all concatenation args to a temporary byte[][ndims] array. */ 698 Type *targselem = Type::tint8->arrayOf (); 699 tree var = build_local_temp (make_array_type (targselem, ndims)); 700 701 /* Loop through each concatenation from right to left. */ 702 vec <constructor_elt, va_gc> *elms = NULL; 703 CatExp *ce = e; 704 int dim = ndims - 1; 705 706 for (Expression *oe = ce->e2; oe != NULL; 707 (ce->e1->op != EXP::concatenate 708 ? (oe = ce->e1) 709 : (ce = ce->e1->isCatExp (), oe = ce->e2))) 710 { 711 tree arg = d_array_convert (etype, oe); 712 tree index = size_int (dim); 713 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg)); 714 715 /* Finished pushing all arrays. */ 716 if (oe == ce->e1) 717 break; 718 719 dim -= 1; 720 } 721 722 /* Check there is no logic bug in constructing byte[][] of arrays. */ 723 gcc_assert (dim == 0); 724 tree init = build_constructor (TREE_TYPE (var), elms); 725 var = compound_expr (modify_expr (var, init), var); 726 727 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()), 728 size_int (ndims), build_address (var)); 729 730 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2, 731 build_typeinfo (e, e->type), arrs); 732 } 733 else 734 { 735 /* Handle single concatenation (a ~ b). */ 736 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3, 737 build_typeinfo (e, e->type), 738 d_array_convert (etype, e->e1), 739 d_array_convert (etype, e->e2)); 740 } 741 742 this->result_ = result; 743 } 744 745 /* Build an assignment operator expression. The right operand is implicitly 746 converted to the type of the left operand, and assigned to it. */ 747 748 void visit (BinAssignExp *e) 749 { 750 tree_code code; 751 Expression *e1b = e->e1; 752 753 switch (e->op) 754 { 755 case EXP::addAssign: 756 code = PLUS_EXPR; 757 break; 758 759 case EXP::minAssign: 760 code = MINUS_EXPR; 761 break; 762 763 case EXP::mulAssign: 764 code = MULT_EXPR; 765 break; 766 767 case EXP::divAssign: 768 code = e->e1->type->isintegral () 769 ? TRUNC_DIV_EXPR : RDIV_EXPR; 770 break; 771 772 case EXP::modAssign: 773 code = e->e1->type->isfloating () 774 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR; 775 break; 776 777 case EXP::andAssign: 778 code = BIT_AND_EXPR; 779 break; 780 781 case EXP::orAssign: 782 code = BIT_IOR_EXPR; 783 break; 784 785 case EXP::xorAssign: 786 code = BIT_XOR_EXPR; 787 break; 788 789 case EXP::powAssign: 790 gcc_unreachable (); 791 792 case EXP::leftShiftAssign: 793 code = LSHIFT_EXPR; 794 break; 795 796 case EXP::rightShiftAssign: 797 case EXP::unsignedRightShiftAssign: 798 /* Use the original lhs type before it was promoted. The left operand 799 of `>>>=' does not undergo integral promotions before shifting. 800 Strip off casts just incase anyway. */ 801 while (e1b->op == EXP::cast_) 802 { 803 CastExp *ce = e1b->isCastExp (); 804 gcc_assert (same_type_p (ce->type, ce->to)); 805 e1b = ce->e1; 806 } 807 code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR; 808 break; 809 810 default: 811 gcc_unreachable (); 812 } 813 814 tree exp = binop_assignment (code, e1b, e->e2); 815 this->result_ = convert_expr (exp, e1b->type, e->type); 816 } 817 818 /* Build a concat assignment expression. The right operand is appended 819 to the left operand. */ 820 821 void visit (CatAssignExp *e) 822 { 823 Type *tb1 = e->e1->type->toBasetype (); 824 Type *tb2 = e->e2->type->toBasetype (); 825 Type *etype = tb1->nextOf ()->toBasetype (); 826 827 /* Save the address of `e1', so it can be evaluated first. 828 As all D run-time library functions for concat assignments update `e1' 829 in-place and then return its value, the saved address can also be used as 830 the result of this expression as well. */ 831 tree lhs = build_expr (e->e1); 832 tree lexpr = stabilize_expr (&lhs); 833 tree ptr = d_save_expr (build_address (lhs)); 834 tree result = NULL_TREE; 835 836 if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar 837 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar)) 838 { 839 /* Append a dchar to a char[] or wchar[]: 840 The assignment is handled by the D run-time library, so only 841 need to call `_d_arrayappend[cw]d(&e1, e2)' */ 842 libcall_fn libcall = (etype->ty == TY::Tchar) 843 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD; 844 845 result = build_libcall (libcall, e->type, 2, 846 ptr, build_expr (e->e2)); 847 } 848 else 849 { 850 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray); 851 852 if ((tb2->ty == TY::Tarray || tb2->ty == TY::Tsarray) 853 && same_type_p (etype, tb2->nextOf ()->toBasetype ())) 854 { 855 /* Append an array to another array: 856 The assignment is handled by the D run-time library, so only 857 need to call `_d_arrayappendT(ti, &e1, e2)' */ 858 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3, 859 build_typeinfo (e->loc, e->type), 860 ptr, d_array_convert (e->e2)); 861 } 862 else if (same_type_p (etype, tb2)) 863 { 864 /* Append an element to an array: 865 The assignment is generated inline, so need to handle temporaries 866 here, and ensure that they are evaluated in the correct order. 867 868 The generated code should end up being equivalent to: 869 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2 870 */ 871 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3, 872 build_typeinfo (e->loc, e->type), 873 ptr, size_one_node); 874 callexp = d_save_expr (callexp); 875 876 /* Assign e2 to last element. */ 877 tree offexp = d_array_length (callexp); 878 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp), 879 offexp, size_one_node); 880 881 tree ptrexp = d_array_ptr (callexp); 882 ptrexp = void_okay_p (ptrexp); 883 ptrexp = build_array_index (ptrexp, offexp); 884 885 /* Evaluate expression before appending. */ 886 tree rhs = build_expr (e->e2); 887 tree rexpr = stabilize_expr (&rhs); 888 889 if (TREE_CODE (rhs) == CALL_EXPR) 890 rhs = force_target_expr (rhs); 891 892 result = modify_expr (build_deref (ptrexp), rhs); 893 result = compound_expr (rexpr, result); 894 } 895 else 896 gcc_unreachable (); 897 } 898 899 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */ 900 result = compound_expr (compound_expr (lexpr, ptr), result); 901 this->result_ = compound_expr (result, build_deref (ptr)); 902 } 903 904 /* Build an assignment expression. The right operand is implicitly 905 converted to the type of the left operand, and assigned to it. */ 906 907 void visit (AssignExp *e) 908 { 909 /* First, handle special assignment semantics. */ 910 911 /* Look for array.length = n; */ 912 if (e->e1->op == EXP::arrayLength) 913 { 914 /* This case should have been rewritten to `_d_arraysetlengthT` in the 915 semantic phase. */ 916 gcc_unreachable (); 917 } 918 919 /* Look for exp = noreturn; */ 920 if (e->e2->type->isTypeNoreturn ()) 921 { 922 /* If the RHS is a `noreturn' expression, there is no point generating 923 any code for the assignment, just evaluate side effects. */ 924 tree t1 = build_expr (e->e1); 925 tree t2 = build_expr (e->e2); 926 this->result_ = compound_expr (t1, t2); 927 return; 928 } 929 930 /* Look for array[] = n; */ 931 if (e->e1->op == EXP::slice) 932 { 933 SliceExp *se = e->e1->isSliceExp (); 934 Type *stype = se->e1->type->toBasetype (); 935 Type *etype = stype->nextOf ()->toBasetype (); 936 937 /* Determine if we need to run postblit or dtor. */ 938 bool postblit = needs_postblit (etype) && lvalue_p (e->e2); 939 bool destructor = needs_dtor (etype); 940 941 if (e->memset == MemorySet::blockAssign) 942 { 943 /* Set a range of elements to one value. */ 944 tree t1 = build_expr (e->e1); 945 tree t2 = build_expr (e->e2); 946 tree result; 947 948 /* Extract any array bounds checks from the slice expression. */ 949 tree init = stabilize_expr (&t1); 950 t1 = d_save_expr (t1); 951 952 if ((postblit || destructor) && e->op != EXP::blit) 953 { 954 /* Need to call postblit/destructor as part of assignment. 955 Construction has already been handled by the front-end. */ 956 gcc_assert (e->op != EXP::construct); 957 958 /* So we can call postblits on const/immutable objects. */ 959 Type *tm = etype->unSharedOf ()->mutableOf (); 960 tree ti = build_typeinfo (e, tm); 961 962 /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */ 963 result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4, 964 d_array_ptr (t1), 965 build_address (t2), 966 d_array_length (t1), ti); 967 } 968 else if (integer_zerop (t2)) 969 { 970 tree size = size_mult_expr (d_array_length (t1), 971 size_int (etype->size ())); 972 result = build_memset_call (d_array_ptr (t1), size); 973 } 974 else 975 result = build_array_set (d_array_ptr (t1), 976 d_array_length (t1), t2); 977 978 result = compound_expr (init, result); 979 this->result_ = compound_expr (result, t1); 980 } 981 else 982 { 983 /* Perform a memcpy operation. */ 984 gcc_assert (e->e2->type->ty != TY::Tpointer); 985 986 if (!postblit && !destructor) 987 { 988 tree t1 = d_save_expr (d_array_convert (e->e1)); 989 tree t2 = d_save_expr (d_array_convert (e->e2)); 990 991 /* References to array data. */ 992 tree t1ptr = d_array_ptr (t1); 993 tree t1len = d_array_length (t1); 994 tree t2ptr = d_array_ptr (t2); 995 996 /* Generate: memcpy(to, from, size) */ 997 tree size = size_mult_expr (t1len, size_int (etype->size ())); 998 tree result = build_memcpy_call (t1ptr, t2ptr, size); 999 1000 /* Insert check that array lengths match and do not overlap. */ 1001 if (array_bounds_check ()) 1002 { 1003 /* tlencmp = (t1len == t2len) */ 1004 tree t2len = d_array_length (t2); 1005 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len); 1006 1007 /* toverlap = (t1ptr + size <= t2ptr 1008 || t2ptr + size <= t1ptr) */ 1009 tree t1ptrcmp = build_boolop (LE_EXPR, 1010 build_offset (t1ptr, size), 1011 t2ptr); 1012 tree t2ptrcmp = build_boolop (LE_EXPR, 1013 build_offset (t2ptr, size), 1014 t1ptr); 1015 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp, 1016 t2ptrcmp); 1017 1018 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */ 1019 tree tassert = build_array_bounds_call (e->loc); 1020 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR, 1021 tlencmp, toverlap); 1022 1023 result = build_condition (void_type_node, tboundscheck, 1024 result, tassert); 1025 } 1026 1027 this->result_ = compound_expr (result, t1); 1028 } 1029 else if ((postblit || destructor) 1030 && e->op != EXP::blit && e->op != EXP::construct) 1031 { 1032 /* Generate: _d_arrayassign(ti, from, to); */ 1033 this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3, 1034 build_typeinfo (e, etype), 1035 d_array_convert (e->e2), 1036 d_array_convert (e->e1)); 1037 } 1038 else 1039 { 1040 /* Generate: _d_arraycopy() */ 1041 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3, 1042 size_int (etype->size ()), 1043 d_array_convert (e->e2), 1044 d_array_convert (e->e1)); 1045 } 1046 } 1047 1048 return; 1049 } 1050 1051 /* Look for reference initializations. */ 1052 if (e->memset == MemorySet::referenceInit) 1053 { 1054 gcc_assert (e->op == EXP::construct || e->op == EXP::blit); 1055 gcc_assert (e->e1->op == EXP::variable); 1056 1057 Declaration *decl = e->e1->isVarExp ()->var; 1058 if (decl->storage_class & (STCout | STCref)) 1059 { 1060 tree t2 = convert_for_assignment (e->e2, e->e1->type); 1061 tree t1 = build_expr (e->e1); 1062 /* Want reference to lhs, not indirect ref. */ 1063 t1 = TREE_OPERAND (t1, 0); 1064 t2 = build_address (t2); 1065 1066 this->result_ = indirect_ref (build_ctype (e->type), 1067 build_assign (INIT_EXPR, t1, t2)); 1068 return; 1069 } 1070 } 1071 1072 /* Other types of assignments that may require post construction. */ 1073 Type *tb1 = e->e1->type->toBasetype (); 1074 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR; 1075 1076 /* Look for struct assignment. */ 1077 if (tb1->ty == TY::Tstruct) 1078 { 1079 tree t1 = build_expr (e->e1); 1080 tree t2 = convert_for_assignment (e->e2, e->e1->type, true); 1081 StructDeclaration *sd = tb1->isTypeStruct ()->sym; 1082 1083 /* Look for struct = 0. */ 1084 if (e->e2->op == EXP::int64) 1085 { 1086 /* Use memset to fill struct. */ 1087 gcc_assert (e->op == EXP::blit); 1088 tree result = build_memset_call (t1); 1089 1090 /* Maybe set-up hidden pointer to outer scope context. */ 1091 if (sd->isNested ()) 1092 { 1093 tree field = get_symbol_decl (sd->vthis); 1094 tree value = build_vthis (sd); 1095 1096 tree vthis_exp = modify_expr (component_ref (t1, field), value); 1097 result = compound_expr (result, vthis_exp); 1098 } 1099 1100 this->result_ = compound_expr (result, t1); 1101 } 1102 else 1103 { 1104 /* Simple struct literal assignment. */ 1105 tree init = NULL_TREE; 1106 1107 /* Fill any alignment holes in the struct using memset. */ 1108 if ((e->op == EXP::construct 1109 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit)) 1110 && (sd->isUnionDeclaration () || !identity_compare_p (sd))) 1111 { 1112 t1 = stabilize_reference (t1); 1113 init = build_memset_call (t1); 1114 } 1115 1116 /* Elide generating assignment if init is all zeroes. */ 1117 if (init != NULL_TREE && initializer_zerop (t2)) 1118 this->result_ = compound_expr (init, t1); 1119 else 1120 { 1121 tree result = build_assign (modifycode, t1, t2); 1122 this->result_ = compound_expr (init, result); 1123 } 1124 } 1125 1126 return; 1127 } 1128 1129 /* Look for static array assignment. */ 1130 if (tb1->ty == TY::Tsarray) 1131 { 1132 /* Look for array = 0. */ 1133 if (e->e2->op == EXP::int64) 1134 { 1135 /* Use memset to fill the array. */ 1136 gcc_assert (e->op == EXP::blit); 1137 this->result_ = build_memset_call (build_expr (e->e1)); 1138 return; 1139 } 1140 1141 Type *etype = tb1->nextOf (); 1142 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray); 1143 1144 /* Determine if we need to run postblit. */ 1145 const bool postblit = needs_postblit (etype); 1146 const bool destructor = needs_dtor (etype); 1147 const bool lvalue = lvalue_p (e->e2); 1148 1149 /* Optimize static array assignment with array literal. Even if the 1150 elements in rhs are all rvalues and don't have to call postblits, 1151 this assignment should call dtors on old assigned elements. */ 1152 if ((!postblit && !destructor) 1153 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral) 1154 || (e->op == EXP::construct && !lvalue && postblit) 1155 || (e->op == EXP::blit || e->e1->type->size () == 0)) 1156 { 1157 tree t1 = build_expr (e->e1); 1158 tree t2 = convert_for_assignment (e->e2, e->e1->type); 1159 1160 this->result_ = build_assign (modifycode, t1, t2); 1161 return; 1162 } 1163 1164 /* All other kinds of lvalue or rvalue static array assignment. 1165 Array construction has already been handled by the front-end. */ 1166 gcc_assert (e->op != EXP::construct); 1167 1168 /* Generate: _d_arrayassign_l() 1169 or: _d_arrayassign_r() */ 1170 libcall_fn libcall = (lvalue) 1171 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R; 1172 tree elembuf = build_local_temp (build_ctype (etype)); 1173 Type *arrtype = (e->type->ty == TY::Tsarray) 1174 ? etype->arrayOf () : e->type; 1175 tree result = build_libcall (libcall, arrtype, 4, 1176 build_typeinfo (e, etype), 1177 d_array_convert (e->e2), 1178 d_array_convert (e->e1), 1179 build_address (elembuf)); 1180 1181 /* Cast the libcall result back to a static array. */ 1182 if (e->type->ty == TY::Tsarray) 1183 result = indirect_ref (build_ctype (e->type), 1184 d_array_ptr (result)); 1185 1186 this->result_ = result; 1187 return; 1188 } 1189 1190 /* Simple assignment. */ 1191 tree t1 = build_expr (e->e1); 1192 tree t2 = convert_for_assignment (e->e2, e->e1->type); 1193 1194 this->result_ = build_assign (modifycode, t1, t2); 1195 } 1196 1197 /* Build a throw expression. */ 1198 1199 void visit (ThrowExp *e) 1200 { 1201 tree arg = build_expr_dtor (e->e1); 1202 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg); 1203 } 1204 1205 /* Build a postfix expression. */ 1206 1207 void visit (PostExp *e) 1208 { 1209 tree result; 1210 1211 if (e->op == EXP::plusPlus) 1212 { 1213 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type), 1214 build_expr (e->e1), build_expr (e->e2)); 1215 } 1216 else if (e->op == EXP::minusMinus) 1217 { 1218 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type), 1219 build_expr (e->e1), build_expr (e->e2)); 1220 } 1221 else 1222 gcc_unreachable (); 1223 1224 TREE_SIDE_EFFECTS (result) = 1; 1225 this->result_ = result; 1226 } 1227 1228 /* Build an index expression. */ 1229 1230 void visit (IndexExp *e) 1231 { 1232 Type *tb1 = e->e1->type->toBasetype (); 1233 1234 if (tb1->ty == TY::Taarray) 1235 { 1236 /* Get the key for the associative array. */ 1237 Type *tkey = tb1->isTypeAArray ()->index->toBasetype (); 1238 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey); 1239 libcall_fn libcall; 1240 tree tinfo, ptr; 1241 1242 if (e->modifiable) 1243 { 1244 libcall = LIBCALL_AAGETY; 1245 ptr = build_address (build_expr (e->e1)); 1246 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ()); 1247 } 1248 else 1249 { 1250 libcall = LIBCALL_AAGETRVALUEX; 1251 ptr = build_expr (e->e1); 1252 tinfo = build_typeinfo (e, tkey); 1253 } 1254 1255 /* Index the associative array. */ 1256 tree result = build_libcall (libcall, e->type->pointerTo (), 4, 1257 ptr, tinfo, 1258 size_int (tb1->nextOf ()->size ()), 1259 build_address (key)); 1260 1261 if (!e->indexIsInBounds && array_bounds_check ()) 1262 { 1263 tree tassert = build_array_bounds_call (e->loc); 1264 1265 result = d_save_expr (result); 1266 result = build_condition (TREE_TYPE (result), 1267 d_truthvalue_conversion (result), 1268 result, tassert); 1269 } 1270 1271 this->result_ = indirect_ref (build_ctype (e->type), result); 1272 } 1273 else 1274 { 1275 /* Get the data pointer and length for static and dynamic arrays. */ 1276 tree array = d_save_expr (build_expr (e->e1)); 1277 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ()); 1278 1279 tree length = NULL_TREE; 1280 if (tb1->ty != TY::Tpointer) 1281 length = get_array_length (array, tb1); 1282 else 1283 gcc_assert (e->lengthVar == NULL); 1284 1285 /* The __dollar variable just becomes a placeholder for the 1286 actual length. */ 1287 if (e->lengthVar) 1288 e->lengthVar->csym = length; 1289 1290 /* Generate the index. */ 1291 tree index = build_expr (e->e2); 1292 1293 /* If it's a static array and the index is constant, the front end has 1294 already checked the bounds. */ 1295 if (tb1->ty != TY::Tpointer) 1296 index = build_bounds_index_condition (e, index, length); 1297 1298 /* Index the .ptr. */ 1299 ptr = void_okay_p (ptr); 1300 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)), 1301 build_array_index (ptr, index)); 1302 } 1303 } 1304 1305 /* Build a comma expression. The type is the type of the right operand. */ 1306 1307 void visit (CommaExp *e) 1308 { 1309 tree t1 = build_expr (e->e1); 1310 tree t2 = build_expr (e->e2); 1311 tree type = e->type ? build_ctype (e->type) : void_type_node; 1312 1313 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2); 1314 } 1315 1316 /* Build an array length expression. Returns the number of elements 1317 in the array. The result is of type size_t. */ 1318 1319 void visit (ArrayLengthExp *e) 1320 { 1321 if (e->e1->type->toBasetype ()->ty == TY::Tarray) 1322 this->result_ = d_array_length (build_expr (e->e1)); 1323 else 1324 { 1325 /* Static arrays have already been handled by the front-end. */ 1326 error ("unexpected type for array length: %qs", e->type->toChars ()); 1327 this->result_ = error_mark_node; 1328 } 1329 } 1330 1331 /* Build a delegate pointer expression. This will return the frame 1332 pointer value as a type void*. */ 1333 1334 void visit (DelegatePtrExp *e) 1335 { 1336 tree t1 = build_expr (e->e1); 1337 this->result_ = delegate_object (t1); 1338 } 1339 1340 /* Build a delegate function pointer expression. This will return the 1341 function pointer value as a function type. */ 1342 1343 void visit (DelegateFuncptrExp *e) 1344 { 1345 tree t1 = build_expr (e->e1); 1346 this->result_ = delegate_method (t1); 1347 } 1348 1349 /* Build a slice expression. */ 1350 1351 void visit (SliceExp *e) 1352 { 1353 Type *tb = e->type->toBasetype (); 1354 Type *tb1 = e->e1->type->toBasetype (); 1355 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray); 1356 1357 /* Use convert-to-dynamic-array code if possible. */ 1358 if (!e->lwr) 1359 { 1360 tree result = build_expr (e->e1); 1361 if (e->e1->type->toBasetype ()->ty == TY::Tsarray) 1362 result = convert_expr (result, e->e1->type, e->type); 1363 1364 this->result_ = result; 1365 return; 1366 } 1367 else 1368 gcc_assert (e->upr != NULL); 1369 1370 /* Get the data pointer and length for static and dynamic arrays. */ 1371 tree array = d_save_expr (build_expr (e->e1)); 1372 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ()); 1373 tree length = NULL_TREE; 1374 1375 /* Our array is already a SAVE_EXPR if necessary, so we don't make length 1376 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */ 1377 if (tb1->ty != TY::Tpointer) 1378 length = get_array_length (array, tb1); 1379 else 1380 gcc_assert (e->lengthVar == NULL); 1381 1382 /* The __dollar variable just becomes a placeholder for the 1383 actual length. */ 1384 if (e->lengthVar) 1385 e->lengthVar->csym = length; 1386 1387 /* Generate upper and lower bounds. */ 1388 tree lwr_tree = d_save_expr (build_expr (e->lwr)); 1389 tree upr_tree = d_save_expr (build_expr (e->upr)); 1390 1391 /* If the upper bound has any side effects, then the lower bound should be 1392 copied to a temporary always. */ 1393 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR) 1394 lwr_tree = save_expr (lwr_tree); 1395 1396 /* Adjust the .ptr offset. */ 1397 if (!integer_zerop (lwr_tree)) 1398 { 1399 tree ptrtype = TREE_TYPE (ptr); 1400 ptr = build_array_index (void_okay_p (ptr), lwr_tree); 1401 ptr = build_nop (ptrtype, ptr); 1402 } 1403 1404 /* Nothing more to do for static arrays, their bounds checking has been 1405 done at compile-time. */ 1406 if (tb->ty == TY::Tsarray) 1407 { 1408 this->result_ = indirect_ref (build_ctype (e->type), ptr); 1409 return; 1410 } 1411 else 1412 gcc_assert (tb->ty == TY::Tarray); 1413 1414 /* Generate bounds checking code. */ 1415 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree, 1416 length); 1417 tree result = d_array_value (build_ctype (e->type), newlength, ptr); 1418 this->result_ = compound_expr (array, result); 1419 } 1420 1421 /* Build a cast expression, which converts the given unary expression to the 1422 type of result. */ 1423 1424 void visit (CastExp *e) 1425 { 1426 Type *ebtype = e->e1->type->toBasetype (); 1427 Type *tbtype = e->to->toBasetype (); 1428 tree result = build_expr (e->e1, this->constp_, this->literalp_); 1429 1430 /* Just evaluate e1 if it has any side effects. */ 1431 if (tbtype->ty == TY::Tvoid) 1432 this->result_ = build_nop (build_ctype (tbtype), result); 1433 else 1434 this->result_ = convert_for_rvalue (result, ebtype, tbtype); 1435 } 1436 1437 /* Build a delete expression. */ 1438 1439 void visit (DeleteExp *e) 1440 { 1441 tree t1 = build_expr (e->e1); 1442 Type *tb1 = e->e1->type->toBasetype (); 1443 1444 if (tb1->ty == TY::Tclass) 1445 { 1446 /* For class object references, if there is a destructor for that class, 1447 the destructor is called for the object instance. */ 1448 gcc_assert (e->e1->op == EXP::variable); 1449 1450 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration (); 1451 gcc_assert (v && v->onstack ()); 1452 1453 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration () 1454 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER; 1455 1456 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1); 1457 return; 1458 } 1459 else 1460 { 1461 error ("don%'t know how to delete %qs", e->e1->toChars ()); 1462 this->result_ = error_mark_node; 1463 } 1464 } 1465 1466 /* Build a remove expression, which removes a particular key from an 1467 associative array. */ 1468 1469 void visit (RemoveExp *e) 1470 { 1471 /* Check that the array is actually an associative array. */ 1472 if (e->e1->type->toBasetype ()->ty == TY::Taarray) 1473 { 1474 Type *tb = e->e1->type->toBasetype (); 1475 Type *tkey = tb->isTypeAArray ()->index->toBasetype (); 1476 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey); 1477 1478 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3, 1479 build_expr (e->e1), 1480 build_typeinfo (e, tkey), 1481 build_address (index)); 1482 } 1483 else 1484 { 1485 error ("%qs is not an associative array", e->e1->toChars ()); 1486 this->result_ = error_mark_node; 1487 } 1488 } 1489 1490 /* Build an unary not expression. */ 1491 1492 void visit (NotExp *e) 1493 { 1494 tree result = convert_for_condition (build_expr (e->e1), e->e1->type); 1495 /* Need to convert to boolean type or this will fail. */ 1496 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result); 1497 1498 this->result_ = d_convert (build_ctype (e->type), result); 1499 } 1500 1501 /* Build a compliment expression, where all the bits in the value are 1502 complemented. Note: unlike in C, the usual integral promotions 1503 are not performed prior to the complement operation. */ 1504 1505 void visit (ComExp *e) 1506 { 1507 TY ty1 = e->e1->type->toBasetype ()->ty; 1508 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray); 1509 1510 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type), 1511 build_expr (e->e1)); 1512 } 1513 1514 /* Build an unary negation expression. */ 1515 1516 void visit (NegExp *e) 1517 { 1518 TY ty1 = e->e1->type->toBasetype ()->ty; 1519 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray); 1520 1521 tree type = build_ctype (e->type); 1522 tree expr = build_expr (e->e1); 1523 1524 /* If the operation needs excess precision. */ 1525 tree eptype = excess_precision_type (type); 1526 if (eptype != NULL_TREE) 1527 expr = d_convert (eptype, expr); 1528 else 1529 eptype = type; 1530 1531 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr); 1532 this->result_ = d_convert (type, ret); 1533 } 1534 1535 /* Build a pointer index expression. */ 1536 1537 void visit (PtrExp *e) 1538 { 1539 Type *tnext = NULL; 1540 dinteger_t offset; 1541 tree result; 1542 1543 if (e->e1->op == EXP::add) 1544 { 1545 AddExp *ae = e->e1->isAddExp (); 1546 if (ae->e1->op == EXP::address 1547 && ae->e2->isConst () && ae->e2->type->isintegral ()) 1548 { 1549 Expression *ex = ae->e1->isAddrExp ()->e1; 1550 tnext = ex->type->toBasetype (); 1551 result = build_expr (ex); 1552 offset = ae->e2->toUInteger (); 1553 } 1554 } 1555 else if (e->e1->op == EXP::symbolOffset) 1556 { 1557 SymOffExp *se = e->e1->isSymOffExp (); 1558 if (!declaration_reference_p (se->var)) 1559 { 1560 tnext = se->var->type->toBasetype (); 1561 result = get_decl_tree (se->var); 1562 offset = se->offset; 1563 } 1564 } 1565 1566 /* Produce better code by converting *(#record + n) to 1567 COMPONENT_REFERENCE. Otherwise, the variable will always be 1568 allocated in memory because its address is taken. */ 1569 if (tnext && tnext->ty == TY::Tstruct) 1570 { 1571 StructDeclaration *sd = tnext->isTypeStruct ()->sym; 1572 1573 for (size_t i = 0; i < sd->fields.length; i++) 1574 { 1575 VarDeclaration *field = sd->fields[i]; 1576 1577 if (field->offset == offset 1578 && same_type_p (field->type, e->type)) 1579 { 1580 /* Catch errors, backend will ICE otherwise. */ 1581 if (error_operand_p (result)) 1582 this->result_ = result; 1583 else 1584 { 1585 result = component_ref (result, get_symbol_decl (field)); 1586 this->result_ = result; 1587 } 1588 return; 1589 } 1590 else if (field->offset > offset) 1591 break; 1592 } 1593 } 1594 1595 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1)); 1596 } 1597 1598 /* Build an unary address expression. */ 1599 1600 void visit (AddrExp *e) 1601 { 1602 tree type = build_ctype (e->type); 1603 tree exp; 1604 1605 /* The frontend optimizer can convert const symbol into a struct literal. 1606 Taking the address of a struct literal is otherwise illegal. */ 1607 if (e->e1->op == EXP::structLiteral) 1608 { 1609 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin; 1610 gcc_assert (sle != NULL); 1611 1612 /* Build the reference symbol, the decl is built first as the 1613 initializer may have recursive references. */ 1614 if (!sle->sym) 1615 { 1616 sle->sym = build_artificial_decl (build_ctype (sle->type), 1617 NULL_TREE, "S"); 1618 DECL_INITIAL (sle->sym) = build_expr (sle, true); 1619 d_pushdecl (sle->sym); 1620 rest_of_decl_compilation (sle->sym, 1, 0); 1621 } 1622 1623 exp = sle->sym; 1624 } 1625 else 1626 exp = build_expr (e->e1, this->constp_, this->literalp_); 1627 1628 TREE_CONSTANT (exp) = 0; 1629 this->result_ = d_convert (type, build_address (exp)); 1630 } 1631 1632 /* Build a function call expression. */ 1633 1634 void visit (CallExp *e) 1635 { 1636 Type *tb = e->e1->type->toBasetype (); 1637 Expression *e1b = e->e1; 1638 1639 tree callee = NULL_TREE; 1640 tree object = NULL_TREE; 1641 tree cleanup = NULL_TREE; 1642 tree returnvalue = NULL_TREE; 1643 TypeFunction *tf = NULL; 1644 1645 /* Calls to delegates can sometimes look like this. */ 1646 if (e1b->op == EXP::comma) 1647 { 1648 e1b = e1b->isCommaExp ()->e2; 1649 gcc_assert (e1b->op == EXP::variable); 1650 1651 Declaration *var = e1b->isVarExp ()->var; 1652 gcc_assert (var->isFuncDeclaration () && !var->needThis ()); 1653 } 1654 1655 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate) 1656 { 1657 DotVarExp *dve = e1b->isDotVarExp (); 1658 1659 /* Don't modify the static initializer for struct literals. */ 1660 if (dve->e1->op == EXP::structLiteral) 1661 { 1662 StructLiteralExp *sle = dve->e1->isStructLiteralExp (); 1663 sle->useStaticInit = false; 1664 } 1665 1666 FuncDeclaration *fd = dve->var->isFuncDeclaration (); 1667 if (fd != NULL) 1668 { 1669 /* Get the correct callee from the DotVarExp object. */ 1670 tree fndecl = get_symbol_decl (fd); 1671 AggregateDeclaration *ad = fd->isThis (); 1672 1673 /* Static method; ignore the object instance. */ 1674 if (!ad) 1675 callee = build_address (fndecl); 1676 else 1677 { 1678 tree thisexp = build_expr (dve->e1); 1679 1680 /* When constructing temporaries, if the constructor throws, 1681 then the object is destructed even though it is not a fully 1682 constructed object yet. And so this call will need to be 1683 moved inside the TARGET_EXPR_INITIAL slot. */ 1684 if (fd->isCtorDeclaration () 1685 && TREE_CODE (thisexp) == COMPOUND_EXPR 1686 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR 1687 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0))) 1688 { 1689 cleanup = TREE_OPERAND (thisexp, 0); 1690 thisexp = TREE_OPERAND (thisexp, 1); 1691 } 1692 1693 if (TREE_CODE (thisexp) == CONSTRUCTOR) 1694 thisexp = force_target_expr (thisexp); 1695 1696 /* Want reference to `this' object. */ 1697 if (!POINTER_TYPE_P (TREE_TYPE (thisexp))) 1698 thisexp = build_address (thisexp); 1699 1700 /* Make the callee a virtual call. */ 1701 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall) 1702 { 1703 tree fntype = build_pointer_type (TREE_TYPE (fndecl)); 1704 tree thistype = build_ctype (ad->handleType ()); 1705 thisexp = build_nop (thistype, d_save_expr (thisexp)); 1706 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex); 1707 } 1708 else 1709 fndecl = build_address (fndecl); 1710 1711 /* C++ constructors return void, even though front-end semantic 1712 treats them as implicitly returning `this'. Set returnvalue 1713 to override the result of this expression. */ 1714 if (fd->isCtorDeclaration ()) 1715 { 1716 thisexp = d_save_expr (thisexp); 1717 returnvalue = thisexp; 1718 } 1719 1720 callee = build_method_call (fndecl, thisexp, fd->type); 1721 } 1722 } 1723 } 1724 1725 if (callee == NULL_TREE) 1726 callee = build_expr (e1b); 1727 1728 if (METHOD_CALL_EXPR (callee)) 1729 { 1730 /* This could be a delegate expression (TY == Tdelegate), but not 1731 actually a delegate variable. */ 1732 if (e1b->op == EXP::dotVariable) 1733 { 1734 /* This gets the true function type, getting the function type 1735 from e1->type can sometimes be incorrect, such as when calling 1736 a `ref' return function. */ 1737 tf = get_function_type (e1b->isDotVarExp ()->var->type); 1738 } 1739 else 1740 tf = get_function_type (tb); 1741 1742 extract_from_method_call (callee, callee, object); 1743 } 1744 else if (tb->ty == TY::Tdelegate) 1745 { 1746 /* Delegate call, extract .object and .funcptr from var. */ 1747 callee = d_save_expr (callee); 1748 tf = get_function_type (tb); 1749 object = delegate_object (callee); 1750 callee = delegate_method (callee); 1751 } 1752 else if (e1b->op == EXP::variable) 1753 { 1754 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration (); 1755 gcc_assert (fd != NULL); 1756 tf = get_function_type (fd->type); 1757 1758 if (fd->isNested ()) 1759 { 1760 /* Maybe re-evaluate symbol storage treating `fd' as public. */ 1761 if (call_by_alias_p (d_function_chain->function, fd)) 1762 TREE_PUBLIC (callee) = 1; 1763 1764 object = get_frame_for_symbol (fd); 1765 } 1766 else if (fd->needThis ()) 1767 { 1768 error_at (make_location_t (e1b->loc), 1769 "need %<this%> to access member %qs", fd->toChars ()); 1770 /* Continue compiling... */ 1771 object = null_pointer_node; 1772 } 1773 } 1774 else 1775 { 1776 /* Normal direct function call. */ 1777 tf = get_function_type (tb); 1778 } 1779 1780 gcc_assert (tf != NULL); 1781 1782 /* Now we have the type, callee and maybe object reference, 1783 build the call expression. */ 1784 tree exp = d_build_call (tf, callee, object, e->arguments); 1785 1786 if (returnvalue != NULL_TREE) 1787 exp = compound_expr (exp, returnvalue); 1788 1789 if (tf->isref ()) 1790 exp = build_deref (exp); 1791 1792 /* Some library calls are defined to return a generic type. 1793 this->type is the real type we want to return. */ 1794 if (e->type->isTypeBasic ()) 1795 exp = d_convert (build_ctype (e->type), exp); 1796 1797 /* If this call was found to be a constructor for a temporary with a 1798 cleanup, then move the call inside the TARGET_EXPR. */ 1799 if (cleanup != NULL_TREE) 1800 { 1801 tree init = TARGET_EXPR_INITIAL (cleanup); 1802 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp); 1803 1804 /* Keep the return value outside the TARGET_EXPR. */ 1805 if (returnvalue != NULL_TREE) 1806 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1)); 1807 1808 exp = cleanup; 1809 } 1810 1811 this->result_ = exp; 1812 } 1813 1814 /* Build a delegate expression. */ 1815 1816 void visit (DelegateExp *e) 1817 { 1818 if (e->func->semanticRun == PASS::semantic3done) 1819 { 1820 /* Add the function as nested function if it belongs to this module. 1821 ie: it is a member of this module, or it is a template instance. */ 1822 Dsymbol *owner = e->func->toParent (); 1823 while (!owner->isTemplateInstance () && owner->toParent ()) 1824 owner = owner->toParent (); 1825 if (owner->isTemplateInstance () || owner == d_function_chain->module) 1826 build_decl_tree (e->func); 1827 } 1828 1829 tree fndecl; 1830 tree object; 1831 1832 if (e->func->isNested () && !e->func->isThis ()) 1833 { 1834 if (e->e1->op == EXP::null_) 1835 object = build_expr (e->e1); 1836 else 1837 object = get_frame_for_symbol (e->func); 1838 1839 fndecl = build_address (get_symbol_decl (e->func)); 1840 } 1841 else 1842 { 1843 if (!e->func->isThis ()) 1844 { 1845 error ("delegates are only for non-static functions"); 1846 this->result_ = error_mark_node; 1847 return; 1848 } 1849 1850 object = build_expr (e->e1); 1851 1852 /* Want reference to `this' object. */ 1853 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer) 1854 object = build_address (object); 1855 1856 /* Object reference could be the outer `this' field of a class or 1857 closure of type `void*'. Cast it to the right type. */ 1858 if (e->e1->type->ty == TY::Tclass) 1859 object = d_convert (build_ctype (e->e1->type), object); 1860 1861 fndecl = get_symbol_decl (e->func); 1862 1863 /* Get pointer to function out of the virtual table. */ 1864 if (e->func->isVirtual () && !e->func->isFinalFunc () 1865 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType) 1866 { 1867 tree fntype = build_pointer_type (TREE_TYPE (fndecl)); 1868 object = d_save_expr (object); 1869 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex); 1870 } 1871 else 1872 fndecl = build_address (fndecl); 1873 } 1874 1875 this->result_ = build_method_call (fndecl, object, e->type); 1876 } 1877 1878 /* Build a type component expression. */ 1879 1880 void visit (DotTypeExp *e) 1881 { 1882 /* Just a pass through to underlying expression. */ 1883 this->result_ = build_expr (e->e1); 1884 } 1885 1886 /* Build a component reference expression. */ 1887 1888 void visit (DotVarExp *e) 1889 { 1890 VarDeclaration *vd = e->var->isVarDeclaration (); 1891 1892 /* This could also be a function, but relying on that being taken 1893 care of by the visitor interface for CallExp. */ 1894 if (vd != NULL) 1895 { 1896 if (!vd->isField ()) 1897 this->result_ = get_decl_tree (vd); 1898 else 1899 { 1900 tree object = build_expr (e->e1); 1901 Type *tb = e->e1->type->toBasetype (); 1902 1903 if (tb->ty != TY::Tstruct) 1904 object = build_deref (object); 1905 1906 /* __complex is represented as a struct in the front-end, but 1907 underlying is really a complex type. */ 1908 if (e->e1->type->ty == TY::Tenum 1909 && e->e1->type->isTypeEnum ()->sym->isSpecial ()) 1910 object = underlying_complex_expr (build_ctype (tb), object); 1911 1912 this->result_ = component_ref (object, get_symbol_decl (vd)); 1913 } 1914 } 1915 else 1916 { 1917 error ("%qs is not a field, but a %qs", 1918 e->var->toChars (), e->var->kind ()); 1919 this->result_ = error_mark_node; 1920 } 1921 } 1922 1923 /* Build an assert expression, used to declare conditions that must hold at 1924 that a given point in the program. */ 1925 1926 void visit (AssertExp *e) 1927 { 1928 Type *tb1 = e->e1->type->toBasetype (); 1929 tree arg = build_expr (e->e1); 1930 tree tmsg = NULL_TREE; 1931 tree assert_pass = void_node; 1932 tree assert_fail; 1933 1934 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ()) 1935 { 1936 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...)) 1937 or: (e1 != null ? e1._invariant() : _d_assert (...)) */ 1938 bool unittest_p = d_function_chain->function->isUnitTestDeclaration (); 1939 libcall_fn libcall; 1940 1941 if (e->msg) 1942 { 1943 tmsg = build_expr_dtor (e->msg); 1944 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG; 1945 } 1946 else 1947 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP; 1948 1949 /* Build a call to _d_assert(). */ 1950 assert_fail = build_assert_call (e->loc, libcall, tmsg); 1951 1952 if (global.params.useInvariants == CHECKENABLEon) 1953 { 1954 /* If the condition is a D class or struct object with an invariant, 1955 call it if the condition result is true. */ 1956 if (tb1->ty == TY::Tclass) 1957 { 1958 ClassDeclaration *cd = tb1->isClassHandle (); 1959 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ()) 1960 { 1961 arg = d_save_expr (arg); 1962 assert_pass = build_libcall (LIBCALL_INVARIANT, 1963 Type::tvoid, 1, arg); 1964 } 1965 } 1966 else if (tb1->ty == TY::Tpointer 1967 && tb1->nextOf ()->ty == TY::Tstruct) 1968 { 1969 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym; 1970 if (sd->inv != NULL) 1971 { 1972 Expressions args; 1973 arg = d_save_expr (arg); 1974 assert_pass = d_build_call_expr (sd->inv, arg, &args); 1975 } 1976 } 1977 } 1978 } 1979 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ()) 1980 { 1981 /* Generate: __builtin_trap() */ 1982 tree fn = builtin_decl_explicit (BUILT_IN_TRAP); 1983 assert_fail = build_call_expr (fn, 0); 1984 } 1985 else 1986 { 1987 /* Assert contracts are turned off. */ 1988 this->result_ = void_node; 1989 return; 1990 } 1991 1992 /* Build condition that we are asserting in this contract. */ 1993 tree condition = convert_for_condition (arg, e->e1->type); 1994 1995 /* We expect the condition to always be true, as what happens if an assert 1996 contract is false is undefined behavior. */ 1997 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT); 1998 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); 1999 tree pred_type = TREE_VALUE (arg_types); 2000 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types)); 2001 2002 condition = build_call_expr (fn, 2, d_convert (pred_type, condition), 2003 build_int_cst (expected_type, 1)); 2004 condition = d_truthvalue_conversion (condition); 2005 2006 this->result_ = build_vcondition (condition, assert_pass, assert_fail); 2007 } 2008 2009 /* Build a declaration expression. */ 2010 2011 void visit (DeclarationExp *e) 2012 { 2013 /* Compile the declaration. */ 2014 push_stmt_list (); 2015 build_decl_tree (e->declaration); 2016 tree result = pop_stmt_list (); 2017 2018 /* Construction of an array for typesafe-variadic function arguments 2019 can cause an empty STMT_LIST here. This can causes problems 2020 during gimplification. */ 2021 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result)) 2022 result = build_empty_stmt (input_location); 2023 2024 this->result_ = result; 2025 } 2026 2027 /* Build a typeid expression. Returns an instance of class TypeInfo 2028 corresponding to. */ 2029 2030 void visit (TypeidExp *e) 2031 { 2032 if (Type *tid = isType (e->obj)) 2033 { 2034 tree ti = build_typeinfo (e, tid); 2035 2036 /* If the typeinfo is at an offset. */ 2037 if (tid->vtinfo->offset) 2038 ti = build_offset (ti, size_int (tid->vtinfo->offset)); 2039 2040 this->result_ = build_nop (build_ctype (e->type), ti); 2041 } 2042 else if (Expression *tid = isExpression (e->obj)) 2043 { 2044 Type *type = tid->type->toBasetype (); 2045 assert (type->ty == TY::Tclass); 2046 2047 /* Generate **classptr to get the classinfo. */ 2048 tree ci = build_expr (tid); 2049 ci = indirect_ref (ptr_type_node, ci); 2050 ci = indirect_ref (ptr_type_node, ci); 2051 2052 /* Add extra indirection for interfaces. */ 2053 if (type->isTypeClass ()->sym->isInterfaceDeclaration ()) 2054 ci = indirect_ref (ptr_type_node, ci); 2055 2056 this->result_ = build_nop (build_ctype (e->type), ci); 2057 } 2058 else 2059 gcc_unreachable (); 2060 } 2061 2062 /* Build a function/lambda expression. */ 2063 2064 void visit (FuncExp *e) 2065 { 2066 Type *ftype = e->type->toBasetype (); 2067 2068 /* This check is for lambda's, remove `vthis' as function isn't nested. */ 2069 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer) 2070 { 2071 e->fd->tok = TOK::function_; 2072 e->fd->vthis = NULL; 2073 } 2074 2075 /* Compile the function literal body. */ 2076 build_decl_tree (e->fd); 2077 2078 /* If nested, this will be a trampoline. */ 2079 if (e->fd->isNested ()) 2080 { 2081 tree func = build_address (get_symbol_decl (e->fd)); 2082 tree object; 2083 2084 if (this->constp_) 2085 { 2086 /* Static delegate variables have no context pointer. */ 2087 object = null_pointer_node; 2088 this->result_ = build_method_call (func, object, e->fd->type); 2089 TREE_CONSTANT (this->result_) = 1; 2090 } 2091 else 2092 { 2093 object = get_frame_for_symbol (e->fd); 2094 this->result_ = build_method_call (func, object, e->fd->type); 2095 } 2096 } 2097 else 2098 { 2099 this->result_ = build_nop (build_ctype (e->type), 2100 build_address (get_symbol_decl (e->fd))); 2101 } 2102 } 2103 2104 /* Build a halt expression. */ 2105 2106 void visit (HaltExp *) 2107 { 2108 /* Should we use trap() or abort()? */ 2109 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP); 2110 this->result_ = build_call_expr (ttrap, 0); 2111 } 2112 2113 /* Build a symbol pointer offset expression. */ 2114 2115 void visit (SymOffExp *e) 2116 { 2117 /* Build the address and offset of the symbol. */ 2118 dinteger_t soffset = e->isSymOffExp ()->offset; 2119 tree result = get_decl_tree (e->var); 2120 TREE_USED (result) = 1; 2121 2122 if (declaration_reference_p (e->var)) 2123 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result))); 2124 else 2125 result = build_address (result); 2126 2127 if (!soffset) 2128 result = d_convert (build_ctype (e->type), result); 2129 else 2130 { 2131 tree offset = size_int (soffset); 2132 result = build_nop (build_ctype (e->type), 2133 build_offset (result, offset)); 2134 } 2135 2136 this->result_ = result; 2137 } 2138 2139 /* Build a variable expression. */ 2140 2141 void visit (VarExp *e) 2142 { 2143 if (e->var->needThis ()) 2144 { 2145 error ("need %<this%> to access member %qs", e->var->ident->toChars ()); 2146 this->result_ = error_mark_node; 2147 return; 2148 } 2149 else if (e->var->ident == Identifier::idPool ("__ctfe")) 2150 { 2151 /* __ctfe is always false at run-time. */ 2152 this->result_ = integer_zero_node; 2153 return; 2154 } 2155 2156 /* This check is same as is done in FuncExp for lambdas. */ 2157 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration (); 2158 if (fld != NULL) 2159 { 2160 if (fld->tok == TOK::reserved) 2161 { 2162 fld->tok = TOK::function_; 2163 fld->vthis = NULL; 2164 } 2165 2166 /* Compiler the function literal body. */ 2167 build_decl_tree (fld); 2168 } 2169 2170 if (this->constp_) 2171 { 2172 /* Want the initializer, not the expression. */ 2173 VarDeclaration *var = e->var->isVarDeclaration (); 2174 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration (); 2175 tree init = NULL_TREE; 2176 2177 if (var && (var->isConst () || var->isImmutable ()) 2178 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init) 2179 { 2180 if (var->inuse) 2181 error_at (make_location_t (e->loc), "recursive reference %qs", 2182 e->toChars ()); 2183 else 2184 { 2185 var->inuse++; 2186 init = build_expr (initializerToExpression (var->_init), true); 2187 var->inuse--; 2188 } 2189 } 2190 else if (sdecl && sdecl->dsym) 2191 { 2192 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ()) 2193 init = layout_struct_initializer (sd); 2194 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ()) 2195 init = layout_class_initializer (cd); 2196 else 2197 gcc_unreachable (); 2198 } 2199 else 2200 error_at (make_location_t (e->loc), "non-constant expression %qs", 2201 e->toChars ()); 2202 2203 if (init != NULL_TREE) 2204 this->result_ = init; 2205 else 2206 this->result_ = error_mark_node; 2207 } 2208 else 2209 { 2210 tree result = get_decl_tree (e->var); 2211 TREE_USED (result) = 1; 2212 2213 /* The variable expression generated for `__traits(initSymbol)'. */ 2214 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ()) 2215 { 2216 if (e->type->isTypeDArray ()) 2217 { 2218 /* Generate a slice for non-zero initialized aggregates, 2219 otherwise create an empty array. */ 2220 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ()); 2221 2222 tree type = build_ctype (e->type); 2223 tree length = size_int (sd->dsym->structsize); 2224 tree ptr = (sd->dsym->isStructDeclaration () 2225 && sd->dsym->type->isZeroInit (e->loc)) 2226 ? null_pointer_node : build_address (result); 2227 2228 this->result_ = d_array_value (type, length, ptr); 2229 return; 2230 } 2231 } 2232 2233 /* For variables that are references - currently only out/inout 2234 arguments; objects don't count - evaluating the variable means 2235 we want what it refers to. */ 2236 if (declaration_reference_p (e->var)) 2237 result = indirect_ref (build_ctype (e->var->type), result); 2238 2239 this->result_ = result; 2240 } 2241 } 2242 2243 /* Build a this variable expression. */ 2244 2245 void visit (ThisExp *e) 2246 { 2247 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL; 2248 tree result = NULL_TREE; 2249 2250 if (e->var) 2251 result = get_decl_tree (e->var); 2252 else 2253 { 2254 gcc_assert (fd && fd->vthis); 2255 result = get_decl_tree (fd->vthis); 2256 } 2257 2258 if (e->type->ty == TY::Tstruct) 2259 result = build_deref (result); 2260 2261 this->result_ = result; 2262 } 2263 2264 /* Build a new expression, which allocates memory either on the garbage 2265 collected heap or by using a class or struct specific allocator. */ 2266 2267 void visit (NewExp *e) 2268 { 2269 Type *tb = e->type->toBasetype (); 2270 tree result; 2271 2272 if (tb->ty == TY::Tclass) 2273 { 2274 /* Allocating a new class. */ 2275 tb = e->newtype->toBasetype (); 2276 2277 ClassDeclaration *cd = tb->isTypeClass ()->sym; 2278 tree type = build_ctype (tb); 2279 tree setup_exp = NULL_TREE; 2280 tree new_call; 2281 2282 if (e->onstack) 2283 { 2284 /* If being used as an initializer for a local variable with scope 2285 storage class, then the instance is allocated on the stack 2286 rather than the heap or using the class specific allocator. */ 2287 tree var = build_local_temp (TREE_TYPE (type)); 2288 new_call = build_nop (type, build_address (var)); 2289 setup_exp = modify_expr (var, aggregate_initializer_decl (cd)); 2290 } 2291 else 2292 { 2293 /* Generate: _d_newclass() */ 2294 tree arg = build_address (get_classinfo_decl (cd)); 2295 libcall_fn libcall = (global.params.ehnogc && e->thrownew) 2296 ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS; 2297 new_call = build_libcall (libcall, tb, 1, arg); 2298 } 2299 2300 /* Set the context pointer for nested classes. */ 2301 if (cd->isNested ()) 2302 { 2303 tree field = get_symbol_decl (cd->vthis); 2304 tree value = NULL_TREE; 2305 2306 if (e->thisexp) 2307 { 2308 ClassDeclaration *tcd = e->thisexp->type->isClassHandle (); 2309 /* The class or function we're nested in. */ 2310 Dsymbol *outer = cd->toParentLocal (); 2311 2312 value = build_expr (e->thisexp); 2313 2314 if (outer != tcd) 2315 { 2316 ClassDeclaration *ocd = outer->isClassDeclaration (); 2317 int offset = 0; 2318 gcc_assert (ocd->isBaseOf (tcd, &offset)); 2319 /* Could just add offset... */ 2320 value = convert_expr (value, e->thisexp->type, ocd->type); 2321 } 2322 } 2323 else 2324 value = build_vthis (cd); 2325 2326 if (value != NULL_TREE) 2327 { 2328 /* Generate: (new())->vthis = this; */ 2329 new_call = d_save_expr (new_call); 2330 field = component_ref (build_deref (new_call), field); 2331 setup_exp = compound_expr (setup_exp, 2332 modify_expr (field, value)); 2333 } 2334 } 2335 new_call = compound_expr (setup_exp, new_call); 2336 2337 /* Call the class constructor. */ 2338 if (e->member) 2339 result = d_build_call_expr (e->member, new_call, e->arguments); 2340 else 2341 result = new_call; 2342 2343 if (e->argprefix) 2344 result = compound_expr (build_expr (e->argprefix), result); 2345 } 2346 else if (tb->ty == TY::Tpointer 2347 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct) 2348 { 2349 /* Allocating memory for a new struct. */ 2350 Type *htype = e->newtype->toBasetype (); 2351 gcc_assert (!e->onstack); 2352 2353 TypeStruct *stype = htype->isTypeStruct (); 2354 StructDeclaration *sd = stype->sym; 2355 tree new_call; 2356 2357 /* Cannot new an opaque struct. */ 2358 if (sd->size (e->loc) == 0) 2359 { 2360 this->result_ = d_convert (build_ctype (e->type), 2361 integer_zero_node); 2362 return; 2363 } 2364 2365 /* Generate: _d_newitemT() */ 2366 libcall_fn libcall = htype->isZeroInit () 2367 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; 2368 tree arg = build_typeinfo (e, e->newtype); 2369 new_call = build_libcall (libcall, tb, 1, arg); 2370 2371 if (e->member || !e->arguments) 2372 { 2373 /* Set the context pointer for nested structs. */ 2374 if (sd->isNested ()) 2375 { 2376 tree value = build_vthis (sd); 2377 tree field = get_symbol_decl (sd->vthis); 2378 tree type = build_ctype (stype); 2379 2380 new_call = d_save_expr (new_call); 2381 field = component_ref (indirect_ref (type, new_call), field); 2382 new_call = compound_expr (modify_expr (field, value), new_call); 2383 } 2384 2385 /* Call the struct constructor. */ 2386 if (e->member) 2387 result = d_build_call_expr (e->member, new_call, e->arguments); 2388 else 2389 result = new_call; 2390 } 2391 else 2392 { 2393 /* If we have a user supplied initializer, then set-up with a 2394 struct literal. */ 2395 if (e->arguments != NULL && sd->fields.length != 0) 2396 { 2397 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd, 2398 e->arguments, 2399 htype); 2400 new_call = d_save_expr (new_call); 2401 se->type = sd->type; 2402 se->sym = new_call; 2403 result = compound_expr (build_expr (se), new_call); 2404 } 2405 else 2406 result = new_call; 2407 } 2408 2409 if (e->argprefix) 2410 result = compound_expr (build_expr (e->argprefix), result); 2411 } 2412 else if (tb->ty == TY::Tarray) 2413 { 2414 /* Allocating memory for a new D array. */ 2415 tb = e->newtype->toBasetype (); 2416 TypeDArray *tarray = tb->isTypeDArray (); 2417 2418 gcc_assert (e->arguments && e->arguments->length >= 1); 2419 2420 if (e->arguments->length == 1) 2421 { 2422 /* Single dimension array allocations. */ 2423 Expression *arg = (*e->arguments)[0]; 2424 2425 if (tarray->next->size () == 0) 2426 { 2427 /* Array element size is unknown. */ 2428 this->result_ = d_array_value (build_ctype (e->type), 2429 size_int (0), null_pointer_node); 2430 return; 2431 } 2432 2433 libcall_fn libcall = tarray->next->isZeroInit () 2434 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT; 2435 result = build_libcall (libcall, tb, 2, 2436 build_typeinfo (e, e->type), 2437 build_expr (arg)); 2438 } 2439 else 2440 { 2441 /* Multidimensional array allocations. */ 2442 tree tarray = make_array_type (Type::tsize_t, e->arguments->length); 2443 tree var = build_local_temp (tarray); 2444 vec <constructor_elt, va_gc> *elms = NULL; 2445 2446 /* Get the base element type for the array, generating the 2447 initializer for the dims parameter along the way. */ 2448 Type *telem = e->newtype->toBasetype (); 2449 for (size_t i = 0; i < e->arguments->length; i++) 2450 { 2451 Expression *arg = (*e->arguments)[i]; 2452 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg)); 2453 2454 gcc_assert (telem->ty == TY::Tarray); 2455 telem = telem->toBasetype ()->nextOf (); 2456 gcc_assert (telem); 2457 } 2458 2459 /* Initialize the temporary. */ 2460 tree init = modify_expr (var, build_constructor (tarray, elms)); 2461 var = compound_expr (init, var); 2462 2463 /* Generate: _d_newarraymTX(ti, dims) 2464 or: _d_newarraymiTX(ti, dims) */ 2465 libcall_fn libcall = telem->isZeroInit () 2466 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX; 2467 2468 tree tinfo = build_typeinfo (e, e->type); 2469 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()), 2470 size_int (e->arguments->length), 2471 build_address (var)); 2472 2473 result = build_libcall (libcall, tb, 2, tinfo, dims); 2474 } 2475 2476 if (e->argprefix) 2477 result = compound_expr (build_expr (e->argprefix), result); 2478 } 2479 else if (tb->ty == TY::Tpointer) 2480 { 2481 /* Allocating memory for a new pointer. */ 2482 TypePointer *tpointer = tb->isTypePointer (); 2483 2484 if (tpointer->next->size () == 0) 2485 { 2486 /* Pointer element size is unknown. */ 2487 this->result_ = d_convert (build_ctype (e->type), 2488 integer_zero_node); 2489 return; 2490 } 2491 2492 libcall_fn libcall = tpointer->next->isZeroInit (e->loc) 2493 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT; 2494 2495 tree arg = build_typeinfo (e, e->newtype); 2496 result = build_libcall (libcall, tb, 1, arg); 2497 2498 if (e->arguments && e->arguments->length == 1) 2499 { 2500 result = d_save_expr (result); 2501 tree init = modify_expr (build_deref (result), 2502 build_expr ((*e->arguments)[0])); 2503 result = compound_expr (init, result); 2504 } 2505 2506 if (e->argprefix) 2507 result = compound_expr (build_expr (e->argprefix), result); 2508 } 2509 else 2510 gcc_unreachable (); 2511 2512 this->result_ = convert_expr (result, tb, e->type); 2513 } 2514 2515 /* Build an integer literal. */ 2516 2517 void visit (IntegerExp *e) 2518 { 2519 tree ctype = build_ctype (e->type->toBasetype ()); 2520 this->result_ = build_integer_cst (e->value, ctype); 2521 } 2522 2523 /* Build a floating-point literal. */ 2524 2525 void visit (RealExp *e) 2526 { 2527 this->result_ = build_float_cst (e->value, e->type->toBasetype ()); 2528 } 2529 2530 /* Build a complex literal. */ 2531 2532 void visit (ComplexExp *e) 2533 { 2534 Type *tnext; 2535 2536 switch (e->type->toBasetype ()->ty) 2537 { 2538 case TY::Tcomplex32: 2539 tnext = (TypeBasic *) Type::tfloat32; 2540 break; 2541 2542 case TY::Tcomplex64: 2543 tnext = (TypeBasic *) Type::tfloat64; 2544 break; 2545 2546 case TY::Tcomplex80: 2547 tnext = (TypeBasic *) Type::tfloat80; 2548 break; 2549 2550 default: 2551 gcc_unreachable (); 2552 } 2553 2554 this->result_ = build_complex (build_ctype (e->type), 2555 build_float_cst (creall (e->value), tnext), 2556 build_float_cst (cimagl (e->value), tnext)); 2557 } 2558 2559 /* Build a string literal, all strings are null terminated except for 2560 static arrays. */ 2561 2562 void visit (StringExp *e) 2563 { 2564 Type *tb = e->type->toBasetype (); 2565 tree type = build_ctype (e->type); 2566 2567 if (tb->ty == TY::Tsarray) 2568 { 2569 /* Turn the string into a constructor for the static array. */ 2570 vec <constructor_elt, va_gc> *elms = NULL; 2571 vec_safe_reserve (elms, e->len); 2572 tree etype = TREE_TYPE (type); 2573 2574 for (size_t i = 0; i < e->len; i++) 2575 { 2576 tree value = build_integer_cst (e->getCodeUnit (i), etype); 2577 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); 2578 } 2579 2580 tree ctor = build_constructor (type, elms); 2581 TREE_CONSTANT (ctor) = 1; 2582 this->result_ = ctor; 2583 } 2584 else 2585 { 2586 /* Copy the string contents to a null terminated string. */ 2587 dinteger_t length = (e->len * e->sz); 2588 char *string = XALLOCAVEC (char, length + 1); 2589 if (length > 0) 2590 memcpy (string, e->string, length); 2591 string[length] = '\0'; 2592 2593 /* String value and type includes the null terminator. */ 2594 tree value = build_string (length, string); 2595 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1); 2596 value = build_address (value); 2597 2598 if (tb->ty == TY::Tarray) 2599 value = d_array_value (type, size_int (e->len), value); 2600 2601 TREE_CONSTANT (value) = 1; 2602 this->result_ = d_convert (type, value); 2603 } 2604 } 2605 2606 /* Build a tuple literal. Just an argument list that may have 2607 side effects that need evaluation. */ 2608 2609 void visit (TupleExp *e) 2610 { 2611 tree result = NULL_TREE; 2612 2613 if (e->e0) 2614 result = build_expr (e->e0, this->constp_, true); 2615 2616 for (size_t i = 0; i < e->exps->length; ++i) 2617 { 2618 Expression *exp = (*e->exps)[i]; 2619 result = compound_expr (result, build_expr (exp, this->constp_, true)); 2620 } 2621 2622 if (result == NULL_TREE) 2623 result = void_node; 2624 2625 this->result_ = result; 2626 } 2627 2628 /* Build an array literal. The common type of the all elements is taken to 2629 be the type of the array element, and all elements are implicitly 2630 converted to that type. */ 2631 2632 void visit (ArrayLiteralExp *e) 2633 { 2634 Type *tb = e->type->toBasetype (); 2635 2636 /* Implicitly convert void[n] to ubyte[n]. */ 2637 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid) 2638 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ()); 2639 2640 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray 2641 || tb->ty == TY::Tpointer); 2642 2643 /* Handle empty array literals. */ 2644 if (e->elements->length == 0) 2645 { 2646 if (tb->ty == TY::Tarray) 2647 this->result_ = d_array_value (build_ctype (e->type), 2648 size_int (0), null_pointer_node); 2649 else 2650 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0), 2651 NULL); 2652 2653 return; 2654 } 2655 2656 /* Build an expression that assigns the expressions in ELEMENTS to 2657 a constructor. */ 2658 vec <constructor_elt, va_gc> *elms = NULL; 2659 vec_safe_reserve (elms, e->elements->length); 2660 bool constant_p = true; 2661 tree saved_elems = NULL_TREE; 2662 2663 Type *etype = tb->nextOf (); 2664 tree satype = make_array_type (etype, e->elements->length); 2665 2666 for (size_t i = 0; i < e->elements->length; i++) 2667 { 2668 Expression *expr = e->getElement (i); 2669 tree value = build_expr (expr, this->constp_, true); 2670 2671 /* Only append nonzero values, the backend will zero out the rest 2672 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */ 2673 if (!initializer_zerop (value)) 2674 { 2675 if (!TREE_CONSTANT (value)) 2676 constant_p = false; 2677 2678 /* Split construction of values out of the constructor if there 2679 may be side effects. */ 2680 tree init = stabilize_expr (&value); 2681 if (init != NULL_TREE) 2682 saved_elems = compound_expr (saved_elems, init); 2683 2684 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), 2685 convert_expr (value, expr->type, etype)); 2686 } 2687 } 2688 2689 /* Now return the constructor as the correct type. For static arrays there 2690 is nothing else to do. For dynamic arrays, return a two field struct. 2691 For pointers, return the address. */ 2692 tree ctor = build_constructor (satype, elms); 2693 tree type = build_ctype (e->type); 2694 2695 /* Nothing else to do for static arrays. */ 2696 if (tb->ty == TY::Tsarray || this->constp_) 2697 { 2698 /* Can't take the address of the constructor, so create an anonymous 2699 static symbol, and then refer to it. */ 2700 if (tb->ty != TY::Tsarray) 2701 { 2702 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A"); 2703 ctor = build_address (decl); 2704 if (tb->ty == TY::Tarray) 2705 ctor = d_array_value (type, size_int (e->elements->length), ctor); 2706 2707 /* Immutable literals can be placed in rodata. */ 2708 if (tb->isImmutable ()) 2709 TREE_READONLY (decl) = 1; 2710 2711 d_pushdecl (decl); 2712 rest_of_decl_compilation (decl, 1, 0); 2713 } 2714 2715 /* If the array literal is readonly or static. */ 2716 if (constant_p) 2717 TREE_CONSTANT (ctor) = 1; 2718 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor))) 2719 TREE_STATIC (ctor) = 1; 2720 2721 /* Use memset to fill any alignment holes in the array. */ 2722 if (!this->constp_ && !this->literalp_) 2723 { 2724 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct (); 2725 2726 if (ts != NULL && (!identity_compare_p (ts->sym) 2727 || ts->sym->isUnionDeclaration ())) 2728 { 2729 tree var = build_local_temp (TREE_TYPE (ctor)); 2730 tree init = build_memset_call (var); 2731 /* Evaluate memset() first, then any saved elements. */ 2732 saved_elems = compound_expr (init, saved_elems); 2733 ctor = compound_expr (modify_expr (var, ctor), var); 2734 } 2735 } 2736 2737 this->result_ = compound_expr (saved_elems, d_convert (type, ctor)); 2738 } 2739 else 2740 { 2741 /* Allocate space on the memory managed heap. */ 2742 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX, 2743 etype->pointerTo (), 2, 2744 build_typeinfo (e, etype->arrayOf ()), 2745 size_int (e->elements->length)); 2746 mem = d_save_expr (mem); 2747 2748 /* Now copy the constructor into memory. */ 2749 tree size = size_mult_expr (size_int (e->elements->length), 2750 size_int (tb->nextOf ()->size ())); 2751 2752 tree result = build_memcpy_call (mem, build_address (ctor), size); 2753 2754 /* Return the array pointed to by MEM. */ 2755 result = compound_expr (result, mem); 2756 2757 if (tb->ty == TY::Tarray) 2758 result = d_array_value (type, size_int (e->elements->length), result); 2759 2760 this->result_ = compound_expr (saved_elems, result); 2761 } 2762 } 2763 2764 /* Build an associative array literal. The common type of the all keys is 2765 taken to be the key type, and common type of all values the value type. 2766 All keys and values are then implicitly converted as needed. */ 2767 2768 void visit (AssocArrayLiteralExp *e) 2769 { 2770 /* Want the mutable type for typeinfo reference. */ 2771 Type *tb = e->type->toBasetype ()->mutableOf (); 2772 2773 /* Handle empty assoc array literals. */ 2774 TypeAArray *ta = tb->isTypeAArray (); 2775 if (e->keys->length == 0) 2776 { 2777 this->result_ = build_constructor (build_ctype (ta), NULL); 2778 return; 2779 } 2780 2781 /* Build an expression that assigns all expressions in KEYS 2782 to a constructor. */ 2783 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length), 2784 e->keys, this->constp_); 2785 tree init = stabilize_expr (&akeys); 2786 2787 /* Do the same with all expressions in VALUES. */ 2788 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length), 2789 e->values, this->constp_); 2790 init = compound_expr (init, stabilize_expr (&avals)); 2791 2792 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */ 2793 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()), 2794 size_int (e->keys->length), 2795 build_address (akeys)); 2796 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()), 2797 size_int (e->values->length), 2798 build_address (avals)); 2799 2800 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3, 2801 build_typeinfo (e, ta), keys, vals); 2802 2803 /* Return an associative array pointed to by MEM. */ 2804 tree aatype = build_ctype (ta); 2805 vec <constructor_elt, va_gc> *ce = NULL; 2806 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem); 2807 2808 tree result = build_nop (build_ctype (e->type), 2809 build_constructor (aatype, ce)); 2810 this->result_ = compound_expr (init, result); 2811 } 2812 2813 /* Build a struct literal. */ 2814 2815 void visit (StructLiteralExp *e) 2816 { 2817 /* Handle empty struct literals. */ 2818 if (e->elements == NULL || e->sd->fields.length == 0) 2819 { 2820 this->result_ = build_constructor (build_ctype (e->type), NULL); 2821 return; 2822 } 2823 2824 /* Building sinit trees are delayed until after frontend semantic 2825 processing has complete. Build the static initializer now. */ 2826 if (e->useStaticInit && !this->constp_) 2827 { 2828 tree init = aggregate_initializer_decl (e->sd); 2829 2830 /* If initializing a symbol, don't forget to set it. */ 2831 if (e->sym != NULL) 2832 { 2833 tree var = build_deref (e->sym); 2834 init = compound_expr (modify_expr (var, init), var); 2835 } 2836 2837 this->result_ = init; 2838 return; 2839 } 2840 2841 /* Build a constructor that assigns the expressions in ELEMENTS 2842 at each field index that has been filled in. */ 2843 vec <constructor_elt, va_gc> *ve = NULL; 2844 tree saved_elems = NULL_TREE; 2845 2846 /* CTFE may fill the hidden pointer by NullExp. */ 2847 gcc_assert (e->elements->length <= e->sd->fields.length); 2848 2849 Type *tb = e->type->toBasetype (); 2850 gcc_assert (tb->ty == TY::Tstruct); 2851 2852 for (size_t i = 0; i < e->elements->length; i++) 2853 { 2854 Expression *exp = (*e->elements)[i]; 2855 if (!exp) 2856 continue; 2857 2858 VarDeclaration *field = e->sd->fields[i]; 2859 Type *type = exp->type->toBasetype (); 2860 Type *ftype = field->type->toBasetype (); 2861 tree value = NULL_TREE; 2862 2863 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype)) 2864 { 2865 /* Initialize a static array with a single element. */ 2866 tree elem = build_expr (exp, this->constp_, true); 2867 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem)); 2868 elem = d_save_expr (elem); 2869 2870 if (initializer_zerop (elem)) 2871 value = build_constructor (build_ctype (ftype), NULL); 2872 else 2873 value = build_array_from_val (ftype, elem); 2874 } 2875 else 2876 { 2877 value = convert_expr (build_expr (exp, this->constp_, true), 2878 exp->type, field->type); 2879 } 2880 2881 /* Split construction of values out of the constructor. */ 2882 saved_elems = compound_expr (saved_elems, stabilize_expr (&value)); 2883 2884 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value); 2885 } 2886 2887 /* Maybe setup hidden pointer to outer scope context. */ 2888 if (e->sd->isNested () && e->elements->length != e->sd->fields.length 2889 && this->constp_ == false) 2890 { 2891 tree field = get_symbol_decl (e->sd->vthis); 2892 tree value = build_vthis (e->sd); 2893 CONSTRUCTOR_APPEND_ELT (ve, field, value); 2894 gcc_assert (e->useStaticInit == false); 2895 } 2896 2897 /* Build a constructor in the correct shape of the aggregate type. */ 2898 tree ctor = build_struct_literal (build_ctype (e->type), ve); 2899 2900 /* Nothing more to do for constant literals. */ 2901 if (this->constp_) 2902 { 2903 /* If the struct literal is a valid for static data. */ 2904 if (TREE_CONSTANT (ctor) 2905 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor))) 2906 TREE_STATIC (ctor) = 1; 2907 2908 this->result_ = compound_expr (saved_elems, ctor); 2909 return; 2910 } 2911 2912 /* Construct the struct literal for run-time. */ 2913 if (e->sym != NULL) 2914 { 2915 /* Store the result in a symbol to initialize the literal. */ 2916 tree var = build_deref (e->sym); 2917 ctor = compound_expr (modify_expr (var, ctor), var); 2918 } 2919 else if (!this->literalp_) 2920 { 2921 /* Use memset to fill any alignment holes in the object. */ 2922 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ()) 2923 { 2924 tree var = build_local_temp (TREE_TYPE (ctor)); 2925 tree init = build_memset_call (var); 2926 /* Evaluate memset() first, then any saved element constructors. */ 2927 saved_elems = compound_expr (init, saved_elems); 2928 ctor = compound_expr (modify_expr (var, ctor), var); 2929 } 2930 } 2931 2932 this->result_ = compound_expr (saved_elems, ctor); 2933 } 2934 2935 /* Build a null literal. */ 2936 2937 void visit (NullExp *e) 2938 { 2939 this->result_ = build_typeof_null_value (e->type); 2940 } 2941 2942 /* Build a vector literal. */ 2943 2944 void visit (VectorExp *e) 2945 { 2946 /* First handle array literal expressions. */ 2947 if (e->e1->op == EXP::arrayLiteral) 2948 { 2949 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp (); 2950 vec <constructor_elt, va_gc> *elms = NULL; 2951 bool constant_p = true; 2952 tree type = build_ctype (e->type); 2953 2954 vec_safe_reserve (elms, ale->elements->length); 2955 for (size_t i = 0; i < ale->elements->length; i++) 2956 { 2957 Expression *expr = ale->getElement (i); 2958 tree value = d_convert (TREE_TYPE (type), 2959 build_expr (expr, this->constp_, true)); 2960 if (!CONSTANT_CLASS_P (value)) 2961 constant_p = false; 2962 2963 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); 2964 } 2965 2966 /* Build a VECTOR_CST from a constant vector constructor. */ 2967 if (constant_p) 2968 this->result_ = build_vector_from_ctor (type, elms); 2969 else 2970 this->result_ = build_constructor (type, elms); 2971 } 2972 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray) 2973 { 2974 /* Build a vector representation from a static array. */ 2975 this->result_ = convert_expr (build_expr (e->e1, this->constp_), 2976 e->e1->type, e->type); 2977 } 2978 else 2979 { 2980 /* Build constructor from single value. */ 2981 tree type = build_ctype (e->type); 2982 tree value = d_convert (TREE_TYPE (type), 2983 build_expr (e->e1, this->constp_, true)); 2984 this->result_ = build_vector_from_val (type, value); 2985 } 2986 } 2987 2988 /* Build a static array representation of a vector expression. */ 2989 2990 void visit (VectorArrayExp *e) 2991 { 2992 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true), 2993 e->e1->type, e->type); 2994 } 2995 2996 /* Build a static class literal, return its reference. */ 2997 2998 void visit (ClassReferenceExp *e) 2999 { 3000 /* The result of build_new_class_expr is a RECORD_TYPE, we want 3001 the reference. */ 3002 tree var = build_address (build_new_class_expr (e)); 3003 3004 /* If the type of this literal is an interface, the we must add the 3005 interface offset to symbol. */ 3006 if (this->constp_) 3007 { 3008 TypeClass *tc = e->type->toBasetype ()->isTypeClass (); 3009 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration (); 3010 3011 if (to != NULL) 3012 { 3013 ClassDeclaration *from = e->originalClass (); 3014 int offset = 0; 3015 3016 gcc_assert (to->isBaseOf (from, &offset) != 0); 3017 3018 if (offset != 0) 3019 var = build_offset (var, size_int (offset)); 3020 } 3021 } 3022 3023 this->result_ = var; 3024 } 3025 3026 /* Build an uninitialized value, generated from void initializers. */ 3027 3028 void visit (VoidInitExp *e) 3029 { 3030 /* The front-end only generates these for the initializer of globals. 3031 Represent `void' as zeroes, regardless of the type's default value. */ 3032 gcc_assert (this->constp_); 3033 this->result_ = build_zero_cst (build_ctype (e->type)); 3034 } 3035 3036 /* These expressions are mainly just a placeholders in the frontend. 3037 We shouldn't see them here. */ 3038 3039 void visit (ScopeExp *e) 3040 { 3041 error_at (make_location_t (e->loc), "%qs is not an expression", 3042 e->toChars ()); 3043 this->result_ = error_mark_node; 3044 } 3045 3046 void visit (TypeExp *e) 3047 { 3048 error_at (make_location_t (e->loc), "type %qs is not an expression", 3049 e->toChars ()); 3050 this->result_ = error_mark_node; 3051 } 3052 }; 3053 3054 3055 /* Main entry point for ExprVisitor interface to generate code for 3056 the Expression AST class E. If CONST_P is true, then E is a 3057 constant expression. If LITERAL_P is true, then E is a value used 3058 in the initialization of another literal. */ 3059 3060 tree 3061 build_expr (Expression *e, bool const_p, bool literal_p) 3062 { 3063 ExprVisitor v = ExprVisitor (const_p, literal_p); 3064 location_t saved_location = input_location; 3065 3066 input_location = make_location_t (e->loc); 3067 e->accept (&v); 3068 tree expr = v.result (); 3069 input_location = saved_location; 3070 3071 /* Check if initializer expression is valid constant. */ 3072 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr))) 3073 { 3074 error_at (make_location_t (e->loc), "non-constant expression %qs", 3075 e->toChars ()); 3076 return error_mark_node; 3077 } 3078 3079 return expr; 3080 } 3081 3082 /* Same as build_expr, but also calls destructors on any temporaries. */ 3083 3084 tree 3085 build_expr_dtor (Expression *e) 3086 { 3087 /* Codegen can be improved by determining if no exceptions can be thrown 3088 between the ctor and dtor, and eliminating the ctor and dtor. */ 3089 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope); 3090 tree result = build_expr (e); 3091 3092 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope)) 3093 { 3094 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result); 3095 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars); 3096 } 3097 3098 return result; 3099 } 3100 3101 /* Same as build_expr_dtor, but handles the result of E as a return value. */ 3102 3103 tree 3104 build_return_dtor (Expression *e, Type *type, TypeFunction *tf) 3105 { 3106 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope); 3107 tree result = build_expr (e); 3108 3109 /* Convert for initializing the DECL_RESULT. */ 3110 if (tf->isref ()) 3111 { 3112 /* If we are returning a reference, take the address. */ 3113 result = convert_expr (result, e->type, type); 3114 result = build_address (result); 3115 } 3116 else 3117 result = convert_for_rvalue (result, e->type, type); 3118 3119 /* The decl to store the return expression. */ 3120 tree decl = DECL_RESULT (cfun->decl); 3121 3122 /* Split comma expressions, so that the result is returned directly. */ 3123 tree expr = stabilize_expr (&result); 3124 result = build_assign (INIT_EXPR, decl, result); 3125 result = compound_expr (expr, return_expr (result)); 3126 3127 /* May nest the return expression inside the try/finally expression. */ 3128 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope)) 3129 { 3130 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result); 3131 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars); 3132 } 3133 3134 return result; 3135 } 3136 3137