d: Merge upstream dmd 47871363d, druntime, c52e28b7, phobos 99e9c1b77.
[official-gcc.git] / gcc / d / d-codegen.cc
blobbb96b2f8d28f9c197a90a878d8cfe9343a871265
1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
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/ctfe.h"
24 #include "dmd/declaration.h"
25 #include "dmd/identifier.h"
26 #include "dmd/module.h"
27 #include "dmd/target.h"
28 #include "dmd/template.h"
30 #include "tree.h"
31 #include "tree-iterator.h"
32 #include "fold-const.h"
33 #include "diagnostic.h"
34 #include "langhooks.h"
35 #include "target.h"
36 #include "stringpool.h"
37 #include "varasm.h"
38 #include "stor-layout.h"
39 #include "attribs.h"
40 #include "function.h"
42 #include "d-tree.h"
45 /* Return the GCC location for the D frontend location LOC. */
47 location_t
48 make_location_t (const Loc &loc)
50 location_t gcc_location = input_location;
52 if (loc.filename)
54 linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
55 linemap_line_start (line_table, loc.linnum, 0);
56 gcc_location = linemap_position_for_column (line_table, loc.charnum);
57 linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
60 return gcc_location;
63 /* Return the DECL_CONTEXT for symbol DSYM. */
65 tree
66 d_decl_context (Dsymbol *dsym)
68 Dsymbol *parent = dsym;
69 Declaration *decl = dsym->isDeclaration ();
70 AggregateDeclaration *ad = dsym->isAggregateDeclaration ();
72 while ((parent = parent->toParent2 ()))
74 /* We've reached the top-level module namespace.
75 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,
76 but only for extern(D) symbols. */
77 if (parent->isModule ())
79 if ((decl != NULL && decl->linkage != LINK::d)
80 || (ad != NULL && ad->classKind != ClassKind::d))
81 return NULL_TREE;
83 return build_import_decl (parent);
86 /* Declarations marked as `static' or `__gshared' are never
87 part of any context except at module level. */
88 if (decl != NULL && decl->isDataseg ())
89 continue;
91 /* Nested functions. */
92 FuncDeclaration *fd = parent->isFuncDeclaration ();
93 if (fd != NULL)
94 return get_symbol_decl (fd);
96 /* Methods of classes or structs. */
97 AggregateDeclaration *ad = parent->isAggregateDeclaration ();
98 if (ad != NULL)
100 tree context = build_ctype (ad->type);
101 /* Want the underlying RECORD_TYPE. */
102 if (ad->isClassDeclaration ())
103 context = TREE_TYPE (context);
105 return context;
109 return NULL_TREE;
112 /* Return a copy of record TYPE but safe to modify in any way. */
114 tree
115 copy_aggregate_type (tree type)
117 tree newtype = build_distinct_type_copy (type);
118 TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type));
120 for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f))
121 DECL_FIELD_CONTEXT (f) = newtype;
123 return newtype;
126 /* Return TRUE if declaration DECL is a reference type. */
128 bool
129 declaration_reference_p (Declaration *decl)
131 Type *tb = decl->type->toBasetype ();
133 /* Declaration is a reference type. */
134 if (tb->ty == TY::Treference || decl->storage_class & (STCout | STCref))
135 return true;
137 return false;
140 /* Returns the real type for declaration DECL. */
142 tree
143 declaration_type (Declaration *decl)
145 /* Lazy declarations are converted to delegates. */
146 if (decl->storage_class & STClazy)
148 TypeFunction *tf = TypeFunction::create (NULL, decl->type,
149 VARARGnone, LINK::d);
150 TypeDelegate *t = TypeDelegate::create (tf);
151 return build_ctype (t->merge2 ());
154 /* Static array va_list have array->pointer conversions applied. */
155 if (decl->isParameter () && valist_array_p (decl->type))
157 Type *valist = decl->type->nextOf ()->pointerTo ();
158 valist = valist->castMod (decl->type->mod);
159 return build_ctype (valist);
162 tree type = build_ctype (decl->type);
164 /* Parameter is passed by reference. */
165 if (declaration_reference_p (decl))
166 return build_reference_type (type);
168 /* The `this' parameter is always const. */
169 if (decl->isThisDeclaration ())
170 return insert_type_modifiers (type, MODconst);
172 return type;
175 /* These should match the Declaration versions above
176 Return TRUE if parameter ARG is a reference type. */
178 bool
179 parameter_reference_p (Parameter *arg)
181 Type *tb = arg->type->toBasetype ();
183 /* Parameter is a reference type. */
184 if (tb->ty == TY::Treference || arg->storageClass & (STCout | STCref))
185 return true;
187 return false;
190 /* Returns the real type for parameter ARG. */
192 tree
193 parameter_type (Parameter *arg)
195 /* Lazy parameters are converted to delegates. */
196 if (arg->storageClass & STClazy)
198 TypeFunction *tf = TypeFunction::create (NULL, arg->type,
199 VARARGnone, LINK::d);
200 TypeDelegate *t = TypeDelegate::create (tf);
201 return build_ctype (t->merge2 ());
204 /* Static array va_list have array->pointer conversions applied. */
205 if (valist_array_p (arg->type))
207 Type *valist = arg->type->nextOf ()->pointerTo ();
208 valist = valist->castMod (arg->type->mod);
209 return build_ctype (valist);
212 tree type = build_ctype (arg->type);
214 /* Parameter is passed by reference. */
215 if (parameter_reference_p (arg))
216 return build_reference_type (type);
218 /* Pass non-POD structs by invisible reference. */
219 if (TREE_ADDRESSABLE (type))
221 type = build_reference_type (type);
222 /* There are no other pointer to this temporary. */
223 type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
226 /* Front-end has already taken care of type promotions. */
227 return type;
230 /* Build INTEGER_CST of type TYPE with the value VALUE. */
232 tree
233 build_integer_cst (dinteger_t value, tree type)
235 /* The type is error_mark_node, we can't do anything. */
236 if (error_operand_p (type))
237 return type;
239 return build_int_cst_type (type, value);
242 /* Build REAL_CST of type TOTYPE with the value VALUE. */
244 tree
245 build_float_cst (const real_t &value, Type *totype)
247 real_t new_value;
248 TypeBasic *tb = totype->isTypeBasic ();
250 gcc_assert (tb != NULL);
252 tree type_node = build_ctype (tb);
253 real_convert (&new_value.rv (), TYPE_MODE (type_node), &value.rv ());
255 return build_real (type_node, new_value.rv ());
258 /* Returns the .length component from the D dynamic array EXP. */
260 tree
261 d_array_length (tree exp)
263 if (error_operand_p (exp))
264 return exp;
266 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
268 /* Get the back-end type for the array and pick out the array
269 length field (assumed to be the first field). */
270 tree len_field = TYPE_FIELDS (TREE_TYPE (exp));
271 return component_ref (exp, len_field);
274 /* Returns the .ptr component from the D dynamic array EXP. */
276 tree
277 d_array_ptr (tree exp)
279 if (error_operand_p (exp))
280 return exp;
282 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
284 /* Get the back-end type for the array and pick out the array
285 data pointer field (assumed to be the second field). */
286 tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
287 return component_ref (exp, ptr_field);
290 /* Returns a constructor for D dynamic array type TYPE of .length LEN
291 and .ptr pointing to DATA. */
293 tree
294 d_array_value (tree type, tree len, tree data)
296 tree len_field, ptr_field;
297 vec <constructor_elt, va_gc> *ce = NULL;
299 gcc_assert (TYPE_DYNAMIC_ARRAY (type));
300 len_field = TYPE_FIELDS (type);
301 ptr_field = TREE_CHAIN (len_field);
303 len = convert (TREE_TYPE (len_field), len);
304 data = convert (TREE_TYPE (ptr_field), data);
306 CONSTRUCTOR_APPEND_ELT (ce, len_field, len);
307 CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);
309 return build_constructor (type, ce);
312 /* Returns value representing the array length of expression EXP.
313 TYPE could be a dynamic or static array. */
315 tree
316 get_array_length (tree exp, Type *type)
318 Type *tb = type->toBasetype ();
320 switch (tb->ty)
322 case TY::Tsarray:
323 return size_int (tb->isTypeSArray ()->dim->toUInteger ());
325 case TY::Tarray:
326 return d_array_length (exp);
328 default:
329 error ("cannot determine the length of a %qs", type->toChars ());
330 return error_mark_node;
334 /* Create BINFO for a ClassDeclaration's inheritance tree.
335 InterfaceDeclaration's are not included. */
337 tree
338 build_class_binfo (tree super, ClassDeclaration *cd)
340 tree binfo = make_tree_binfo (1);
341 tree ctype = build_ctype (cd->type);
343 /* Want RECORD_TYPE, not POINTER_TYPE. */
344 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
345 BINFO_INHERITANCE_CHAIN (binfo) = super;
346 BINFO_OFFSET (binfo) = integer_zero_node;
348 if (cd->baseClass)
349 BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass));
351 return binfo;
354 /* Create BINFO for an InterfaceDeclaration's inheritance tree.
355 In order to access all inherited methods in the debugger,
356 the entire tree must be described.
357 This function makes assumptions about interface layout. */
359 tree
360 build_interface_binfo (tree super, ClassDeclaration *cd, unsigned &offset)
362 tree binfo = make_tree_binfo (cd->baseclasses->length);
363 tree ctype = build_ctype (cd->type);
365 /* Want RECORD_TYPE, not POINTER_TYPE. */
366 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
367 BINFO_INHERITANCE_CHAIN (binfo) = super;
368 BINFO_OFFSET (binfo) = size_int (offset * target.ptrsize);
369 BINFO_VIRTUAL_P (binfo) = 1;
371 for (size_t i = 0; i < cd->baseclasses->length; i++, offset++)
373 BaseClass *bc = (*cd->baseclasses)[i];
374 BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset));
377 return binfo;
380 /* Returns the .funcptr component from the D delegate EXP. */
382 tree
383 delegate_method (tree exp)
385 /* Get the back-end type for the delegate and pick out the funcptr field
386 (assumed to be the second field). */
387 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
388 tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
389 return component_ref (exp, method_field);
392 /* Returns the .object component from the delegate EXP. */
394 tree
395 delegate_object (tree exp)
397 /* Get the back-end type for the delegate and pick out the object field
398 (assumed to be the first field). */
399 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
400 tree obj_field = TYPE_FIELDS (TREE_TYPE (exp));
401 return component_ref (exp, obj_field);
404 /* Build a delegate literal of type TYPE whose pointer function is
405 METHOD, and hidden object is OBJECT. */
407 tree
408 build_delegate_cst (tree method, tree object, Type *type)
410 tree ctor = make_node (CONSTRUCTOR);
411 tree ctype;
413 Type *tb = type->toBasetype ();
414 if (tb->ty == TY::Tdelegate)
415 ctype = build_ctype (type);
416 else
418 /* Convert a function method into an anonymous delegate. */
419 ctype = make_struct_type ("delegate()", 2,
420 get_identifier ("object"), TREE_TYPE (object),
421 get_identifier ("func"), TREE_TYPE (method));
422 TYPE_DELEGATE (ctype) = 1;
425 vec <constructor_elt, va_gc> *ce = NULL;
426 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object);
427 CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method);
429 CONSTRUCTOR_ELTS (ctor) = ce;
430 TREE_TYPE (ctor) = ctype;
432 return ctor;
435 /* Builds a temporary tree to store the CALLEE and OBJECT
436 of a method call expression of type TYPE. */
438 tree
439 build_method_call (tree callee, tree object, Type *type)
441 tree t = build_delegate_cst (callee, object, type);
442 METHOD_CALL_EXPR (t) = 1;
443 return t;
446 /* Extract callee and object from T and return in to CALLEE and OBJECT. */
448 void
449 extract_from_method_call (tree t, tree &callee, tree &object)
451 gcc_assert (METHOD_CALL_EXPR (t));
452 object = CONSTRUCTOR_ELT (t, 0)->value;
453 callee = CONSTRUCTOR_ELT (t, 1)->value;
456 /* Build a typeof(null) constant of type TYPE. Handles certain special case
457 conversions, where the underlying type is an aggregate with a nullable
458 interior pointer. */
460 tree
461 build_typeof_null_value (Type *type)
463 Type *tb = type->toBasetype ();
464 tree value;
466 /* For dynamic arrays, set length and pointer fields to zero. */
467 if (tb->ty == TY::Tarray)
468 value = d_array_value (build_ctype (type), size_int (0), null_pointer_node);
470 /* For associative arrays, set the pointer field to null. */
471 else if (tb->ty == TY::Taarray)
473 tree ctype = build_ctype (type);
474 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype));
476 value = build_constructor_single (ctype, TYPE_FIELDS (ctype),
477 null_pointer_node);
480 /* For delegates, set the frame and function pointer fields to null. */
481 else if (tb->ty == TY::Tdelegate)
482 value = build_delegate_cst (null_pointer_node, null_pointer_node, type);
484 /* Simple zero constant for all other types. */
485 else
486 value = build_zero_cst (build_ctype (type));
488 TREE_CONSTANT (value) = 1;
489 return value;
492 /* Build a dereference into the virtual table for OBJECT to retrieve
493 a function pointer of type FNTYPE at position INDEX. */
495 tree
496 build_vindex_ref (tree object, tree fntype, size_t index)
498 /* The vtable is the first field. Interface methods are also in the class's
499 vtable, so we don't need to convert from a class to an interface. */
500 tree result = build_deref (object);
501 result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result)));
503 gcc_assert (POINTER_TYPE_P (fntype));
505 return build_memref (fntype, result, size_int (target.ptrsize * index));
508 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
509 made into temporaries, otherwise any assignments will be lost. */
511 static bool
512 lvalue_p (tree exp)
514 const enum tree_code code = TREE_CODE (exp);
516 switch (code)
518 case SAVE_EXPR:
519 return false;
521 case ARRAY_REF:
522 case INDIRECT_REF:
523 case VAR_DECL:
524 case PARM_DECL:
525 case RESULT_DECL:
526 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp));
528 case IMAGPART_EXPR:
529 case REALPART_EXPR:
530 case COMPONENT_REF:
531 CASE_CONVERT:
532 return lvalue_p (TREE_OPERAND (exp, 0));
534 case COND_EXPR:
535 return (lvalue_p (TREE_OPERAND (exp, 1)
536 ? TREE_OPERAND (exp, 1)
537 : TREE_OPERAND (exp, 0))
538 && lvalue_p (TREE_OPERAND (exp, 2)));
540 case TARGET_EXPR:
541 return true;
543 case COMPOUND_EXPR:
544 return lvalue_p (TREE_OPERAND (exp, 1));
546 default:
547 return false;
551 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
552 more than once in an expression. */
554 tree
555 d_save_expr (tree exp)
557 if (TREE_SIDE_EFFECTS (exp))
559 if (lvalue_p (exp))
560 return stabilize_reference (exp);
562 return save_expr (exp);
565 return exp;
568 /* VALUEP is an expression we want to pre-evaluate or perform a computation on.
569 The expression returned by this function is the part whose value we don't
570 care about, storing the value in VALUEP. Callers must ensure that the
571 returned expression is evaluated before VALUEP. */
573 tree
574 stabilize_expr (tree *valuep)
576 tree expr = *valuep;
577 const enum tree_code code = TREE_CODE (expr);
578 tree lhs;
579 tree rhs;
581 switch (code)
583 case COMPOUND_EXPR:
584 /* Given ((e1, ...), eN):
585 Store the last RHS 'eN' expression in VALUEP. */
586 lhs = TREE_OPERAND (expr, 0);
587 rhs = TREE_OPERAND (expr, 1);
588 lhs = compound_expr (lhs, stabilize_expr (&rhs));
589 *valuep = rhs;
590 return lhs;
592 default:
593 return NULL_TREE;
597 /* Return a TARGET_EXPR, initializing the DECL with EXP. */
599 tree
600 build_target_expr (tree decl, tree exp)
602 tree type = TREE_TYPE (decl);
603 tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE);
605 if (EXPR_HAS_LOCATION (exp))
606 SET_EXPR_LOCATION (result, EXPR_LOCATION (exp));
608 /* If decl must always reside in memory. */
609 if (TREE_ADDRESSABLE (type))
610 d_mark_addressable (decl);
612 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
613 TARGET_EXPR. If there really turn out to be no side effects, then the
614 optimizer should be able to remove it. */
615 TREE_SIDE_EFFECTS (result) = 1;
617 return result;
620 /* Like the above function, but initializes a new temporary. */
622 tree
623 force_target_expr (tree exp)
625 tree decl = build_decl (input_location, VAR_DECL, NULL_TREE,
626 TREE_TYPE (exp));
627 DECL_CONTEXT (decl) = current_function_decl;
628 DECL_ARTIFICIAL (decl) = 1;
629 DECL_IGNORED_P (decl) = 1;
630 layout_decl (decl, 0);
632 return build_target_expr (decl, exp);
635 /* Returns the address of the expression EXP. */
637 tree
638 build_address (tree exp)
640 if (error_operand_p (exp))
641 return exp;
643 tree ptrtype;
644 tree type = TREE_TYPE (exp);
646 if (TREE_CODE (exp) == STRING_CST)
648 /* Just convert string literals (char[]) to C-style strings (char *),
649 otherwise the latter method (char[]*) causes conversion problems
650 during gimplification. */
651 ptrtype = build_pointer_type (TREE_TYPE (type));
653 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node)
654 && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE)
656 /* Special case for va_list, allow arrays to decay to a pointer. */
657 ptrtype = build_pointer_type (TREE_TYPE (type));
659 else
660 ptrtype = build_pointer_type (type);
662 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
663 tree init = stabilize_expr (&exp);
665 /* Can't take the address of a manifest constant, instead use its value. */
666 if (TREE_CODE (exp) == CONST_DECL)
667 exp = DECL_INITIAL (exp);
669 /* Some expression lowering may request an address of a compile-time constant,
670 or other non-lvalue expression. Make sure it is assigned to a location we
671 can reference. */
672 if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
673 exp = force_target_expr (exp);
674 else if (TREE_CODE (exp) == CALL_EXPR)
676 /* When a struct or array is returned in registers, we need to again fill
677 in all alignment holes. */
678 if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
679 && !aggregate_value_p (TREE_TYPE (exp), exp))
681 tree tmp = build_local_temp (TREE_TYPE (exp));
682 init = compound_expr (init, build_memset_call (tmp));
683 init = compound_expr (init, modify_expr (tmp, exp));
684 exp = tmp;
686 else
687 exp = force_target_expr (exp);
690 d_mark_addressable (exp);
691 exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype);
693 if (TREE_CODE (exp) == ADDR_EXPR)
694 TREE_NO_TRAMPOLINE (exp) = 1;
696 return compound_expr (init, exp);
699 /* Mark EXP saying that we need to be able to take the
700 address of it; it should not be allocated in a register. */
702 tree
703 d_mark_addressable (tree exp)
705 switch (TREE_CODE (exp))
707 case ADDR_EXPR:
708 case COMPONENT_REF:
709 case ARRAY_REF:
710 case REALPART_EXPR:
711 case IMAGPART_EXPR:
712 d_mark_addressable (TREE_OPERAND (exp, 0));
713 break;
715 case PARM_DECL:
716 case VAR_DECL:
717 case RESULT_DECL:
718 case CONST_DECL:
719 case FUNCTION_DECL:
720 TREE_ADDRESSABLE (exp) = 1;
721 break;
723 case CONSTRUCTOR:
724 TREE_ADDRESSABLE (exp) = 1;
725 break;
727 case TARGET_EXPR:
728 TREE_ADDRESSABLE (exp) = 1;
729 d_mark_addressable (TREE_OPERAND (exp, 0));
730 break;
732 default:
733 break;
736 return exp;
739 /* Mark EXP as "used" in the program for the benefit of
740 -Wunused warning purposes. */
742 tree
743 d_mark_used (tree exp)
745 switch (TREE_CODE (exp))
747 case VAR_DECL:
748 case CONST_DECL:
749 case PARM_DECL:
750 case RESULT_DECL:
751 case FUNCTION_DECL:
752 TREE_USED (exp) = 1;
753 break;
755 case ARRAY_REF:
756 case COMPONENT_REF:
757 case MODIFY_EXPR:
758 case REALPART_EXPR:
759 case IMAGPART_EXPR:
760 case NOP_EXPR:
761 case CONVERT_EXPR:
762 case ADDR_EXPR:
763 d_mark_used (TREE_OPERAND (exp, 0));
764 break;
766 case COMPOUND_EXPR:
767 d_mark_used (TREE_OPERAND (exp, 0));
768 d_mark_used (TREE_OPERAND (exp, 1));
769 break;
771 default:
772 break;
774 return exp;
777 /* Mark EXP as read, not just set, for set but not used -Wunused
778 warning purposes. */
780 tree
781 d_mark_read (tree exp)
783 switch (TREE_CODE (exp))
785 case VAR_DECL:
786 case PARM_DECL:
787 TREE_USED (exp) = 1;
788 DECL_READ_P (exp) = 1;
789 break;
791 case ARRAY_REF:
792 case COMPONENT_REF:
793 case MODIFY_EXPR:
794 case REALPART_EXPR:
795 case IMAGPART_EXPR:
796 case NOP_EXPR:
797 case CONVERT_EXPR:
798 case ADDR_EXPR:
799 d_mark_read (TREE_OPERAND (exp, 0));
800 break;
802 case COMPOUND_EXPR:
803 d_mark_read (TREE_OPERAND (exp, 1));
804 break;
806 default:
807 break;
809 return exp;
812 /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */
814 tree
815 build_memcmp_call (tree ptr1, tree ptr2, tree num)
817 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,
818 ptr1, ptr2, num);
821 /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */
823 tree
824 build_memcpy_call (tree dst, tree src, tree num)
826 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
827 dst, src, num);
830 /* Build a call to memset(), fills the first NUM bytes of PTR with zeros.
831 If NUM is NULL, then we expect PTR to be object that requires filling. */
833 tree
834 build_memset_call (tree ptr, tree num)
836 if (num == NULL_TREE)
838 gcc_assert (TREE_CODE (ptr) != ADDR_EXPR);
839 num = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
840 ptr = build_address (ptr);
843 /* Use a zero constant to fill the destination if setting the entire object.
844 For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
845 which can then be merged with other stores to the object. */
846 tree valtype = TREE_TYPE (TREE_TYPE (ptr));
847 if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num))
849 tree cst = build_zero_cst (valtype);
850 if (TREE_CODE (cst) == CONSTRUCTOR)
851 return build_memcpy_call (ptr, build_address (cst), num);
853 return modify_expr (build_deref (ptr), cst);
856 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3,
857 ptr, integer_zero_node, num);
860 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
861 This is because we don't guarantee that padding is zero-initialized for
862 a stack variable, so we can't use memcmp to compare struct values. */
864 bool
865 identity_compare_p (StructDeclaration *sd)
867 if (sd->isUnionDeclaration ())
868 return true;
870 unsigned offset = 0;
872 for (size_t i = 0; i < sd->fields.length; i++)
874 VarDeclaration *vd = sd->fields[i];
875 Type *tb = vd->type->toBasetype ();
877 /* Check inner data structures. */
878 if (TypeStruct *ts = tb->isTypeStruct ())
880 if (!identity_compare_p (ts->sym))
881 return false;
884 /* Check for types that may have padding. */
885 if ((tb->ty == TY::Tcomplex80
886 || tb->ty == TY::Tfloat80
887 || tb->ty == TY::Timaginary80)
888 && target.realpad != 0)
889 return false;
891 if (offset <= vd->offset)
893 /* There's a hole in the struct. */
894 if (offset != vd->offset)
895 return false;
897 offset += vd->type->size ();
901 /* Any trailing padding may not be zero. */
902 if (offset < sd->structsize)
903 return false;
905 return true;
908 /* Build a floating-point identity comparison between T1 and T2, ignoring any
909 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
911 tree
912 build_float_identity (tree_code code, tree t1, tree t2)
914 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
915 tree result = build_memcmp_call (build_address (t1),
916 build_address (t2), size);
917 return build_boolop (code, result, integer_zero_node);
920 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
921 CODE is the EQ_EXPR or NE_EXPR comparison. */
923 static tree
924 lower_struct_comparison (tree_code code, StructDeclaration *sd,
925 tree t1, tree t2)
927 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
928 tree tmemcmp = NULL_TREE;
930 /* We can skip the compare if the structs are empty. */
931 if (sd->fields.length == 0)
933 tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node);
934 if (TREE_SIDE_EFFECTS (t2))
935 tmemcmp = compound_expr (t2, tmemcmp);
936 if (TREE_SIDE_EFFECTS (t1))
937 tmemcmp = compound_expr (t1, tmemcmp);
939 return tmemcmp;
942 /* Let back-end take care of union comparisons. */
943 if (sd->isUnionDeclaration ())
945 tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
946 size_int (sd->structsize));
947 return build_boolop (code, tmemcmp, integer_zero_node);
950 for (size_t i = 0; i < sd->fields.length; i++)
952 VarDeclaration *vd = sd->fields[i];
953 Type *type = vd->type->toBasetype ();
954 tree sfield = get_symbol_decl (vd);
956 tree t1ref = component_ref (t1, sfield);
957 tree t2ref = component_ref (t2, sfield);
958 tree tcmp;
960 if (TypeStruct *ts = type->isTypeStruct ())
962 /* Compare inner data structures. */
963 tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref);
965 else if (type->ty != TY::Tvector && type->isintegral ())
967 /* Integer comparison, no special handling required. */
968 tcmp = build_boolop (code, t1ref, t2ref);
970 else if (type->ty != TY::Tvector && type->isfloating ())
972 /* Floating-point comparison, don't compare padding in type. */
973 if (!type->iscomplex ())
974 tcmp = build_float_identity (code, t1ref, t2ref);
975 else
977 tree req = build_float_identity (code, real_part (t1ref),
978 real_part (t2ref));
979 tree ieq = build_float_identity (code, imaginary_part (t1ref),
980 imaginary_part (t2ref));
982 tcmp = build_boolop (tcode, req, ieq);
985 else
987 tree stype = build_ctype (type);
988 opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));
990 if (mode.exists ())
992 /* Compare field bits as their corresponding integer type.
993 *((T*) &t1) == *((T*) &t2) */
994 tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1);
996 if (tmode == NULL_TREE)
997 tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
999 t1ref = build_vconvert (tmode, t1ref);
1000 t2ref = build_vconvert (tmode, t2ref);
1002 tcmp = build_boolop (code, t1ref, t2ref);
1004 else
1006 /* Simple memcmp between types. */
1007 tcmp = build_memcmp_call (build_address (t1ref),
1008 build_address (t2ref),
1009 TYPE_SIZE_UNIT (stype));
1010 tcmp = build_boolop (code, tcmp, integer_zero_node);
1014 tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp;
1017 return tmemcmp;
1021 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
1022 If possible, use memcmp, otherwise field-by-field comparison is done.
1023 CODE is the EQ_EXPR or NE_EXPR comparison. */
1025 tree
1026 build_struct_comparison (tree_code code, StructDeclaration *sd,
1027 tree t1, tree t2)
1029 /* We can skip the compare if the structs are empty. */
1030 if (sd->fields.length == 0)
1032 tree exp = build_boolop (code, integer_zero_node, integer_zero_node);
1033 if (TREE_SIDE_EFFECTS (t2))
1034 exp = compound_expr (t2, exp);
1035 if (TREE_SIDE_EFFECTS (t1))
1036 exp = compound_expr (t1, exp);
1038 return exp;
1041 /* Make temporaries to prevent multiple evaluations. */
1042 tree t1init = stabilize_expr (&t1);
1043 tree t2init = stabilize_expr (&t2);
1044 tree result;
1046 t1 = d_save_expr (t1);
1047 t2 = d_save_expr (t2);
1049 /* Bitwise comparison of structs not returned in memory may not work
1050 due to data holes loosing its zero padding upon return.
1051 As a heuristic, small structs are not compared using memcmp either. */
1052 if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd))
1053 result = lower_struct_comparison (code, sd, t1, t2);
1054 else
1056 /* Do bit compare of structs. */
1057 tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
1058 size_int (sd->structsize));
1059 result = build_boolop (code, tmemcmp, integer_zero_node);
1062 return compound_expr (compound_expr (t1init, t2init), result);
1065 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1066 The pointer references are T1 and T2, and the element type is SD.
1067 CODE is the EQ_EXPR or NE_EXPR comparison. */
1069 tree
1070 build_array_struct_comparison (tree_code code, StructDeclaration *sd,
1071 tree length, tree t1, tree t2)
1073 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
1075 /* Build temporary for the result of the comparison.
1076 Initialize as either 0 or 1 depending on operation. */
1077 tree result = build_local_temp (d_bool_type);
1078 tree init = build_boolop (code, integer_zero_node, integer_zero_node);
1079 add_stmt (build_assign (INIT_EXPR, result, init));
1081 /* Cast pointer-to-array to pointer-to-struct. */
1082 tree ptrtype = build_ctype (sd->type->pointerTo ());
1083 tree lentype = TREE_TYPE (length);
1085 push_binding_level (level_block);
1086 push_stmt_list ();
1088 /* Build temporary locals for length and pointers. */
1089 tree t = build_local_temp (size_type_node);
1090 add_stmt (build_assign (INIT_EXPR, t, length));
1091 length = t;
1093 t = build_local_temp (ptrtype);
1094 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1)));
1095 t1 = t;
1097 t = build_local_temp (ptrtype);
1098 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2)));
1099 t2 = t;
1101 /* Build loop for comparing each element. */
1102 push_stmt_list ();
1104 /* Exit logic for the loop.
1105 if (length == 0 || result OP 0) break; */
1106 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1107 t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,
1108 boolean_false_node));
1109 t = build1 (EXIT_EXPR, void_type_node, t);
1110 add_stmt (t);
1112 /* Do comparison, caching the value.
1113 result = result OP (*t1 == *t2); */
1114 t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2));
1115 t = build_boolop (tcode, result, t);
1116 t = modify_expr (result, t);
1117 add_stmt (t);
1119 /* Move both pointers to next element position.
1120 t1++, t2++; */
1121 tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)));
1122 t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size);
1123 add_stmt (t);
1124 t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size);
1125 add_stmt (t);
1127 /* Decrease loop counter.
1128 length -= 1; */
1129 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1130 d_convert (lentype, integer_one_node));
1131 add_stmt (t);
1133 /* Pop statements and finish loop. */
1134 tree body = pop_stmt_list ();
1135 add_stmt (build1 (LOOP_EXPR, void_type_node, body));
1137 /* Wrap it up into a bind expression. */
1138 tree stmt_list = pop_stmt_list ();
1139 tree block = pop_binding_level ();
1141 body = build3 (BIND_EXPR, void_type_node,
1142 BLOCK_VARS (block), stmt_list, block);
1144 return compound_expr (body, result);
1147 /* Build a constructor for a variable of aggregate type TYPE using the
1148 initializer INIT, an ordered flat list of fields and values provided
1149 by the frontend. The returned constructor should be a value that
1150 matches the layout of TYPE. */
1152 tree
1153 build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
1155 /* If the initializer was empty, use default zero initialization. */
1156 if (vec_safe_is_empty (init))
1157 return build_constructor (type, NULL);
1159 /* Struct literals can be seen for special enums representing `_Complex',
1160 make sure to reinterpret the literal as the correct type. */
1161 if (COMPLEX_FLOAT_TYPE_P (type))
1163 gcc_assert (vec_safe_length (init) == 2);
1164 return complex_expr (type, (*init)[0].value, (*init)[1].value);
1167 vec <constructor_elt, va_gc> *ve = NULL;
1168 HOST_WIDE_INT offset = 0;
1169 bool constant_p = true;
1170 bool finished = false;
1172 /* Walk through each field, matching our initializer list. */
1173 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1175 bool is_initialized = false;
1176 tree value;
1178 if (DECL_NAME (field) == NULL_TREE
1179 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1180 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1182 /* Search all nesting aggregates, if nothing is found, then
1183 this will return an empty initializer to fill the hole. */
1184 value = build_struct_literal (TREE_TYPE (field), init);
1186 if (!initializer_zerop (value))
1187 is_initialized = true;
1189 else
1191 /* Search for the value to initialize the next field. Once found,
1192 pop it from the init list so we don't look at it again. */
1193 unsigned HOST_WIDE_INT idx;
1194 tree index;
1196 FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value)
1198 /* If the index is NULL, then just assign it to the next field.
1199 This comes from layout_typeinfo(), which generates a flat
1200 list of values that we must shape into the record type. */
1201 if (index == field || index == NULL_TREE)
1203 init->ordered_remove (idx);
1204 if (!finished)
1205 is_initialized = true;
1206 break;
1211 if (is_initialized)
1213 HOST_WIDE_INT fieldpos = int_byte_position (field);
1214 gcc_assert (value != NULL_TREE);
1216 /* Must not initialize fields that overlap. */
1217 if (fieldpos < offset)
1219 /* Find the nearest user defined type and field. */
1220 tree vtype = type;
1221 while (ANON_AGGR_TYPE_P (vtype))
1222 vtype = TYPE_CONTEXT (vtype);
1224 tree vfield = field;
1225 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield))
1226 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield)))
1227 vfield = TYPE_FIELDS (TREE_TYPE (vfield));
1229 /* Must not generate errors for compiler generated fields. */
1230 gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield));
1231 error ("overlapping initializer for field %qT.%qD",
1232 TYPE_NAME (vtype), DECL_NAME (vfield));
1235 if (!TREE_CONSTANT (value))
1236 constant_p = false;
1238 CONSTRUCTOR_APPEND_ELT (ve, field, value);
1240 /* For unions, only the first field is initialized, any other field
1241 initializers found for this union are drained and ignored. */
1242 if (TREE_CODE (type) == UNION_TYPE)
1243 finished = true;
1246 /* Move offset to the next position in the struct. */
1247 if (TREE_CODE (type) == RECORD_TYPE)
1249 offset = int_byte_position (field)
1250 + int_size_in_bytes (TREE_TYPE (field));
1253 /* If all initializers have been assigned, there's nothing else to do. */
1254 if (vec_safe_is_empty (init))
1255 break;
1258 /* Ensure that we have consumed all values. */
1259 gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
1261 tree ctor = build_constructor (type, ve);
1263 if (constant_p)
1264 TREE_CONSTANT (ctor) = 1;
1266 return ctor;
1269 /* Given the TYPE of an anonymous field inside T, return the
1270 FIELD_DECL for the field. If not found return NULL_TREE.
1271 Because anonymous types can nest, we must also search all
1272 anonymous fields that are directly reachable. */
1274 static tree
1275 lookup_anon_field (tree t, tree type)
1277 t = TYPE_MAIN_VARIANT (t);
1279 for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
1281 if (DECL_NAME (field) == NULL_TREE)
1283 /* If we find it directly, return the field. */
1284 if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
1285 return field;
1287 /* Otherwise, it could be nested, search harder. */
1288 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1289 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1291 tree subfield = lookup_anon_field (TREE_TYPE (field), type);
1292 if (subfield)
1293 return subfield;
1298 return NULL_TREE;
1301 /* Builds OBJECT.FIELD component reference. */
1303 tree
1304 component_ref (tree object, tree field)
1306 if (error_operand_p (object) || error_operand_p (field))
1307 return error_mark_node;
1309 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1311 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1312 tree init = stabilize_expr (&object);
1314 /* If the FIELD is from an anonymous aggregate, generate a reference
1315 to the anonymous data member, and recur to find FIELD. */
1316 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field)))
1318 tree anonymous_field = lookup_anon_field (TREE_TYPE (object),
1319 DECL_CONTEXT (field));
1320 object = component_ref (object, anonymous_field);
1323 tree result = fold_build3_loc (input_location, COMPONENT_REF,
1324 TREE_TYPE (field), object, field, NULL_TREE);
1326 return compound_expr (init, result);
1329 /* Build an assignment expression of lvalue LHS from value RHS.
1330 CODE is the code for a binary operator that we use to combine
1331 the old value of LHS with RHS to get the new value. */
1333 tree
1334 build_assign (tree_code code, tree lhs, tree rhs)
1336 tree result;
1337 tree init = stabilize_expr (&lhs);
1338 init = compound_expr (init, stabilize_expr (&rhs));
1340 /* If initializing the LHS using a function that returns via NRVO. */
1341 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
1342 && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
1343 && aggregate_value_p (TREE_TYPE (rhs), rhs))
1345 /* Mark as addressable here, which should ensure the return slot is the
1346 address of the LHS expression, taken care of by back-end. */
1347 d_mark_addressable (lhs);
1348 CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
1350 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
1351 else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs))
1352 && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR)
1354 /* LHS may be referenced by the RHS expression, so force a temporary. */
1355 rhs = force_target_expr (rhs);
1358 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1359 if (TREE_CODE (rhs) == TARGET_EXPR)
1361 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1362 since that would cause the LHS to be constructed twice. */
1363 if (code != INIT_EXPR)
1365 init = compound_expr (init, rhs);
1366 result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs));
1368 else
1370 d_mark_addressable (lhs);
1371 TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs,
1372 TARGET_EXPR_INITIAL (rhs));
1373 result = rhs;
1376 else
1378 /* Simple assignment. */
1379 result = fold_build2_loc (input_location, code,
1380 TREE_TYPE (lhs), lhs, rhs);
1383 return compound_expr (init, result);
1386 /* Build an assignment expression of lvalue LHS from value RHS. */
1388 tree
1389 modify_expr (tree lhs, tree rhs)
1391 return build_assign (MODIFY_EXPR, lhs, rhs);
1394 /* Return EXP represented as TYPE. */
1396 tree
1397 build_nop (tree type, tree exp)
1399 if (error_operand_p (exp))
1400 return exp;
1402 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1403 tree init = stabilize_expr (&exp);
1404 exp = fold_build1_loc (input_location, NOP_EXPR, type, exp);
1406 return compound_expr (init, exp);
1409 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1410 except that EXP is type-punned, rather than a straight-forward cast. */
1412 tree
1413 build_vconvert (tree type, tree exp)
1415 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1416 makes sure this works for vector-to-array viewing, or if EXP ends up being
1417 used as the LHS of a MODIFY_EXPR. */
1418 return indirect_ref (type, build_address (exp));
1421 /* Maybe warn about ARG being an address that can never be null. */
1423 static void
1424 warn_for_null_address (tree arg)
1426 if (TREE_CODE (arg) == ADDR_EXPR
1427 && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0)))
1428 warning (OPT_Waddress,
1429 "the address of %qD will never be %<null%>",
1430 TREE_OPERAND (arg, 0));
1433 /* Build a boolean ARG0 op ARG1 expression. */
1435 tree
1436 build_boolop (tree_code code, tree arg0, tree arg1)
1438 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1439 so need to remove all side effects incase its address is taken. */
1440 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0)))
1441 arg0 = d_save_expr (arg0);
1442 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1)))
1443 arg1 = d_save_expr (arg1);
1445 if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1)))
1447 /* Build a vector comparison.
1448 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1449 tree type = TREE_TYPE (arg0);
1450 tree cmptype = truth_type_for (type);
1451 tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1);
1453 return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp,
1454 build_minus_one_cst (type),
1455 build_zero_cst (type));
1458 if (code == EQ_EXPR || code == NE_EXPR)
1460 /* Check if comparing the address of a variable to null. */
1461 if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1))
1462 warn_for_null_address (arg0);
1463 if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0))
1464 warn_for_null_address (arg1);
1467 return fold_build2_loc (input_location, code, d_bool_type,
1468 arg0, d_convert (TREE_TYPE (arg0), arg1));
1471 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1472 arguments to the conditional expression. */
1474 tree
1475 build_condition (tree type, tree arg0, tree arg1, tree arg2)
1477 if (arg1 == void_node)
1478 arg1 = build_empty_stmt (input_location);
1480 if (arg2 == void_node)
1481 arg2 = build_empty_stmt (input_location);
1483 return fold_build3_loc (input_location, COND_EXPR,
1484 type, arg0, arg1, arg2);
1487 tree
1488 build_vcondition (tree arg0, tree arg1, tree arg2)
1490 return build_condition (void_type_node, arg0, arg1, arg2);
1493 /* Build a compound expr to join ARG0 and ARG1 together. */
1495 tree
1496 compound_expr (tree arg0, tree arg1)
1498 if (arg1 == NULL_TREE)
1499 return arg0;
1501 if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0))
1502 return arg1;
1504 /* Remove intermediate expressions that have no side-effects. */
1505 while (TREE_CODE (arg0) == COMPOUND_EXPR
1506 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
1507 arg0 = TREE_OPERAND (arg0, 0);
1509 if (TREE_CODE (arg1) == TARGET_EXPR)
1511 /* If the rhs is a TARGET_EXPR, then build the compound expression
1512 inside the target_expr's initializer. This helps the compiler
1513 to eliminate unnecessary temporaries. */
1514 tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1));
1515 TARGET_EXPR_INITIAL (arg1) = init;
1517 return arg1;
1520 return fold_build2_loc (input_location, COMPOUND_EXPR,
1521 TREE_TYPE (arg1), arg0, arg1);
1524 /* Build a return expression. */
1526 tree
1527 return_expr (tree ret)
1529 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary
1530 in TARGET_EXPR_SLOT. */
1531 if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR)
1533 tree exp = TARGET_EXPR_INITIAL (ret);
1534 tree init = stabilize_expr (&exp);
1536 exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp);
1537 TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp);
1539 return ret;
1542 return fold_build1_loc (input_location, RETURN_EXPR,
1543 void_type_node, ret);
1546 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1548 tree
1549 size_mult_expr (tree arg0, tree arg1)
1551 return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1552 d_convert (size_type_node, arg0),
1553 d_convert (size_type_node, arg1));
1557 /* Return the real part of CE, which should be a complex expression. */
1559 tree
1560 real_part (tree ce)
1562 return fold_build1_loc (input_location, REALPART_EXPR,
1563 TREE_TYPE (TREE_TYPE (ce)), ce);
1566 /* Return the imaginary part of CE, which should be a complex expression. */
1568 tree
1569 imaginary_part (tree ce)
1571 return fold_build1_loc (input_location, IMAGPART_EXPR,
1572 TREE_TYPE (TREE_TYPE (ce)), ce);
1575 /* Build a complex expression of type TYPE using RE and IM. */
1577 tree
1578 complex_expr (tree type, tree re, tree im)
1580 return fold_build2_loc (input_location, COMPLEX_EXPR,
1581 type, re, im);
1584 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1585 The back-end requires this cast in many cases. */
1587 tree
1588 indirect_ref (tree type, tree exp)
1590 if (error_operand_p (exp))
1591 return exp;
1593 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1594 tree init = stabilize_expr (&exp);
1596 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
1597 exp = fold_build1 (INDIRECT_REF, type, exp);
1598 else
1600 exp = build_nop (build_pointer_type (type), exp);
1601 exp = build_deref (exp);
1604 return compound_expr (init, exp);
1607 /* Returns indirect reference of EXP, which must be a pointer type. */
1609 tree
1610 build_deref (tree exp)
1612 if (error_operand_p (exp))
1613 return exp;
1615 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1616 tree init = stabilize_expr (&exp);
1618 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
1620 if (TREE_CODE (exp) == ADDR_EXPR)
1621 exp = TREE_OPERAND (exp, 0);
1622 else
1623 exp = build_fold_indirect_ref (exp);
1625 return compound_expr (init, exp);
1628 /* Builds pointer offset expression PTR[INDEX]. */
1630 tree
1631 build_array_index (tree ptr, tree index)
1633 if (error_operand_p (ptr) || error_operand_p (index))
1634 return error_mark_node;
1636 tree ptr_type = TREE_TYPE (ptr);
1637 tree target_type = TREE_TYPE (ptr_type);
1639 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1640 TYPE_UNSIGNED (sizetype));
1642 /* Array element size. */
1643 tree size_exp = size_in_bytes (target_type);
1645 if (integer_zerop (size_exp) || integer_onep (size_exp))
1647 /* Array of void or bytes -- No need to multiply. */
1648 index = fold_convert (type, index);
1650 else
1652 index = d_convert (type, index);
1653 index = fold_build2 (MULT_EXPR, TREE_TYPE (index),
1654 index, d_convert (TREE_TYPE (index), size_exp));
1655 index = fold_convert (type, index);
1658 if (integer_zerop (index))
1659 return ptr;
1661 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);
1664 /* Builds pointer offset expression *(PTR OP OFFSET)
1665 OP could be a plus or minus expression. */
1667 tree
1668 build_offset_op (tree_code op, tree ptr, tree offset)
1670 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);
1672 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1673 TYPE_UNSIGNED (sizetype));
1674 offset = fold_convert (type, offset);
1676 if (op == MINUS_EXPR)
1677 offset = fold_build1 (NEGATE_EXPR, type, offset);
1679 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);
1682 /* Builds pointer offset expression *(PTR + OFFSET). */
1684 tree
1685 build_offset (tree ptr, tree offset)
1687 return build_offset_op (PLUS_EXPR, ptr, offset);
1690 tree
1691 build_memref (tree type, tree ptr, tree offset)
1693 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));
1696 /* Create a tree node to set multiple elements to a single value. */
1698 tree
1699 build_array_set (tree ptr, tree length, tree value)
1701 tree ptrtype = TREE_TYPE (ptr);
1702 tree lentype = TREE_TYPE (length);
1704 push_binding_level (level_block);
1705 push_stmt_list ();
1707 /* Build temporary locals for length and ptr, and maybe value. */
1708 tree t = build_local_temp (size_type_node);
1709 add_stmt (build_assign (INIT_EXPR, t, length));
1710 length = t;
1712 t = build_local_temp (ptrtype);
1713 add_stmt (build_assign (INIT_EXPR, t, ptr));
1714 ptr = t;
1716 if (TREE_SIDE_EFFECTS (value))
1718 t = build_local_temp (TREE_TYPE (value));
1719 add_stmt (build_assign (INIT_EXPR, t, value));
1720 value = t;
1723 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1724 push_stmt_list ();
1726 /* Exit logic for the loop.
1727 if (length == 0) break; */
1728 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1729 t = build1 (EXIT_EXPR, void_type_node, t);
1730 add_stmt (t);
1732 /* Assign value to the current pointer position.
1733 *ptr = value; */
1734 t = modify_expr (build_deref (ptr), value);
1735 add_stmt (t);
1737 /* Move pointer to next element position.
1738 ptr++; */
1739 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));
1740 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));
1741 add_stmt (t);
1743 /* Decrease loop counter.
1744 length -= 1; */
1745 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1746 d_convert (lentype, integer_one_node));
1747 add_stmt (t);
1749 /* Pop statements and finish loop. */
1750 tree loop_body = pop_stmt_list ();
1751 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));
1753 /* Wrap it up into a bind expression. */
1754 tree stmt_list = pop_stmt_list ();
1755 tree block = pop_binding_level ();
1757 return build3 (BIND_EXPR, void_type_node,
1758 BLOCK_VARS (block), stmt_list, block);
1762 /* Build an array of type TYPE where all the elements are VAL. */
1764 tree
1765 build_array_from_val (Type *type, tree val)
1767 tree etype = build_ctype (type->nextOf ());
1769 /* Initializing a multidimensional array. */
1770 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)
1771 val = build_array_from_val (type->nextOf (), val);
1773 size_t dims = type->isTypeSArray ()->dim->toInteger ();
1774 vec <constructor_elt, va_gc> *elms = NULL;
1775 vec_safe_reserve (elms, dims);
1777 val = d_convert (etype, val);
1779 for (size_t i = 0; i < dims; i++)
1780 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
1782 return build_constructor (build_ctype (type), elms);
1785 /* Build a static array of type TYPE from an array of EXPS.
1786 If CONST_P is true, then all elements in EXPS are constants. */
1788 tree
1789 build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
1791 /* Build a CONSTRUCTOR from all expressions. */
1792 vec <constructor_elt, va_gc> *elms = NULL;
1793 vec_safe_reserve (elms, exps->length);
1795 Type *etype = type->nextOf ();
1796 tree satype = make_array_type (etype, exps->length);
1798 for (size_t i = 0; i < exps->length; i++)
1800 Expression *expr = (*exps)[i];
1801 tree t = build_expr (expr, const_p);
1802 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1803 convert_expr (t, expr->type, etype));
1806 /* Create a new temporary to store the array. */
1807 tree var = build_local_temp (satype);
1809 /* Fill any alignment holes with zeroes. */
1810 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
1811 tree init = NULL;
1812 if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ()))
1813 init = build_memset_call (var);
1815 /* Initialize the temporary. */
1816 tree assign = modify_expr (var, build_constructor (satype, elms));
1817 return compound_expr (compound_expr (init, assign), var);
1821 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1823 tree
1824 void_okay_p (tree t)
1826 tree type = TREE_TYPE (t);
1828 if (VOID_TYPE_P (TREE_TYPE (type)))
1830 tree totype = build_ctype (Type::tuns8->pointerTo ());
1831 return fold_convert (totype, t);
1834 return t;
1837 /* Builds a STRING_CST representing the filename of location LOC. When the
1838 location is not valid, the name of the source module is used instead. */
1840 static tree
1841 build_filename_from_loc (const Loc &loc)
1843 const char *filename = loc.filename
1844 ? loc.filename : d_function_chain->module->srcfile.toChars ();
1846 unsigned length = strlen (filename);
1847 tree str = build_string (length, filename);
1848 TREE_TYPE (str) = make_array_type (Type::tchar, length + 1);
1850 return build_address (str);
1853 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1854 an assert check fails. When calling the msg variant functions, MSG is the
1855 error message supplied by the user. */
1857 tree
1858 build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
1860 tree file;
1861 tree line = size_int (loc.linnum);
1863 switch (libcall)
1865 case LIBCALL_ASSERT_MSG:
1866 case LIBCALL_UNITTEST_MSG:
1867 /* File location is passed as a D string. */
1868 if (loc.filename)
1870 unsigned len = strlen (loc.filename);
1871 tree str = build_string (len, loc.filename);
1872 TREE_TYPE (str) = make_array_type (Type::tchar, len);
1874 file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
1875 size_int (len), build_address (str));
1877 else
1878 file = null_array_node;
1879 break;
1881 case LIBCALL_ASSERTP:
1882 case LIBCALL_UNITTESTP:
1883 file = build_filename_from_loc (loc);
1884 break;
1886 default:
1887 gcc_unreachable ();
1891 if (msg != NULL_TREE)
1892 return build_libcall (libcall, Type::tvoid, 3, msg, file, line);
1893 else
1894 return build_libcall (libcall, Type::tvoid, 2, file, line);
1897 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
1898 array bounds check fails. */
1900 tree
1901 build_array_bounds_call (const Loc &loc)
1903 /* Terminate the program with a trap if no D runtime present. */
1904 if (checkaction_trap_p ())
1905 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1906 else
1908 return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
1909 build_filename_from_loc (loc),
1910 size_int (loc.linnum));
1914 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1915 in the index expression IE. The condition returns the INDEX if true, or
1916 throws a `ArrayIndexError`. */
1918 tree
1919 build_bounds_index_condition (IndexExp *ie, tree index, tree length)
1921 if (ie->indexIsInBounds || !array_bounds_check ())
1922 return index;
1924 /* Prevent multiple evaluations of the index. */
1925 index = d_save_expr (index);
1927 /* Generate INDEX >= LENGTH && throw RangeError.
1928 No need to check whether INDEX >= 0 as the front-end should
1929 have already taken care of implicit casts to unsigned. */
1930 tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length);
1931 tree boundserr;
1933 if (checkaction_trap_p ())
1934 boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1935 else
1937 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
1938 build_filename_from_loc (ie->e2->loc),
1939 size_int (ie->e2->loc.linnum), index, length);
1942 return build_condition (TREE_TYPE (index), condition, boundserr, index);
1945 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1946 the slice expression SE of the source array length LENGTH. The condition
1947 returns the new array length if true, or throws an `ArraySliceError`. */
1949 tree
1950 build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
1952 if (array_bounds_check ())
1954 tree condition = NULL_TREE;
1956 /* Enforces that `upper <= length`. */
1957 if (!se->upperIsInBounds && length != NULL_TREE)
1958 condition = fold_build2 (GT_EXPR, d_bool_type, upper, length);
1959 else
1960 length = integer_zero_node;
1962 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1963 we've already ensured that `upper <= length`. */
1964 if (!se->lowerIsLessThanUpper)
1966 tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper);
1968 if (condition != NULL_TREE)
1969 condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond);
1970 else
1971 condition = lwr_cond;
1974 if (condition != NULL_TREE)
1976 tree boundserr;
1978 if (checkaction_trap_p ())
1980 boundserr =
1981 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1983 else
1985 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
1986 Type::tvoid, 5,
1987 build_filename_from_loc (se->loc),
1988 size_int (se->loc.linnum),
1989 lower, upper, length);
1992 upper = build_condition (TREE_TYPE (upper), condition,
1993 boundserr, upper);
1997 /* Need to ensure lower always gets evaluated first, as it may be a function
1998 call. Generates (lower, upper) - lower. */
1999 return fold_build2 (MINUS_EXPR, TREE_TYPE (upper),
2000 compound_expr (lower, upper), lower);
2003 /* Returns TRUE if array bounds checking code generation is turned on. */
2005 bool
2006 array_bounds_check (void)
2008 FuncDeclaration *fd;
2010 switch (global.params.useArrayBounds)
2012 case CHECKENABLEoff:
2013 return false;
2015 case CHECKENABLEon:
2016 return true;
2018 case CHECKENABLEsafeonly:
2019 /* For D2 safe functions only. */
2020 fd = d_function_chain->function;
2021 if (fd && fd->type->ty == TY::Tfunction)
2023 if (fd->type->isTypeFunction ()->trust == TRUST::safe)
2024 return true;
2026 return false;
2028 default:
2029 gcc_unreachable ();
2033 /* Returns TRUE if we terminate the program with a trap if an array bounds or
2034 contract check fails. */
2036 bool
2037 checkaction_trap_p (void)
2039 switch (global.params.checkAction)
2041 case CHECKACTION_D:
2042 case CHECKACTION_context:
2043 return false;
2045 case CHECKACTION_C:
2046 case CHECKACTION_halt:
2047 return true;
2049 default:
2050 gcc_unreachable ();
2054 /* Returns the TypeFunction class for Type T.
2055 Assumes T is already ->toBasetype(). */
2057 TypeFunction *
2058 get_function_type (Type *t)
2060 TypeFunction *tf = NULL;
2061 if (t->ty == TY::Tpointer)
2062 t = t->nextOf ()->toBasetype ();
2063 if (t->ty == TY::Tfunction)
2064 tf = t->isTypeFunction ();
2065 else if (t->ty == TY::Tdelegate)
2066 tf = t->isTypeDelegate ()->next->isTypeFunction ();
2067 return tf;
2070 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
2071 CALLER. In which case, CALLEE is being called through an alias that was
2072 passed to CALLER. */
2074 bool
2075 call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)
2077 if (!callee->isNested ())
2078 return false;
2080 if (caller->toParent () == callee->toParent ())
2081 return false;
2083 Dsymbol *dsym = callee;
2085 while (dsym)
2087 if (dsym->isTemplateInstance ())
2088 return false;
2089 else if (dsym->isFuncDeclaration () == caller)
2090 return false;
2091 dsym = dsym->toParent ();
2094 return true;
2097 /* Entry point for call routines. Builds a function call to FD.
2098 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
2100 tree
2101 d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)
2103 return d_build_call (get_function_type (fd->type),
2104 build_address (get_symbol_decl (fd)), object, arguments);
2107 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
2108 ARGUMENTS are evaluated in left to right order, saved and promoted
2109 before passing. */
2111 tree
2112 d_build_call (TypeFunction *tf, tree callable, tree object,
2113 Expressions *arguments)
2115 tree ctype = TREE_TYPE (callable);
2116 tree callee = callable;
2118 if (POINTER_TYPE_P (ctype))
2119 ctype = TREE_TYPE (ctype);
2120 else
2121 callee = build_address (callable);
2123 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));
2124 gcc_assert (tf != NULL);
2125 gcc_assert (tf->ty == TY::Tfunction);
2127 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)
2129 /* Front-end apparently doesn't check this. */
2130 if (TREE_CODE (callable) == FUNCTION_DECL)
2132 error ("need %<this%> to access member %qE", DECL_NAME (callable));
2133 return error_mark_node;
2136 /* Probably an internal error. */
2137 gcc_unreachable ();
2140 /* Build the argument list for the call. */
2141 vec <tree, va_gc> *args = NULL;
2142 tree saved_args = NULL_TREE;
2143 bool noreturn_call = false;
2145 /* If this is a delegate call or a nested function being called as
2146 a delegate, the object should not be NULL. */
2147 if (object != NULL_TREE)
2148 vec_safe_push (args, object);
2150 if (arguments)
2152 /* First pass, evaluated expanded tuples in function arguments. */
2153 for (size_t i = 0; i < arguments->length; ++i)
2155 Lagain:
2156 Expression *arg = (*arguments)[i];
2157 gcc_assert (arg->op != EXP::tuple);
2159 if (arg->op == EXP::comma)
2161 CommaExp *ce = arg->isCommaExp ();
2162 tree tce = build_expr (ce->e1);
2163 saved_args = compound_expr (saved_args, tce);
2164 (*arguments)[i] = ce->e2;
2165 goto Lagain;
2169 const size_t nparams = tf->parameterList.length ();
2170 /* if _arguments[] is the first argument. */
2171 const size_t varargs = tf->isDstyleVariadic ();
2173 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2174 for (size_t i = 0; i < arguments->length; ++i)
2176 Expression *arg = (*arguments)[i];
2177 tree targ = build_expr (arg);
2179 if (i - varargs < nparams && i >= varargs)
2181 /* Actual arguments for declared formal arguments. */
2182 Parameter *parg = tf->parameterList[i - varargs];
2183 targ = convert_for_argument (targ, parg);
2186 /* Don't pass empty aggregates by value. */
2187 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
2188 && TREE_CODE (targ) != CONSTRUCTOR)
2190 tree t = build_constructor (TREE_TYPE (targ), NULL);
2191 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
2194 /* Parameter is a struct or array passed by invisible reference. */
2195 if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
2197 Type *t = arg->type->toBasetype ();
2198 StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
2200 /* Nested structs also have ADDRESSABLE set, but if the type has
2201 neither a copy constructor nor a destructor available, then we
2202 need to take care of copying its value before passing it. */
2203 if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor))
2204 targ = force_target_expr (targ);
2206 targ = convert (build_reference_type (TREE_TYPE (targ)),
2207 build_address (targ));
2210 /* Type `noreturn` is a terminator, as no other arguments can possibly
2211 be evaluated after it. */
2212 if (TREE_TYPE (targ) == noreturn_type_node)
2213 noreturn_call = true;
2215 vec_safe_push (args, targ);
2219 /* Evaluate the callee before calling it. */
2220 if (TREE_SIDE_EFFECTS (callee))
2222 callee = d_save_expr (callee);
2223 saved_args = compound_expr (callee, saved_args);
2226 /* If we saw a `noreturn` parameter, any unreachable argument evaluations
2227 after it are discarded, as well as the function call itself. */
2228 if (noreturn_call)
2230 if (TREE_SIDE_EFFECTS (callee))
2231 saved_args = compound_expr (callee, saved_args);
2233 tree arg;
2234 unsigned int ix;
2236 FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
2237 saved_args = compound_expr (saved_args, arg);
2239 /* Add a stub result type for the expression. */
2240 tree result = build_zero_cst (TREE_TYPE (ctype));
2241 return compound_expr (saved_args, result);
2244 tree result = build_call_vec (TREE_TYPE (ctype), callee, args);
2245 SET_EXPR_LOCATION (result, input_location);
2247 result = maybe_expand_intrinsic (result);
2249 /* Return the value in a temporary slot so that it can be evaluated
2250 multiple times by the caller. */
2251 if (TREE_CODE (result) == CALL_EXPR
2252 && AGGREGATE_TYPE_P (TREE_TYPE (result))
2253 && TREE_ADDRESSABLE (TREE_TYPE (result)))
2255 CALL_EXPR_RETURN_SLOT_OPT (result) = true;
2256 result = force_target_expr (result);
2259 return compound_expr (saved_args, result);
2262 /* Build and return the correct call to fmod depending on TYPE.
2263 ARG0 and ARG1 are the arguments pass to the function. */
2265 tree
2266 build_float_modulus (tree type, tree arg0, tree arg1)
2268 tree fmodfn = NULL_TREE;
2269 tree basetype = type;
2271 if (COMPLEX_FLOAT_TYPE_P (basetype))
2272 basetype = TREE_TYPE (basetype);
2274 if (TYPE_MAIN_VARIANT (basetype) == double_type_node
2275 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)
2276 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);
2277 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node
2278 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)
2279 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);
2280 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node
2281 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)
2282 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);
2284 if (!fmodfn)
2286 error ("tried to perform floating-point modulo division on %qT", type);
2287 return error_mark_node;
2290 if (COMPLEX_FLOAT_TYPE_P (type))
2292 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);
2293 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);
2295 return complex_expr (type, re, im);
2298 if (SCALAR_FLOAT_TYPE_P (type))
2299 return build_call_expr (fmodfn, 2, arg0, arg1);
2301 /* Should have caught this above. */
2302 gcc_unreachable ();
2305 /* Build a function type whose first argument is a pointer to BASETYPE,
2306 which is to be used for the `vthis' context parameter for TYPE.
2307 The base type may be a record for member functions, or a void for
2308 nested functions and delegates. */
2310 tree
2311 build_vthis_function (tree basetype, tree type)
2313 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
2315 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),
2316 TYPE_ARG_TYPES (type));
2317 tree fntype = build_function_type (TREE_TYPE (type), argtypes);
2319 /* Copy volatile qualifiers from the original function type. */
2320 if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE)
2321 fntype = build_qualified_type (fntype, TYPE_QUAL_VOLATILE);
2323 if (RECORD_OR_UNION_TYPE_P (basetype))
2324 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);
2325 else
2326 gcc_assert (VOID_TYPE_P (basetype));
2328 return fntype;
2331 /* Raise an error at that the context pointer of the function or object SYM is
2332 not accessible from the current scope. */
2334 tree
2335 error_no_frame_access (Dsymbol *sym)
2337 error_at (input_location, "cannot get frame pointer to %qs",
2338 sym->toPrettyChars ());
2339 return null_pointer_node;
2342 /* If SYM is a nested function, return the static chain to be
2343 used when calling that function from the current function.
2345 If SYM is a nested class or struct, return the static chain
2346 to be used when creating an instance of the class from CFUN. */
2348 tree
2349 get_frame_for_symbol (Dsymbol *sym)
2351 FuncDeclaration *thisfd
2352 = d_function_chain ? d_function_chain->function : NULL;
2353 FuncDeclaration *fd = sym->isFuncDeclaration ();
2354 FuncDeclaration *fdparent = NULL;
2355 FuncDeclaration *fdoverride = NULL;
2357 if (fd != NULL)
2359 /* Check that the nested function is properly defined. */
2360 if (!fd->fbody)
2362 /* Should instead error on line that references `fd'. */
2363 error_at (make_location_t (fd->loc), "nested function missing body");
2364 return null_pointer_node;
2367 fdparent = fd->toParent2 ()->isFuncDeclaration ();
2369 /* Special case for __ensure and __require. */
2370 if ((fd->ident == Identifier::idPool ("__ensure")
2371 || fd->ident == Identifier::idPool ("__require"))
2372 && fdparent != thisfd)
2374 fdoverride = fdparent;
2375 fdparent = thisfd;
2378 else
2380 /* It's a class (or struct). NewExp codegen has already determined its
2381 outer scope is not another class, so it must be a function. */
2382 while (sym && !sym->isFuncDeclaration ())
2383 sym = sym->toParent2 ();
2385 fdparent = (FuncDeclaration *) sym;
2388 /* Not a nested function, there is no frame pointer to pass. */
2389 if (fdparent == NULL)
2391 /* Only delegate literals report as being nested, even if they are in
2392 global scope. */
2393 gcc_assert (fd && fd->isFuncLiteralDeclaration ());
2394 return null_pointer_node;
2397 gcc_assert (thisfd != NULL);
2399 if (thisfd != fdparent)
2401 /* If no frame pointer for this function. */
2402 if (!thisfd->vthis)
2404 error_at (make_location_t (sym->loc),
2405 "%qs is a nested function and cannot be accessed from %qs",
2406 fdparent->toPrettyChars (), thisfd->toPrettyChars ());
2407 return null_pointer_node;
2410 /* Make sure we can get the frame pointer to the outer function.
2411 Go up each nesting level until we find the enclosing function. */
2412 Dsymbol *dsym = thisfd;
2414 while (fd != dsym)
2416 /* Check if enclosing function is a function. */
2417 FuncDeclaration *fdp = dsym->isFuncDeclaration ();
2418 Dsymbol *parent = dsym->toParent2 ();
2420 if (fdp != NULL)
2422 if (fdparent == parent)
2423 break;
2425 gcc_assert (fdp->isNested () || fdp->vthis);
2426 dsym = parent;
2427 continue;
2430 /* Check if enclosed by an aggregate. That means the current
2431 function must be a member function of that aggregate. */
2432 AggregateDeclaration *adp = dsym->isAggregateDeclaration ();
2434 if (adp != NULL)
2436 if ((adp->isClassDeclaration () || adp->isStructDeclaration ())
2437 && fdparent == parent)
2438 break;
2441 /* No frame to outer function found. */
2442 if (!adp || !adp->isNested () || !adp->vthis)
2443 return error_no_frame_access (sym);
2445 dsym = parent;
2449 tree ffo = get_frameinfo (fdparent);
2450 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2452 tree frame_ref = get_framedecl (thisfd, fdparent);
2454 /* If `thisfd' is a derived member function, then `fdparent' is the
2455 overridden member function in the base class. Even if there's a
2456 closure environment, we should give the original stack data as the
2457 nested function frame. */
2458 if (fdoverride)
2460 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2461 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2462 gcc_assert (cdo && cd);
2464 int offset;
2465 if (cdo->isBaseOf (cd, &offset) && offset != 0)
2467 /* Generate a new frame to pass to the overriden function that
2468 has the `this' pointer adjusted. */
2469 gcc_assert (offset != OFFSET_RUNTIME);
2471 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2472 tree fields = TYPE_FIELDS (type);
2473 /* The `this' field comes immediately after the `__chain'. */
2474 tree thisfield = chain_index (1, fields);
2475 vec <constructor_elt, va_gc> *ve = NULL;
2477 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2478 frame_ref = build_deref (frame_ref);
2480 for (tree field = fields; field; field = DECL_CHAIN (field))
2482 tree value = component_ref (frame_ref, framefields);
2483 if (field == thisfield)
2484 value = build_offset (value, size_int (offset));
2486 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2487 framefields = DECL_CHAIN (framefields);
2490 frame_ref = build_address (build_constructor (type, ve));
2494 return frame_ref;
2497 return null_pointer_node;
2500 /* Return the parent function of a nested class or struct AD. */
2502 static FuncDeclaration *
2503 get_outer_function (AggregateDeclaration *ad)
2505 FuncDeclaration *fd = NULL;
2506 while (ad && ad->isNested ())
2508 Dsymbol *dsym = ad->toParent2 ();
2509 if ((fd = dsym->isFuncDeclaration ()))
2510 return fd;
2511 else
2512 ad = dsym->isAggregateDeclaration ();
2515 return NULL;
2518 /* Starting from the current function FD, try to find a suitable value of
2519 `this' in nested function instances. A suitable `this' value is an
2520 instance of OCD or a class that has OCD as a base. */
2522 static tree
2523 find_this_tree (ClassDeclaration *ocd)
2525 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2527 while (fd)
2529 AggregateDeclaration *ad = fd->isThis ();
2530 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;
2532 if (cd != NULL)
2534 if (ocd == cd)
2535 return get_decl_tree (fd->vthis);
2536 else if (ocd->isBaseOf (cd, NULL))
2537 return convert_expr (get_decl_tree (fd->vthis),
2538 cd->type, ocd->type);
2540 fd = get_outer_function (cd);
2541 continue;
2544 if (fd->isNested ())
2546 fd = fd->toParent2 ()->isFuncDeclaration ();
2547 continue;
2550 fd = NULL;
2553 return NULL_TREE;
2556 /* Retrieve the outer class/struct `this' value of DECL from
2557 the current function. */
2559 tree
2560 build_vthis (AggregateDeclaration *decl)
2562 ClassDeclaration *cd = decl->isClassDeclaration ();
2563 StructDeclaration *sd = decl->isStructDeclaration ();
2565 /* If an aggregate nested in a function has no methods and there are no
2566 other nested functions, any static chain created here will never be
2567 translated. Use a null pointer for the link in this case. */
2568 tree vthis_value = null_pointer_node;
2570 if (cd != NULL || sd != NULL)
2572 Dsymbol *outer = decl->toParent2 ();
2574 /* If the parent is a templated struct, the outer context is instead
2575 the enclosing symbol of where the instantiation happened. */
2576 if (outer->isStructDeclaration ())
2578 gcc_assert (outer->parent && outer->parent->isTemplateInstance ());
2579 outer = ((TemplateInstance *) outer->parent)->enclosing;
2582 /* For outer classes, get a suitable `this' value.
2583 For outer functions, get a suitable frame/closure pointer. */
2584 ClassDeclaration *cdo = outer->isClassDeclaration ();
2585 FuncDeclaration *fdo = outer->isFuncDeclaration ();
2587 if (cdo)
2589 vthis_value = find_this_tree (cdo);
2590 gcc_assert (vthis_value != NULL_TREE);
2592 else if (fdo)
2594 tree ffo = get_frameinfo (fdo);
2595 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)
2596 || fdo->hasNestedFrameRefs ())
2597 vthis_value = get_frame_for_symbol (decl);
2598 else if (cd != NULL)
2600 /* Classes nested in methods are allowed to access any outer
2601 class fields, use the function chain in this case. */
2602 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)
2603 vthis_value = get_decl_tree (fdo->vthis);
2606 else
2607 gcc_unreachable ();
2610 return vthis_value;
2613 /* Build the RECORD_TYPE that describes the function frame or closure type for
2614 the function FD. FFI is the tree holding all frame information. */
2616 static tree
2617 build_frame_type (tree ffi, FuncDeclaration *fd)
2619 if (FRAMEINFO_TYPE (ffi))
2620 return FRAMEINFO_TYPE (ffi);
2622 tree frame_rec_type = make_node (RECORD_TYPE);
2623 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.",
2624 fd->toPrettyChars (), NULL);
2625 TYPE_NAME (frame_rec_type) = get_identifier (name);
2626 free (name);
2628 tree fields = NULL_TREE;
2630 /* Function is a member or nested, so must have field for outer context. */
2631 if (fd->vthis)
2633 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
2634 get_identifier ("__chain"), ptr_type_node);
2635 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;
2636 fields = chainon (NULL_TREE, ptr_field);
2637 DECL_NONADDRESSABLE_P (ptr_field) = 1;
2640 /* The __ensure and __require are called directly, so never make the outer
2641 functions closure, but nevertheless could still be referencing parameters
2642 of the calling function non-locally. So we add all parameters with nested
2643 refs to the function frame, this should also mean overriding methods will
2644 have the same frame layout when inheriting a contract. */
2645 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2646 || (global.params.useOut == CHECKENABLEon && fd->fensure))
2648 if (fd->parameters)
2650 for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++)
2652 VarDeclaration *v = (*fd->parameters)[i];
2653 /* Remove if already in closureVars so can push to front. */
2654 size_t j = fd->closureVars.find (v);
2656 if (j < fd->closureVars.length)
2657 fd->closureVars.remove (j);
2659 fd->closureVars.insert (i, v);
2663 /* Also add hidden `this' to outer context. */
2664 if (fd->vthis)
2666 size_t i = fd->closureVars.find (fd->vthis);
2668 if (i < fd->closureVars.length)
2669 fd->closureVars.remove (i);
2671 fd->closureVars.insert (0, fd->vthis);
2675 for (size_t i = 0; i < fd->closureVars.length; i++)
2677 VarDeclaration *v = fd->closureVars[i];
2678 tree vsym = get_symbol_decl (v);
2679 tree ident = v->ident
2680 ? get_identifier (v->ident->toChars ()) : NULL_TREE;
2682 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,
2683 TREE_TYPE (vsym));
2684 SET_DECL_LANG_FRAME_FIELD (vsym, field);
2685 DECL_FIELD_CONTEXT (field) = frame_rec_type;
2686 fields = chainon (fields, field);
2687 TREE_USED (vsym) = 1;
2689 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
2690 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
2691 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
2693 if (DECL_LANG_NRVO (vsym))
2695 /* Store the nrvo variable in the frame by reference. */
2696 TREE_TYPE (field) = build_reference_type (TREE_TYPE (field));
2698 /* Can't do nrvo if the variable is put in a closure, since what the
2699 return slot points to may no longer exist. */
2700 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi));
2703 if (FRAMEINFO_IS_CLOSURE (ffi))
2705 /* Because the value needs to survive the end of the scope. */
2706 if ((v->edtor && (v->storage_class & STCparameter))
2707 || v->needsScopeDtor ())
2708 error_at (make_location_t (v->loc),
2709 "has scoped destruction, cannot build closure");
2713 TYPE_FIELDS (frame_rec_type) = fields;
2714 TYPE_READONLY (frame_rec_type) = 1;
2715 TYPE_CXX_ODR_P (frame_rec_type) = 1;
2716 layout_type (frame_rec_type);
2717 d_keep (frame_rec_type);
2719 return frame_rec_type;
2722 /* Closures are implemented by taking the local variables that
2723 need to survive the scope of the function, and copying them
2724 into a GC allocated chuck of memory. That chunk, called the
2725 closure here, is inserted into the linked list of stack
2726 frames instead of the usual stack frame.
2728 If a closure is not required, but FD still needs a frame to lower
2729 nested refs, then instead build custom static chain decl on stack. */
2731 void
2732 build_closure (FuncDeclaration *fd)
2734 tree ffi = get_frameinfo (fd);
2736 if (!FRAMEINFO_CREATES_FRAME (ffi))
2737 return;
2739 tree type = FRAMEINFO_TYPE (ffi);
2740 gcc_assert (COMPLETE_TYPE_P (type));
2742 tree decl, decl_ref;
2744 if (FRAMEINFO_IS_CLOSURE (ffi))
2746 decl = build_local_temp (build_pointer_type (type));
2747 DECL_NAME (decl) = get_identifier ("__closptr");
2748 decl_ref = build_deref (decl);
2750 /* Allocate memory for closure. */
2751 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
2752 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
2754 tree init_exp = build_assign (INIT_EXPR, decl,
2755 build_nop (TREE_TYPE (decl), init));
2756 add_stmt (init_exp);
2758 else
2760 decl = build_local_temp (type);
2761 DECL_NAME (decl) = get_identifier ("__frame");
2762 decl_ref = decl;
2765 /* Set the first entry to the parent closure/frame, if any. */
2766 if (fd->vthis)
2768 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));
2769 tree chain_expr = modify_expr (chain_field,
2770 d_function_chain->static_chain);
2771 add_stmt (chain_expr);
2774 /* Copy parameters that are referenced nonlocally. */
2775 for (size_t i = 0; i < fd->closureVars.length; i++)
2777 VarDeclaration *v = fd->closureVars[i];
2778 tree vsym = get_symbol_decl (v);
2780 if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym))
2781 continue;
2783 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));
2785 /* Variable is an alias for the NRVO slot, store the reference. */
2786 if (DECL_LANG_NRVO (vsym))
2787 vsym = build_address (DECL_LANG_NRVO (vsym));
2789 tree expr = modify_expr (field, vsym);
2790 add_stmt (expr);
2793 if (!FRAMEINFO_IS_CLOSURE (ffi))
2794 decl = build_address (decl);
2796 d_function_chain->static_chain = decl;
2799 /* Return the frame of FD. This could be a static chain or a closure
2800 passed via the hidden `this' pointer. */
2802 tree
2803 get_frameinfo (FuncDeclaration *fd)
2805 tree fds = get_symbol_decl (fd);
2806 if (DECL_LANG_FRAMEINFO (fds))
2807 return DECL_LANG_FRAMEINFO (fds);
2809 tree ffi = make_node (FUNCFRAME_INFO);
2811 DECL_LANG_FRAMEINFO (fds) = ffi;
2813 if (fd->needsClosure ())
2815 /* Set-up a closure frame, this will be allocated on the heap. */
2816 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2817 FRAMEINFO_IS_CLOSURE (ffi) = 1;
2819 else if (fd->hasNestedFrameRefs ())
2821 /* Functions with nested refs must create a static frame for local
2822 variables to be referenced from. */
2823 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2825 else
2827 /* For nested functions, default to creating a frame. Even if there are
2828 no fields to populate the frame, create it anyway, as this will be
2829 used as the record type instead of `void*` for the this parameter. */
2830 if (fd->vthis && fd->vthis->type == Type::tvoidptr)
2831 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2833 /* In checkNestedReference, references from contracts are not added to the
2834 closureVars array, so assume all parameters referenced. */
2835 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2836 || (global.params.useOut == CHECKENABLEon && fd->fensure))
2837 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2839 /* If however `fd` is nested (deeply) in a function that creates a
2840 closure, then `fd` instead inherits that closure via hidden vthis
2841 pointer, and doesn't create a stack frame at all. */
2842 FuncDeclaration *ff = fd;
2844 while (ff)
2846 tree ffo = get_frameinfo (ff);
2848 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))
2850 gcc_assert (FRAMEINFO_TYPE (ffo));
2851 FRAMEINFO_CREATES_FRAME (ffi) = 0;
2852 FRAMEINFO_STATIC_CHAIN (ffi) = 1;
2853 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);
2854 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));
2855 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);
2856 break;
2859 /* Stop looking if no frame pointer for this function. */
2860 if (ff->vthis == NULL)
2861 break;
2863 AggregateDeclaration *ad = ff->isThis ();
2864 if (ad && ad->isNested ())
2866 while (ad->isNested ())
2868 Dsymbol *d = ad->toParent2 ();
2869 ad = d->isAggregateDeclaration ();
2870 ff = d->isFuncDeclaration ();
2872 if (ad == NULL)
2873 break;
2876 else
2877 ff = ff->toParent2 ()->isFuncDeclaration ();
2881 /* Build type now as may be referenced from another module. */
2882 if (FRAMEINFO_CREATES_FRAME (ffi))
2883 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);
2885 return ffi;
2888 /* Return a pointer to the frame/closure block of OUTER
2889 so can be accessed from the function INNER. */
2891 tree
2892 get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
2894 tree result = d_function_chain->static_chain;
2895 FuncDeclaration *fd = inner;
2897 while (fd && fd != outer)
2899 /* Parent frame link is the first field. */
2900 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))
2901 result = indirect_ref (ptr_type_node, result);
2903 if (fd->isNested ())
2904 fd = fd->toParent2 ()->isFuncDeclaration ();
2905 /* The frame/closure record always points to the outer function's
2906 frame, even if there are intervening nested classes or structs.
2907 So, we can just skip over these. */
2908 else
2909 fd = get_outer_function (fd->isThis ());
2912 if (fd != outer)
2913 return error_no_frame_access (outer);
2915 /* Go get our frame record. */
2916 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
2918 if (frame_type != NULL_TREE)
2920 result = build_nop (build_pointer_type (frame_type), result);
2921 return result;
2923 else
2925 error_at (make_location_t (inner->loc),
2926 "forward reference to frame of %qs", outer->toChars ());
2927 return null_pointer_node;