testsuite: Use posix_memalign on AIX for tsvc
[official-gcc.git] / gcc / d / d-codegen.cc
blobe63365055d37b2c4dd3afc5b64d2cf2d79e357d0
1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
2 Copyright (C) 2006-2021 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 != LINKd)
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 == 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, LINKd);
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 == 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, LINKd);
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 Tsarray:
323 return size_int (tb->isTypeSArray ()->dim->toUInteger ());
325 case 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 == 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 == 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 == 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 == 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 == Tcomplex80 || tb->ty == Tfloat80 || tb->ty == Timaginary80)
886 && target.realpad != 0)
887 return false;
889 if (offset <= vd->offset)
891 /* There's a hole in the struct. */
892 if (offset != vd->offset)
893 return false;
895 offset += vd->type->size ();
899 /* Any trailing padding may not be zero. */
900 if (offset < sd->structsize)
901 return false;
903 return true;
906 /* Build a floating-point identity comparison between T1 and T2, ignoring any
907 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
909 tree
910 build_float_identity (tree_code code, tree t1, tree t2)
912 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
913 tree result = build_memcmp_call (build_address (t1),
914 build_address (t2), size);
915 return build_boolop (code, result, integer_zero_node);
918 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
919 CODE is the EQ_EXPR or NE_EXPR comparison. */
921 static tree
922 lower_struct_comparison (tree_code code, StructDeclaration *sd,
923 tree t1, tree t2)
925 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
926 tree tmemcmp = NULL_TREE;
928 /* We can skip the compare if the structs are empty. */
929 if (sd->fields.length == 0)
931 tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node);
932 if (TREE_SIDE_EFFECTS (t2))
933 tmemcmp = compound_expr (t2, tmemcmp);
934 if (TREE_SIDE_EFFECTS (t1))
935 tmemcmp = compound_expr (t1, tmemcmp);
937 return tmemcmp;
940 /* Let back-end take care of union comparisons. */
941 if (sd->isUnionDeclaration ())
943 tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
944 size_int (sd->structsize));
945 return build_boolop (code, tmemcmp, integer_zero_node);
948 for (size_t i = 0; i < sd->fields.length; i++)
950 VarDeclaration *vd = sd->fields[i];
951 Type *type = vd->type->toBasetype ();
952 tree sfield = get_symbol_decl (vd);
954 tree t1ref = component_ref (t1, sfield);
955 tree t2ref = component_ref (t2, sfield);
956 tree tcmp;
958 if (TypeStruct *ts = type->isTypeStruct ())
960 /* Compare inner data structures. */
961 tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref);
963 else if (type->ty != Tvector && type->isintegral ())
965 /* Integer comparison, no special handling required. */
966 tcmp = build_boolop (code, t1ref, t2ref);
968 else if (type->ty != Tvector && type->isfloating ())
970 /* Floating-point comparison, don't compare padding in type. */
971 if (!type->iscomplex ())
972 tcmp = build_float_identity (code, t1ref, t2ref);
973 else
975 tree req = build_float_identity (code, real_part (t1ref),
976 real_part (t2ref));
977 tree ieq = build_float_identity (code, imaginary_part (t1ref),
978 imaginary_part (t2ref));
980 tcmp = build_boolop (tcode, req, ieq);
983 else
985 tree stype = build_ctype (type);
986 opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));
988 if (mode.exists ())
990 /* Compare field bits as their corresponding integer type.
991 *((T*) &t1) == *((T*) &t2) */
992 tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1);
994 if (tmode == NULL_TREE)
995 tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
997 t1ref = build_vconvert (tmode, t1ref);
998 t2ref = build_vconvert (tmode, t2ref);
1000 tcmp = build_boolop (code, t1ref, t2ref);
1002 else
1004 /* Simple memcmp between types. */
1005 tcmp = build_memcmp_call (build_address (t1ref),
1006 build_address (t2ref),
1007 TYPE_SIZE_UNIT (stype));
1008 tcmp = build_boolop (code, tcmp, integer_zero_node);
1012 tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp;
1015 return tmemcmp;
1019 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
1020 If possible, use memcmp, otherwise field-by-field comparison is done.
1021 CODE is the EQ_EXPR or NE_EXPR comparison. */
1023 tree
1024 build_struct_comparison (tree_code code, StructDeclaration *sd,
1025 tree t1, tree t2)
1027 /* We can skip the compare if the structs are empty. */
1028 if (sd->fields.length == 0)
1030 tree exp = build_boolop (code, integer_zero_node, integer_zero_node);
1031 if (TREE_SIDE_EFFECTS (t2))
1032 exp = compound_expr (t2, exp);
1033 if (TREE_SIDE_EFFECTS (t1))
1034 exp = compound_expr (t1, exp);
1036 return exp;
1039 /* Make temporaries to prevent multiple evaluations. */
1040 tree t1init = stabilize_expr (&t1);
1041 tree t2init = stabilize_expr (&t2);
1042 tree result;
1044 t1 = d_save_expr (t1);
1045 t2 = d_save_expr (t2);
1047 /* Bitwise comparison of structs not returned in memory may not work
1048 due to data holes loosing its zero padding upon return.
1049 As a heuristic, small structs are not compared using memcmp either. */
1050 if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd))
1051 result = lower_struct_comparison (code, sd, t1, t2);
1052 else
1054 /* Do bit compare of structs. */
1055 tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
1056 size_int (sd->structsize));
1057 result = build_boolop (code, tmemcmp, integer_zero_node);
1060 return compound_expr (compound_expr (t1init, t2init), result);
1063 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1064 The pointer references are T1 and T2, and the element type is SD.
1065 CODE is the EQ_EXPR or NE_EXPR comparison. */
1067 tree
1068 build_array_struct_comparison (tree_code code, StructDeclaration *sd,
1069 tree length, tree t1, tree t2)
1071 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
1073 /* Build temporary for the result of the comparison.
1074 Initialize as either 0 or 1 depending on operation. */
1075 tree result = build_local_temp (d_bool_type);
1076 tree init = build_boolop (code, integer_zero_node, integer_zero_node);
1077 add_stmt (build_assign (INIT_EXPR, result, init));
1079 /* Cast pointer-to-array to pointer-to-struct. */
1080 tree ptrtype = build_ctype (sd->type->pointerTo ());
1081 tree lentype = TREE_TYPE (length);
1083 push_binding_level (level_block);
1084 push_stmt_list ();
1086 /* Build temporary locals for length and pointers. */
1087 tree t = build_local_temp (size_type_node);
1088 add_stmt (build_assign (INIT_EXPR, t, length));
1089 length = t;
1091 t = build_local_temp (ptrtype);
1092 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1)));
1093 t1 = t;
1095 t = build_local_temp (ptrtype);
1096 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2)));
1097 t2 = t;
1099 /* Build loop for comparing each element. */
1100 push_stmt_list ();
1102 /* Exit logic for the loop.
1103 if (length == 0 || result OP 0) break; */
1104 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1105 t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,
1106 boolean_false_node));
1107 t = build1 (EXIT_EXPR, void_type_node, t);
1108 add_stmt (t);
1110 /* Do comparison, caching the value.
1111 result = result OP (*t1 == *t2); */
1112 t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2));
1113 t = build_boolop (tcode, result, t);
1114 t = modify_expr (result, t);
1115 add_stmt (t);
1117 /* Move both pointers to next element position.
1118 t1++, t2++; */
1119 tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)));
1120 t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size);
1121 add_stmt (t);
1122 t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size);
1123 add_stmt (t);
1125 /* Decrease loop counter.
1126 length -= 1; */
1127 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1128 d_convert (lentype, integer_one_node));
1129 add_stmt (t);
1131 /* Pop statements and finish loop. */
1132 tree body = pop_stmt_list ();
1133 add_stmt (build1 (LOOP_EXPR, void_type_node, body));
1135 /* Wrap it up into a bind expression. */
1136 tree stmt_list = pop_stmt_list ();
1137 tree block = pop_binding_level ();
1139 body = build3 (BIND_EXPR, void_type_node,
1140 BLOCK_VARS (block), stmt_list, block);
1142 return compound_expr (body, result);
1145 /* Build a constructor for a variable of aggregate type TYPE using the
1146 initializer INIT, an ordered flat list of fields and values provided
1147 by the frontend. The returned constructor should be a value that
1148 matches the layout of TYPE. */
1150 tree
1151 build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
1153 /* If the initializer was empty, use default zero initialization. */
1154 if (vec_safe_is_empty (init))
1155 return build_constructor (type, NULL);
1157 /* Struct literals can be seen for special enums representing `_Complex',
1158 make sure to reinterpret the literal as the correct type. */
1159 if (COMPLEX_FLOAT_TYPE_P (type))
1161 gcc_assert (vec_safe_length (init) == 2);
1162 return build_complex (type, (*init)[0].value, (*init)[1].value);
1165 vec <constructor_elt, va_gc> *ve = NULL;
1166 HOST_WIDE_INT offset = 0;
1167 bool constant_p = true;
1168 bool finished = false;
1170 /* Walk through each field, matching our initializer list. */
1171 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1173 bool is_initialized = false;
1174 tree value;
1176 if (DECL_NAME (field) == NULL_TREE
1177 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1178 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1180 /* Search all nesting aggregates, if nothing is found, then
1181 this will return an empty initializer to fill the hole. */
1182 value = build_struct_literal (TREE_TYPE (field), init);
1184 if (!initializer_zerop (value))
1185 is_initialized = true;
1187 else
1189 /* Search for the value to initialize the next field. Once found,
1190 pop it from the init list so we don't look at it again. */
1191 unsigned HOST_WIDE_INT idx;
1192 tree index;
1194 FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value)
1196 /* If the index is NULL, then just assign it to the next field.
1197 This comes from layout_typeinfo(), which generates a flat
1198 list of values that we must shape into the record type. */
1199 if (index == field || index == NULL_TREE)
1201 init->ordered_remove (idx);
1202 if (!finished)
1203 is_initialized = true;
1204 break;
1209 if (is_initialized)
1211 HOST_WIDE_INT fieldpos = int_byte_position (field);
1212 gcc_assert (value != NULL_TREE);
1214 /* Must not initialize fields that overlap. */
1215 if (fieldpos < offset)
1217 /* Find the nearest user defined type and field. */
1218 tree vtype = type;
1219 while (ANON_AGGR_TYPE_P (vtype))
1220 vtype = TYPE_CONTEXT (vtype);
1222 tree vfield = field;
1223 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield))
1224 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield)))
1225 vfield = TYPE_FIELDS (TREE_TYPE (vfield));
1227 /* Must not generate errors for compiler generated fields. */
1228 gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield));
1229 error ("overlapping initializer for field %qT.%qD",
1230 TYPE_NAME (vtype), DECL_NAME (vfield));
1233 if (!TREE_CONSTANT (value))
1234 constant_p = false;
1236 CONSTRUCTOR_APPEND_ELT (ve, field, value);
1238 /* For unions, only the first field is initialized, any other field
1239 initializers found for this union are drained and ignored. */
1240 if (TREE_CODE (type) == UNION_TYPE)
1241 finished = true;
1244 /* Move offset to the next position in the struct. */
1245 if (TREE_CODE (type) == RECORD_TYPE)
1247 offset = int_byte_position (field)
1248 + int_size_in_bytes (TREE_TYPE (field));
1251 /* If all initializers have been assigned, there's nothing else to do. */
1252 if (vec_safe_is_empty (init))
1253 break;
1256 /* Ensure that we have consumed all values. */
1257 gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
1259 tree ctor = build_constructor (type, ve);
1261 if (constant_p)
1262 TREE_CONSTANT (ctor) = 1;
1264 return ctor;
1267 /* Given the TYPE of an anonymous field inside T, return the
1268 FIELD_DECL for the field. If not found return NULL_TREE.
1269 Because anonymous types can nest, we must also search all
1270 anonymous fields that are directly reachable. */
1272 static tree
1273 lookup_anon_field (tree t, tree type)
1275 t = TYPE_MAIN_VARIANT (t);
1277 for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
1279 if (DECL_NAME (field) == NULL_TREE)
1281 /* If we find it directly, return the field. */
1282 if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
1283 return field;
1285 /* Otherwise, it could be nested, search harder. */
1286 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1287 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1289 tree subfield = lookup_anon_field (TREE_TYPE (field), type);
1290 if (subfield)
1291 return subfield;
1296 return NULL_TREE;
1299 /* Builds OBJECT.FIELD component reference. */
1301 tree
1302 component_ref (tree object, tree field)
1304 if (error_operand_p (object) || error_operand_p (field))
1305 return error_mark_node;
1307 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1309 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1310 tree init = stabilize_expr (&object);
1312 /* If the FIELD is from an anonymous aggregate, generate a reference
1313 to the anonymous data member, and recur to find FIELD. */
1314 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field)))
1316 tree anonymous_field = lookup_anon_field (TREE_TYPE (object),
1317 DECL_CONTEXT (field));
1318 object = component_ref (object, anonymous_field);
1321 tree result = fold_build3_loc (input_location, COMPONENT_REF,
1322 TREE_TYPE (field), object, field, NULL_TREE);
1324 return compound_expr (init, result);
1327 /* Build an assignment expression of lvalue LHS from value RHS.
1328 CODE is the code for a binary operator that we use to combine
1329 the old value of LHS with RHS to get the new value. */
1331 tree
1332 build_assign (tree_code code, tree lhs, tree rhs)
1334 tree result;
1335 tree init = stabilize_expr (&lhs);
1336 init = compound_expr (init, stabilize_expr (&rhs));
1338 /* If initializing the LHS using a function that returns via NRVO. */
1339 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
1340 && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
1341 && aggregate_value_p (TREE_TYPE (rhs), rhs))
1343 /* Mark as addressable here, which should ensure the return slot is the
1344 address of the LHS expression, taken care of by back-end. */
1345 d_mark_addressable (lhs);
1346 CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
1348 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
1349 else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs))
1350 && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR)
1352 /* LHS may be referenced by the RHS expression, so force a temporary. */
1353 rhs = force_target_expr (rhs);
1356 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1357 if (TREE_CODE (rhs) == TARGET_EXPR)
1359 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1360 since that would cause the LHS to be constructed twice. */
1361 if (code != INIT_EXPR)
1363 init = compound_expr (init, rhs);
1364 result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs));
1366 else
1368 d_mark_addressable (lhs);
1369 TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs,
1370 TARGET_EXPR_INITIAL (rhs));
1371 result = rhs;
1374 else
1376 /* Simple assignment. */
1377 result = fold_build2_loc (input_location, code,
1378 TREE_TYPE (lhs), lhs, rhs);
1381 return compound_expr (init, result);
1384 /* Build an assignment expression of lvalue LHS from value RHS. */
1386 tree
1387 modify_expr (tree lhs, tree rhs)
1389 return build_assign (MODIFY_EXPR, lhs, rhs);
1392 /* Return EXP represented as TYPE. */
1394 tree
1395 build_nop (tree type, tree exp)
1397 if (error_operand_p (exp))
1398 return exp;
1400 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1401 tree init = stabilize_expr (&exp);
1402 exp = fold_build1_loc (input_location, NOP_EXPR, type, exp);
1404 return compound_expr (init, exp);
1407 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1408 except that EXP is type-punned, rather than a straight-forward cast. */
1410 tree
1411 build_vconvert (tree type, tree exp)
1413 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1414 makes sure this works for vector-to-array viewing, or if EXP ends up being
1415 used as the LHS of a MODIFY_EXPR. */
1416 return indirect_ref (type, build_address (exp));
1419 /* Maybe warn about ARG being an address that can never be null. */
1421 static void
1422 warn_for_null_address (tree arg)
1424 if (TREE_CODE (arg) == ADDR_EXPR
1425 && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0)))
1426 warning (OPT_Waddress,
1427 "the address of %qD will never be %<null%>",
1428 TREE_OPERAND (arg, 0));
1431 /* Build a boolean ARG0 op ARG1 expression. */
1433 tree
1434 build_boolop (tree_code code, tree arg0, tree arg1)
1436 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1437 so need to remove all side effects incase its address is taken. */
1438 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0)))
1439 arg0 = d_save_expr (arg0);
1440 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1)))
1441 arg1 = d_save_expr (arg1);
1443 if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1)))
1445 /* Build a vector comparison.
1446 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1447 tree type = TREE_TYPE (arg0);
1448 tree cmptype = truth_type_for (type);
1449 tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1);
1451 return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp,
1452 build_minus_one_cst (type),
1453 build_zero_cst (type));
1456 if (code == EQ_EXPR || code == NE_EXPR)
1458 /* Check if comparing the address of a variable to null. */
1459 if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1))
1460 warn_for_null_address (arg0);
1461 if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0))
1462 warn_for_null_address (arg1);
1465 return fold_build2_loc (input_location, code, d_bool_type,
1466 arg0, d_convert (TREE_TYPE (arg0), arg1));
1469 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1470 arguments to the conditional expression. */
1472 tree
1473 build_condition (tree type, tree arg0, tree arg1, tree arg2)
1475 if (arg1 == void_node)
1476 arg1 = build_empty_stmt (input_location);
1478 if (arg2 == void_node)
1479 arg2 = build_empty_stmt (input_location);
1481 return fold_build3_loc (input_location, COND_EXPR,
1482 type, arg0, arg1, arg2);
1485 tree
1486 build_vcondition (tree arg0, tree arg1, tree arg2)
1488 return build_condition (void_type_node, arg0, arg1, arg2);
1491 /* Build a compound expr to join ARG0 and ARG1 together. */
1493 tree
1494 compound_expr (tree arg0, tree arg1)
1496 if (arg1 == NULL_TREE)
1497 return arg0;
1499 if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0))
1500 return arg1;
1502 /* Remove intermediate expressions that have no side-effects. */
1503 while (TREE_CODE (arg0) == COMPOUND_EXPR
1504 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
1505 arg0 = TREE_OPERAND (arg0, 0);
1507 if (TREE_CODE (arg1) == TARGET_EXPR)
1509 /* If the rhs is a TARGET_EXPR, then build the compound expression
1510 inside the target_expr's initializer. This helps the compiler
1511 to eliminate unnecessary temporaries. */
1512 tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1));
1513 TARGET_EXPR_INITIAL (arg1) = init;
1515 return arg1;
1518 return fold_build2_loc (input_location, COMPOUND_EXPR,
1519 TREE_TYPE (arg1), arg0, arg1);
1522 /* Build a return expression. */
1524 tree
1525 return_expr (tree ret)
1527 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary
1528 in TARGET_EXPR_SLOT. */
1529 if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR)
1531 tree exp = TARGET_EXPR_INITIAL (ret);
1532 tree init = stabilize_expr (&exp);
1534 exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp);
1535 TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp);
1537 return ret;
1540 return fold_build1_loc (input_location, RETURN_EXPR,
1541 void_type_node, ret);
1544 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1546 tree
1547 size_mult_expr (tree arg0, tree arg1)
1549 return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1550 d_convert (size_type_node, arg0),
1551 d_convert (size_type_node, arg1));
1555 /* Return the real part of CE, which should be a complex expression. */
1557 tree
1558 real_part (tree ce)
1560 return fold_build1_loc (input_location, REALPART_EXPR,
1561 TREE_TYPE (TREE_TYPE (ce)), ce);
1564 /* Return the imaginary part of CE, which should be a complex expression. */
1566 tree
1567 imaginary_part (tree ce)
1569 return fold_build1_loc (input_location, IMAGPART_EXPR,
1570 TREE_TYPE (TREE_TYPE (ce)), ce);
1573 /* Build a complex expression of type TYPE using RE and IM. */
1575 tree
1576 complex_expr (tree type, tree re, tree im)
1578 return fold_build2_loc (input_location, COMPLEX_EXPR,
1579 type, re, im);
1582 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1583 The back-end requires this cast in many cases. */
1585 tree
1586 indirect_ref (tree type, tree exp)
1588 if (error_operand_p (exp))
1589 return exp;
1591 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1592 tree init = stabilize_expr (&exp);
1594 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
1595 exp = fold_build1 (INDIRECT_REF, type, exp);
1596 else
1598 exp = build_nop (build_pointer_type (type), exp);
1599 exp = build_deref (exp);
1602 return compound_expr (init, exp);
1605 /* Returns indirect reference of EXP, which must be a pointer type. */
1607 tree
1608 build_deref (tree exp)
1610 if (error_operand_p (exp))
1611 return exp;
1613 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1614 tree init = stabilize_expr (&exp);
1616 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
1618 if (TREE_CODE (exp) == ADDR_EXPR)
1619 exp = TREE_OPERAND (exp, 0);
1620 else
1621 exp = build_fold_indirect_ref (exp);
1623 return compound_expr (init, exp);
1626 /* Builds pointer offset expression PTR[INDEX]. */
1628 tree
1629 build_array_index (tree ptr, tree index)
1631 if (error_operand_p (ptr) || error_operand_p (index))
1632 return error_mark_node;
1634 tree ptr_type = TREE_TYPE (ptr);
1635 tree target_type = TREE_TYPE (ptr_type);
1637 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1638 TYPE_UNSIGNED (sizetype));
1640 /* Array element size. */
1641 tree size_exp = size_in_bytes (target_type);
1643 if (integer_zerop (size_exp) || integer_onep (size_exp))
1645 /* Array of void or bytes -- No need to multiply. */
1646 index = fold_convert (type, index);
1648 else
1650 index = d_convert (type, index);
1651 index = fold_build2 (MULT_EXPR, TREE_TYPE (index),
1652 index, d_convert (TREE_TYPE (index), size_exp));
1653 index = fold_convert (type, index);
1656 if (integer_zerop (index))
1657 return ptr;
1659 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);
1662 /* Builds pointer offset expression *(PTR OP OFFSET)
1663 OP could be a plus or minus expression. */
1665 tree
1666 build_offset_op (tree_code op, tree ptr, tree offset)
1668 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);
1670 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1671 TYPE_UNSIGNED (sizetype));
1672 offset = fold_convert (type, offset);
1674 if (op == MINUS_EXPR)
1675 offset = fold_build1 (NEGATE_EXPR, type, offset);
1677 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);
1680 /* Builds pointer offset expression *(PTR + OFFSET). */
1682 tree
1683 build_offset (tree ptr, tree offset)
1685 return build_offset_op (PLUS_EXPR, ptr, offset);
1688 tree
1689 build_memref (tree type, tree ptr, tree offset)
1691 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));
1694 /* Create a tree node to set multiple elements to a single value. */
1696 tree
1697 build_array_set (tree ptr, tree length, tree value)
1699 tree ptrtype = TREE_TYPE (ptr);
1700 tree lentype = TREE_TYPE (length);
1702 push_binding_level (level_block);
1703 push_stmt_list ();
1705 /* Build temporary locals for length and ptr, and maybe value. */
1706 tree t = build_local_temp (size_type_node);
1707 add_stmt (build_assign (INIT_EXPR, t, length));
1708 length = t;
1710 t = build_local_temp (ptrtype);
1711 add_stmt (build_assign (INIT_EXPR, t, ptr));
1712 ptr = t;
1714 if (TREE_SIDE_EFFECTS (value))
1716 t = build_local_temp (TREE_TYPE (value));
1717 add_stmt (build_assign (INIT_EXPR, t, value));
1718 value = t;
1721 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1722 push_stmt_list ();
1724 /* Exit logic for the loop.
1725 if (length == 0) break; */
1726 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1727 t = build1 (EXIT_EXPR, void_type_node, t);
1728 add_stmt (t);
1730 /* Assign value to the current pointer position.
1731 *ptr = value; */
1732 t = modify_expr (build_deref (ptr), value);
1733 add_stmt (t);
1735 /* Move pointer to next element position.
1736 ptr++; */
1737 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));
1738 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));
1739 add_stmt (t);
1741 /* Decrease loop counter.
1742 length -= 1; */
1743 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1744 d_convert (lentype, integer_one_node));
1745 add_stmt (t);
1747 /* Pop statements and finish loop. */
1748 tree loop_body = pop_stmt_list ();
1749 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));
1751 /* Wrap it up into a bind expression. */
1752 tree stmt_list = pop_stmt_list ();
1753 tree block = pop_binding_level ();
1755 return build3 (BIND_EXPR, void_type_node,
1756 BLOCK_VARS (block), stmt_list, block);
1760 /* Build an array of type TYPE where all the elements are VAL. */
1762 tree
1763 build_array_from_val (Type *type, tree val)
1765 tree etype = build_ctype (type->nextOf ());
1767 /* Initializing a multidimensional array. */
1768 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)
1769 val = build_array_from_val (type->nextOf (), val);
1771 size_t dims = type->isTypeSArray ()->dim->toInteger ();
1772 vec <constructor_elt, va_gc> *elms = NULL;
1773 vec_safe_reserve (elms, dims);
1775 val = d_convert (etype, val);
1777 for (size_t i = 0; i < dims; i++)
1778 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
1780 return build_constructor (build_ctype (type), elms);
1783 /* Build a static array of type TYPE from an array of EXPS.
1784 If CONST_P is true, then all elements in EXPS are constants. */
1786 tree
1787 build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
1789 /* Build a CONSTRUCTOR from all expressions. */
1790 vec <constructor_elt, va_gc> *elms = NULL;
1791 vec_safe_reserve (elms, exps->length);
1793 Type *etype = type->nextOf ();
1794 tree satype = make_array_type (etype, exps->length);
1796 for (size_t i = 0; i < exps->length; i++)
1798 Expression *expr = (*exps)[i];
1799 tree t = build_expr (expr, const_p);
1800 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1801 convert_expr (t, expr->type, etype));
1804 /* Create a new temporary to store the array. */
1805 tree var = build_local_temp (satype);
1807 /* Fill any alignment holes with zeroes. */
1808 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
1809 tree init = NULL;
1810 if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ()))
1811 init = build_memset_call (var);
1813 /* Initialize the temporary. */
1814 tree assign = modify_expr (var, build_constructor (satype, elms));
1815 return compound_expr (compound_expr (init, assign), var);
1819 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1821 tree
1822 void_okay_p (tree t)
1824 tree type = TREE_TYPE (t);
1826 if (VOID_TYPE_P (TREE_TYPE (type)))
1828 tree totype = build_ctype (Type::tuns8->pointerTo ());
1829 return fold_convert (totype, t);
1832 return t;
1835 /* Builds a STRING_CST representing the filename of location LOC. When the
1836 location is not valid, the name of the source module is used instead. */
1838 static tree
1839 build_filename_from_loc (const Loc &loc)
1841 const char *filename = loc.filename
1842 ? loc.filename : d_function_chain->module->srcfile->toChars ();
1844 unsigned length = strlen (filename);
1845 tree str = build_string (length, filename);
1846 TREE_TYPE (str) = make_array_type (Type::tchar, length + 1);
1848 return build_address (str);
1851 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1852 an assert check fails. When calling the msg variant functions, MSG is the
1853 error message supplied by the user. */
1855 tree
1856 build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
1858 tree file;
1859 tree line = size_int (loc.linnum);
1861 switch (libcall)
1863 case LIBCALL_ASSERT_MSG:
1864 case LIBCALL_UNITTEST_MSG:
1865 case LIBCALL_SWITCH_ERROR:
1866 /* File location is passed as a D string. */
1867 if (loc.filename)
1869 unsigned len = strlen (loc.filename);
1870 tree str = build_string (len, loc.filename);
1871 TREE_TYPE (str) = make_array_type (Type::tchar, len);
1873 file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
1874 size_int (len), build_address (str));
1876 else
1877 file = null_array_node;
1878 break;
1880 case LIBCALL_ASSERTP:
1881 case LIBCALL_UNITTESTP:
1882 file = build_filename_from_loc (loc);
1883 break;
1885 default:
1886 gcc_unreachable ();
1890 if (msg != NULL_TREE)
1891 return build_libcall (libcall, Type::tvoid, 3, msg, file, line);
1892 else
1893 return build_libcall (libcall, Type::tvoid, 2, file, line);
1896 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
1897 array bounds check fails. */
1899 tree
1900 build_array_bounds_call (const Loc &loc)
1902 /* Terminate the program with a trap if no D runtime present. */
1903 if (checkaction_trap_p ())
1904 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1905 else
1907 return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
1908 build_filename_from_loc (loc),
1909 size_int (loc.linnum));
1913 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1914 in the index expression IE. The condition returns the INDEX if true, or
1915 throws a `RangeError`. */
1917 tree
1918 build_bounds_index_condition (IndexExp *ie, tree index, tree length)
1920 if (ie->indexIsInBounds || !array_bounds_check ())
1921 return index;
1923 /* Prevent multiple evaluations of the index. */
1924 index = d_save_expr (index);
1926 /* Generate INDEX >= LENGTH && throw RangeError.
1927 No need to check whether INDEX >= 0 as the front-end should
1928 have already taken care of implicit casts to unsigned. */
1929 tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length);
1930 tree boundserr = build_array_bounds_call (ie->e2->loc);
1932 return build_condition (TREE_TYPE (index), condition, boundserr, index);
1935 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1936 the slice expression SE of the source array length LENGTH. The condition
1937 returns the new array length if true, or throws an `ArraySliceError`. */
1939 tree
1940 build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
1942 if (array_bounds_check ())
1944 tree condition = NULL_TREE;
1946 /* Enforces that `upper <= length`. */
1947 if (!se->upperIsInBounds && length != NULL_TREE)
1948 condition = fold_build2 (GT_EXPR, d_bool_type, upper, length);
1949 else
1950 length = integer_zero_node;
1952 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1953 we've already ensured that `upper <= length`. */
1954 if (!se->lowerIsLessThanUpper)
1956 tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper);
1958 if (condition != NULL_TREE)
1959 condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond);
1960 else
1961 condition = lwr_cond;
1964 if (condition != NULL_TREE)
1966 tree boundserr = build_array_bounds_call (se->loc);
1967 upper = build_condition (TREE_TYPE (upper), condition,
1968 boundserr, upper);
1972 /* Need to ensure lower always gets evaluated first, as it may be a function
1973 call. Generates (lower, upper) - lower. */
1974 return fold_build2 (MINUS_EXPR, TREE_TYPE (upper),
1975 compound_expr (lower, upper), lower);
1978 /* Returns TRUE if array bounds checking code generation is turned on. */
1980 bool
1981 array_bounds_check (void)
1983 FuncDeclaration *fd;
1985 switch (global.params.useArrayBounds)
1987 case CHECKENABLEoff:
1988 return false;
1990 case CHECKENABLEon:
1991 return true;
1993 case CHECKENABLEsafeonly:
1994 /* For D2 safe functions only. */
1995 fd = d_function_chain->function;
1996 if (fd && fd->type->ty == Tfunction)
1998 if (fd->type->isTypeFunction ()->trust == TRUSTsafe)
1999 return true;
2001 return false;
2003 default:
2004 gcc_unreachable ();
2008 /* Returns TRUE if we terminate the program with a trap if an array bounds or
2009 contract check fails. */
2011 bool
2012 checkaction_trap_p (void)
2014 switch (global.params.checkAction)
2016 case CHECKACTION_D:
2017 return false;
2019 case CHECKACTION_C:
2020 case CHECKACTION_halt:
2021 return true;
2023 default:
2024 gcc_unreachable ();
2028 /* Returns the TypeFunction class for Type T.
2029 Assumes T is already ->toBasetype(). */
2031 TypeFunction *
2032 get_function_type (Type *t)
2034 TypeFunction *tf = NULL;
2035 if (t->ty == Tpointer)
2036 t = t->nextOf ()->toBasetype ();
2037 if (t->ty == Tfunction)
2038 tf = t->isTypeFunction ();
2039 else if (t->ty == Tdelegate)
2040 tf = t->isTypeDelegate ()->next->isTypeFunction ();
2041 return tf;
2044 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
2045 CALLER. In which case, CALLEE is being called through an alias that was
2046 passed to CALLER. */
2048 bool
2049 call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)
2051 if (!callee->isNested ())
2052 return false;
2054 if (caller->toParent () == callee->toParent ())
2055 return false;
2057 Dsymbol *dsym = callee;
2059 while (dsym)
2061 if (dsym->isTemplateInstance ())
2062 return false;
2063 else if (dsym->isFuncDeclaration () == caller)
2064 return false;
2065 dsym = dsym->toParent ();
2068 return true;
2071 /* Entry point for call routines. Builds a function call to FD.
2072 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
2074 tree
2075 d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)
2077 return d_build_call (get_function_type (fd->type),
2078 build_address (get_symbol_decl (fd)), object, arguments);
2081 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
2082 ARGUMENTS are evaluated in left to right order, saved and promoted
2083 before passing. */
2085 tree
2086 d_build_call (TypeFunction *tf, tree callable, tree object,
2087 Expressions *arguments)
2089 tree ctype = TREE_TYPE (callable);
2090 tree callee = callable;
2092 if (POINTER_TYPE_P (ctype))
2093 ctype = TREE_TYPE (ctype);
2094 else
2095 callee = build_address (callable);
2097 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));
2098 gcc_assert (tf != NULL);
2099 gcc_assert (tf->ty == Tfunction);
2101 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)
2103 /* Front-end apparently doesn't check this. */
2104 if (TREE_CODE (callable) == FUNCTION_DECL)
2106 error ("need %<this%> to access member %qE", DECL_NAME (callable));
2107 return error_mark_node;
2110 /* Probably an internal error. */
2111 gcc_unreachable ();
2114 /* Build the argument list for the call. */
2115 vec <tree, va_gc> *args = NULL;
2116 tree saved_args = NULL_TREE;
2118 /* If this is a delegate call or a nested function being called as
2119 a delegate, the object should not be NULL. */
2120 if (object != NULL_TREE)
2121 vec_safe_push (args, object);
2123 if (arguments)
2125 /* First pass, evaluated expanded tuples in function arguments. */
2126 for (size_t i = 0; i < arguments->length; ++i)
2128 Lagain:
2129 Expression *arg = (*arguments)[i];
2130 gcc_assert (arg->op != TOKtuple);
2132 if (arg->op == TOKcomma)
2134 CommaExp *ce = arg->isCommaExp ();
2135 tree tce = build_expr (ce->e1);
2136 saved_args = compound_expr (saved_args, tce);
2137 (*arguments)[i] = ce->e2;
2138 goto Lagain;
2142 size_t nparams = tf->parameterList.length ();
2143 /* if _arguments[] is the first argument. */
2144 size_t varargs = tf->isDstyleVariadic ();
2146 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2147 for (size_t i = 0; i < arguments->length; ++i)
2149 Expression *arg = (*arguments)[i];
2150 tree targ = build_expr (arg);
2152 if (i - varargs < nparams && i >= varargs)
2154 /* Actual arguments for declared formal arguments. */
2155 Parameter *parg = tf->parameterList[i - varargs];
2156 targ = convert_for_argument (targ, parg);
2159 /* Don't pass empty aggregates by value. */
2160 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
2161 && TREE_CODE (targ) != CONSTRUCTOR)
2163 tree t = build_constructor (TREE_TYPE (targ), NULL);
2164 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
2167 /* Parameter is a struct or array passed by invisible reference. */
2168 if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
2170 Type *t = arg->type->toBasetype ();
2171 StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
2173 /* Nested structs also have ADDRESSABLE set, but if the type has
2174 neither a copy constructor nor a destructor available, then we
2175 need to take care of copying its value before passing it. */
2176 if (arg->op == TOKstructliteral || (!sd->postblit && !sd->dtor))
2177 targ = force_target_expr (targ);
2179 targ = convert (build_reference_type (TREE_TYPE (targ)),
2180 build_address (targ));
2183 vec_safe_push (args, targ);
2187 /* Evaluate the callee before calling it. */
2188 if (TREE_SIDE_EFFECTS (callee))
2190 callee = d_save_expr (callee);
2191 saved_args = compound_expr (callee, saved_args);
2194 tree result = build_call_vec (TREE_TYPE (ctype), callee, args);
2195 SET_EXPR_LOCATION (result, input_location);
2197 /* Enforce left to right evaluation. */
2198 if (tf->linkage == LINKd)
2199 CALL_EXPR_ARGS_ORDERED (result) = 1;
2201 result = maybe_expand_intrinsic (result);
2203 /* Return the value in a temporary slot so that it can be evaluated
2204 multiple times by the caller. */
2205 if (TREE_CODE (result) == CALL_EXPR
2206 && AGGREGATE_TYPE_P (TREE_TYPE (result))
2207 && TREE_ADDRESSABLE (TREE_TYPE (result)))
2209 CALL_EXPR_RETURN_SLOT_OPT (result) = true;
2210 result = force_target_expr (result);
2213 return compound_expr (saved_args, result);
2216 /* Build and return the correct call to fmod depending on TYPE.
2217 ARG0 and ARG1 are the arguments pass to the function. */
2219 tree
2220 build_float_modulus (tree type, tree arg0, tree arg1)
2222 tree fmodfn = NULL_TREE;
2223 tree basetype = type;
2225 if (COMPLEX_FLOAT_TYPE_P (basetype))
2226 basetype = TREE_TYPE (basetype);
2228 if (TYPE_MAIN_VARIANT (basetype) == double_type_node
2229 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)
2230 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);
2231 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node
2232 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)
2233 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);
2234 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node
2235 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)
2236 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);
2238 if (!fmodfn)
2240 error ("tried to perform floating-point modulo division on %qT", type);
2241 return error_mark_node;
2244 if (COMPLEX_FLOAT_TYPE_P (type))
2246 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);
2247 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);
2249 return complex_expr (type, re, im);
2252 if (SCALAR_FLOAT_TYPE_P (type))
2253 return build_call_expr (fmodfn, 2, arg0, arg1);
2255 /* Should have caught this above. */
2256 gcc_unreachable ();
2259 /* Build a function type whose first argument is a pointer to BASETYPE,
2260 which is to be used for the `vthis' context parameter for TYPE.
2261 The base type may be a record for member functions, or a void for
2262 nested functions and delegates. */
2264 tree
2265 build_vthis_function (tree basetype, tree type)
2267 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
2269 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),
2270 TYPE_ARG_TYPES (type));
2271 tree fntype = build_function_type (TREE_TYPE (type), argtypes);
2273 if (RECORD_OR_UNION_TYPE_P (basetype))
2274 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);
2275 else
2276 gcc_assert (VOID_TYPE_P (basetype));
2278 return fntype;
2281 /* Raise an error at that the context pointer of the function or object SYM is
2282 not accessible from the current scope. */
2284 tree
2285 error_no_frame_access (Dsymbol *sym)
2287 error_at (input_location, "cannot get frame pointer to %qs",
2288 sym->toPrettyChars ());
2289 return null_pointer_node;
2292 /* If SYM is a nested function, return the static chain to be
2293 used when calling that function from the current function.
2295 If SYM is a nested class or struct, return the static chain
2296 to be used when creating an instance of the class from CFUN. */
2298 tree
2299 get_frame_for_symbol (Dsymbol *sym)
2301 FuncDeclaration *thisfd
2302 = d_function_chain ? d_function_chain->function : NULL;
2303 FuncDeclaration *fd = sym->isFuncDeclaration ();
2304 FuncDeclaration *fdparent = NULL;
2305 FuncDeclaration *fdoverride = NULL;
2307 if (fd != NULL)
2309 /* Check that the nested function is properly defined. */
2310 if (!fd->fbody)
2312 /* Should instead error on line that references `fd'. */
2313 error_at (make_location_t (fd->loc), "nested function missing body");
2314 return null_pointer_node;
2317 fdparent = fd->toParent2 ()->isFuncDeclaration ();
2319 /* Special case for __ensure and __require. */
2320 if ((fd->ident == Identifier::idPool ("__ensure")
2321 || fd->ident == Identifier::idPool ("__require"))
2322 && fdparent != thisfd)
2324 fdoverride = fdparent;
2325 fdparent = thisfd;
2328 else
2330 /* It's a class (or struct). NewExp codegen has already determined its
2331 outer scope is not another class, so it must be a function. */
2332 while (sym && !sym->isFuncDeclaration ())
2333 sym = sym->toParent2 ();
2335 fdparent = (FuncDeclaration *) sym;
2338 /* Not a nested function, there is no frame pointer to pass. */
2339 if (fdparent == NULL)
2341 /* Only delegate literals report as being nested, even if they are in
2342 global scope. */
2343 gcc_assert (fd && fd->isFuncLiteralDeclaration ());
2344 return null_pointer_node;
2347 gcc_assert (thisfd != NULL);
2349 if (thisfd != fdparent)
2351 /* If no frame pointer for this function. */
2352 if (!thisfd->vthis)
2354 error_at (make_location_t (sym->loc),
2355 "%qs is a nested function and cannot be accessed from %qs",
2356 fdparent->toPrettyChars (), thisfd->toPrettyChars ());
2357 return null_pointer_node;
2360 /* Make sure we can get the frame pointer to the outer function.
2361 Go up each nesting level until we find the enclosing function. */
2362 Dsymbol *dsym = thisfd;
2364 while (fd != dsym)
2366 /* Check if enclosing function is a function. */
2367 FuncDeclaration *fdp = dsym->isFuncDeclaration ();
2368 Dsymbol *parent = dsym->toParent2 ();
2370 if (fdp != NULL)
2372 if (fdparent == parent)
2373 break;
2375 gcc_assert (fdp->isNested () || fdp->vthis);
2376 dsym = parent;
2377 continue;
2380 /* Check if enclosed by an aggregate. That means the current
2381 function must be a member function of that aggregate. */
2382 AggregateDeclaration *adp = dsym->isAggregateDeclaration ();
2384 if (adp != NULL)
2386 if ((adp->isClassDeclaration () || adp->isStructDeclaration ())
2387 && fdparent == parent)
2388 break;
2391 /* No frame to outer function found. */
2392 if (!adp || !adp->isNested () || !adp->vthis)
2393 return error_no_frame_access (sym);
2395 dsym = parent;
2399 tree ffo = get_frameinfo (fdparent);
2400 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2402 tree frame_ref = get_framedecl (thisfd, fdparent);
2404 /* If `thisfd' is a derived member function, then `fdparent' is the
2405 overridden member function in the base class. Even if there's a
2406 closure environment, we should give the original stack data as the
2407 nested function frame. */
2408 if (fdoverride)
2410 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2411 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2412 gcc_assert (cdo && cd);
2414 int offset;
2415 if (cdo->isBaseOf (cd, &offset) && offset != 0)
2417 /* Generate a new frame to pass to the overriden function that
2418 has the `this' pointer adjusted. */
2419 gcc_assert (offset != OFFSET_RUNTIME);
2421 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2422 tree fields = TYPE_FIELDS (type);
2423 /* The `this' field comes immediately after the `__chain'. */
2424 tree thisfield = chain_index (1, fields);
2425 vec <constructor_elt, va_gc> *ve = NULL;
2427 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2428 frame_ref = build_deref (frame_ref);
2430 for (tree field = fields; field; field = DECL_CHAIN (field))
2432 tree value = component_ref (frame_ref, framefields);
2433 if (field == thisfield)
2434 value = build_offset (value, size_int (offset));
2436 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2437 framefields = DECL_CHAIN (framefields);
2440 frame_ref = build_address (build_constructor (type, ve));
2444 return frame_ref;
2447 return null_pointer_node;
2450 /* Return the parent function of a nested class or struct AD. */
2452 static FuncDeclaration *
2453 get_outer_function (AggregateDeclaration *ad)
2455 FuncDeclaration *fd = NULL;
2456 while (ad && ad->isNested ())
2458 Dsymbol *dsym = ad->toParent2 ();
2459 if ((fd = dsym->isFuncDeclaration ()))
2460 return fd;
2461 else
2462 ad = dsym->isAggregateDeclaration ();
2465 return NULL;
2468 /* Starting from the current function FD, try to find a suitable value of
2469 `this' in nested function instances. A suitable `this' value is an
2470 instance of OCD or a class that has OCD as a base. */
2472 static tree
2473 find_this_tree (ClassDeclaration *ocd)
2475 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2477 while (fd)
2479 AggregateDeclaration *ad = fd->isThis ();
2480 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;
2482 if (cd != NULL)
2484 if (ocd == cd)
2485 return get_decl_tree (fd->vthis);
2486 else if (ocd->isBaseOf (cd, NULL))
2487 return convert_expr (get_decl_tree (fd->vthis),
2488 cd->type, ocd->type);
2490 fd = get_outer_function (cd);
2491 continue;
2494 if (fd->isNested ())
2496 fd = fd->toParent2 ()->isFuncDeclaration ();
2497 continue;
2500 fd = NULL;
2503 return NULL_TREE;
2506 /* Retrieve the outer class/struct `this' value of DECL from
2507 the current function. */
2509 tree
2510 build_vthis (AggregateDeclaration *decl)
2512 ClassDeclaration *cd = decl->isClassDeclaration ();
2513 StructDeclaration *sd = decl->isStructDeclaration ();
2515 /* If an aggregate nested in a function has no methods and there are no
2516 other nested functions, any static chain created here will never be
2517 translated. Use a null pointer for the link in this case. */
2518 tree vthis_value = null_pointer_node;
2520 if (cd != NULL || sd != NULL)
2522 Dsymbol *outer = decl->toParent2 ();
2524 /* If the parent is a templated struct, the outer context is instead
2525 the enclosing symbol of where the instantiation happened. */
2526 if (outer->isStructDeclaration ())
2528 gcc_assert (outer->parent && outer->parent->isTemplateInstance ());
2529 outer = ((TemplateInstance *) outer->parent)->enclosing;
2532 /* For outer classes, get a suitable `this' value.
2533 For outer functions, get a suitable frame/closure pointer. */
2534 ClassDeclaration *cdo = outer->isClassDeclaration ();
2535 FuncDeclaration *fdo = outer->isFuncDeclaration ();
2537 if (cdo)
2539 vthis_value = find_this_tree (cdo);
2540 gcc_assert (vthis_value != NULL_TREE);
2542 else if (fdo)
2544 tree ffo = get_frameinfo (fdo);
2545 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)
2546 || fdo->hasNestedFrameRefs ())
2547 vthis_value = get_frame_for_symbol (decl);
2548 else if (cd != NULL)
2550 /* Classes nested in methods are allowed to access any outer
2551 class fields, use the function chain in this case. */
2552 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)
2553 vthis_value = get_decl_tree (fdo->vthis);
2556 else
2557 gcc_unreachable ();
2560 return vthis_value;
2563 /* Build the RECORD_TYPE that describes the function frame or closure type for
2564 the function FD. FFI is the tree holding all frame information. */
2566 static tree
2567 build_frame_type (tree ffi, FuncDeclaration *fd)
2569 if (FRAMEINFO_TYPE (ffi))
2570 return FRAMEINFO_TYPE (ffi);
2572 tree frame_rec_type = make_node (RECORD_TYPE);
2573 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.",
2574 fd->toPrettyChars (), NULL);
2575 TYPE_NAME (frame_rec_type) = get_identifier (name);
2576 free (name);
2578 tree fields = NULL_TREE;
2580 /* Function is a member or nested, so must have field for outer context. */
2581 if (fd->vthis)
2583 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
2584 get_identifier ("__chain"), ptr_type_node);
2585 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;
2586 fields = chainon (NULL_TREE, ptr_field);
2587 DECL_NONADDRESSABLE_P (ptr_field) = 1;
2590 /* The __ensure and __require are called directly, so never make the outer
2591 functions closure, but nevertheless could still be referencing parameters
2592 of the calling function non-locally. So we add all parameters with nested
2593 refs to the function frame, this should also mean overriding methods will
2594 have the same frame layout when inheriting a contract. */
2595 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2596 || (global.params.useOut == CHECKENABLEon && fd->fensure))
2598 if (fd->parameters)
2600 for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++)
2602 VarDeclaration *v = (*fd->parameters)[i];
2603 /* Remove if already in closureVars so can push to front. */
2604 size_t j = fd->closureVars.find (v);
2606 if (j < fd->closureVars.length)
2607 fd->closureVars.remove (j);
2609 fd->closureVars.insert (i, v);
2613 /* Also add hidden `this' to outer context. */
2614 if (fd->vthis)
2616 size_t i = fd->closureVars.find (fd->vthis);
2618 if (i < fd->closureVars.length)
2619 fd->closureVars.remove (i);
2621 fd->closureVars.insert (0, fd->vthis);
2625 for (size_t i = 0; i < fd->closureVars.length; i++)
2627 VarDeclaration *v = fd->closureVars[i];
2628 tree vsym = get_symbol_decl (v);
2629 tree ident = v->ident
2630 ? get_identifier (v->ident->toChars ()) : NULL_TREE;
2632 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,
2633 TREE_TYPE (vsym));
2634 SET_DECL_LANG_FRAME_FIELD (vsym, field);
2635 DECL_FIELD_CONTEXT (field) = frame_rec_type;
2636 fields = chainon (fields, field);
2637 TREE_USED (vsym) = 1;
2639 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
2640 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
2641 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
2643 /* Can't do nrvo if the variable is put in a frame. */
2644 if (fd->nrvo_can && fd->nrvo_var == v)
2645 fd->nrvo_can = 0;
2647 if (FRAMEINFO_IS_CLOSURE (ffi))
2649 /* Because the value needs to survive the end of the scope. */
2650 if ((v->edtor && (v->storage_class & STCparameter))
2651 || v->needsScopeDtor ())
2652 error_at (make_location_t (v->loc),
2653 "has scoped destruction, cannot build closure");
2657 TYPE_FIELDS (frame_rec_type) = fields;
2658 TYPE_READONLY (frame_rec_type) = 1;
2659 TYPE_CXX_ODR_P (frame_rec_type) = 1;
2660 layout_type (frame_rec_type);
2661 d_keep (frame_rec_type);
2663 return frame_rec_type;
2666 /* Closures are implemented by taking the local variables that
2667 need to survive the scope of the function, and copying them
2668 into a GC allocated chuck of memory. That chunk, called the
2669 closure here, is inserted into the linked list of stack
2670 frames instead of the usual stack frame.
2672 If a closure is not required, but FD still needs a frame to lower
2673 nested refs, then instead build custom static chain decl on stack. */
2675 void
2676 build_closure (FuncDeclaration *fd)
2678 tree ffi = get_frameinfo (fd);
2680 if (!FRAMEINFO_CREATES_FRAME (ffi))
2681 return;
2683 tree type = FRAMEINFO_TYPE (ffi);
2684 gcc_assert (COMPLETE_TYPE_P (type));
2686 tree decl, decl_ref;
2688 if (FRAMEINFO_IS_CLOSURE (ffi))
2690 decl = build_local_temp (build_pointer_type (type));
2691 DECL_NAME (decl) = get_identifier ("__closptr");
2692 decl_ref = build_deref (decl);
2694 /* Allocate memory for closure. */
2695 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
2696 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
2698 tree init_exp = build_assign (INIT_EXPR, decl,
2699 build_nop (TREE_TYPE (decl), init));
2700 add_stmt (init_exp);
2702 else
2704 decl = build_local_temp (type);
2705 DECL_NAME (decl) = get_identifier ("__frame");
2706 decl_ref = decl;
2709 /* Set the first entry to the parent closure/frame, if any. */
2710 if (fd->vthis)
2712 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));
2713 tree chain_expr = modify_expr (chain_field,
2714 d_function_chain->static_chain);
2715 add_stmt (chain_expr);
2718 /* Copy parameters that are referenced nonlocally. */
2719 for (size_t i = 0; i < fd->closureVars.length; i++)
2721 VarDeclaration *v = fd->closureVars[i];
2723 if (!v->isParameter ())
2724 continue;
2726 tree vsym = get_symbol_decl (v);
2728 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));
2729 tree expr = modify_expr (field, vsym);
2730 add_stmt (expr);
2733 if (!FRAMEINFO_IS_CLOSURE (ffi))
2734 decl = build_address (decl);
2736 d_function_chain->static_chain = decl;
2739 /* Return the frame of FD. This could be a static chain or a closure
2740 passed via the hidden `this' pointer. */
2742 tree
2743 get_frameinfo (FuncDeclaration *fd)
2745 tree fds = get_symbol_decl (fd);
2746 if (DECL_LANG_FRAMEINFO (fds))
2747 return DECL_LANG_FRAMEINFO (fds);
2749 tree ffi = make_node (FUNCFRAME_INFO);
2751 DECL_LANG_FRAMEINFO (fds) = ffi;
2753 if (fd->needsClosure ())
2755 /* Set-up a closure frame, this will be allocated on the heap. */
2756 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2757 FRAMEINFO_IS_CLOSURE (ffi) = 1;
2759 else if (fd->hasNestedFrameRefs ())
2761 /* Functions with nested refs must create a static frame for local
2762 variables to be referenced from. */
2763 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2765 else
2767 /* For nested functions, default to creating a frame. Even if there are
2768 no fields to populate the frame, create it anyway, as this will be
2769 used as the record type instead of `void*` for the this parameter. */
2770 if (fd->vthis && fd->vthis->type == Type::tvoidptr)
2771 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2773 /* In checkNestedReference, references from contracts are not added to the
2774 closureVars array, so assume all parameters referenced. */
2775 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2776 || (global.params.useOut == CHECKENABLEon && fd->fensure))
2777 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2779 /* If however `fd` is nested (deeply) in a function that creates a
2780 closure, then `fd` instead inherits that closure via hidden vthis
2781 pointer, and doesn't create a stack frame at all. */
2782 FuncDeclaration *ff = fd;
2784 while (ff)
2786 tree ffo = get_frameinfo (ff);
2788 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))
2790 gcc_assert (FRAMEINFO_TYPE (ffo));
2791 FRAMEINFO_CREATES_FRAME (ffi) = 0;
2792 FRAMEINFO_STATIC_CHAIN (ffi) = 1;
2793 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);
2794 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));
2795 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);
2796 break;
2799 /* Stop looking if no frame pointer for this function. */
2800 if (ff->vthis == NULL)
2801 break;
2803 AggregateDeclaration *ad = ff->isThis ();
2804 if (ad && ad->isNested ())
2806 while (ad->isNested ())
2808 Dsymbol *d = ad->toParent2 ();
2809 ad = d->isAggregateDeclaration ();
2810 ff = d->isFuncDeclaration ();
2812 if (ad == NULL)
2813 break;
2816 else
2817 ff = ff->toParent2 ()->isFuncDeclaration ();
2821 /* Build type now as may be referenced from another module. */
2822 if (FRAMEINFO_CREATES_FRAME (ffi))
2823 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);
2825 return ffi;
2828 /* Return a pointer to the frame/closure block of OUTER
2829 so can be accessed from the function INNER. */
2831 tree
2832 get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
2834 tree result = d_function_chain->static_chain;
2835 FuncDeclaration *fd = inner;
2837 while (fd && fd != outer)
2839 /* Parent frame link is the first field. */
2840 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))
2841 result = indirect_ref (ptr_type_node, result);
2843 if (fd->isNested ())
2844 fd = fd->toParent2 ()->isFuncDeclaration ();
2845 /* The frame/closure record always points to the outer function's
2846 frame, even if there are intervening nested classes or structs.
2847 So, we can just skip over these. */
2848 else
2849 fd = get_outer_function (fd->isThis ());
2852 if (fd != outer)
2853 return error_no_frame_access (outer);
2855 /* Go get our frame record. */
2856 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
2858 if (frame_type != NULL_TREE)
2860 result = build_nop (build_pointer_type (frame_type), result);
2861 return result;
2863 else
2865 error_at (make_location_t (inner->loc),
2866 "forward reference to frame of %qs", outer->toChars ());
2867 return null_pointer_node;