Update baseline symbols for hppa-linux.
[official-gcc.git] / gcc / d / d-convert.cc
blobec5da6c10a6edf59e26909f059e5fe953c40b7bc
1 /* d-convert.cc -- Data type conversion routines.
2 Copyright (C) 2006-2022 Free Software Foundation, Inc.
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.
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.
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/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/declaration.h"
24 #include "dmd/expression.h"
25 #include "dmd/mtype.h"
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "diagnostic.h"
30 #include "langhooks.h"
31 #include "target.h"
32 #include "convert.h"
33 #include "stor-layout.h"
35 #include "d-tree.h"
38 /* Build CODE expression with operands OP0 and OP1.
39 Helper function for d_truthvalue_conversion, so assumes bool result. */
41 static tree
42 d_build_truthvalue_op (tree_code code, tree op0, tree op1)
44 tree type0, type1;
46 tree result_type = NULL_TREE;
48 type0 = TREE_TYPE (op0);
49 type1 = TREE_TYPE (op1);
51 /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
52 STRIP_TYPE_NOPS (op0);
53 STRIP_TYPE_NOPS (op1);
55 /* Also need to convert pointer/int comparison. */
56 if (POINTER_TYPE_P (type0) && TREE_CODE (op1) == INTEGER_CST
57 && integer_zerop (op1))
59 result_type = type0;
61 else if (POINTER_TYPE_P (type1) && TREE_CODE (op0) == INTEGER_CST
62 && integer_zerop (op0))
64 result_type = type1;
66 /* If integral, need to convert unsigned/signed comparison.
67 Will also need to convert if type precisions differ. */
68 else if (INTEGRAL_TYPE_P (type0) && INTEGRAL_TYPE_P (type1))
70 if (TYPE_PRECISION (type0) > TYPE_PRECISION (type1))
71 result_type = type0;
72 else if (TYPE_PRECISION (type0) < TYPE_PRECISION (type1))
73 result_type = type1;
74 else if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1))
75 result_type = TYPE_UNSIGNED (type0) ? type0 : type1;
78 if (result_type)
80 if (TREE_TYPE (op0) != result_type)
81 op0 = convert (result_type, op0);
82 if (TREE_TYPE (op1) != result_type)
83 op1 = convert (result_type, op1);
86 return fold_build2 (code, d_bool_type, op0, op1);
89 /* Return whether EXPR is a declaration whose address can never be NULL. */
91 bool
92 decl_with_nonnull_addr_p (const_tree expr)
94 return (DECL_P (expr)
95 && (TREE_CODE (expr) == PARM_DECL
96 || TREE_CODE (expr) == LABEL_DECL
97 || !DECL_WEAK (expr)));
100 /* Convert EXPR to be a truth-value, validating its type for this purpose. */
102 tree
103 d_truthvalue_conversion (tree expr)
105 switch (TREE_CODE (expr))
107 case EQ_EXPR: case NE_EXPR: case LE_EXPR:
108 case GE_EXPR: case LT_EXPR: case GT_EXPR:
109 if (TREE_TYPE (expr) == d_bool_type)
110 return expr;
111 return build2 (TREE_CODE (expr), d_bool_type,
112 TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
114 case TRUTH_ANDIF_EXPR:
115 case TRUTH_ORIF_EXPR:
116 case TRUTH_AND_EXPR:
117 case TRUTH_OR_EXPR:
118 case TRUTH_XOR_EXPR:
119 if (TREE_TYPE (expr) == d_bool_type)
120 return expr;
121 return build2 (TREE_CODE (expr), d_bool_type,
122 d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
123 d_truthvalue_conversion (TREE_OPERAND (expr, 1)));
125 case TRUTH_NOT_EXPR:
126 if (TREE_TYPE (expr) == d_bool_type)
127 return expr;
128 return build1 (TREE_CODE (expr), d_bool_type,
129 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
131 case ERROR_MARK:
132 return expr;
134 case INTEGER_CST:
135 return integer_zerop (expr) ? boolean_false_node
136 : boolean_true_node;
138 case REAL_CST:
139 return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
140 ? boolean_true_node
141 : boolean_false_node;
143 case ADDR_EXPR:
144 /* If we are taking the address of a decl that can never be null,
145 then the return result is always true. */
146 if (decl_with_nonnull_addr_p (TREE_OPERAND (expr, 0)))
148 warning (OPT_Waddress,
149 "the address of %qD will always evaluate as %<true%>",
150 TREE_OPERAND (expr, 0));
151 return boolean_true_node;
153 break;
155 case COMPLEX_EXPR:
156 return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
157 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
158 d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
159 d_truthvalue_conversion (TREE_OPERAND (expr, 1)));
161 case NEGATE_EXPR:
162 case ABS_EXPR:
163 case FLOAT_EXPR:
164 /* These don't change whether an object is nonzero or zero. */
165 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
167 case LROTATE_EXPR:
168 case RROTATE_EXPR:
169 /* These don't change whether an object is zero or nonzero, but
170 we can't ignore them if their second arg has side-effects. */
171 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
173 return build2 (COMPOUND_EXPR, d_bool_type, TREE_OPERAND (expr, 1),
174 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
176 else
177 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
179 case COND_EXPR:
180 /* Distribute the conversion into the arms of a COND_EXPR. */
181 return fold_build3 (COND_EXPR, d_bool_type, TREE_OPERAND (expr, 0),
182 d_truthvalue_conversion (TREE_OPERAND (expr, 1)),
183 d_truthvalue_conversion (TREE_OPERAND (expr, 2)));
185 case CONVERT_EXPR:
186 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
187 since that affects how `default_conversion' will behave. */
188 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
189 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
190 break;
191 /* Fall through. */
193 case NOP_EXPR:
194 /* If this isn't narrowing the argument, we can ignore it. */
195 if (TYPE_PRECISION (TREE_TYPE (expr))
196 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
197 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
198 break;
200 default:
201 break;
204 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
206 tree t = save_expr (expr);
207 return d_build_truthvalue_op ((TREE_SIDE_EFFECTS (expr)
208 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
209 d_truthvalue_conversion (real_part (t)),
210 d_truthvalue_conversion (imaginary_part (t)));
212 else
213 return d_build_truthvalue_op (NE_EXPR, expr,
214 build_zero_cst (TREE_TYPE (expr)));
218 /* Creates an expression whose value is that of EXPR, converted to type TYPE.
219 This function implements all reasonable scalar conversions. */
221 tree
222 convert (tree type, tree expr)
224 tree e = expr;
225 tree_code code = TREE_CODE (type);
227 if (type == error_mark_node
228 || expr == error_mark_node
229 || TREE_TYPE (expr) == error_mark_node)
230 return error_mark_node;
232 const char *invalid_conv_diag
233 = targetm.invalid_conversion (TREE_TYPE (expr), type);
235 if (invalid_conv_diag)
237 error ("%s", invalid_conv_diag);
238 return error_mark_node;
241 if (type == TREE_TYPE (expr))
242 return expr;
244 if (TREE_CODE (type) == ARRAY_TYPE
245 && TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
246 && TYPE_DOMAIN (type) == TYPE_DOMAIN (TREE_TYPE (expr)))
247 return expr;
249 tree ret = targetm.convert_to_type (type, expr);
250 if (ret)
251 return ret;
253 STRIP_TYPE_NOPS (e);
254 tree etype = TREE_TYPE (e);
256 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
257 return fold_convert (type, expr);
258 if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
259 return error_mark_node;
260 if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
262 error ("void value not ignored as it ought to be");
263 return error_mark_node;
266 switch (code)
268 case VOID_TYPE:
269 return fold_convert (type, e);
271 case INTEGER_TYPE:
272 case ENUMERAL_TYPE:
273 if (TREE_CODE (etype) == POINTER_TYPE
274 || TREE_CODE (etype) == REFERENCE_TYPE)
276 if (integer_zerop (e))
277 return build_int_cst (type, 0);
279 /* Convert to an unsigned integer of the correct width first, and
280 from there widen/truncate to the required type. */
281 tree utype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
283 ret = fold_build1 (CONVERT_EXPR, utype, e);
284 return fold_convert (type, ret);
287 return fold (convert_to_integer (type, e));
289 case BOOLEAN_TYPE:
290 return fold_convert (type, d_truthvalue_conversion (expr));
292 case POINTER_TYPE:
293 case REFERENCE_TYPE:
294 return fold (convert_to_pointer (type, e));
296 case REAL_TYPE:
297 if (TREE_CODE (etype) == COMPLEX_TYPE && TYPE_IMAGINARY_FLOAT (type))
298 e = build1 (IMAGPART_EXPR, TREE_TYPE (etype), e);
300 return fold (convert_to_real (type, e));
302 case COMPLEX_TYPE:
303 if (TREE_CODE (etype) == REAL_TYPE && TYPE_IMAGINARY_FLOAT (etype))
304 return fold_build2 (COMPLEX_EXPR, type,
305 build_zero_cst (TREE_TYPE (type)),
306 convert (TREE_TYPE (type), expr));
308 return fold (convert_to_complex (type, e));
310 case VECTOR_TYPE:
311 return fold (convert_to_vector (type, e));
313 case RECORD_TYPE:
314 case UNION_TYPE:
315 if (lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
316 return fold_build1 (VIEW_CONVERT_EXPR, type, expr);
317 break;
319 default:
320 break;
323 error ("conversion to non-scalar type requested");
324 return error_mark_node;
327 /* Return expression EXP, whose type has been converted to TYPE. */
329 tree
330 d_convert (tree type, tree exp)
332 /* Check this first before retrieving frontend type. */
333 if (error_operand_p (type) || error_operand_p (exp))
334 return error_mark_node;
336 Type *totype = TYPE_LANG_FRONTEND (type);
337 Type *etype = TYPE_LANG_FRONTEND (TREE_TYPE (exp));
339 if (totype && etype)
340 return convert_expr (exp, etype, totype);
342 return convert (type, exp);
345 /* Return expression EXP, whose type has been convert from ETYPE to TOTYPE. */
347 tree
348 convert_expr (tree exp, Type *etype, Type *totype)
350 tree result = NULL_TREE;
352 gcc_assert (etype && totype);
353 Type *ebtype = etype->toBasetype ();
354 Type *tbtype = totype->toBasetype ();
356 if (same_type_p (etype, totype))
357 return exp;
359 if (error_operand_p (exp))
360 return exp;
362 switch (ebtype->ty)
364 case TY::Tdelegate:
365 if (tbtype->ty == TY::Tdelegate)
367 exp = d_save_expr (exp);
368 return build_delegate_cst (delegate_method (exp),
369 delegate_object (exp), totype);
371 else if (tbtype->ty == TY::Tpointer)
373 /* The front-end converts <delegate>.ptr to cast (void *)<delegate>.
374 Maybe should only allow void* ? */
375 exp = delegate_object (exp);
377 else
379 error ("cannot convert a delegate expression to %qs",
380 totype->toChars ());
381 return error_mark_node;
383 break;
385 case TY::Tstruct:
386 if (tbtype->ty == TY::Tstruct)
388 if (totype->size () == etype->size ())
390 /* Allowed to cast to structs with same type size. */
391 result = build_vconvert (build_ctype (totype), exp);
393 else
395 error ("cannot convert struct %qs to %qs",
396 etype->toChars (), totype->toChars ());
397 return error_mark_node;
400 /* else, default conversion, which should produce an error. */
401 break;
403 case TY::Tclass:
404 if (tbtype->ty == TY::Tclass)
406 ClassDeclaration *cdfrom = ebtype->isClassHandle ();
407 ClassDeclaration *cdto = tbtype->isClassHandle ();
408 int offset;
410 if (cdto->isBaseOf (cdfrom, &offset) && offset != OFFSET_RUNTIME)
412 /* Casting up the inheritance tree: Don't do anything special.
413 Cast to an implemented interface: Handle at compile-time. */
414 if (offset)
416 /* Forward references should not leak from the frontend. */
417 gcc_assert (offset != OFFSET_FWDREF);
419 tree type = build_ctype (totype);
420 exp = d_save_expr (exp);
422 tree cond = build_boolop (NE_EXPR, exp, null_pointer_node);
423 tree object = build_offset (exp, size_int (offset));
425 return build_condition (build_ctype (totype), cond,
426 build_nop (type, object),
427 build_nop (type, null_pointer_node));
430 /* d_convert will make a no-op cast. */
431 break;
433 else if (cdfrom->isCPPclass () || cdto->isCPPclass ())
435 /* Downcasting in C++ is a no-op. */
436 if (cdfrom->isCPPclass () && cdto->isCPPclass ())
437 break;
439 /* Casting from a C++ interface to a class/non-C++ interface
440 always results in null as there is no run-time information,
441 and no way one can derive from the other. */
442 warning (OPT_Wcast_result, "cast to %qs will produce null result",
443 totype->toChars ());
444 result = d_convert (build_ctype (totype), null_pointer_node);
446 /* Make sure the expression is still evaluated if necessary. */
447 if (TREE_SIDE_EFFECTS (exp))
448 result = compound_expr (exp, result);
450 break;
453 /* The offset can only be determined at run-time, do dynamic cast. */
454 libcall_fn libcall = cdfrom->isInterfaceDeclaration ()
455 ? LIBCALL_INTERFACE_CAST : LIBCALL_DYNAMIC_CAST;
457 return build_libcall (libcall, totype, 2, exp,
458 build_address (get_classinfo_decl (cdto)));
460 /* else default conversion. */
461 break;
463 case TY::Tsarray:
464 if (tbtype->ty == TY::Tpointer)
466 result = build_nop (build_ctype (totype), build_address (exp));
468 else if (tbtype->ty == TY::Tarray)
470 dinteger_t dim = ebtype->isTypeSArray ()->dim->toInteger ();
471 dinteger_t esize = ebtype->nextOf ()->size ();
472 dinteger_t tsize = tbtype->nextOf ()->size ();
474 tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
476 if (esize != tsize)
478 /* Array element sizes do not match, so we must adjust the
479 dimensions. */
480 if (tsize == 0 || (dim * esize) % tsize != 0)
482 error ("cannot cast %qs to %qs since sizes do not line up",
483 etype->toChars (), totype->toChars ());
484 return error_mark_node;
486 dim = (dim * esize) / tsize;
489 /* Assumes casting to dynamic array of same type or void. */
490 return d_array_value (build_ctype (totype), size_int (dim),
491 build_nop (ptrtype, build_address (exp)));
493 else if (tbtype->ty == TY::Tsarray)
495 /* D allows casting a static array to any static array type. */
496 return build_nop (build_ctype (totype), exp);
498 else if (tbtype->ty == TY::Tstruct)
500 /* And allows casting a static array to any struct type too.
501 Type sizes should have already been checked by the frontend. */
502 gcc_assert (totype->size () == etype->size ());
503 result = build_vconvert (build_ctype (totype), exp);
505 else if (tbtype->ty == TY::Tvector && tbtype->size () == ebtype->size ())
507 /* Allow casting from array to vector as if its an unaligned load. */
508 tree type = build_ctype (totype);
509 tree unaligned_type = build_variant_type_copy (type);
510 SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
511 TYPE_USER_ALIGN (unaligned_type) = 1;
512 result = convert (type, build_vconvert (unaligned_type, exp));
514 else
516 error ("cannot cast expression of type %qs to type %qs",
517 etype->toChars (), totype->toChars ());
518 return error_mark_node;
520 break;
522 case TY::Tarray:
523 if (tbtype->ty == TY::Tpointer)
525 return d_convert (build_ctype (totype), d_array_ptr (exp));
527 else if (tbtype->ty == TY::Tarray)
529 /* Assume tvoid->size() == 1. */
530 dinteger_t fsize = ebtype->nextOf ()->toBasetype ()->size ();
531 dinteger_t tsize = tbtype->nextOf ()->toBasetype ()->size ();
533 if (fsize != tsize)
535 /* Conversion requires a reinterpret cast of array.
536 This case should have been lowered in the semantic pass. */
537 if (tsize != 0 && fsize % tsize == 0)
539 /* Set array dimension to (length * (fsize / tsize)). */
540 tree newlength = size_mult_expr (d_array_length (exp),
541 size_int (fsize / tsize));
542 return d_array_value (build_ctype (totype), newlength,
543 d_array_ptr (exp));
545 else
546 gcc_unreachable ();
548 else
550 /* Convert from void[] or elements are the same size
551 -- don't change length. */
552 return build_vconvert (build_ctype (totype), exp);
555 else if (tbtype->ty == TY::Tsarray)
557 /* Strings are treated as dynamic arrays in D2. */
558 if (ebtype->isString () && tbtype->isString ())
559 return indirect_ref (build_ctype (totype), d_array_ptr (exp));
561 else
563 error ("cannot cast expression of type %qs to %qs",
564 etype->toChars (), totype->toChars ());
565 return error_mark_node;
567 break;
569 case TY::Taarray:
570 if (tbtype->ty == TY::Taarray)
571 return build_vconvert (build_ctype (totype), exp);
572 /* Can convert associative arrays to void pointers. */
573 else if (tbtype->ty == TY::Tpointer && tbtype->nextOf ()->ty == TY::Tvoid)
574 return build_vconvert (build_ctype (totype), exp);
575 /* Else, default conversion, which should product an error. */
576 break;
578 case TY::Tpointer:
579 /* Can convert void pointers to associative arrays too. */
580 if (tbtype->ty == TY::Taarray && ebtype->nextOf ()->ty == TY::Tvoid)
581 return build_vconvert (build_ctype (totype), exp);
582 break;
584 case TY::Tnull:
585 case TY::Tnoreturn:
586 /* Casting from `typeof(null)' for `null' expressions, or `typeof(*null)'
587 for `noreturn' expressions is represented as all zeros. */
588 result = build_typeof_null_value (totype);
590 /* Make sure the expression is still evaluated if necessary. */
591 if (TREE_SIDE_EFFECTS (exp))
592 result = compound_expr (exp, result);
593 break;
595 case TY::Tvector:
596 if (tbtype->ty == TY::Tsarray)
598 if (tbtype->size () == ebtype->size ())
599 return build_vconvert (build_ctype (totype), exp);
601 break;
603 default:
604 /* All casts between imaginary and non-imaginary result in 0.0,
605 except for casts between complex and imaginary types. */
606 if (!ebtype->iscomplex () && !tbtype->iscomplex ()
607 && (ebtype->isimaginary () != tbtype->isimaginary ()))
609 warning (OPT_Wcast_result,
610 "cast from %qs to %qs will produce zero result",
611 ebtype->toChars (), tbtype->toChars ());
613 return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
616 gcc_assert (TREE_CODE (exp) != STRING_CST);
617 break;
620 return result ? result : convert (build_ctype (totype), exp);
623 /* Return a TREE represenwation of EXPR, whose type has been converted from
624 * ETYPE to TOTYPE, and is being used in an rvalue context. */
626 tree
627 convert_for_rvalue (tree expr, Type *etype, Type *totype)
629 tree result = NULL_TREE;
631 Type *ebtype = etype->toBasetype ();
632 Type *tbtype = totype->toBasetype ();
634 if (ebtype->ty == TY::Tbool)
636 /* If casting from bool, the result is either 0 or 1, any other value
637 violates @safe code, so enforce that it is never invalid. */
638 if (CONSTANT_CLASS_P (expr))
639 result = d_truthvalue_conversion (expr);
640 else
642 /* Reinterpret the boolean as an integer and test the first bit.
643 The generated code should end up being equivalent to:
644 *cast(ubyte *)&expr & 1; */
645 machine_mode bool_mode = TYPE_MODE (TREE_TYPE (expr));
646 tree mtype = lang_hooks.types.type_for_mode (bool_mode, 1);
647 result = fold_build2 (BIT_AND_EXPR, mtype,
648 build_vconvert (mtype, expr),
649 build_one_cst (mtype));
652 result = convert (build_ctype (tbtype), result);
655 if (tbtype->ty == TY::Tsarray
656 && ebtype->ty == TY::Tsarray
657 && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
658 && INDIRECT_REF_P (expr)
659 && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
660 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
662 /* If expression is a vector that was casted to an array either by
663 explicit type cast or by taking the vector's `.array' value, strip the
664 reinterpret cast and build a constructor instead. */
665 tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
667 if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
669 /* Rewrite: `*(Array *)&vector'
670 into: `{ vector[0], vector[1], ... }' */
671 tree array = d_save_expr (TREE_OPERAND (ptr, 0));
672 array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
674 uinteger_t dim = tbtype->isTypeSArray ()->dim->toUInteger ();
675 vec <constructor_elt, va_gc> *elms = NULL;
676 for (uinteger_t i = 0; i < dim; i++)
678 tree index = size_int (i);
679 tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
680 array, index, NULL_TREE, NULL_TREE);
681 CONSTRUCTOR_APPEND_ELT (elms, index, value);
684 return build_constructor (build_ctype (totype), elms);
688 return result ? result : convert_expr (expr, etype, totype);
691 /* Apply semantics of assignment to a value of type TOTYPE to EXPR
692 (e.g., pointer = array -> pointer = &array[0])
694 Return a TREE representation of EXPR implicitly converted to TOTYPE
695 for use in assignment expressions MODIFY_EXPR, INIT_EXPR. */
697 tree
698 convert_for_assignment (tree expr, Type *etype, Type *totype)
700 Type *ebtype = etype->toBasetype ();
701 Type *tbtype = totype->toBasetype ();
703 /* Assuming this only has to handle converting a non Tsarray type to
704 arbitrarily dimensioned Tsarrays. */
705 if (tbtype->ty == TY::Tsarray)
707 Type *telem = tbtype->nextOf ()->baseElemOf ();
709 if (same_type_p (telem, ebtype))
711 TypeSArray *sa_type = tbtype->isTypeSArray ();
712 uinteger_t count = sa_type->dim->toUInteger ();
714 tree ctor = build_constructor (build_ctype (totype), NULL);
715 if (count)
717 vec <constructor_elt, va_gc> *ce = NULL;
718 tree index = build2 (RANGE_EXPR, build_ctype (Type::tsize_t),
719 size_zero_node, size_int (count - 1));
720 tree value = convert_for_assignment (expr, etype, sa_type->next);
722 /* Can't use VAR_DECLs in CONSTRUCTORS. */
723 if (VAR_P (value))
725 value = DECL_INITIAL (value);
726 gcc_assert (value);
729 CONSTRUCTOR_APPEND_ELT (ce, index, value);
730 CONSTRUCTOR_ELTS (ctor) = ce;
732 TREE_READONLY (ctor) = 1;
733 TREE_CONSTANT (ctor) = 1;
734 return ctor;
738 /* D Front end uses IntegerExp(0) to mean zero-init an array or structure. */
739 if ((tbtype->ty == TY::Tsarray || tbtype->ty == TY::Tstruct)
740 && ebtype->isintegral ())
742 if (!integer_zerop (expr))
743 gcc_unreachable ();
745 return expr;
748 return convert_for_rvalue (expr, etype, totype);
751 /* Return a TREE representation of EXPR converted to represent
752 the parameter type ARG. */
754 tree
755 convert_for_argument (tree expr, Parameter *arg)
757 /* Lazy arguments: expr should already be a delegate. */
758 if (arg->storageClass & STClazy)
759 return expr;
761 if (valist_array_p (arg->type))
763 /* Do nothing if the va_list has already been decayed to a pointer. */
764 if (!POINTER_TYPE_P (TREE_TYPE (expr)))
765 return build_address (expr);
767 else if (parameter_reference_p (arg))
769 /* Front-end shouldn't automatically take the address. */
770 return convert (parameter_type (arg), build_address (expr));
773 return expr;
776 /* Perform default promotions for data used in expressions.
777 Arrays and functions are converted to pointers;
778 enumeral types or short or char, to int.
779 In addition, manifest constants symbols are replaced by their values.
781 Return truth-value conversion of expression EXPR from value type TYPE. */
783 tree
784 convert_for_condition (tree expr, Type *type)
786 tree result = NULL_TREE;
788 switch (type->toBasetype ()->ty)
790 case TY::Taarray:
791 /* Checks that aa.ptr !is null. */
792 result = component_ref (expr, TYPE_FIELDS (TREE_TYPE (expr)));
793 break;
795 case TY::Tarray:
797 /* Checks (arr.length || arr.ptr) (i.e arr !is null). */
798 expr = d_save_expr (expr);
799 tree len = d_array_length (expr);
800 tree ptr = d_array_ptr (expr);
801 if (TYPE_MODE (TREE_TYPE (len)) == TYPE_MODE (TREE_TYPE (ptr)))
803 result = build2 (BIT_IOR_EXPR, TREE_TYPE (len), len,
804 d_convert (TREE_TYPE (len), ptr));
806 else
808 len = d_truthvalue_conversion (len);
809 ptr = d_truthvalue_conversion (ptr);
810 /* Probably not worth using TRUTH_OROR here. */
811 result = build2 (TRUTH_OR_EXPR, TREE_TYPE (len), len, ptr);
813 break;
816 case TY::Tdelegate:
818 /* Checks (function || object), but what good is it if there is
819 a null function pointer? */
820 tree obj, func;
821 if (METHOD_CALL_EXPR (expr))
822 extract_from_method_call (expr, obj, func);
823 else
825 expr = d_save_expr (expr);
826 obj = delegate_object (expr);
827 func = delegate_method (expr);
830 obj = d_truthvalue_conversion (obj);
831 func = d_truthvalue_conversion (func);
832 /* Probably not worth using TRUTH_ORIF here. */
833 result = build2 (BIT_IOR_EXPR, TREE_TYPE (obj), obj, func);
834 break;
837 case TY::Tnoreturn:
838 /* Front-end allows conditionals that never return, represent the
839 conditional result value as all zeros. */
840 result = build_zero_cst (d_bool_type);
842 /* Make sure the expression is still evaluated if necessary. */
843 if (TREE_SIDE_EFFECTS (expr))
844 result = compound_expr (expr, result);
845 break;
847 default:
848 result = expr;
849 break;
852 return d_truthvalue_conversion (result);
856 /* Convert EXP to a dynamic array.
857 EXP must be a static array or dynamic array. */
859 tree
860 d_array_convert (Expression *exp)
862 Type *tb = exp->type->toBasetype ();
864 if (tb->ty == TY::Tarray)
865 return build_expr (exp);
867 if (tb->ty == TY::Tsarray)
869 Type *totype = tb->nextOf ()->arrayOf ();
870 return convert_expr (build_expr (exp), exp->type, totype);
873 /* Invalid type passed. */
874 gcc_unreachable ();
877 /* Convert EXP to a dynamic array, where ETYPE is the element type.
878 Similar to above, except that EXP is allowed to be an element of an array.
879 Temporary variables are created inline if EXP is not an lvalue. */
881 tree
882 d_array_convert (Type *etype, Expression *exp)
884 Type *tb = exp->type->toBasetype ();
886 if ((tb->ty != TY::Tarray && tb->ty != TY::Tsarray)
887 || same_type_p (tb, etype))
889 /* Convert single element to an array. */
890 tree expr = build_expr (exp);
892 if (!exp->isLvalue ())
894 tree var = build_local_temp (TREE_TYPE (expr));
895 expr = compound_expr (modify_expr (var, expr), var);
898 return d_array_value (build_ctype (exp->type->arrayOf ()),
899 size_int (1), build_address (expr));
901 else
902 return d_array_convert (exp);