bpf: create modifier for mem operand for xchg and cmpxchg
[official-gcc.git] / gcc / d / d-codegen.cc
blob2b3089b5f6dd02753ad9a73d03ecaca0b2ee46c1
1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
2 Copyright (C) 2006-2024 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"
41 #include "gimple-expr.h"
43 #include "d-tree.h"
46 /* Return the GCC location for the D frontend location LOC. */
48 location_t
49 make_location_t (const Loc &loc)
51 location_t gcc_location = input_location;
53 if (const char *filename = loc.filename ())
55 linemap_add (line_table, LC_ENTER, 0, filename, loc.linnum ());
56 linemap_line_start (line_table, loc.linnum (), 0);
57 gcc_location = linemap_position_for_column (line_table, loc.charnum ());
58 linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
61 return gcc_location;
64 /* Return the DECL_CONTEXT for symbol DSYM. */
66 tree
67 d_decl_context (Dsymbol *dsym)
69 Dsymbol *parent = dsym;
70 Declaration *decl = dsym->isDeclaration ();
71 AggregateDeclaration *ad = dsym->isAggregateDeclaration ();
73 while ((parent = parent->toParent2 ()))
75 /* We've reached the top-level module namespace.
76 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,
77 but only for extern(D) symbols. */
78 if (parent->isModule ())
80 if ((decl != NULL && decl->resolvedLinkage () != LINK::d)
81 || (ad != NULL && ad->classKind != ClassKind::d))
82 return NULL_TREE;
84 return build_import_decl (parent);
87 /* Declarations marked as `static' or `__gshared' are never
88 part of any context except at module level. */
89 if (decl != NULL && decl->isDataseg ())
90 continue;
92 /* Nested functions. */
93 FuncDeclaration *fd = parent->isFuncDeclaration ();
94 if (fd != NULL)
95 return get_symbol_decl (fd);
97 /* Methods of classes or structs. */
98 AggregateDeclaration *ad = parent->isAggregateDeclaration ();
99 if (ad != NULL)
101 tree context = build_ctype (ad->type);
102 /* Want the underlying RECORD_TYPE. */
103 if (ad->isClassDeclaration ())
104 context = TREE_TYPE (context);
106 return context;
110 return NULL_TREE;
113 /* Return a copy of record TYPE but safe to modify in any way. */
115 tree
116 copy_aggregate_type (tree type)
118 tree newtype = build_distinct_type_copy (type);
119 TYPE_STUB_DECL (newtype) = TYPE_NAME (newtype);
120 TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type));
122 for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f))
123 DECL_FIELD_CONTEXT (f) = newtype;
125 return newtype;
128 /* Return TRUE if declaration DECL is a reference type. */
130 bool
131 declaration_reference_p (Declaration *decl)
133 Type *tb = decl->type->toBasetype ();
135 /* Declaration is a reference type. */
136 if (tb->ty == TY::Treference || decl->storage_class & (STCout | STCref))
137 return true;
139 return false;
142 /* Returns the real type for declaration DECL. */
144 tree
145 declaration_type (Declaration *decl)
147 /* Lazy declarations are converted to delegates. */
148 if (decl->storage_class & STClazy)
150 TypeFunction *tf = TypeFunction::create (NULL, decl->type,
151 VARARGnone, LINK::d);
152 TypeDelegate *t = TypeDelegate::create (tf);
153 return build_ctype (dmd::merge2 (t));
156 /* Static array va_list have array->pointer conversions applied. */
157 if (decl->isParameter () && valist_array_p (decl->type))
159 Type *valist = dmd::pointerTo (decl->type->nextOf ());
160 valist = dmd::castMod (valist, decl->type->mod);
161 return build_ctype (valist);
164 tree type = build_ctype (decl->type);
166 /* Parameter is passed by reference. */
167 if (declaration_reference_p (decl))
168 return build_reference_type (type);
170 /* The `this' parameter is always const. */
171 if (decl->isThisDeclaration ())
172 return insert_type_modifiers (type, MODconst);
174 return type;
177 /* These should match the Declaration versions above
178 Return TRUE if parameter ARG is a reference type. */
180 bool
181 parameter_reference_p (Parameter *arg)
183 Type *tb = arg->type->toBasetype ();
185 /* Parameter is a reference type. */
186 if (tb->ty == TY::Treference || arg->storageClass & (STCout | STCref))
187 return true;
189 return false;
192 /* Returns the real type for parameter ARG. */
194 tree
195 parameter_type (Parameter *arg)
197 /* Lazy parameters are converted to delegates. */
198 if (arg->storageClass & STClazy)
200 TypeFunction *tf = TypeFunction::create (NULL, arg->type,
201 VARARGnone, LINK::d);
202 TypeDelegate *t = TypeDelegate::create (tf);
203 return build_ctype (dmd::merge2 (t));
206 /* Static array va_list have array->pointer conversions applied. */
207 if (valist_array_p (arg->type))
209 Type *valist = dmd::pointerTo (arg->type->nextOf ());
210 valist = dmd::castMod (valist, arg->type->mod);
211 return build_ctype (valist);
214 tree type = build_ctype (arg->type);
216 /* Parameter is passed by reference. */
217 if (parameter_reference_p (arg))
218 return build_reference_type (type);
220 /* Pass non-POD structs by invisible reference. */
221 if (TREE_ADDRESSABLE (type))
223 type = build_reference_type (type);
224 /* There are no other pointer to this temporary. */
225 type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
228 /* Front-end has already taken care of type promotions. */
229 return type;
232 /* Build INTEGER_CST of type TYPE with the value VALUE. */
234 tree
235 build_integer_cst (dinteger_t value, tree type)
237 /* The type is error_mark_node, we can't do anything. */
238 if (error_operand_p (type))
239 return type;
241 return build_int_cst_type (type, value);
244 /* Build REAL_CST of type TOTYPE with the value VALUE. */
246 tree
247 build_float_cst (const real_t &value, Type *totype)
249 real_t new_value;
250 TypeBasic *tb = totype->isTypeBasic ();
252 gcc_assert (tb != NULL);
254 tree type_node = build_ctype (tb);
255 real_convert (&new_value.rv (), TYPE_MODE (type_node), &value.rv ());
257 return build_real (type_node, new_value.rv ());
260 /* Returns the .length component from the D dynamic array EXP. */
262 tree
263 d_array_length (tree exp)
265 if (error_operand_p (exp))
266 return exp;
268 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
270 /* Get the back-end type for the array and pick out the array
271 length field (assumed to be the first field). */
272 tree len_field = TYPE_FIELDS (TREE_TYPE (exp));
273 return component_ref (exp, len_field);
276 /* Returns the .ptr component from the D dynamic array EXP. */
278 tree
279 d_array_ptr (tree exp)
281 if (error_operand_p (exp))
282 return exp;
284 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
286 /* Get the back-end type for the array and pick out the array
287 data pointer field (assumed to be the second field). */
288 tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
289 return component_ref (exp, ptr_field);
292 /* Returns a constructor for D dynamic array type TYPE of .length LEN
293 and .ptr pointing to DATA. */
295 tree
296 d_array_value (tree type, tree len, tree data)
298 tree len_field, ptr_field;
299 vec <constructor_elt, va_gc> *ce = NULL;
301 gcc_assert (TYPE_DYNAMIC_ARRAY (type));
302 len_field = TYPE_FIELDS (type);
303 ptr_field = TREE_CHAIN (len_field);
305 len = convert (TREE_TYPE (len_field), len);
306 data = convert (TREE_TYPE (ptr_field), data);
308 CONSTRUCTOR_APPEND_ELT (ce, len_field, len);
309 CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);
311 return build_constructor (type, ce);
314 /* Returns value representing the array length of expression EXP.
315 TYPE could be a dynamic or static array. */
317 tree
318 get_array_length (tree exp, Type *type)
320 Type *tb = type->toBasetype ();
322 switch (tb->ty)
324 case TY::Tsarray:
325 return size_int (tb->isTypeSArray ()->dim->toUInteger ());
327 case TY::Tarray:
328 return d_array_length (exp);
330 default:
331 error ("cannot determine the length of a %qs", type->toChars ());
332 return error_mark_node;
336 /* Create BINFO for a ClassDeclaration's inheritance tree.
337 InterfaceDeclaration's are not included. */
339 tree
340 build_class_binfo (tree super, ClassDeclaration *cd)
342 tree binfo = make_tree_binfo (1);
343 tree ctype = build_ctype (cd->type);
345 /* Want RECORD_TYPE, not POINTER_TYPE. */
346 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
347 BINFO_INHERITANCE_CHAIN (binfo) = super;
348 BINFO_OFFSET (binfo) = integer_zero_node;
350 if (cd->baseClass)
351 BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass));
353 return binfo;
356 /* Create BINFO for an InterfaceDeclaration's inheritance tree.
357 In order to access all inherited methods in the debugger,
358 the entire tree must be described.
359 This function makes assumptions about interface layout. */
361 tree
362 build_interface_binfo (tree super, ClassDeclaration *cd, unsigned &offset)
364 tree binfo = make_tree_binfo (cd->baseclasses->length);
365 tree ctype = build_ctype (cd->type);
367 /* Want RECORD_TYPE, not POINTER_TYPE. */
368 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
369 BINFO_INHERITANCE_CHAIN (binfo) = super;
370 BINFO_OFFSET (binfo) = size_int (offset * target.ptrsize);
371 BINFO_VIRTUAL_P (binfo) = 1;
373 for (size_t i = 0; i < cd->baseclasses->length; i++, offset++)
375 BaseClass *bc = (*cd->baseclasses)[i];
376 BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset));
379 return binfo;
382 /* Returns the .funcptr component from the D delegate EXP. */
384 tree
385 delegate_method (tree exp)
387 /* Get the back-end type for the delegate and pick out the funcptr field
388 (assumed to be the second field). */
389 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
390 tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
391 return component_ref (exp, method_field);
394 /* Returns the .object component from the delegate EXP. */
396 tree
397 delegate_object (tree exp)
399 /* Get the back-end type for the delegate and pick out the object field
400 (assumed to be the first field). */
401 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
402 tree obj_field = TYPE_FIELDS (TREE_TYPE (exp));
403 return component_ref (exp, obj_field);
406 /* Build a delegate literal of type TYPE whose pointer function is
407 METHOD, and hidden object is OBJECT. */
409 tree
410 build_delegate_cst (tree method, tree object, Type *type)
412 tree ctor = make_node (CONSTRUCTOR);
413 tree ctype;
415 Type *tb = type->toBasetype ();
416 if (tb->ty == TY::Tdelegate)
417 ctype = build_ctype (type);
418 else
420 /* Convert a function method into an anonymous delegate. */
421 ctype = make_struct_type ("delegate()", 2,
422 get_identifier ("ptr"), TREE_TYPE (object),
423 get_identifier ("funcptr"), TREE_TYPE (method));
424 TYPE_DELEGATE (ctype) = 1;
427 vec <constructor_elt, va_gc> *ce = NULL;
428 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object);
429 CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method);
431 CONSTRUCTOR_ELTS (ctor) = ce;
432 TREE_TYPE (ctor) = ctype;
434 return ctor;
437 /* Builds a temporary tree to store the CALLEE and OBJECT
438 of a method call expression of type TYPE. */
440 tree
441 build_method_call (tree callee, tree object, Type *type)
443 tree t = build_delegate_cst (callee, object, type);
444 METHOD_CALL_EXPR (t) = 1;
445 return t;
448 /* Extract callee and object from T and return in to CALLEE and OBJECT. */
450 void
451 extract_from_method_call (tree t, tree &callee, tree &object)
453 gcc_assert (METHOD_CALL_EXPR (t));
454 object = CONSTRUCTOR_ELT (t, 0)->value;
455 callee = CONSTRUCTOR_ELT (t, 1)->value;
458 /* Build a typeof(null) constant of type TYPE. Handles certain special case
459 conversions, where the underlying type is an aggregate with a nullable
460 interior pointer. */
462 tree
463 build_typeof_null_value (Type *type)
465 Type *tb = type->toBasetype ();
466 tree value;
468 /* For dynamic arrays, set length and pointer fields to zero. */
469 if (tb->ty == TY::Tarray)
470 value = d_array_value (build_ctype (type), size_int (0), null_pointer_node);
472 /* For associative arrays, set the pointer field to null. */
473 else if (tb->ty == TY::Taarray)
475 tree ctype = build_ctype (type);
476 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype));
478 value = build_constructor_single (ctype, TYPE_FIELDS (ctype),
479 null_pointer_node);
482 /* For delegates, set the frame and function pointer fields to null. */
483 else if (tb->ty == TY::Tdelegate)
484 value = build_delegate_cst (null_pointer_node, null_pointer_node, type);
486 /* Simple zero constant for all other types. */
487 else
488 value = build_zero_cst (build_ctype (type));
490 TREE_CONSTANT (value) = 1;
491 return value;
494 /* Build a dereference into the virtual table for OBJECT to retrieve
495 a function pointer of type FNTYPE at position INDEX. */
497 tree
498 build_vindex_ref (tree object, tree fntype, size_t index)
500 /* The vtable is the first field. Interface methods are also in the class's
501 vtable, so we don't need to convert from a class to an interface. */
502 tree result = build_deref (object);
503 result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result)));
505 gcc_assert (POINTER_TYPE_P (fntype));
507 return build_memref (fntype, result, size_int (target.ptrsize * index));
510 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
511 made into temporaries, otherwise any assignments will be lost. */
513 static bool
514 lvalue_p (tree exp)
516 const enum tree_code code = TREE_CODE (exp);
518 switch (code)
520 case SAVE_EXPR:
521 return false;
523 case ARRAY_REF:
524 case INDIRECT_REF:
525 case VAR_DECL:
526 case PARM_DECL:
527 case RESULT_DECL:
528 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp));
530 case IMAGPART_EXPR:
531 case REALPART_EXPR:
532 case COMPONENT_REF:
533 CASE_CONVERT:
534 return lvalue_p (TREE_OPERAND (exp, 0));
536 case COND_EXPR:
537 return (lvalue_p (TREE_OPERAND (exp, 1)
538 ? TREE_OPERAND (exp, 1)
539 : TREE_OPERAND (exp, 0))
540 && lvalue_p (TREE_OPERAND (exp, 2)));
542 case TARGET_EXPR:
543 return true;
545 case COMPOUND_EXPR:
546 return lvalue_p (TREE_OPERAND (exp, 1));
548 default:
549 return false;
553 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
554 more than once in an expression. */
556 tree
557 d_save_expr (tree exp)
559 if (TREE_SIDE_EFFECTS (exp))
561 if (lvalue_p (exp))
562 return stabilize_reference (exp);
564 return save_expr (exp);
567 return exp;
570 /* VALUEP is an expression we want to pre-evaluate or perform a computation on.
571 The expression returned by this function is the part whose value we don't
572 care about, storing the value in VALUEP. Callers must ensure that the
573 returned expression is evaluated before VALUEP. */
575 tree
576 stabilize_expr (tree *valuep)
578 tree expr = *valuep;
579 const enum tree_code code = TREE_CODE (expr);
580 tree lhs;
581 tree rhs;
583 switch (code)
585 case COMPOUND_EXPR:
586 /* Given ((e1, ...), eN):
587 Store the last RHS 'eN' expression in VALUEP. */
588 lhs = TREE_OPERAND (expr, 0);
589 rhs = TREE_OPERAND (expr, 1);
590 lhs = compound_expr (lhs, stabilize_expr (&rhs));
591 *valuep = rhs;
592 return lhs;
594 default:
595 return NULL_TREE;
599 /* Return a TARGET_EXPR, initializing the DECL with EXP. */
601 tree
602 build_target_expr (tree decl, tree exp)
604 tree type = TREE_TYPE (decl);
605 tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE);
607 if (EXPR_HAS_LOCATION (exp))
608 SET_EXPR_LOCATION (result, EXPR_LOCATION (exp));
610 /* If decl must always reside in memory. */
611 if (TREE_ADDRESSABLE (type))
612 d_mark_addressable (decl);
614 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
615 TARGET_EXPR. If there really turn out to be no side effects, then the
616 optimizer should be able to remove it. */
617 TREE_SIDE_EFFECTS (result) = 1;
619 return result;
622 /* Like the above function, but initializes a new temporary. */
624 tree
625 force_target_expr (tree exp)
627 tree decl = create_tmp_var_raw (TREE_TYPE (exp));
628 DECL_CONTEXT (decl) = current_function_decl;
629 layout_decl (decl, 0);
631 return build_target_expr (decl, exp);
634 /* Returns the address of the expression EXP. */
636 tree
637 build_address (tree exp)
639 if (error_operand_p (exp))
640 return exp;
642 tree ptrtype;
643 tree type = TREE_TYPE (exp);
645 if (TREE_CODE (exp) == STRING_CST)
647 /* Just convert string literals (char[]) to C-style strings (char *),
648 otherwise the latter method (char[]*) causes conversion problems
649 during gimplification. */
650 ptrtype = build_pointer_type (TREE_TYPE (type));
652 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node)
653 && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE)
655 /* Special case for va_list, allow arrays to decay to a pointer. */
656 ptrtype = build_pointer_type (TREE_TYPE (type));
658 else
659 ptrtype = build_pointer_type (type);
661 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
662 tree init = stabilize_expr (&exp);
664 /* Can't take the address of a manifest constant, instead use its value. */
665 if (TREE_CODE (exp) == CONST_DECL)
666 exp = DECL_INITIAL (exp);
668 /* Some expression lowering may request an address of a compile-time constant,
669 or other non-lvalue expression. Make sure it is assigned to a location we
670 can reference. */
671 if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
672 exp = force_target_expr (exp);
673 else if (TREE_CODE (exp) == CALL_EXPR)
675 /* When a struct or array is returned in registers, we need to again fill
676 in all alignment holes. */
677 if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
678 && !aggregate_value_p (TREE_TYPE (exp), exp))
680 tree tmp = build_local_temp (TREE_TYPE (exp));
681 init = compound_expr (init, build_memset_call (tmp));
682 init = compound_expr (init, modify_expr (tmp, exp));
683 exp = tmp;
685 else
686 exp = force_target_expr (exp);
689 d_mark_addressable (exp);
690 exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype);
692 if (TREE_CODE (exp) == ADDR_EXPR)
693 TREE_NO_TRAMPOLINE (exp) = 1;
695 return compound_expr (init, exp);
698 /* Mark EXP saying that we need to be able to take the address of it; it should
699 not be allocated in a register. When COMPLAIN is true, issue an error if we
700 are marking a register variable. */
702 tree
703 d_mark_addressable (tree exp, bool complain)
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 VAR_DECL:
716 if (complain && DECL_REGISTER (exp))
718 if (DECL_HARD_REGISTER (exp) || DECL_EXTERNAL (exp))
719 error ("address of explicit register variable %qD requested", exp);
720 else
721 error ("address of register variable %qD requested", exp);
724 /* Fall through. */
725 case PARM_DECL:
726 case RESULT_DECL:
727 case CONST_DECL:
728 case FUNCTION_DECL:
729 if (!VAR_P (exp) || !DECL_HARD_REGISTER (exp))
730 TREE_ADDRESSABLE (exp) = 1;
731 break;
733 case CONSTRUCTOR:
734 TREE_ADDRESSABLE (exp) = 1;
735 break;
737 case TARGET_EXPR:
738 TREE_ADDRESSABLE (exp) = 1;
739 d_mark_addressable (TREE_OPERAND (exp, 0));
740 break;
742 default:
743 break;
746 return exp;
749 /* Mark EXP as "used" in the program for the benefit of
750 -Wunused warning purposes. */
752 tree
753 d_mark_used (tree exp)
755 switch (TREE_CODE (exp))
757 case VAR_DECL:
758 case CONST_DECL:
759 case PARM_DECL:
760 case RESULT_DECL:
761 case FUNCTION_DECL:
762 TREE_USED (exp) = 1;
763 break;
765 case ARRAY_REF:
766 case COMPONENT_REF:
767 case MODIFY_EXPR:
768 case REALPART_EXPR:
769 case IMAGPART_EXPR:
770 case NOP_EXPR:
771 case CONVERT_EXPR:
772 case ADDR_EXPR:
773 d_mark_used (TREE_OPERAND (exp, 0));
774 break;
776 case COMPOUND_EXPR:
777 d_mark_used (TREE_OPERAND (exp, 0));
778 d_mark_used (TREE_OPERAND (exp, 1));
779 break;
781 default:
782 break;
784 return exp;
787 /* Mark EXP as read, not just set, for set but not used -Wunused
788 warning purposes. */
790 tree
791 d_mark_read (tree exp)
793 switch (TREE_CODE (exp))
795 case VAR_DECL:
796 case PARM_DECL:
797 TREE_USED (exp) = 1;
798 DECL_READ_P (exp) = 1;
799 break;
801 case ARRAY_REF:
802 case COMPONENT_REF:
803 case MODIFY_EXPR:
804 case REALPART_EXPR:
805 case IMAGPART_EXPR:
806 case NOP_EXPR:
807 case CONVERT_EXPR:
808 case ADDR_EXPR:
809 d_mark_read (TREE_OPERAND (exp, 0));
810 break;
812 case COMPOUND_EXPR:
813 d_mark_read (TREE_OPERAND (exp, 1));
814 break;
816 default:
817 break;
819 return exp;
822 /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */
824 tree
825 build_memcmp_call (tree ptr1, tree ptr2, tree num)
827 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,
828 ptr1, ptr2, num);
831 /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */
833 tree
834 build_memcpy_call (tree dst, tree src, tree num)
836 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
837 dst, src, num);
840 /* Build a call to memset(), fills the first NUM bytes of PTR with zeros.
841 If NUM is NULL, then we expect PTR to be object that requires filling. */
843 tree
844 build_memset_call (tree ptr, tree num)
846 if (num == NULL_TREE)
848 gcc_assert (TREE_CODE (ptr) != ADDR_EXPR);
849 num = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
850 ptr = build_address (ptr);
853 /* Use a zero constant to fill the destination if setting the entire object.
854 For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
855 which can then be merged with other stores to the object. */
856 tree valtype = TREE_TYPE (TREE_TYPE (ptr));
857 if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num))
859 tree cst = build_zero_cst (valtype);
860 if (TREE_CODE (cst) == CONSTRUCTOR)
861 return build_memcpy_call (ptr, build_address (cst), num);
863 return modify_expr (build_deref (ptr), cst);
866 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3,
867 ptr, integer_zero_node, num);
870 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
871 This is because we don't guarantee that padding is zero-initialized for
872 a stack variable, so we can't use memcmp to compare struct values. */
874 bool
875 identity_compare_p (StructDeclaration *sd)
877 if (sd->isUnionDeclaration ())
878 return true;
880 unsigned offset = 0;
882 for (size_t i = 0; i < sd->fields.length; i++)
884 VarDeclaration *vd = sd->fields[i];
885 Type *tb = vd->type->toBasetype ();
887 /* Check inner data structures. */
888 if (TypeStruct *ts = tb->isTypeStruct ())
890 if (!identity_compare_p (ts->sym))
891 return false;
894 /* Check for types that may have padding. */
895 if ((tb->ty == TY::Tcomplex80
896 || tb->ty == TY::Tfloat80
897 || tb->ty == TY::Timaginary80)
898 && target.realpad != 0)
899 return false;
901 if (offset <= vd->offset)
903 /* There's a hole in the struct. */
904 if (offset != vd->offset)
905 return false;
907 offset += vd->type->size ();
911 /* Any trailing padding may not be zero. */
912 if (offset < sd->structsize)
913 return false;
915 return true;
918 /* Build a floating-point identity comparison between T1 and T2, ignoring any
919 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
921 tree
922 build_float_identity (tree_code code, tree t1, tree t2)
924 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
925 tree result = build_memcmp_call (build_address (t1),
926 build_address (t2), size);
927 return build_boolop (code, result, integer_zero_node);
930 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
931 CODE is the EQ_EXPR or NE_EXPR comparison. */
933 static tree
934 lower_struct_comparison (tree_code code, StructDeclaration *sd,
935 tree t1, tree t2)
937 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
938 tree tmemcmp = NULL_TREE;
940 /* We can skip the compare if the structs are empty. */
941 if (sd->fields.length == 0)
943 tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node);
944 if (TREE_SIDE_EFFECTS (t2))
945 tmemcmp = compound_expr (t2, tmemcmp);
946 if (TREE_SIDE_EFFECTS (t1))
947 tmemcmp = compound_expr (t1, tmemcmp);
949 return tmemcmp;
952 /* Let back-end take care of union comparisons. */
953 if (sd->isUnionDeclaration ())
955 tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
956 size_int (sd->structsize));
957 return build_boolop (code, tmemcmp, integer_zero_node);
960 for (size_t i = 0; i < sd->fields.length; i++)
962 VarDeclaration *vd = sd->fields[i];
963 Type *type = vd->type->toBasetype ();
964 tree sfield = get_symbol_decl (vd);
966 tree t1ref = component_ref (t1, sfield);
967 tree t2ref = component_ref (t2, sfield);
968 tree tcmp;
970 if (TypeStruct *ts = type->isTypeStruct ())
972 /* Compare inner data structures. */
973 tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref);
975 else if (type->ty != TY::Tvector && type->isintegral ())
977 /* Integer comparison, no special handling required. */
978 tcmp = build_boolop (code, t1ref, t2ref);
980 else if (type->ty != TY::Tvector && type->isfloating ())
982 /* Floating-point comparison, don't compare padding in type. */
983 if (!type->iscomplex ())
984 tcmp = build_float_identity (code, t1ref, t2ref);
985 else
987 tree req = build_float_identity (code, real_part (t1ref),
988 real_part (t2ref));
989 tree ieq = build_float_identity (code, imaginary_part (t1ref),
990 imaginary_part (t2ref));
992 tcmp = build_boolop (tcode, req, ieq);
995 else
997 tree stype = build_ctype (type);
998 opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));
1000 if (mode.exists ())
1002 /* Compare field bits as their corresponding integer type.
1003 *((T*) &t1) == *((T*) &t2) */
1004 tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1);
1006 if (tmode == NULL_TREE)
1007 tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
1009 tmode = build_aligned_type (tmode, TYPE_ALIGN (stype));
1010 t1ref = build_vconvert (tmode, t1ref);
1011 t2ref = build_vconvert (tmode, t2ref);
1013 tcmp = build_boolop (code, t1ref, t2ref);
1015 else
1017 /* Simple memcmp between types. */
1018 tcmp = build_memcmp_call (build_address (t1ref),
1019 build_address (t2ref),
1020 TYPE_SIZE_UNIT (stype));
1021 tcmp = build_boolop (code, tcmp, integer_zero_node);
1025 tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp;
1028 return tmemcmp;
1032 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
1033 If possible, use memcmp, otherwise field-by-field comparison is done.
1034 CODE is the EQ_EXPR or NE_EXPR comparison. */
1036 tree
1037 build_struct_comparison (tree_code code, StructDeclaration *sd,
1038 tree t1, tree t2)
1040 /* We can skip the compare if the structs are empty. */
1041 if (sd->fields.length == 0)
1043 tree exp = build_boolop (code, integer_zero_node, integer_zero_node);
1044 if (TREE_SIDE_EFFECTS (t2))
1045 exp = compound_expr (t2, exp);
1046 if (TREE_SIDE_EFFECTS (t1))
1047 exp = compound_expr (t1, exp);
1049 return exp;
1052 /* Make temporaries to prevent multiple evaluations. */
1053 tree t1init = stabilize_expr (&t1);
1054 tree t2init = stabilize_expr (&t2);
1055 tree result;
1057 t1 = d_save_expr (t1);
1058 t2 = d_save_expr (t2);
1060 /* Bitwise comparison of structs not returned in memory may not work
1061 due to data holes loosing its zero padding upon return.
1062 As a heuristic, small structs are not compared using memcmp either. */
1063 if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd))
1064 result = lower_struct_comparison (code, sd, t1, t2);
1065 else
1067 /* Do bit compare of structs. */
1068 tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
1069 size_int (sd->structsize));
1070 result = build_boolop (code, tmemcmp, integer_zero_node);
1073 return compound_expr (compound_expr (t1init, t2init), result);
1076 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1077 The pointer references are T1 and T2, and the element type is SD.
1078 CODE is the EQ_EXPR or NE_EXPR comparison. */
1080 tree
1081 build_array_struct_comparison (tree_code code, StructDeclaration *sd,
1082 tree length, tree t1, tree t2)
1084 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
1086 /* Build temporary for the result of the comparison.
1087 Initialize as either 0 or 1 depending on operation. */
1088 tree result = build_local_temp (d_bool_type);
1089 tree init = build_boolop (code, integer_zero_node, integer_zero_node);
1090 add_stmt (build_assign (INIT_EXPR, result, init));
1092 /* Cast pointer-to-array to pointer-to-struct. */
1093 tree ptrtype = build_ctype (dmd::pointerTo (sd->type));
1094 tree lentype = TREE_TYPE (length);
1096 push_binding_level (level_block);
1097 push_stmt_list ();
1099 /* Build temporary locals for length and pointers. */
1100 tree t = build_local_temp (size_type_node);
1101 add_stmt (build_assign (INIT_EXPR, t, length));
1102 length = t;
1104 t = build_local_temp (ptrtype);
1105 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1)));
1106 t1 = t;
1108 t = build_local_temp (ptrtype);
1109 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2)));
1110 t2 = t;
1112 /* Build loop for comparing each element. */
1113 push_stmt_list ();
1115 /* Exit logic for the loop.
1116 if (length == 0 || result OP 0) break; */
1117 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1118 t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,
1119 d_bool_false_node));
1120 t = build1 (EXIT_EXPR, void_type_node, t);
1121 add_stmt (t);
1123 /* Do comparison, caching the value.
1124 result = result OP (*t1 == *t2); */
1125 t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2));
1126 t = build_boolop (tcode, result, t);
1127 t = modify_expr (result, t);
1128 add_stmt (t);
1130 /* Move both pointers to next element position.
1131 t1++, t2++; */
1132 tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)));
1133 t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size);
1134 add_stmt (t);
1135 t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size);
1136 add_stmt (t);
1138 /* Decrease loop counter.
1139 length -= 1; */
1140 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1141 d_convert (lentype, integer_one_node));
1142 add_stmt (t);
1144 /* Pop statements and finish loop. */
1145 tree body = pop_stmt_list ();
1146 add_stmt (build1 (LOOP_EXPR, void_type_node, body));
1148 /* Wrap it up into a bind expression. */
1149 tree stmt_list = pop_stmt_list ();
1150 tree block = pop_binding_level ();
1152 body = build3 (BIND_EXPR, void_type_node,
1153 BLOCK_VARS (block), stmt_list, block);
1155 return compound_expr (body, result);
1158 /* Build a constructor for a variable of aggregate type TYPE using the
1159 initializer INIT, an ordered flat list of fields and values provided
1160 by the frontend. The returned constructor should be a value that
1161 matches the layout of TYPE. */
1163 tree
1164 build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
1166 /* If the initializer was empty, use default zero initialization. */
1167 if (vec_safe_is_empty (init))
1168 return build_constructor (type, NULL);
1170 /* Struct literals can be seen for special enums representing `_Complex',
1171 make sure to reinterpret the literal as the correct type. */
1172 if (COMPLEX_FLOAT_TYPE_P (type))
1174 gcc_assert (vec_safe_length (init) == 2);
1175 return complex_expr (type, (*init)[0].value, (*init)[1].value);
1178 vec <constructor_elt, va_gc> *ve = NULL;
1179 HOST_WIDE_INT bitoffset = 0;
1180 bool constant_p = true;
1181 bool finished = false;
1183 /* Walk through each field, matching our initializer list. */
1184 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1186 bool is_initialized = false;
1187 tree value;
1189 if (DECL_NAME (field) == NULL_TREE
1190 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1191 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1193 /* Search all nesting aggregates, if nothing is found, then
1194 this will return an empty initializer to fill the hole. */
1195 value = build_struct_literal (TREE_TYPE (field), init);
1197 if (!initializer_zerop (value))
1198 is_initialized = true;
1200 else
1202 /* Search for the value to initialize the next field. Once found,
1203 pop it from the init list so we don't look at it again. */
1204 unsigned HOST_WIDE_INT idx;
1205 tree index;
1207 FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value)
1209 /* If the index is NULL, then just assign it to the next field.
1210 This comes from layout_typeinfo(), which generates a flat
1211 list of values that we must shape into the record type. */
1212 if (index == field || index == NULL_TREE)
1214 init->ordered_remove (idx);
1215 if (!finished)
1216 is_initialized = true;
1217 break;
1222 if (is_initialized)
1224 HOST_WIDE_INT fieldpos = int_bit_position (field);
1225 gcc_assert (value != NULL_TREE);
1227 /* Must not initialize fields that overlap. */
1228 if (fieldpos < bitoffset)
1230 /* Find the nearest user defined type and field. */
1231 tree vtype = type;
1232 while (ANON_AGGR_TYPE_P (vtype))
1233 vtype = TYPE_CONTEXT (vtype);
1235 tree vfield = field;
1236 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield))
1237 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield)))
1238 vfield = TYPE_FIELDS (TREE_TYPE (vfield));
1240 /* Must not generate errors for compiler generated fields. */
1241 gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield));
1242 error ("overlapping initializer for field %qT.%qD",
1243 TYPE_NAME (vtype), DECL_NAME (vfield));
1246 if (!TREE_CONSTANT (value))
1247 constant_p = false;
1249 CONSTRUCTOR_APPEND_ELT (ve, field, value);
1251 /* For unions, only the first field is initialized, any other field
1252 initializers found for this union are drained and ignored. */
1253 if (TREE_CODE (type) == UNION_TYPE)
1254 finished = true;
1257 /* Move bit offset to the next position in the struct. */
1258 if (TREE_CODE (type) == RECORD_TYPE && DECL_SIZE (field))
1259 bitoffset = int_bit_position (field) + tree_to_shwi (DECL_SIZE (field));
1261 /* If all initializers have been assigned, there's nothing else to do. */
1262 if (vec_safe_is_empty (init))
1263 break;
1266 /* Ensure that we have consumed all values. */
1267 gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
1269 tree ctor = build_constructor (type, ve);
1271 if (constant_p)
1272 TREE_CONSTANT (ctor) = 1;
1274 return ctor;
1277 /* Given the TYPE of an anonymous field inside T, return the
1278 FIELD_DECL for the field. If not found return NULL_TREE.
1279 Because anonymous types can nest, we must also search all
1280 anonymous fields that are directly reachable. */
1282 static tree
1283 lookup_anon_field (tree t, tree type)
1285 t = TYPE_MAIN_VARIANT (t);
1287 for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
1289 if (DECL_NAME (field) == NULL_TREE)
1291 /* If we find it directly, return the field. */
1292 if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
1293 return field;
1295 /* Otherwise, it could be nested, search harder. */
1296 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1297 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1299 tree subfield = lookup_anon_field (TREE_TYPE (field), type);
1300 if (subfield)
1301 return subfield;
1306 return NULL_TREE;
1309 /* Builds OBJECT.FIELD component reference. */
1311 tree
1312 component_ref (tree object, tree field)
1314 if (error_operand_p (object) || error_operand_p (field))
1315 return error_mark_node;
1317 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1319 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1320 tree init = stabilize_expr (&object);
1322 /* If the FIELD is from an anonymous aggregate, generate a reference
1323 to the anonymous data member, and recur to find FIELD. */
1324 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field)))
1326 tree anonymous_field = lookup_anon_field (TREE_TYPE (object),
1327 DECL_CONTEXT (field));
1328 object = component_ref (object, anonymous_field);
1331 tree result = fold_build3_loc (input_location, COMPONENT_REF,
1332 TREE_TYPE (field), object, field, NULL_TREE);
1334 return compound_expr (init, result);
1337 /* Build an assignment expression of lvalue LHS from value RHS.
1338 CODE is the code for a binary operator that we use to combine
1339 the old value of LHS with RHS to get the new value. */
1341 tree
1342 build_assign (tree_code code, tree lhs, tree rhs)
1344 tree result;
1345 tree init = stabilize_expr (&lhs);
1346 init = compound_expr (init, stabilize_expr (&rhs));
1348 /* If initializing the LHS using a function that returns via NRVO. */
1349 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
1350 && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
1351 && aggregate_value_p (TREE_TYPE (rhs), rhs))
1353 /* Mark as addressable here, which should ensure the return slot is the
1354 address of the LHS expression, taken care of by back-end. */
1355 d_mark_addressable (lhs);
1356 CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
1358 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
1359 else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs))
1360 && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR)
1362 /* LHS may be referenced by the RHS expression, so force a temporary. */
1363 rhs = force_target_expr (rhs);
1366 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1367 if (TREE_CODE (rhs) == TARGET_EXPR)
1369 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1370 since that would cause the LHS to be constructed twice. */
1371 if (code != INIT_EXPR)
1373 init = compound_expr (init, rhs);
1374 result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs));
1376 else
1378 d_mark_addressable (lhs);
1379 TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs,
1380 TARGET_EXPR_INITIAL (rhs));
1381 result = rhs;
1384 else
1386 /* Simple assignment. */
1387 result = fold_build2_loc (input_location, code,
1388 TREE_TYPE (lhs), lhs, rhs);
1391 return compound_expr (init, result);
1394 /* Build an assignment expression of lvalue LHS from value RHS. */
1396 tree
1397 modify_expr (tree lhs, tree rhs)
1399 return build_assign (MODIFY_EXPR, lhs, rhs);
1402 /* Return EXP represented as TYPE. */
1404 tree
1405 build_nop (tree type, tree exp)
1407 if (error_operand_p (exp))
1408 return exp;
1410 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1411 tree init = stabilize_expr (&exp);
1412 exp = fold_build1_loc (input_location, NOP_EXPR, type, exp);
1414 return compound_expr (init, exp);
1417 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1418 except that EXP is type-punned, rather than a straight-forward cast. */
1420 tree
1421 build_vconvert (tree type, tree exp)
1423 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1424 makes sure this works for vector-to-array viewing, or if EXP ends up being
1425 used as the LHS of a MODIFY_EXPR. */
1426 return indirect_ref (type, build_address (exp));
1429 /* Maybe warn about ARG being an address that can never be null. */
1431 static void
1432 warn_for_null_address (tree arg)
1434 if (TREE_CODE (arg) == ADDR_EXPR
1435 && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0)))
1436 warning (OPT_Waddress,
1437 "the address of %qD will never be %<null%>",
1438 TREE_OPERAND (arg, 0));
1441 /* Build a boolean ARG0 op ARG1 expression. */
1443 tree
1444 build_boolop (tree_code code, tree arg0, tree arg1)
1446 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1447 so need to remove all side effects incase its address is taken. */
1448 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0)))
1449 arg0 = d_save_expr (arg0);
1450 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1)))
1451 arg1 = d_save_expr (arg1);
1453 if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1)))
1455 /* Build a vector comparison.
1456 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1457 tree cmptype = truth_type_for (TREE_TYPE (arg0));
1458 tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1);
1460 return fold_build3_loc (input_location, VEC_COND_EXPR, cmptype, cmp,
1461 build_minus_one_cst (cmptype),
1462 build_zero_cst (cmptype));
1465 if (code == EQ_EXPR || code == NE_EXPR)
1467 /* Check if comparing the address of a variable to null. */
1468 if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1))
1469 warn_for_null_address (arg0);
1470 if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0))
1471 warn_for_null_address (arg1);
1474 return fold_build2_loc (input_location, code, d_bool_type,
1475 arg0, d_convert (TREE_TYPE (arg0), arg1));
1478 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1479 arguments to the conditional expression. */
1481 tree
1482 build_condition (tree type, tree arg0, tree arg1, tree arg2)
1484 if (arg1 == void_node)
1485 arg1 = build_empty_stmt (input_location);
1487 if (arg2 == void_node)
1488 arg2 = build_empty_stmt (input_location);
1490 return fold_build3_loc (input_location, COND_EXPR,
1491 type, arg0, arg1, arg2);
1494 tree
1495 build_vcondition (tree arg0, tree arg1, tree arg2)
1497 return build_condition (void_type_node, arg0, arg1, arg2);
1500 /* Build a compound expr to join ARG0 and ARG1 together. */
1502 tree
1503 compound_expr (tree arg0, tree arg1)
1505 if (arg1 == NULL_TREE)
1506 return arg0;
1508 if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0))
1509 return arg1;
1511 /* Remove intermediate expressions that have no side-effects. */
1512 while (TREE_CODE (arg0) == COMPOUND_EXPR
1513 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
1514 arg0 = TREE_OPERAND (arg0, 0);
1516 if (TREE_CODE (arg1) == TARGET_EXPR)
1518 /* If the rhs is a TARGET_EXPR, then build the compound expression
1519 inside the target_expr's initializer. This helps the compiler
1520 to eliminate unnecessary temporaries. */
1521 tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1));
1522 TARGET_EXPR_INITIAL (arg1) = init;
1524 return arg1;
1527 return fold_build2_loc (input_location, COMPOUND_EXPR,
1528 TREE_TYPE (arg1), arg0, arg1);
1531 /* Build a return expression. */
1533 tree
1534 return_expr (tree ret)
1536 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary
1537 in TARGET_EXPR_SLOT. */
1538 if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR)
1540 tree exp = TARGET_EXPR_INITIAL (ret);
1541 tree init = stabilize_expr (&exp);
1543 exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp);
1544 TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp);
1546 return ret;
1549 return fold_build1_loc (input_location, RETURN_EXPR,
1550 void_type_node, ret);
1553 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1555 tree
1556 size_mult_expr (tree arg0, tree arg1)
1558 return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1559 d_convert (size_type_node, arg0),
1560 d_convert (size_type_node, arg1));
1564 /* Return the real part of CE, which should be a complex expression. */
1566 tree
1567 real_part (tree ce)
1569 return fold_build1_loc (input_location, REALPART_EXPR,
1570 TREE_TYPE (TREE_TYPE (ce)), ce);
1573 /* Return the imaginary part of CE, which should be a complex expression. */
1575 tree
1576 imaginary_part (tree ce)
1578 return fold_build1_loc (input_location, IMAGPART_EXPR,
1579 TREE_TYPE (TREE_TYPE (ce)), ce);
1582 /* Build a complex expression of type TYPE using RE and IM. */
1584 tree
1585 complex_expr (tree type, tree re, tree im)
1587 return fold_build2_loc (input_location, COMPLEX_EXPR,
1588 type, re, im);
1591 /* Build a two-field record TYPE representing the complex expression EXPR. */
1593 tree
1594 underlying_complex_expr (tree type, tree expr)
1596 gcc_assert (list_length (TYPE_FIELDS (type)) == 2);
1598 expr = d_save_expr (expr);
1600 /* Build a constructor from the real and imaginary parts. */
1601 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (expr)) &&
1602 (!INDIRECT_REF_P (expr)
1603 || !CONVERT_EXPR_P (TREE_OPERAND (expr, 0))))
1605 vec <constructor_elt, va_gc> *ve = NULL;
1606 CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type),
1607 real_part (expr));
1608 CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)),
1609 imaginary_part (expr));
1610 return build_constructor (type, ve);
1613 /* Replace type in the reinterpret cast with a cast to the record type. */
1614 return build_vconvert (type, expr);
1617 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1618 The back-end requires this cast in many cases. */
1620 tree
1621 indirect_ref (tree type, tree exp)
1623 if (error_operand_p (exp))
1624 return exp;
1626 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1627 tree init = stabilize_expr (&exp);
1629 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
1630 exp = fold_build1 (INDIRECT_REF, type, exp);
1631 else
1633 exp = build_nop (build_pointer_type (type), exp);
1634 exp = build_deref (exp);
1637 return compound_expr (init, exp);
1640 /* Returns indirect reference of EXP, which must be a pointer type. */
1642 tree
1643 build_deref (tree exp)
1645 if (error_operand_p (exp))
1646 return exp;
1648 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1649 tree init = stabilize_expr (&exp);
1651 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
1653 if (TREE_CODE (exp) == ADDR_EXPR)
1654 exp = TREE_OPERAND (exp, 0);
1655 else
1656 exp = build_fold_indirect_ref (exp);
1658 return compound_expr (init, exp);
1661 /* Builds pointer offset expression PTR[INDEX]. */
1663 tree
1664 build_pointer_index (tree ptr, tree index)
1666 if (error_operand_p (ptr) || error_operand_p (index))
1667 return error_mark_node;
1669 tree ptr_type = TREE_TYPE (ptr);
1670 tree target_type = TREE_TYPE (ptr_type);
1672 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1673 TYPE_UNSIGNED (sizetype));
1675 /* Array element size. */
1676 tree size_exp = size_in_bytes (target_type);
1678 if (integer_zerop (size_exp) || integer_onep (size_exp))
1680 /* Array of void or bytes -- No need to multiply. */
1681 index = fold_convert (type, index);
1683 else
1685 index = d_convert (type, index);
1686 index = fold_build2 (MULT_EXPR, TREE_TYPE (index),
1687 index, d_convert (TREE_TYPE (index), size_exp));
1688 index = fold_convert (type, index);
1691 if (integer_zerop (index))
1692 return ptr;
1694 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);
1697 /* Builds pointer offset expression *(PTR OP OFFSET)
1698 OP could be a plus or minus expression. */
1700 tree
1701 build_offset_op (tree_code op, tree ptr, tree offset)
1703 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);
1705 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1706 TYPE_UNSIGNED (sizetype));
1707 offset = fold_convert (type, offset);
1709 if (op == MINUS_EXPR)
1710 offset = fold_build1 (NEGATE_EXPR, type, offset);
1712 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);
1715 /* Builds pointer offset expression *(PTR + OFFSET). */
1717 tree
1718 build_offset (tree ptr, tree offset)
1720 return build_offset_op (PLUS_EXPR, ptr, offset);
1723 tree
1724 build_memref (tree type, tree ptr, tree offset)
1726 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));
1729 /* Create a tree node to set multiple elements to a single value. */
1731 tree
1732 build_array_set (tree ptr, tree length, tree value)
1734 tree ptrtype = TREE_TYPE (ptr);
1735 tree lentype = TREE_TYPE (length);
1737 push_binding_level (level_block);
1738 push_stmt_list ();
1740 /* Build temporary locals for length and ptr, and maybe value. */
1741 tree t = build_local_temp (size_type_node);
1742 add_stmt (build_assign (INIT_EXPR, t, length));
1743 length = t;
1745 t = build_local_temp (ptrtype);
1746 add_stmt (build_assign (INIT_EXPR, t, ptr));
1747 ptr = t;
1749 if (TREE_SIDE_EFFECTS (value))
1751 t = build_local_temp (TREE_TYPE (value));
1752 add_stmt (build_assign (INIT_EXPR, t, value));
1753 value = t;
1756 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1757 push_stmt_list ();
1759 /* Exit logic for the loop.
1760 if (length == 0) break; */
1761 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1762 t = build1 (EXIT_EXPR, void_type_node, t);
1763 add_stmt (t);
1765 /* Assign value to the current pointer position.
1766 *ptr = value; */
1767 t = modify_expr (build_deref (ptr), value);
1768 add_stmt (t);
1770 /* Move pointer to next element position.
1771 ptr++; */
1772 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));
1773 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));
1774 add_stmt (t);
1776 /* Decrease loop counter.
1777 length -= 1; */
1778 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1779 d_convert (lentype, integer_one_node));
1780 add_stmt (t);
1782 /* Pop statements and finish loop. */
1783 tree loop_body = pop_stmt_list ();
1784 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));
1786 /* Wrap it up into a bind expression. */
1787 tree stmt_list = pop_stmt_list ();
1788 tree block = pop_binding_level ();
1790 return build3 (BIND_EXPR, void_type_node,
1791 BLOCK_VARS (block), stmt_list, block);
1795 /* Build an array of type TYPE where all the elements are VAL. */
1797 tree
1798 build_array_from_val (Type *type, tree val)
1800 tree etype = build_ctype (type->nextOf ());
1802 /* Initializing a multidimensional array. */
1803 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)
1804 val = build_array_from_val (type->nextOf (), val);
1806 size_t dims = type->isTypeSArray ()->dim->toInteger ();
1807 vec <constructor_elt, va_gc> *elms = NULL;
1808 vec_safe_reserve (elms, dims);
1810 val = d_convert (etype, val);
1812 for (size_t i = 0; i < dims; i++)
1813 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
1815 return build_constructor (build_ctype (type), elms);
1818 /* Build a static array of type TYPE from an array of EXPS.
1819 If CONST_P is true, then all elements in EXPS are constants. */
1821 tree
1822 build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
1824 /* Build a CONSTRUCTOR from all expressions. */
1825 vec <constructor_elt, va_gc> *elms = NULL;
1826 vec_safe_reserve (elms, exps->length);
1828 Type *etype = type->nextOf ();
1829 tree satype = make_array_type (etype, exps->length);
1831 for (size_t i = 0; i < exps->length; i++)
1833 Expression *expr = (*exps)[i];
1834 tree t = build_expr (expr, const_p);
1835 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1836 convert_expr (t, expr->type, etype));
1839 /* Create a new temporary to store the array. */
1840 tree var = build_local_temp (satype);
1842 /* Fill any alignment holes with zeroes. */
1843 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
1844 tree init = NULL;
1845 if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ()))
1846 init = build_memset_call (var);
1848 /* Initialize the temporary. */
1849 tree assign = modify_expr (var, build_constructor (satype, elms));
1850 return compound_expr (compound_expr (init, assign), var);
1854 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1856 tree
1857 void_okay_p (tree t)
1859 tree type = TREE_TYPE (t);
1861 if (VOID_TYPE_P (TREE_TYPE (type)))
1863 tree totype = build_ctype (dmd::pointerTo (Type::tuns8));
1864 return fold_convert (totype, t);
1867 return t;
1870 /* Builds a STRING_CST representing the filename of location LOC. When the
1871 location is not valid, the name of the source module is used instead. */
1873 static tree
1874 build_filename_from_loc (const Loc &loc)
1876 const char *filename = loc.filename ();
1878 if (filename == NULL)
1879 filename = d_function_chain->module->srcfile.toChars ();
1881 unsigned length = strlen (filename);
1882 tree str = build_string (length, filename);
1883 TREE_TYPE (str) = make_array_type (Type::tchar, length + 1);
1885 return build_address (str);
1888 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1889 an assert check fails. When calling the msg variant functions, MSG is the
1890 error message supplied by the user. */
1892 tree
1893 build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
1895 tree file;
1896 tree line = size_int (loc.linnum ());
1898 switch (libcall)
1900 case LIBCALL_ASSERT_MSG:
1901 case LIBCALL_UNITTEST_MSG:
1902 /* File location is passed as a D string. */
1903 if (const char *filename = loc.filename ())
1905 unsigned len = strlen (filename);
1906 tree str = build_string (len, filename);
1907 TREE_TYPE (str) = make_array_type (Type::tchar, len);
1909 file = d_array_value (build_ctype (dmd::arrayOf (Type::tchar)),
1910 size_int (len), build_address (str));
1912 else
1913 file = null_array_node;
1914 break;
1916 case LIBCALL_ASSERTP:
1917 case LIBCALL_UNITTESTP:
1918 file = build_filename_from_loc (loc);
1919 break;
1921 default:
1922 gcc_unreachable ();
1926 if (msg != NULL_TREE)
1927 return build_libcall (libcall, Type::tvoid, 3, msg, file, line);
1928 else
1929 return build_libcall (libcall, Type::tvoid, 2, file, line);
1932 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
1933 array bounds check fails. */
1935 tree
1936 build_array_bounds_call (const Loc &loc)
1938 /* Terminate the program with a trap if no D runtime present. */
1939 if (checkaction_trap_p ())
1940 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1941 else
1943 return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
1944 build_filename_from_loc (loc),
1945 size_int (loc.linnum ()));
1949 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1950 in the index expression IE. The condition returns the INDEX if true, or
1951 throws a `ArrayIndexError`. */
1953 tree
1954 build_bounds_index_condition (IndexExp *ie, tree index, tree length)
1956 if (ie->indexIsInBounds || !array_bounds_check ())
1957 return index;
1959 /* Prevent multiple evaluations of the index. */
1960 index = d_save_expr (index);
1962 /* Generate INDEX >= LENGTH && throw RangeError.
1963 No need to check whether INDEX >= 0 as the front-end should
1964 have already taken care of implicit casts to unsigned. */
1965 tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length);
1966 tree boundserr;
1968 if (checkaction_trap_p ())
1969 boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1970 else
1972 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
1973 build_filename_from_loc (ie->e2->loc),
1974 size_int (ie->e2->loc.linnum ()),
1975 index, length);
1978 return build_condition (TREE_TYPE (index), condition, boundserr, index);
1981 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1982 the slice expression SE of the source array length LENGTH. The condition
1983 returns the new array length if true, or throws an `ArraySliceError`. */
1985 tree
1986 build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
1988 if (array_bounds_check ())
1990 tree condition = NULL_TREE;
1992 /* Enforces that `upper <= length`. */
1993 if (!se->upperIsInBounds () && length != NULL_TREE)
1994 condition = fold_build2 (GT_EXPR, d_bool_type, upper, length);
1995 else
1996 length = integer_zero_node;
1998 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1999 we've already ensured that `upper <= length`. */
2000 if (!se->lowerIsLessThanUpper ())
2002 tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper);
2004 if (condition != NULL_TREE)
2005 condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond);
2006 else
2007 condition = lwr_cond;
2010 if (condition != NULL_TREE)
2012 tree boundserr;
2014 if (checkaction_trap_p ())
2016 boundserr =
2017 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2019 else
2021 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
2022 Type::tvoid, 5,
2023 build_filename_from_loc (se->loc),
2024 size_int (se->loc.linnum ()),
2025 lower, upper, length);
2028 upper = build_condition (TREE_TYPE (upper), condition,
2029 boundserr, upper);
2033 /* Need to ensure lower always gets evaluated first, as it may be a function
2034 call. Generates (lower, upper) - lower. */
2035 return fold_build2 (MINUS_EXPR, TREE_TYPE (upper),
2036 compound_expr (lower, upper), lower);
2039 /* Returns TRUE if array bounds checking code generation is turned on. */
2041 bool
2042 array_bounds_check (void)
2044 FuncDeclaration *fd;
2046 switch (global.params.useArrayBounds)
2048 case CHECKENABLEoff:
2049 return false;
2051 case CHECKENABLEon:
2052 return true;
2054 case CHECKENABLEsafeonly:
2055 /* For D2 safe functions only. */
2056 fd = d_function_chain->function;
2057 if (fd && fd->type->ty == TY::Tfunction)
2059 if (fd->type->isTypeFunction ()->trust == TRUST::safe)
2060 return true;
2062 return false;
2064 default:
2065 gcc_unreachable ();
2069 /* Returns TRUE if we terminate the program with a trap if an array bounds or
2070 contract check fails. */
2072 bool
2073 checkaction_trap_p (void)
2075 switch (global.params.checkAction)
2077 case CHECKACTION_D:
2078 case CHECKACTION_context:
2079 return false;
2081 case CHECKACTION_C:
2082 case CHECKACTION_halt:
2083 return true;
2085 default:
2086 gcc_unreachable ();
2090 /* Returns the TypeFunction class for Type T.
2091 Assumes T is already ->toBasetype(). */
2093 TypeFunction *
2094 get_function_type (Type *t)
2096 TypeFunction *tf = NULL;
2097 if (t->ty == TY::Tpointer)
2098 t = t->nextOf ()->toBasetype ();
2099 if (t->ty == TY::Tfunction)
2100 tf = t->isTypeFunction ();
2101 else if (t->ty == TY::Tdelegate)
2102 tf = t->isTypeDelegate ()->next->isTypeFunction ();
2103 return tf;
2106 /* Returns TRUE if calling the function FUNC, or calling a function or delegate
2107 object of type TYPE is be free of side effects. */
2109 bool
2110 call_side_effect_free_p (FuncDeclaration *func, Type *type)
2112 gcc_assert (func != NULL || type != NULL);
2114 if (func != NULL)
2116 /* Constructor and invariant calls can't be `pure'. */
2117 if (func->isCtorDeclaration () || func->isInvariantDeclaration ())
2118 return false;
2120 /* Must be a `nothrow' function. */
2121 TypeFunction *tf = func->type->toTypeFunction ();
2122 if (!tf->isnothrow ())
2123 return false;
2125 /* Return type can't be `void' or `noreturn', as that implies all work is
2126 done via side effects. */
2127 if (tf->next->ty == TY::Tvoid || tf->next->ty == TY::Tnoreturn)
2128 return false;
2130 /* Only consider it as `pure' if it can't modify its arguments. */
2131 if (func->isPure () == PURE::const_)
2132 return true;
2135 if (type != NULL)
2137 TypeFunction *tf = get_function_type (type);
2139 /* Must be a `nothrow` function type. */
2140 if (tf == NULL || !tf->isnothrow ())
2141 return false;
2143 /* Return type can't be `void' or `noreturn', as that implies all work is
2144 done via side effects. */
2145 if (tf->next->ty == TY::Tvoid || tf->next->ty == TY::Tnoreturn)
2146 return false;
2148 /* Delegates that can modify its context can't be `pure'. */
2149 if (type->isTypeDelegate () && tf->isMutable ())
2150 return false;
2152 /* Only consider it as `pure' if it can't modify its arguments. */
2153 if (tf->purity == PURE::const_)
2154 return true;
2157 return false;
2160 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
2161 CALLER. In which case, CALLEE is being called through an alias that was
2162 passed to CALLER. */
2164 bool
2165 call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)
2167 if (!callee->isNested ())
2168 return false;
2170 if (caller->toParent () == callee->toParent ())
2171 return false;
2173 Dsymbol *dsym = callee;
2175 while (dsym)
2177 if (dsym->isTemplateInstance ())
2178 return false;
2179 else if (dsym->isFuncDeclaration () == caller)
2180 return false;
2181 dsym = dsym->toParent ();
2184 return true;
2187 /* Entry point for call routines. Builds a function call to FD.
2188 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
2190 tree
2191 d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)
2193 return d_build_call (get_function_type (fd->type),
2194 build_address (get_symbol_decl (fd)), object, arguments);
2197 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
2198 ARGUMENTS are evaluated in left to right order, saved and promoted
2199 before passing. */
2201 tree
2202 d_build_call (TypeFunction *tf, tree callable, tree object,
2203 Expressions *arguments)
2205 tree ctype = TREE_TYPE (callable);
2206 tree callee = callable;
2208 if (POINTER_TYPE_P (ctype))
2209 ctype = TREE_TYPE (ctype);
2210 else
2211 callee = build_address (callable);
2213 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));
2214 gcc_assert (tf != NULL);
2215 gcc_assert (tf->ty == TY::Tfunction);
2217 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)
2219 /* Front-end apparently doesn't check this. */
2220 if (TREE_CODE (callable) == FUNCTION_DECL)
2222 error ("need %<this%> to access member %qE", DECL_NAME (callable));
2223 return error_mark_node;
2226 /* Probably an internal error. */
2227 gcc_unreachable ();
2230 /* Build the argument list for the call. */
2231 vec <tree, va_gc> *args = NULL;
2232 bool noreturn_call = false;
2234 /* If this is a delegate call or a nested function being called as
2235 a delegate, the object should not be NULL. */
2236 if (object != NULL_TREE)
2237 vec_safe_push (args, object);
2239 if (arguments)
2241 const size_t nparams = tf->parameterList.length ();
2242 /* if _arguments[] is the first argument. */
2243 const size_t varargs = tf->isDstyleVariadic ();
2245 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2246 for (size_t i = 0; i < arguments->length; ++i)
2248 Expression *arg = (*arguments)[i];
2249 tree targ;
2251 if (i - varargs < nparams && i >= varargs)
2253 /* Actual arguments for declared formal arguments. */
2254 Parameter *parg = tf->parameterList[i - varargs];
2255 targ = convert_for_argument (arg, parg);
2257 else
2258 targ = build_expr (arg);
2260 /* Don't pass empty aggregates by value. */
2261 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
2262 && TREE_CODE (targ) != CONSTRUCTOR)
2264 tree t = build_constructor (TREE_TYPE (targ), NULL);
2265 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
2268 /* Parameter is a struct or array passed by invisible reference. */
2269 if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
2271 Type *t = arg->type->toBasetype ();
2272 StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
2274 /* Need to take care of copying its value before passing the
2275 argument in the following scenarios:
2276 - The argument is a literal expression; a CONSTRUCTOR can't
2277 have its address taken.
2278 - The type has neither a copy constructor nor a destructor
2279 available; nested structs also have ADDRESSABLE set.
2280 - The ABI of the function expects the callee to destroy its
2281 arguments; when the caller is handles destruction, then `targ'
2282 has already been made into a temporary. */
2283 if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor)
2284 || target.isCalleeDestroyingArgs (tf))
2285 targ = force_target_expr (targ);
2287 targ = convert (build_reference_type (TREE_TYPE (targ)),
2288 build_address (targ));
2291 /* Complex types are exposed as special types with an underlying
2292 struct representation, if we are passing the native type to a
2293 function that accepts the library-defined version, then ensure
2294 it is properly reinterpreted as the underlying struct type. */
2295 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (targ))
2296 && arg->type->isTypeStruct ())
2297 targ = underlying_complex_expr (build_ctype (arg->type), targ);
2299 /* Type `noreturn` is a terminator, as no other arguments can possibly
2300 be evaluated after it. */
2301 if (TREE_TYPE (targ) == noreturn_type_node)
2302 noreturn_call = true;
2304 vec_safe_push (args, targ);
2308 /* If we saw a `noreturn` parameter, any unreachable argument evaluations
2309 after it are discarded, as well as the function call itself. */
2310 if (noreturn_call)
2312 tree saved_args = NULL_TREE;
2314 if (TREE_SIDE_EFFECTS (callee))
2315 saved_args = compound_expr (callee, saved_args);
2317 tree arg;
2318 unsigned int ix;
2320 FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
2321 saved_args = compound_expr (saved_args, arg);
2323 /* Add a stub result type for the expression. */
2324 tree result = build_zero_cst (TREE_TYPE (ctype));
2325 return compound_expr (saved_args, result);
2328 tree result = build_call_vec (TREE_TYPE (ctype), callee, args);
2329 SET_EXPR_LOCATION (result, input_location);
2331 result = maybe_expand_intrinsic (result);
2333 /* Return the value in a temporary slot so that it can be evaluated
2334 multiple times by the caller. */
2335 if (TREE_CODE (result) == CALL_EXPR
2336 && AGGREGATE_TYPE_P (TREE_TYPE (result))
2337 && TREE_ADDRESSABLE (TREE_TYPE (result)))
2339 CALL_EXPR_RETURN_SLOT_OPT (result) = true;
2340 result = force_target_expr (result);
2343 return result;
2346 /* Build and return the correct call to fmod depending on TYPE.
2347 ARG0 and ARG1 are the arguments pass to the function. */
2349 tree
2350 build_float_modulus (tree type, tree arg0, tree arg1)
2352 tree fmodfn = NULL_TREE;
2353 tree basetype = type;
2355 if (COMPLEX_FLOAT_TYPE_P (basetype))
2356 basetype = TREE_TYPE (basetype);
2358 if (TYPE_MAIN_VARIANT (basetype) == double_type_node
2359 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)
2360 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);
2361 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node
2362 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)
2363 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);
2364 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node
2365 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)
2366 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);
2368 if (!fmodfn)
2370 error ("tried to perform floating-point modulo division on %qT", type);
2371 return error_mark_node;
2374 if (COMPLEX_FLOAT_TYPE_P (type))
2376 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);
2377 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);
2379 return complex_expr (type, re, im);
2382 if (SCALAR_FLOAT_TYPE_P (type))
2383 return build_call_expr (fmodfn, 2, arg0, arg1);
2385 /* Should have caught this above. */
2386 gcc_unreachable ();
2389 /* Build a function type whose first argument is a pointer to BASETYPE,
2390 which is to be used for the `vthis' context parameter for TYPE.
2391 The base type may be a record for member functions, or a void for
2392 nested functions and delegates. */
2394 tree
2395 build_vthis_function (tree basetype, tree type)
2397 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
2399 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),
2400 TYPE_ARG_TYPES (type));
2401 tree fntype = build_function_type (TREE_TYPE (type), argtypes);
2403 /* Copy volatile qualifiers from the original function type. */
2404 if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE)
2405 fntype = build_qualified_type (fntype, TYPE_QUAL_VOLATILE);
2407 if (RECORD_OR_UNION_TYPE_P (basetype))
2408 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);
2409 else
2410 gcc_assert (VOID_TYPE_P (basetype));
2412 return fntype;
2415 /* Raise an error at that the context pointer of the function or object SYM is
2416 not accessible from the current scope. */
2418 tree
2419 error_no_frame_access (Dsymbol *sym)
2421 error_at (input_location, "cannot get frame pointer to %qs",
2422 sym->toPrettyChars ());
2423 return null_pointer_node;
2426 /* If SYM is a nested function, return the static chain to be
2427 used when calling that function from the current function.
2429 If SYM is a nested class or struct, return the static chain
2430 to be used when creating an instance of the class from CFUN. */
2432 tree
2433 get_frame_for_symbol (Dsymbol *sym)
2435 FuncDeclaration *thisfd
2436 = d_function_chain ? d_function_chain->function : NULL;
2437 FuncDeclaration *fd = sym->isFuncDeclaration ();
2438 FuncDeclaration *fdparent = NULL;
2439 FuncDeclaration *fdoverride = NULL;
2441 if (fd != NULL)
2443 /* Check that the nested function is properly defined. */
2444 if (!fd->fbody)
2446 /* Should instead error on line that references `fd'. */
2447 error_at (make_location_t (fd->loc), "nested function missing body");
2448 return null_pointer_node;
2451 fdparent = fd->toParent2 ()->isFuncDeclaration ();
2453 /* Special case for __ensure and __require. */
2454 if ((fd->ident == Identifier::idPool ("__ensure")
2455 || fd->ident == Identifier::idPool ("__require"))
2456 && fdparent != thisfd)
2458 fdoverride = fdparent;
2459 fdparent = thisfd;
2462 else
2464 /* It's a class (or struct). NewExp codegen has already determined its
2465 outer scope is not another class, so it must be a function. */
2466 while (sym && !sym->isFuncDeclaration ())
2467 sym = sym->toParent2 ();
2469 fdparent = (FuncDeclaration *) sym;
2472 /* Not a nested function, there is no frame pointer to pass. */
2473 if (fdparent == NULL)
2475 /* Only delegate literals report as being nested, even if they are in
2476 global scope. */
2477 gcc_assert (fd && fd->isFuncLiteralDeclaration ());
2478 return null_pointer_node;
2481 gcc_assert (thisfd != NULL);
2483 if (thisfd != fdparent)
2485 /* If no frame pointer for this function. */
2486 if (!thisfd->vthis)
2488 error_at (make_location_t (sym->loc),
2489 "%qs is a nested function and cannot be accessed from %qs",
2490 fdparent->toPrettyChars (), thisfd->toPrettyChars ());
2491 return null_pointer_node;
2494 /* Make sure we can get the frame pointer to the outer function.
2495 Go up each nesting level until we find the enclosing function. */
2496 Dsymbol *dsym = thisfd;
2498 while (fd != dsym)
2500 /* Check if enclosing function is a function. */
2501 FuncDeclaration *fdp = dsym->isFuncDeclaration ();
2502 Dsymbol *parent = dsym->toParent2 ();
2504 if (fdp != NULL)
2506 if (fdparent == parent)
2507 break;
2509 gcc_assert (fdp->isNested () || fdp->vthis);
2510 dsym = parent;
2511 continue;
2514 /* Check if enclosed by an aggregate. That means the current
2515 function must be a member function of that aggregate. */
2516 AggregateDeclaration *adp = dsym->isAggregateDeclaration ();
2518 if (adp != NULL)
2520 if ((adp->isClassDeclaration () || adp->isStructDeclaration ())
2521 && fdparent == parent)
2522 break;
2525 /* No frame to outer function found. */
2526 if (!adp || !adp->isNested () || !adp->vthis)
2527 return error_no_frame_access (sym);
2529 dsym = parent;
2533 tree ffo = get_frameinfo (fdparent);
2534 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2536 tree frame_ref = get_framedecl (thisfd, fdparent);
2538 /* If `thisfd' is a derived member function, then `fdparent' is the
2539 overridden member function in the base class. Even if there's a
2540 closure environment, we should give the original stack data as the
2541 nested function frame. */
2542 if (fdoverride)
2544 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2545 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2546 gcc_assert (cdo && cd);
2548 int offset;
2549 if (cdo->isBaseOf (cd, &offset) && offset != 0)
2551 /* Generate a new frame to pass to the overriden function that
2552 has the `this' pointer adjusted. */
2553 gcc_assert (offset != OFFSET_RUNTIME);
2555 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2556 tree fields = TYPE_FIELDS (type);
2557 /* The `this' field comes immediately after the `__chain'. */
2558 tree thisfield = chain_index (1, fields);
2559 vec <constructor_elt, va_gc> *ve = NULL;
2561 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2562 frame_ref = build_deref (frame_ref);
2564 for (tree field = fields; field; field = DECL_CHAIN (field))
2566 tree value = component_ref (frame_ref, framefields);
2567 if (field == thisfield)
2568 value = build_offset (value, size_int (offset));
2570 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2571 framefields = DECL_CHAIN (framefields);
2574 frame_ref = build_address (build_constructor (type, ve));
2578 return frame_ref;
2581 return null_pointer_node;
2584 /* Return the parent function of a nested class or struct AD. */
2586 static FuncDeclaration *
2587 get_outer_function (AggregateDeclaration *ad)
2589 FuncDeclaration *fd = NULL;
2590 while (ad && ad->isNested ())
2592 Dsymbol *dsym = ad->toParent2 ();
2593 if ((fd = dsym->isFuncDeclaration ()))
2594 return fd;
2595 else
2596 ad = dsym->isAggregateDeclaration ();
2599 return NULL;
2602 /* Starting from the current function FD, try to find a suitable value of
2603 `this' in nested function instances. A suitable `this' value is an
2604 instance of OCD or a class that has OCD as a base. */
2606 static tree
2607 find_this_tree (ClassDeclaration *ocd)
2609 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2611 while (fd)
2613 AggregateDeclaration *ad = fd->isThis ();
2614 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;
2616 if (cd != NULL)
2618 if (ocd == cd)
2619 return get_decl_tree (fd->vthis);
2620 else if (ocd->isBaseOf (cd, NULL))
2621 return convert_expr (get_decl_tree (fd->vthis),
2622 cd->type, ocd->type);
2624 fd = get_outer_function (cd);
2625 continue;
2628 if (fd->isNested ())
2630 fd = fd->toParent2 ()->isFuncDeclaration ();
2631 continue;
2634 fd = NULL;
2637 return NULL_TREE;
2640 /* Retrieve the outer class/struct `this' value of DECL from
2641 the current function. */
2643 tree
2644 build_vthis (AggregateDeclaration *decl)
2646 ClassDeclaration *cd = decl->isClassDeclaration ();
2647 StructDeclaration *sd = decl->isStructDeclaration ();
2649 /* If an aggregate nested in a function has no methods and there are no
2650 other nested functions, any static chain created here will never be
2651 translated. Use a null pointer for the link in this case. */
2652 tree vthis_value = null_pointer_node;
2654 if (cd != NULL || sd != NULL)
2656 Dsymbol *outer = decl->toParent2 ();
2658 /* If the parent is a templated struct, the outer context is instead
2659 the enclosing symbol of where the instantiation happened. */
2660 if (outer->isStructDeclaration ())
2662 gcc_assert (outer->parent && outer->parent->isTemplateInstance ());
2663 outer = ((TemplateInstance *) outer->parent)->enclosing;
2666 /* For outer classes, get a suitable `this' value.
2667 For outer functions, get a suitable frame/closure pointer. */
2668 ClassDeclaration *cdo = outer->isClassDeclaration ();
2669 FuncDeclaration *fdo = outer->isFuncDeclaration ();
2671 if (cdo)
2673 vthis_value = find_this_tree (cdo);
2674 gcc_assert (vthis_value != NULL_TREE);
2676 else if (fdo)
2678 tree ffo = get_frameinfo (fdo);
2679 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)
2680 || fdo->hasNestedFrameRefs ())
2681 vthis_value = get_frame_for_symbol (decl);
2682 else if (cd != NULL)
2684 /* Classes nested in methods are allowed to access any outer
2685 class fields, use the function chain in this case. */
2686 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)
2687 vthis_value = get_decl_tree (fdo->vthis);
2690 else
2691 gcc_unreachable ();
2694 return vthis_value;
2697 /* Build the RECORD_TYPE that describes the function frame or closure type for
2698 the function FD. FFI is the tree holding all frame information. */
2700 static tree
2701 build_frame_type (tree ffi, FuncDeclaration *fd)
2703 if (FRAMEINFO_TYPE (ffi))
2704 return FRAMEINFO_TYPE (ffi);
2706 tree frame_rec_type = make_node (RECORD_TYPE);
2707 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.",
2708 fd->toPrettyChars (), NULL);
2709 TYPE_NAME (frame_rec_type) = get_identifier (name);
2710 free (name);
2712 tree fields = NULL_TREE;
2714 /* Function is a member or nested, so must have field for outer context. */
2715 if (fd->vthis)
2717 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
2718 get_identifier ("__chain"), ptr_type_node);
2719 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;
2720 fields = chainon (NULL_TREE, ptr_field);
2721 DECL_NONADDRESSABLE_P (ptr_field) = 1;
2724 /* The __ensure and __require are called directly, so never make the outer
2725 functions closure, but nevertheless could still be referencing parameters
2726 of the calling function non-locally. So we add all parameters with nested
2727 refs to the function frame, this should also mean overriding methods will
2728 have the same frame layout when inheriting a contract. */
2729 if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
2730 || (global.params.useOut == CHECKENABLEon && fd->fensure ()))
2732 if (fd->parameters)
2734 for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++)
2736 VarDeclaration *v = (*fd->parameters)[i];
2737 /* Remove if already in closureVars so can push to front. */
2738 size_t j = fd->closureVars.find (v);
2740 if (j < fd->closureVars.length)
2741 fd->closureVars.remove (j);
2743 fd->closureVars.insert (i, v);
2747 /* Also add hidden `this' to outer context. */
2748 if (fd->vthis)
2750 size_t i = fd->closureVars.find (fd->vthis);
2752 if (i < fd->closureVars.length)
2753 fd->closureVars.remove (i);
2755 fd->closureVars.insert (0, fd->vthis);
2759 for (size_t i = 0; i < fd->closureVars.length; i++)
2761 VarDeclaration *v = fd->closureVars[i];
2762 tree vsym = get_symbol_decl (v);
2763 tree ident = v->ident
2764 ? get_identifier (v->ident->toChars ()) : NULL_TREE;
2766 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,
2767 TREE_TYPE (vsym));
2768 SET_DECL_LANG_FRAME_FIELD (vsym, field);
2769 DECL_FIELD_CONTEXT (field) = frame_rec_type;
2770 fields = chainon (fields, field);
2771 TREE_USED (vsym) = 1;
2773 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
2774 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
2775 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
2776 SET_DECL_ALIGN (field, DECL_ALIGN (vsym));
2778 /* Update alignment for frame record type. */
2779 if (TYPE_ALIGN (frame_rec_type) < DECL_ALIGN (field))
2780 SET_TYPE_ALIGN (frame_rec_type, DECL_ALIGN (field));
2782 if (DECL_LANG_NRVO (vsym))
2784 /* Store the nrvo variable in the frame by reference. */
2785 TREE_TYPE (field) = build_reference_type (TREE_TYPE (field));
2787 /* Can't do nrvo if the variable is put in a closure, since what the
2788 return slot points to may no longer exist. */
2789 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi));
2792 if (FRAMEINFO_IS_CLOSURE (ffi))
2794 /* Because the value needs to survive the end of the scope. */
2795 if ((v->edtor && (v->storage_class & STCparameter))
2796 || v->needsScopeDtor ())
2797 error_at (make_location_t (v->loc),
2798 "variable %qs has scoped destruction, "
2799 "cannot build closure", v->toChars ());
2802 if (DECL_REGISTER (vsym))
2804 /* Because the value will be in memory, not a register. */
2805 error_at (make_location_t (v->loc),
2806 "explicit register variable %qs cannot be used in nested "
2807 "function", v->toChars ());
2811 TYPE_FIELDS (frame_rec_type) = fields;
2812 TYPE_READONLY (frame_rec_type) = 1;
2813 TYPE_CXX_ODR_P (frame_rec_type) = 1;
2814 layout_type (frame_rec_type);
2815 d_keep (frame_rec_type);
2817 return frame_rec_type;
2820 /* Closures are implemented by taking the local variables that
2821 need to survive the scope of the function, and copying them
2822 into a GC allocated chuck of memory. That chunk, called the
2823 closure here, is inserted into the linked list of stack
2824 frames instead of the usual stack frame.
2826 If a closure is not required, but FD still needs a frame to lower
2827 nested refs, then instead build custom static chain decl on stack. */
2829 void
2830 build_closure (FuncDeclaration *fd)
2832 tree ffi = get_frameinfo (fd);
2834 if (!FRAMEINFO_CREATES_FRAME (ffi))
2835 return;
2837 tree type = FRAMEINFO_TYPE (ffi);
2838 gcc_assert (COMPLETE_TYPE_P (type));
2840 tree decl, decl_ref;
2842 if (FRAMEINFO_IS_CLOSURE (ffi))
2844 decl = build_local_temp (build_pointer_type (type));
2845 DECL_NAME (decl) = get_identifier ("__closptr");
2846 decl_ref = build_deref (decl);
2848 /* Allocate memory for closure. */
2849 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
2850 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
2852 tree init_exp = build_assign (INIT_EXPR, decl,
2853 build_nop (TREE_TYPE (decl), init));
2854 add_stmt (init_exp);
2856 else
2858 decl = build_local_temp (type);
2859 DECL_NAME (decl) = get_identifier ("__frame");
2860 decl_ref = decl;
2863 /* Set the first entry to the parent closure/frame, if any. */
2864 if (fd->vthis)
2866 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));
2867 tree chain_expr = modify_expr (chain_field,
2868 d_function_chain->static_chain);
2869 add_stmt (chain_expr);
2872 /* Copy parameters that are referenced nonlocally. */
2873 for (size_t i = 0; i < fd->closureVars.length; i++)
2875 VarDeclaration *v = fd->closureVars[i];
2876 tree vsym = get_symbol_decl (v);
2878 if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym))
2879 continue;
2881 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));
2883 /* Variable is an alias for the NRVO slot, store the reference. */
2884 if (DECL_LANG_NRVO (vsym))
2885 vsym = build_address (DECL_LANG_NRVO (vsym));
2887 tree expr = modify_expr (field, vsym);
2888 add_stmt (expr);
2891 if (!FRAMEINFO_IS_CLOSURE (ffi))
2892 decl = build_address (decl);
2894 d_function_chain->static_chain = decl;
2897 /* Return the frame of FD. This could be a static chain or a closure
2898 passed via the hidden `this' pointer. */
2900 tree
2901 get_frameinfo (FuncDeclaration *fd)
2903 tree fds = get_symbol_decl (fd);
2904 if (DECL_LANG_FRAMEINFO (fds))
2905 return DECL_LANG_FRAMEINFO (fds);
2907 tree ffi = make_node (FUNCFRAME_INFO);
2909 DECL_LANG_FRAMEINFO (fds) = ffi;
2911 const bool requiresClosure = fd->requiresClosure;
2912 if (fd->needsClosure ())
2914 /* This can shift due to templates being expanded that access alias
2915 symbols, give it a decent error for now. */
2916 if (requiresClosure != fd->requiresClosure
2917 && (fd->nrvo_var || !global.params.useGC))
2918 fd->checkClosure ();
2920 /* Set-up a closure frame, this will be allocated on the heap. */
2921 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2922 FRAMEINFO_IS_CLOSURE (ffi) = 1;
2924 else if (fd->hasNestedFrameRefs ())
2926 /* Functions with nested refs must create a static frame for local
2927 variables to be referenced from. */
2928 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2930 else
2932 /* For nested functions, default to creating a frame. Even if there are
2933 no fields to populate the frame, create it anyway, as this will be
2934 used as the record type instead of `void*` for the this parameter. */
2935 if (fd->vthis && fd->vthis->type == Type::tvoidptr)
2936 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2938 /* In checkNestedReference, references from contracts are not added to the
2939 closureVars array, so assume all parameters referenced. */
2940 if ((global.params.useIn == CHECKENABLEon && fd->frequire ())
2941 || (global.params.useOut == CHECKENABLEon && fd->fensure ()))
2942 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2944 /* If however `fd` is nested (deeply) in a function that creates a
2945 closure, then `fd` instead inherits that closure via hidden vthis
2946 pointer, and doesn't create a stack frame at all. */
2947 FuncDeclaration *ff = fd;
2949 while (ff)
2951 tree ffo = get_frameinfo (ff);
2953 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))
2955 gcc_assert (FRAMEINFO_TYPE (ffo));
2956 FRAMEINFO_CREATES_FRAME (ffi) = 0;
2957 FRAMEINFO_STATIC_CHAIN (ffi) = 1;
2958 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);
2959 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));
2960 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);
2961 break;
2964 /* Stop looking if no frame pointer for this function. */
2965 if (ff->vthis == NULL)
2966 break;
2968 AggregateDeclaration *ad = ff->isThis ();
2969 if (ad && ad->isNested ())
2971 while (ad->isNested ())
2973 Dsymbol *d = ad->toParent2 ();
2974 ad = d->isAggregateDeclaration ();
2975 ff = d->isFuncDeclaration ();
2977 if (ad == NULL)
2978 break;
2981 else
2982 ff = ff->toParent2 ()->isFuncDeclaration ();
2986 /* Build type now as may be referenced from another module. */
2987 if (FRAMEINFO_CREATES_FRAME (ffi))
2988 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);
2990 return ffi;
2993 /* Return a pointer to the frame/closure block of OUTER
2994 so can be accessed from the function INNER. */
2996 tree
2997 get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
2999 tree result = d_function_chain->static_chain;
3000 FuncDeclaration *fd = inner;
3002 while (fd && fd != outer)
3004 /* Parent frame link is the first field. */
3005 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))
3006 result = indirect_ref (ptr_type_node, result);
3008 if (fd->isNested ())
3009 fd = fd->toParent2 ()->isFuncDeclaration ();
3010 /* The frame/closure record always points to the outer function's
3011 frame, even if there are intervening nested classes or structs.
3012 So, we can just skip over these. */
3013 else
3014 fd = get_outer_function (fd->isThis ());
3017 if (fd != outer)
3018 return error_no_frame_access (outer);
3020 /* Go get our frame record. */
3021 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
3023 if (frame_type != NULL_TREE)
3025 result = build_nop (build_pointer_type (frame_type), result);
3026 return result;
3028 else
3030 error_at (make_location_t (inner->loc),
3031 "forward reference to frame of %qs", outer->toChars ());
3032 return null_pointer_node;