d: Fix internal compiler error: Segmentation fault at gimple-expr.cc:88
[official-gcc.git] / gcc / d / d-codegen.cc
blob0f2110ec7c12a985bd4dfd9e7429dddad82252ba
1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
2 Copyright (C) 2006-2022 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/ctfe.h"
24 #include "dmd/declaration.h"
25 #include "dmd/identifier.h"
26 #include "dmd/module.h"
27 #include "dmd/target.h"
28 #include "dmd/template.h"
30 #include "tree.h"
31 #include "tree-iterator.h"
32 #include "fold-const.h"
33 #include "diagnostic.h"
34 #include "langhooks.h"
35 #include "target.h"
36 #include "stringpool.h"
37 #include "varasm.h"
38 #include "stor-layout.h"
39 #include "attribs.h"
40 #include "function.h"
42 #include "d-tree.h"
45 /* Return the GCC location for the D frontend location LOC. */
47 location_t
48 make_location_t (const Loc &loc)
50 location_t gcc_location = input_location;
52 if (loc.filename)
54 linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
55 linemap_line_start (line_table, loc.linnum, 0);
56 gcc_location = linemap_position_for_column (line_table, loc.charnum);
57 linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
60 return gcc_location;
63 /* Return the DECL_CONTEXT for symbol DSYM. */
65 tree
66 d_decl_context (Dsymbol *dsym)
68 Dsymbol *parent = dsym;
69 Declaration *decl = dsym->isDeclaration ();
70 AggregateDeclaration *ad = dsym->isAggregateDeclaration ();
72 while ((parent = parent->toParent2 ()))
74 /* We've reached the top-level module namespace.
75 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,
76 but only for extern(D) symbols. */
77 if (parent->isModule ())
79 if ((decl != NULL && decl->resolvedLinkage () != LINK::d)
80 || (ad != NULL && ad->classKind != ClassKind::d))
81 return NULL_TREE;
83 return build_import_decl (parent);
86 /* Declarations marked as `static' or `__gshared' are never
87 part of any context except at module level. */
88 if (decl != NULL && decl->isDataseg ())
89 continue;
91 /* Nested functions. */
92 FuncDeclaration *fd = parent->isFuncDeclaration ();
93 if (fd != NULL)
94 return get_symbol_decl (fd);
96 /* Methods of classes or structs. */
97 AggregateDeclaration *ad = parent->isAggregateDeclaration ();
98 if (ad != NULL)
100 tree context = build_ctype (ad->type);
101 /* Want the underlying RECORD_TYPE. */
102 if (ad->isClassDeclaration ())
103 context = TREE_TYPE (context);
105 return context;
109 return NULL_TREE;
112 /* Return a copy of record TYPE but safe to modify in any way. */
114 tree
115 copy_aggregate_type (tree type)
117 tree newtype = build_distinct_type_copy (type);
118 TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type));
120 for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f))
121 DECL_FIELD_CONTEXT (f) = newtype;
123 return newtype;
126 /* Return TRUE if declaration DECL is a reference type. */
128 bool
129 declaration_reference_p (Declaration *decl)
131 Type *tb = decl->type->toBasetype ();
133 /* Declaration is a reference type. */
134 if (tb->ty == TY::Treference || decl->storage_class & (STCout | STCref))
135 return true;
137 return false;
140 /* Returns the real type for declaration DECL. */
142 tree
143 declaration_type (Declaration *decl)
145 /* Lazy declarations are converted to delegates. */
146 if (decl->storage_class & STClazy)
148 TypeFunction *tf = TypeFunction::create (NULL, decl->type,
149 VARARGnone, LINK::d);
150 TypeDelegate *t = TypeDelegate::create (tf);
151 return build_ctype (t->merge2 ());
154 /* Static array va_list have array->pointer conversions applied. */
155 if (decl->isParameter () && valist_array_p (decl->type))
157 Type *valist = decl->type->nextOf ()->pointerTo ();
158 valist = valist->castMod (decl->type->mod);
159 return build_ctype (valist);
162 tree type = build_ctype (decl->type);
164 /* Parameter is passed by reference. */
165 if (declaration_reference_p (decl))
166 return build_reference_type (type);
168 /* The `this' parameter is always const. */
169 if (decl->isThisDeclaration ())
170 return insert_type_modifiers (type, MODconst);
172 return type;
175 /* These should match the Declaration versions above
176 Return TRUE if parameter ARG is a reference type. */
178 bool
179 parameter_reference_p (Parameter *arg)
181 Type *tb = arg->type->toBasetype ();
183 /* Parameter is a reference type. */
184 if (tb->ty == TY::Treference || arg->storageClass & (STCout | STCref))
185 return true;
187 return false;
190 /* Returns the real type for parameter ARG. */
192 tree
193 parameter_type (Parameter *arg)
195 /* Lazy parameters are converted to delegates. */
196 if (arg->storageClass & STClazy)
198 TypeFunction *tf = TypeFunction::create (NULL, arg->type,
199 VARARGnone, LINK::d);
200 TypeDelegate *t = TypeDelegate::create (tf);
201 return build_ctype (t->merge2 ());
204 /* Static array va_list have array->pointer conversions applied. */
205 if (valist_array_p (arg->type))
207 Type *valist = arg->type->nextOf ()->pointerTo ();
208 valist = valist->castMod (arg->type->mod);
209 return build_ctype (valist);
212 tree type = build_ctype (arg->type);
214 /* Parameter is passed by reference. */
215 if (parameter_reference_p (arg))
216 return build_reference_type (type);
218 /* Pass non-POD structs by invisible reference. */
219 if (TREE_ADDRESSABLE (type))
221 type = build_reference_type (type);
222 /* There are no other pointer to this temporary. */
223 type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
226 /* Front-end has already taken care of type promotions. */
227 return type;
230 /* Build INTEGER_CST of type TYPE with the value VALUE. */
232 tree
233 build_integer_cst (dinteger_t value, tree type)
235 /* The type is error_mark_node, we can't do anything. */
236 if (error_operand_p (type))
237 return type;
239 return build_int_cst_type (type, value);
242 /* Build REAL_CST of type TOTYPE with the value VALUE. */
244 tree
245 build_float_cst (const real_t &value, Type *totype)
247 real_t new_value;
248 TypeBasic *tb = totype->isTypeBasic ();
250 gcc_assert (tb != NULL);
252 tree type_node = build_ctype (tb);
253 real_convert (&new_value.rv (), TYPE_MODE (type_node), &value.rv ());
255 return build_real (type_node, new_value.rv ());
258 /* Returns the .length component from the D dynamic array EXP. */
260 tree
261 d_array_length (tree exp)
263 if (error_operand_p (exp))
264 return exp;
266 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
268 /* Get the back-end type for the array and pick out the array
269 length field (assumed to be the first field). */
270 tree len_field = TYPE_FIELDS (TREE_TYPE (exp));
271 return component_ref (exp, len_field);
274 /* Returns the .ptr component from the D dynamic array EXP. */
276 tree
277 d_array_ptr (tree exp)
279 if (error_operand_p (exp))
280 return exp;
282 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
284 /* Get the back-end type for the array and pick out the array
285 data pointer field (assumed to be the second field). */
286 tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
287 return component_ref (exp, ptr_field);
290 /* Returns a constructor for D dynamic array type TYPE of .length LEN
291 and .ptr pointing to DATA. */
293 tree
294 d_array_value (tree type, tree len, tree data)
296 tree len_field, ptr_field;
297 vec <constructor_elt, va_gc> *ce = NULL;
299 gcc_assert (TYPE_DYNAMIC_ARRAY (type));
300 len_field = TYPE_FIELDS (type);
301 ptr_field = TREE_CHAIN (len_field);
303 len = convert (TREE_TYPE (len_field), len);
304 data = convert (TREE_TYPE (ptr_field), data);
306 CONSTRUCTOR_APPEND_ELT (ce, len_field, len);
307 CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);
309 return build_constructor (type, ce);
312 /* Returns value representing the array length of expression EXP.
313 TYPE could be a dynamic or static array. */
315 tree
316 get_array_length (tree exp, Type *type)
318 Type *tb = type->toBasetype ();
320 switch (tb->ty)
322 case TY::Tsarray:
323 return size_int (tb->isTypeSArray ()->dim->toUInteger ());
325 case TY::Tarray:
326 return d_array_length (exp);
328 default:
329 error ("cannot determine the length of a %qs", type->toChars ());
330 return error_mark_node;
334 /* Create BINFO for a ClassDeclaration's inheritance tree.
335 InterfaceDeclaration's are not included. */
337 tree
338 build_class_binfo (tree super, ClassDeclaration *cd)
340 tree binfo = make_tree_binfo (1);
341 tree ctype = build_ctype (cd->type);
343 /* Want RECORD_TYPE, not POINTER_TYPE. */
344 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
345 BINFO_INHERITANCE_CHAIN (binfo) = super;
346 BINFO_OFFSET (binfo) = integer_zero_node;
348 if (cd->baseClass)
349 BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass));
351 return binfo;
354 /* Create BINFO for an InterfaceDeclaration's inheritance tree.
355 In order to access all inherited methods in the debugger,
356 the entire tree must be described.
357 This function makes assumptions about interface layout. */
359 tree
360 build_interface_binfo (tree super, ClassDeclaration *cd, unsigned &offset)
362 tree binfo = make_tree_binfo (cd->baseclasses->length);
363 tree ctype = build_ctype (cd->type);
365 /* Want RECORD_TYPE, not POINTER_TYPE. */
366 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
367 BINFO_INHERITANCE_CHAIN (binfo) = super;
368 BINFO_OFFSET (binfo) = size_int (offset * target.ptrsize);
369 BINFO_VIRTUAL_P (binfo) = 1;
371 for (size_t i = 0; i < cd->baseclasses->length; i++, offset++)
373 BaseClass *bc = (*cd->baseclasses)[i];
374 BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset));
377 return binfo;
380 /* Returns the .funcptr component from the D delegate EXP. */
382 tree
383 delegate_method (tree exp)
385 /* Get the back-end type for the delegate and pick out the funcptr field
386 (assumed to be the second field). */
387 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
388 tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
389 return component_ref (exp, method_field);
392 /* Returns the .object component from the delegate EXP. */
394 tree
395 delegate_object (tree exp)
397 /* Get the back-end type for the delegate and pick out the object field
398 (assumed to be the first field). */
399 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
400 tree obj_field = TYPE_FIELDS (TREE_TYPE (exp));
401 return component_ref (exp, obj_field);
404 /* Build a delegate literal of type TYPE whose pointer function is
405 METHOD, and hidden object is OBJECT. */
407 tree
408 build_delegate_cst (tree method, tree object, Type *type)
410 tree ctor = make_node (CONSTRUCTOR);
411 tree ctype;
413 Type *tb = type->toBasetype ();
414 if (tb->ty == TY::Tdelegate)
415 ctype = build_ctype (type);
416 else
418 /* Convert a function method into an anonymous delegate. */
419 ctype = make_struct_type ("delegate()", 2,
420 get_identifier ("object"), TREE_TYPE (object),
421 get_identifier ("func"), TREE_TYPE (method));
422 TYPE_DELEGATE (ctype) = 1;
425 vec <constructor_elt, va_gc> *ce = NULL;
426 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object);
427 CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method);
429 CONSTRUCTOR_ELTS (ctor) = ce;
430 TREE_TYPE (ctor) = ctype;
432 return ctor;
435 /* Builds a temporary tree to store the CALLEE and OBJECT
436 of a method call expression of type TYPE. */
438 tree
439 build_method_call (tree callee, tree object, Type *type)
441 tree t = build_delegate_cst (callee, object, type);
442 METHOD_CALL_EXPR (t) = 1;
443 return t;
446 /* Extract callee and object from T and return in to CALLEE and OBJECT. */
448 void
449 extract_from_method_call (tree t, tree &callee, tree &object)
451 gcc_assert (METHOD_CALL_EXPR (t));
452 object = CONSTRUCTOR_ELT (t, 0)->value;
453 callee = CONSTRUCTOR_ELT (t, 1)->value;
456 /* Build a typeof(null) constant of type TYPE. Handles certain special case
457 conversions, where the underlying type is an aggregate with a nullable
458 interior pointer. */
460 tree
461 build_typeof_null_value (Type *type)
463 Type *tb = type->toBasetype ();
464 tree value;
466 /* For dynamic arrays, set length and pointer fields to zero. */
467 if (tb->ty == TY::Tarray)
468 value = d_array_value (build_ctype (type), size_int (0), null_pointer_node);
470 /* For associative arrays, set the pointer field to null. */
471 else if (tb->ty == TY::Taarray)
473 tree ctype = build_ctype (type);
474 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype));
476 value = build_constructor_single (ctype, TYPE_FIELDS (ctype),
477 null_pointer_node);
480 /* For delegates, set the frame and function pointer fields to null. */
481 else if (tb->ty == TY::Tdelegate)
482 value = build_delegate_cst (null_pointer_node, null_pointer_node, type);
484 /* Simple zero constant for all other types. */
485 else
486 value = build_zero_cst (build_ctype (type));
488 TREE_CONSTANT (value) = 1;
489 return value;
492 /* Build a dereference into the virtual table for OBJECT to retrieve
493 a function pointer of type FNTYPE at position INDEX. */
495 tree
496 build_vindex_ref (tree object, tree fntype, size_t index)
498 /* The vtable is the first field. Interface methods are also in the class's
499 vtable, so we don't need to convert from a class to an interface. */
500 tree result = build_deref (object);
501 result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result)));
503 gcc_assert (POINTER_TYPE_P (fntype));
505 return build_memref (fntype, result, size_int (target.ptrsize * index));
508 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
509 made into temporaries, otherwise any assignments will be lost. */
511 static bool
512 lvalue_p (tree exp)
514 const enum tree_code code = TREE_CODE (exp);
516 switch (code)
518 case SAVE_EXPR:
519 return false;
521 case ARRAY_REF:
522 case INDIRECT_REF:
523 case VAR_DECL:
524 case PARM_DECL:
525 case RESULT_DECL:
526 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp));
528 case IMAGPART_EXPR:
529 case REALPART_EXPR:
530 case COMPONENT_REF:
531 CASE_CONVERT:
532 return lvalue_p (TREE_OPERAND (exp, 0));
534 case COND_EXPR:
535 return (lvalue_p (TREE_OPERAND (exp, 1)
536 ? TREE_OPERAND (exp, 1)
537 : TREE_OPERAND (exp, 0))
538 && lvalue_p (TREE_OPERAND (exp, 2)));
540 case TARGET_EXPR:
541 return true;
543 case COMPOUND_EXPR:
544 return lvalue_p (TREE_OPERAND (exp, 1));
546 default:
547 return false;
551 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
552 more than once in an expression. */
554 tree
555 d_save_expr (tree exp)
557 if (TREE_SIDE_EFFECTS (exp))
559 if (lvalue_p (exp))
560 return stabilize_reference (exp);
562 return save_expr (exp);
565 return exp;
568 /* VALUEP is an expression we want to pre-evaluate or perform a computation on.
569 The expression returned by this function is the part whose value we don't
570 care about, storing the value in VALUEP. Callers must ensure that the
571 returned expression is evaluated before VALUEP. */
573 tree
574 stabilize_expr (tree *valuep)
576 tree expr = *valuep;
577 const enum tree_code code = TREE_CODE (expr);
578 tree lhs;
579 tree rhs;
581 switch (code)
583 case COMPOUND_EXPR:
584 /* Given ((e1, ...), eN):
585 Store the last RHS 'eN' expression in VALUEP. */
586 lhs = TREE_OPERAND (expr, 0);
587 rhs = TREE_OPERAND (expr, 1);
588 lhs = compound_expr (lhs, stabilize_expr (&rhs));
589 *valuep = rhs;
590 return lhs;
592 default:
593 return NULL_TREE;
597 /* Return a TARGET_EXPR, initializing the DECL with EXP. */
599 tree
600 build_target_expr (tree decl, tree exp)
602 tree type = TREE_TYPE (decl);
603 tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE);
605 if (EXPR_HAS_LOCATION (exp))
606 SET_EXPR_LOCATION (result, EXPR_LOCATION (exp));
608 /* If decl must always reside in memory. */
609 if (TREE_ADDRESSABLE (type))
610 d_mark_addressable (decl);
612 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
613 TARGET_EXPR. If there really turn out to be no side effects, then the
614 optimizer should be able to remove it. */
615 TREE_SIDE_EFFECTS (result) = 1;
617 return result;
620 /* Like the above function, but initializes a new temporary. */
622 tree
623 force_target_expr (tree exp)
625 tree decl = build_decl (input_location, VAR_DECL, NULL_TREE,
626 TREE_TYPE (exp));
627 DECL_CONTEXT (decl) = current_function_decl;
628 DECL_ARTIFICIAL (decl) = 1;
629 DECL_IGNORED_P (decl) = 1;
630 layout_decl (decl, 0);
632 return build_target_expr (decl, exp);
635 /* Returns the address of the expression EXP. */
637 tree
638 build_address (tree exp)
640 if (error_operand_p (exp))
641 return exp;
643 tree ptrtype;
644 tree type = TREE_TYPE (exp);
646 if (TREE_CODE (exp) == STRING_CST)
648 /* Just convert string literals (char[]) to C-style strings (char *),
649 otherwise the latter method (char[]*) causes conversion problems
650 during gimplification. */
651 ptrtype = build_pointer_type (TREE_TYPE (type));
653 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node)
654 && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE)
656 /* Special case for va_list, allow arrays to decay to a pointer. */
657 ptrtype = build_pointer_type (TREE_TYPE (type));
659 else
660 ptrtype = build_pointer_type (type);
662 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
663 tree init = stabilize_expr (&exp);
665 /* Can't take the address of a manifest constant, instead use its value. */
666 if (TREE_CODE (exp) == CONST_DECL)
667 exp = DECL_INITIAL (exp);
669 /* Some expression lowering may request an address of a compile-time constant,
670 or other non-lvalue expression. Make sure it is assigned to a location we
671 can reference. */
672 if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
673 exp = force_target_expr (exp);
674 else if (TREE_CODE (exp) == CALL_EXPR)
676 /* When a struct or array is returned in registers, we need to again fill
677 in all alignment holes. */
678 if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
679 && !aggregate_value_p (TREE_TYPE (exp), exp))
681 tree tmp = build_local_temp (TREE_TYPE (exp));
682 init = compound_expr (init, build_memset_call (tmp));
683 init = compound_expr (init, modify_expr (tmp, exp));
684 exp = tmp;
686 else
687 exp = force_target_expr (exp);
690 d_mark_addressable (exp);
691 exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype);
693 if (TREE_CODE (exp) == ADDR_EXPR)
694 TREE_NO_TRAMPOLINE (exp) = 1;
696 return compound_expr (init, exp);
699 /* Mark EXP saying that we need to be able to take the
700 address of it; it should not be allocated in a register. */
702 tree
703 d_mark_addressable (tree exp)
705 switch (TREE_CODE (exp))
707 case ADDR_EXPR:
708 case COMPONENT_REF:
709 case ARRAY_REF:
710 case REALPART_EXPR:
711 case IMAGPART_EXPR:
712 d_mark_addressable (TREE_OPERAND (exp, 0));
713 break;
715 case PARM_DECL:
716 case VAR_DECL:
717 case RESULT_DECL:
718 case CONST_DECL:
719 case FUNCTION_DECL:
720 TREE_ADDRESSABLE (exp) = 1;
721 break;
723 case CONSTRUCTOR:
724 TREE_ADDRESSABLE (exp) = 1;
725 break;
727 case TARGET_EXPR:
728 TREE_ADDRESSABLE (exp) = 1;
729 d_mark_addressable (TREE_OPERAND (exp, 0));
730 break;
732 default:
733 break;
736 return exp;
739 /* Mark EXP as "used" in the program for the benefit of
740 -Wunused warning purposes. */
742 tree
743 d_mark_used (tree exp)
745 switch (TREE_CODE (exp))
747 case VAR_DECL:
748 case CONST_DECL:
749 case PARM_DECL:
750 case RESULT_DECL:
751 case FUNCTION_DECL:
752 TREE_USED (exp) = 1;
753 break;
755 case ARRAY_REF:
756 case COMPONENT_REF:
757 case MODIFY_EXPR:
758 case REALPART_EXPR:
759 case IMAGPART_EXPR:
760 case NOP_EXPR:
761 case CONVERT_EXPR:
762 case ADDR_EXPR:
763 d_mark_used (TREE_OPERAND (exp, 0));
764 break;
766 case COMPOUND_EXPR:
767 d_mark_used (TREE_OPERAND (exp, 0));
768 d_mark_used (TREE_OPERAND (exp, 1));
769 break;
771 default:
772 break;
774 return exp;
777 /* Mark EXP as read, not just set, for set but not used -Wunused
778 warning purposes. */
780 tree
781 d_mark_read (tree exp)
783 switch (TREE_CODE (exp))
785 case VAR_DECL:
786 case PARM_DECL:
787 TREE_USED (exp) = 1;
788 DECL_READ_P (exp) = 1;
789 break;
791 case ARRAY_REF:
792 case COMPONENT_REF:
793 case MODIFY_EXPR:
794 case REALPART_EXPR:
795 case IMAGPART_EXPR:
796 case NOP_EXPR:
797 case CONVERT_EXPR:
798 case ADDR_EXPR:
799 d_mark_read (TREE_OPERAND (exp, 0));
800 break;
802 case COMPOUND_EXPR:
803 d_mark_read (TREE_OPERAND (exp, 1));
804 break;
806 default:
807 break;
809 return exp;
812 /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */
814 tree
815 build_memcmp_call (tree ptr1, tree ptr2, tree num)
817 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,
818 ptr1, ptr2, num);
821 /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */
823 tree
824 build_memcpy_call (tree dst, tree src, tree num)
826 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
827 dst, src, num);
830 /* Build a call to memset(), fills the first NUM bytes of PTR with zeros.
831 If NUM is NULL, then we expect PTR to be object that requires filling. */
833 tree
834 build_memset_call (tree ptr, tree num)
836 if (num == NULL_TREE)
838 gcc_assert (TREE_CODE (ptr) != ADDR_EXPR);
839 num = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
840 ptr = build_address (ptr);
843 /* Use a zero constant to fill the destination if setting the entire object.
844 For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
845 which can then be merged with other stores to the object. */
846 tree valtype = TREE_TYPE (TREE_TYPE (ptr));
847 if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num))
849 tree cst = build_zero_cst (valtype);
850 if (TREE_CODE (cst) == CONSTRUCTOR)
851 return build_memcpy_call (ptr, build_address (cst), num);
853 return modify_expr (build_deref (ptr), cst);
856 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3,
857 ptr, integer_zero_node, num);
860 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
861 This is because we don't guarantee that padding is zero-initialized for
862 a stack variable, so we can't use memcmp to compare struct values. */
864 bool
865 identity_compare_p (StructDeclaration *sd)
867 if (sd->isUnionDeclaration ())
868 return true;
870 unsigned offset = 0;
872 for (size_t i = 0; i < sd->fields.length; i++)
874 VarDeclaration *vd = sd->fields[i];
875 Type *tb = vd->type->toBasetype ();
877 /* Check inner data structures. */
878 if (TypeStruct *ts = tb->isTypeStruct ())
880 if (!identity_compare_p (ts->sym))
881 return false;
884 /* Check for types that may have padding. */
885 if ((tb->ty == TY::Tcomplex80
886 || tb->ty == TY::Tfloat80
887 || tb->ty == TY::Timaginary80)
888 && target.realpad != 0)
889 return false;
891 if (offset <= vd->offset)
893 /* There's a hole in the struct. */
894 if (offset != vd->offset)
895 return false;
897 offset += vd->type->size ();
901 /* Any trailing padding may not be zero. */
902 if (offset < sd->structsize)
903 return false;
905 return true;
908 /* Build a floating-point identity comparison between T1 and T2, ignoring any
909 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
911 tree
912 build_float_identity (tree_code code, tree t1, tree t2)
914 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
915 tree result = build_memcmp_call (build_address (t1),
916 build_address (t2), size);
917 return build_boolop (code, result, integer_zero_node);
920 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
921 CODE is the EQ_EXPR or NE_EXPR comparison. */
923 static tree
924 lower_struct_comparison (tree_code code, StructDeclaration *sd,
925 tree t1, tree t2)
927 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
928 tree tmemcmp = NULL_TREE;
930 /* We can skip the compare if the structs are empty. */
931 if (sd->fields.length == 0)
933 tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node);
934 if (TREE_SIDE_EFFECTS (t2))
935 tmemcmp = compound_expr (t2, tmemcmp);
936 if (TREE_SIDE_EFFECTS (t1))
937 tmemcmp = compound_expr (t1, tmemcmp);
939 return tmemcmp;
942 /* Let back-end take care of union comparisons. */
943 if (sd->isUnionDeclaration ())
945 tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
946 size_int (sd->structsize));
947 return build_boolop (code, tmemcmp, integer_zero_node);
950 for (size_t i = 0; i < sd->fields.length; i++)
952 VarDeclaration *vd = sd->fields[i];
953 Type *type = vd->type->toBasetype ();
954 tree sfield = get_symbol_decl (vd);
956 tree t1ref = component_ref (t1, sfield);
957 tree t2ref = component_ref (t2, sfield);
958 tree tcmp;
960 if (TypeStruct *ts = type->isTypeStruct ())
962 /* Compare inner data structures. */
963 tcmp = lower_struct_comparison (code, ts->sym, t1ref, t2ref);
965 else if (type->ty != TY::Tvector && type->isintegral ())
967 /* Integer comparison, no special handling required. */
968 tcmp = build_boolop (code, t1ref, t2ref);
970 else if (type->ty != TY::Tvector && type->isfloating ())
972 /* Floating-point comparison, don't compare padding in type. */
973 if (!type->iscomplex ())
974 tcmp = build_float_identity (code, t1ref, t2ref);
975 else
977 tree req = build_float_identity (code, real_part (t1ref),
978 real_part (t2ref));
979 tree ieq = build_float_identity (code, imaginary_part (t1ref),
980 imaginary_part (t2ref));
982 tcmp = build_boolop (tcode, req, ieq);
985 else
987 tree stype = build_ctype (type);
988 opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));
990 if (mode.exists ())
992 /* Compare field bits as their corresponding integer type.
993 *((T*) &t1) == *((T*) &t2) */
994 tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1);
996 if (tmode == NULL_TREE)
997 tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
999 t1ref = build_vconvert (tmode, t1ref);
1000 t2ref = build_vconvert (tmode, t2ref);
1002 tcmp = build_boolop (code, t1ref, t2ref);
1004 else
1006 /* Simple memcmp between types. */
1007 tcmp = build_memcmp_call (build_address (t1ref),
1008 build_address (t2ref),
1009 TYPE_SIZE_UNIT (stype));
1010 tcmp = build_boolop (code, tcmp, integer_zero_node);
1014 tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp;
1017 return tmemcmp;
1021 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
1022 If possible, use memcmp, otherwise field-by-field comparison is done.
1023 CODE is the EQ_EXPR or NE_EXPR comparison. */
1025 tree
1026 build_struct_comparison (tree_code code, StructDeclaration *sd,
1027 tree t1, tree t2)
1029 /* We can skip the compare if the structs are empty. */
1030 if (sd->fields.length == 0)
1032 tree exp = build_boolop (code, integer_zero_node, integer_zero_node);
1033 if (TREE_SIDE_EFFECTS (t2))
1034 exp = compound_expr (t2, exp);
1035 if (TREE_SIDE_EFFECTS (t1))
1036 exp = compound_expr (t1, exp);
1038 return exp;
1041 /* Make temporaries to prevent multiple evaluations. */
1042 tree t1init = stabilize_expr (&t1);
1043 tree t2init = stabilize_expr (&t2);
1044 tree result;
1046 t1 = d_save_expr (t1);
1047 t2 = d_save_expr (t2);
1049 /* Bitwise comparison of structs not returned in memory may not work
1050 due to data holes loosing its zero padding upon return.
1051 As a heuristic, small structs are not compared using memcmp either. */
1052 if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd))
1053 result = lower_struct_comparison (code, sd, t1, t2);
1054 else
1056 /* Do bit compare of structs. */
1057 tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
1058 size_int (sd->structsize));
1059 result = build_boolop (code, tmemcmp, integer_zero_node);
1062 return compound_expr (compound_expr (t1init, t2init), result);
1065 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1066 The pointer references are T1 and T2, and the element type is SD.
1067 CODE is the EQ_EXPR or NE_EXPR comparison. */
1069 tree
1070 build_array_struct_comparison (tree_code code, StructDeclaration *sd,
1071 tree length, tree t1, tree t2)
1073 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
1075 /* Build temporary for the result of the comparison.
1076 Initialize as either 0 or 1 depending on operation. */
1077 tree result = build_local_temp (d_bool_type);
1078 tree init = build_boolop (code, integer_zero_node, integer_zero_node);
1079 add_stmt (build_assign (INIT_EXPR, result, init));
1081 /* Cast pointer-to-array to pointer-to-struct. */
1082 tree ptrtype = build_ctype (sd->type->pointerTo ());
1083 tree lentype = TREE_TYPE (length);
1085 push_binding_level (level_block);
1086 push_stmt_list ();
1088 /* Build temporary locals for length and pointers. */
1089 tree t = build_local_temp (size_type_node);
1090 add_stmt (build_assign (INIT_EXPR, t, length));
1091 length = t;
1093 t = build_local_temp (ptrtype);
1094 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1)));
1095 t1 = t;
1097 t = build_local_temp (ptrtype);
1098 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2)));
1099 t2 = t;
1101 /* Build loop for comparing each element. */
1102 push_stmt_list ();
1104 /* Exit logic for the loop.
1105 if (length == 0 || result OP 0) break; */
1106 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1107 t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,
1108 boolean_false_node));
1109 t = build1 (EXIT_EXPR, void_type_node, t);
1110 add_stmt (t);
1112 /* Do comparison, caching the value.
1113 result = result OP (*t1 == *t2); */
1114 t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2));
1115 t = build_boolop (tcode, result, t);
1116 t = modify_expr (result, t);
1117 add_stmt (t);
1119 /* Move both pointers to next element position.
1120 t1++, t2++; */
1121 tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)));
1122 t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size);
1123 add_stmt (t);
1124 t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size);
1125 add_stmt (t);
1127 /* Decrease loop counter.
1128 length -= 1; */
1129 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1130 d_convert (lentype, integer_one_node));
1131 add_stmt (t);
1133 /* Pop statements and finish loop. */
1134 tree body = pop_stmt_list ();
1135 add_stmt (build1 (LOOP_EXPR, void_type_node, body));
1137 /* Wrap it up into a bind expression. */
1138 tree stmt_list = pop_stmt_list ();
1139 tree block = pop_binding_level ();
1141 body = build3 (BIND_EXPR, void_type_node,
1142 BLOCK_VARS (block), stmt_list, block);
1144 return compound_expr (body, result);
1147 /* Build a constructor for a variable of aggregate type TYPE using the
1148 initializer INIT, an ordered flat list of fields and values provided
1149 by the frontend. The returned constructor should be a value that
1150 matches the layout of TYPE. */
1152 tree
1153 build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
1155 /* If the initializer was empty, use default zero initialization. */
1156 if (vec_safe_is_empty (init))
1157 return build_constructor (type, NULL);
1159 /* Struct literals can be seen for special enums representing `_Complex',
1160 make sure to reinterpret the literal as the correct type. */
1161 if (COMPLEX_FLOAT_TYPE_P (type))
1163 gcc_assert (vec_safe_length (init) == 2);
1164 return complex_expr (type, (*init)[0].value, (*init)[1].value);
1167 vec <constructor_elt, va_gc> *ve = NULL;
1168 HOST_WIDE_INT bitoffset = 0;
1169 bool constant_p = true;
1170 bool finished = false;
1172 /* Walk through each field, matching our initializer list. */
1173 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1175 bool is_initialized = false;
1176 tree value;
1178 if (DECL_NAME (field) == NULL_TREE
1179 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1180 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1182 /* Search all nesting aggregates, if nothing is found, then
1183 this will return an empty initializer to fill the hole. */
1184 value = build_struct_literal (TREE_TYPE (field), init);
1186 if (!initializer_zerop (value))
1187 is_initialized = true;
1189 else
1191 /* Search for the value to initialize the next field. Once found,
1192 pop it from the init list so we don't look at it again. */
1193 unsigned HOST_WIDE_INT idx;
1194 tree index;
1196 FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value)
1198 /* If the index is NULL, then just assign it to the next field.
1199 This comes from layout_typeinfo(), which generates a flat
1200 list of values that we must shape into the record type. */
1201 if (index == field || index == NULL_TREE)
1203 init->ordered_remove (idx);
1204 if (!finished)
1205 is_initialized = true;
1206 break;
1211 if (is_initialized)
1213 HOST_WIDE_INT fieldpos = int_bit_position (field);
1214 gcc_assert (value != NULL_TREE);
1216 /* Must not initialize fields that overlap. */
1217 if (fieldpos < bitoffset)
1219 /* Find the nearest user defined type and field. */
1220 tree vtype = type;
1221 while (ANON_AGGR_TYPE_P (vtype))
1222 vtype = TYPE_CONTEXT (vtype);
1224 tree vfield = field;
1225 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield))
1226 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield)))
1227 vfield = TYPE_FIELDS (TREE_TYPE (vfield));
1229 /* Must not generate errors for compiler generated fields. */
1230 gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield));
1231 error ("overlapping initializer for field %qT.%qD",
1232 TYPE_NAME (vtype), DECL_NAME (vfield));
1235 if (!TREE_CONSTANT (value))
1236 constant_p = false;
1238 CONSTRUCTOR_APPEND_ELT (ve, field, value);
1240 /* For unions, only the first field is initialized, any other field
1241 initializers found for this union are drained and ignored. */
1242 if (TREE_CODE (type) == UNION_TYPE)
1243 finished = true;
1246 /* Move bit offset to the next position in the struct. */
1247 if (TREE_CODE (type) == RECORD_TYPE && DECL_SIZE (field))
1248 bitoffset = int_bit_position (field) + tree_to_shwi (DECL_SIZE (field));
1250 /* If all initializers have been assigned, there's nothing else to do. */
1251 if (vec_safe_is_empty (init))
1252 break;
1255 /* Ensure that we have consumed all values. */
1256 gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
1258 tree ctor = build_constructor (type, ve);
1260 if (constant_p)
1261 TREE_CONSTANT (ctor) = 1;
1263 return ctor;
1266 /* Given the TYPE of an anonymous field inside T, return the
1267 FIELD_DECL for the field. If not found return NULL_TREE.
1268 Because anonymous types can nest, we must also search all
1269 anonymous fields that are directly reachable. */
1271 static tree
1272 lookup_anon_field (tree t, tree type)
1274 t = TYPE_MAIN_VARIANT (t);
1276 for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
1278 if (DECL_NAME (field) == NULL_TREE)
1280 /* If we find it directly, return the field. */
1281 if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
1282 return field;
1284 /* Otherwise, it could be nested, search harder. */
1285 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1286 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1288 tree subfield = lookup_anon_field (TREE_TYPE (field), type);
1289 if (subfield)
1290 return subfield;
1295 return NULL_TREE;
1298 /* Builds OBJECT.FIELD component reference. */
1300 tree
1301 component_ref (tree object, tree field)
1303 if (error_operand_p (object) || error_operand_p (field))
1304 return error_mark_node;
1306 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1308 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1309 tree init = stabilize_expr (&object);
1311 /* If the FIELD is from an anonymous aggregate, generate a reference
1312 to the anonymous data member, and recur to find FIELD. */
1313 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field)))
1315 tree anonymous_field = lookup_anon_field (TREE_TYPE (object),
1316 DECL_CONTEXT (field));
1317 object = component_ref (object, anonymous_field);
1320 tree result = fold_build3_loc (input_location, COMPONENT_REF,
1321 TREE_TYPE (field), object, field, NULL_TREE);
1323 return compound_expr (init, result);
1326 /* Build an assignment expression of lvalue LHS from value RHS.
1327 CODE is the code for a binary operator that we use to combine
1328 the old value of LHS with RHS to get the new value. */
1330 tree
1331 build_assign (tree_code code, tree lhs, tree rhs)
1333 tree result;
1334 tree init = stabilize_expr (&lhs);
1335 init = compound_expr (init, stabilize_expr (&rhs));
1337 /* If initializing the LHS using a function that returns via NRVO. */
1338 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
1339 && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
1340 && aggregate_value_p (TREE_TYPE (rhs), rhs))
1342 /* Mark as addressable here, which should ensure the return slot is the
1343 address of the LHS expression, taken care of by back-end. */
1344 d_mark_addressable (lhs);
1345 CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
1347 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
1348 else if (code == MODIFY_EXPR && TREE_ADDRESSABLE (TREE_TYPE (lhs))
1349 && TREE_SIDE_EFFECTS (rhs) && TREE_CODE (rhs) != TARGET_EXPR)
1351 /* LHS may be referenced by the RHS expression, so force a temporary. */
1352 rhs = force_target_expr (rhs);
1355 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1356 if (TREE_CODE (rhs) == TARGET_EXPR)
1358 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1359 since that would cause the LHS to be constructed twice. */
1360 if (code != INIT_EXPR)
1362 init = compound_expr (init, rhs);
1363 result = build_assign (code, lhs, TARGET_EXPR_SLOT (rhs));
1365 else
1367 d_mark_addressable (lhs);
1368 TARGET_EXPR_INITIAL (rhs) = build_assign (code, lhs,
1369 TARGET_EXPR_INITIAL (rhs));
1370 result = rhs;
1373 else
1375 /* Simple assignment. */
1376 result = fold_build2_loc (input_location, code,
1377 TREE_TYPE (lhs), lhs, rhs);
1380 return compound_expr (init, result);
1383 /* Build an assignment expression of lvalue LHS from value RHS. */
1385 tree
1386 modify_expr (tree lhs, tree rhs)
1388 return build_assign (MODIFY_EXPR, lhs, rhs);
1391 /* Return EXP represented as TYPE. */
1393 tree
1394 build_nop (tree type, tree exp)
1396 if (error_operand_p (exp))
1397 return exp;
1399 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1400 tree init = stabilize_expr (&exp);
1401 exp = fold_build1_loc (input_location, NOP_EXPR, type, exp);
1403 return compound_expr (init, exp);
1406 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1407 except that EXP is type-punned, rather than a straight-forward cast. */
1409 tree
1410 build_vconvert (tree type, tree exp)
1412 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1413 makes sure this works for vector-to-array viewing, or if EXP ends up being
1414 used as the LHS of a MODIFY_EXPR. */
1415 return indirect_ref (type, build_address (exp));
1418 /* Maybe warn about ARG being an address that can never be null. */
1420 static void
1421 warn_for_null_address (tree arg)
1423 if (TREE_CODE (arg) == ADDR_EXPR
1424 && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0)))
1425 warning (OPT_Waddress,
1426 "the address of %qD will never be %<null%>",
1427 TREE_OPERAND (arg, 0));
1430 /* Build a boolean ARG0 op ARG1 expression. */
1432 tree
1433 build_boolop (tree_code code, tree arg0, tree arg1)
1435 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1436 so need to remove all side effects incase its address is taken. */
1437 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0)))
1438 arg0 = d_save_expr (arg0);
1439 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1)))
1440 arg1 = d_save_expr (arg1);
1442 if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1)))
1444 /* Build a vector comparison.
1445 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1446 tree type = TREE_TYPE (arg0);
1447 tree cmptype = truth_type_for (type);
1448 tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1);
1450 return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp,
1451 build_minus_one_cst (type),
1452 build_zero_cst (type));
1455 if (code == EQ_EXPR || code == NE_EXPR)
1457 /* Check if comparing the address of a variable to null. */
1458 if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1))
1459 warn_for_null_address (arg0);
1460 if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0))
1461 warn_for_null_address (arg1);
1464 return fold_build2_loc (input_location, code, d_bool_type,
1465 arg0, d_convert (TREE_TYPE (arg0), arg1));
1468 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1469 arguments to the conditional expression. */
1471 tree
1472 build_condition (tree type, tree arg0, tree arg1, tree arg2)
1474 if (arg1 == void_node)
1475 arg1 = build_empty_stmt (input_location);
1477 if (arg2 == void_node)
1478 arg2 = build_empty_stmt (input_location);
1480 return fold_build3_loc (input_location, COND_EXPR,
1481 type, arg0, arg1, arg2);
1484 tree
1485 build_vcondition (tree arg0, tree arg1, tree arg2)
1487 return build_condition (void_type_node, arg0, arg1, arg2);
1490 /* Build a compound expr to join ARG0 and ARG1 together. */
1492 tree
1493 compound_expr (tree arg0, tree arg1)
1495 if (arg1 == NULL_TREE)
1496 return arg0;
1498 if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0))
1499 return arg1;
1501 /* Remove intermediate expressions that have no side-effects. */
1502 while (TREE_CODE (arg0) == COMPOUND_EXPR
1503 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
1504 arg0 = TREE_OPERAND (arg0, 0);
1506 if (TREE_CODE (arg1) == TARGET_EXPR)
1508 /* If the rhs is a TARGET_EXPR, then build the compound expression
1509 inside the target_expr's initializer. This helps the compiler
1510 to eliminate unnecessary temporaries. */
1511 tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1));
1512 TARGET_EXPR_INITIAL (arg1) = init;
1514 return arg1;
1517 return fold_build2_loc (input_location, COMPOUND_EXPR,
1518 TREE_TYPE (arg1), arg0, arg1);
1521 /* Build a return expression. */
1523 tree
1524 return_expr (tree ret)
1526 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary
1527 in TARGET_EXPR_SLOT. */
1528 if (ret != NULL_TREE && TREE_CODE (ret) == TARGET_EXPR)
1530 tree exp = TARGET_EXPR_INITIAL (ret);
1531 tree init = stabilize_expr (&exp);
1533 exp = fold_build1_loc (input_location, RETURN_EXPR, void_type_node, exp);
1534 TARGET_EXPR_INITIAL (ret) = compound_expr (init, exp);
1536 return ret;
1539 return fold_build1_loc (input_location, RETURN_EXPR,
1540 void_type_node, ret);
1543 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1545 tree
1546 size_mult_expr (tree arg0, tree arg1)
1548 return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1549 d_convert (size_type_node, arg0),
1550 d_convert (size_type_node, arg1));
1554 /* Return the real part of CE, which should be a complex expression. */
1556 tree
1557 real_part (tree ce)
1559 return fold_build1_loc (input_location, REALPART_EXPR,
1560 TREE_TYPE (TREE_TYPE (ce)), ce);
1563 /* Return the imaginary part of CE, which should be a complex expression. */
1565 tree
1566 imaginary_part (tree ce)
1568 return fold_build1_loc (input_location, IMAGPART_EXPR,
1569 TREE_TYPE (TREE_TYPE (ce)), ce);
1572 /* Build a complex expression of type TYPE using RE and IM. */
1574 tree
1575 complex_expr (tree type, tree re, tree im)
1577 return fold_build2_loc (input_location, COMPLEX_EXPR,
1578 type, re, im);
1581 /* Build a two-field record TYPE representing the complex expression EXPR. */
1583 tree
1584 underlying_complex_expr (tree type, tree expr)
1586 gcc_assert (list_length (TYPE_FIELDS (type)) == 2);
1588 expr = d_save_expr (expr);
1590 /* Build a constructor from the real and imaginary parts. */
1591 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (expr)) &&
1592 (!INDIRECT_REF_P (expr)
1593 || !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))))
1595 vec <constructor_elt, va_gc> *ve = NULL;
1596 CONSTRUCTOR_APPEND_ELT (ve, TYPE_FIELDS (type),
1597 real_part (expr));
1598 CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)),
1599 imaginary_part (expr));
1600 return build_constructor (type, ve);
1603 /* Replace type in the reinterpret cast with a cast to the record type. */
1604 return build_vconvert (type, expr);
1607 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1608 The back-end requires this cast in many cases. */
1610 tree
1611 indirect_ref (tree type, tree exp)
1613 if (error_operand_p (exp))
1614 return exp;
1616 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1617 tree init = stabilize_expr (&exp);
1619 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
1620 exp = fold_build1 (INDIRECT_REF, type, exp);
1621 else
1623 exp = build_nop (build_pointer_type (type), exp);
1624 exp = build_deref (exp);
1627 return compound_expr (init, exp);
1630 /* Returns indirect reference of EXP, which must be a pointer type. */
1632 tree
1633 build_deref (tree exp)
1635 if (error_operand_p (exp))
1636 return exp;
1638 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1639 tree init = stabilize_expr (&exp);
1641 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
1643 if (TREE_CODE (exp) == ADDR_EXPR)
1644 exp = TREE_OPERAND (exp, 0);
1645 else
1646 exp = build_fold_indirect_ref (exp);
1648 return compound_expr (init, exp);
1651 /* Builds pointer offset expression PTR[INDEX]. */
1653 tree
1654 build_array_index (tree ptr, tree index)
1656 if (error_operand_p (ptr) || error_operand_p (index))
1657 return error_mark_node;
1659 tree ptr_type = TREE_TYPE (ptr);
1660 tree target_type = TREE_TYPE (ptr_type);
1662 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1663 TYPE_UNSIGNED (sizetype));
1665 /* Array element size. */
1666 tree size_exp = size_in_bytes (target_type);
1668 if (integer_zerop (size_exp) || integer_onep (size_exp))
1670 /* Array of void or bytes -- No need to multiply. */
1671 index = fold_convert (type, index);
1673 else
1675 index = d_convert (type, index);
1676 index = fold_build2 (MULT_EXPR, TREE_TYPE (index),
1677 index, d_convert (TREE_TYPE (index), size_exp));
1678 index = fold_convert (type, index);
1681 if (integer_zerop (index))
1682 return ptr;
1684 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);
1687 /* Builds pointer offset expression *(PTR OP OFFSET)
1688 OP could be a plus or minus expression. */
1690 tree
1691 build_offset_op (tree_code op, tree ptr, tree offset)
1693 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);
1695 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1696 TYPE_UNSIGNED (sizetype));
1697 offset = fold_convert (type, offset);
1699 if (op == MINUS_EXPR)
1700 offset = fold_build1 (NEGATE_EXPR, type, offset);
1702 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);
1705 /* Builds pointer offset expression *(PTR + OFFSET). */
1707 tree
1708 build_offset (tree ptr, tree offset)
1710 return build_offset_op (PLUS_EXPR, ptr, offset);
1713 tree
1714 build_memref (tree type, tree ptr, tree offset)
1716 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));
1719 /* Create a tree node to set multiple elements to a single value. */
1721 tree
1722 build_array_set (tree ptr, tree length, tree value)
1724 tree ptrtype = TREE_TYPE (ptr);
1725 tree lentype = TREE_TYPE (length);
1727 push_binding_level (level_block);
1728 push_stmt_list ();
1730 /* Build temporary locals for length and ptr, and maybe value. */
1731 tree t = build_local_temp (size_type_node);
1732 add_stmt (build_assign (INIT_EXPR, t, length));
1733 length = t;
1735 t = build_local_temp (ptrtype);
1736 add_stmt (build_assign (INIT_EXPR, t, ptr));
1737 ptr = t;
1739 if (TREE_SIDE_EFFECTS (value))
1741 t = build_local_temp (TREE_TYPE (value));
1742 add_stmt (build_assign (INIT_EXPR, t, value));
1743 value = t;
1746 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1747 push_stmt_list ();
1749 /* Exit logic for the loop.
1750 if (length == 0) break; */
1751 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1752 t = build1 (EXIT_EXPR, void_type_node, t);
1753 add_stmt (t);
1755 /* Assign value to the current pointer position.
1756 *ptr = value; */
1757 t = modify_expr (build_deref (ptr), value);
1758 add_stmt (t);
1760 /* Move pointer to next element position.
1761 ptr++; */
1762 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));
1763 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));
1764 add_stmt (t);
1766 /* Decrease loop counter.
1767 length -= 1; */
1768 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1769 d_convert (lentype, integer_one_node));
1770 add_stmt (t);
1772 /* Pop statements and finish loop. */
1773 tree loop_body = pop_stmt_list ();
1774 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));
1776 /* Wrap it up into a bind expression. */
1777 tree stmt_list = pop_stmt_list ();
1778 tree block = pop_binding_level ();
1780 return build3 (BIND_EXPR, void_type_node,
1781 BLOCK_VARS (block), stmt_list, block);
1785 /* Build an array of type TYPE where all the elements are VAL. */
1787 tree
1788 build_array_from_val (Type *type, tree val)
1790 tree etype = build_ctype (type->nextOf ());
1792 /* Initializing a multidimensional array. */
1793 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)
1794 val = build_array_from_val (type->nextOf (), val);
1796 size_t dims = type->isTypeSArray ()->dim->toInteger ();
1797 vec <constructor_elt, va_gc> *elms = NULL;
1798 vec_safe_reserve (elms, dims);
1800 val = d_convert (etype, val);
1802 for (size_t i = 0; i < dims; i++)
1803 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
1805 return build_constructor (build_ctype (type), elms);
1808 /* Build a static array of type TYPE from an array of EXPS.
1809 If CONST_P is true, then all elements in EXPS are constants. */
1811 tree
1812 build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
1814 /* Build a CONSTRUCTOR from all expressions. */
1815 vec <constructor_elt, va_gc> *elms = NULL;
1816 vec_safe_reserve (elms, exps->length);
1818 Type *etype = type->nextOf ();
1819 tree satype = make_array_type (etype, exps->length);
1821 for (size_t i = 0; i < exps->length; i++)
1823 Expression *expr = (*exps)[i];
1824 tree t = build_expr (expr, const_p);
1825 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1826 convert_expr (t, expr->type, etype));
1829 /* Create a new temporary to store the array. */
1830 tree var = build_local_temp (satype);
1832 /* Fill any alignment holes with zeroes. */
1833 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
1834 tree init = NULL;
1835 if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ()))
1836 init = build_memset_call (var);
1838 /* Initialize the temporary. */
1839 tree assign = modify_expr (var, build_constructor (satype, elms));
1840 return compound_expr (compound_expr (init, assign), var);
1844 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1846 tree
1847 void_okay_p (tree t)
1849 tree type = TREE_TYPE (t);
1851 if (VOID_TYPE_P (TREE_TYPE (type)))
1853 tree totype = build_ctype (Type::tuns8->pointerTo ());
1854 return fold_convert (totype, t);
1857 return t;
1860 /* Builds a STRING_CST representing the filename of location LOC. When the
1861 location is not valid, the name of the source module is used instead. */
1863 static tree
1864 build_filename_from_loc (const Loc &loc)
1866 const char *filename = loc.filename
1867 ? loc.filename : d_function_chain->module->srcfile.toChars ();
1869 unsigned length = strlen (filename);
1870 tree str = build_string (length, filename);
1871 TREE_TYPE (str) = make_array_type (Type::tchar, length + 1);
1873 return build_address (str);
1876 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1877 an assert check fails. When calling the msg variant functions, MSG is the
1878 error message supplied by the user. */
1880 tree
1881 build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
1883 tree file;
1884 tree line = size_int (loc.linnum);
1886 switch (libcall)
1888 case LIBCALL_ASSERT_MSG:
1889 case LIBCALL_UNITTEST_MSG:
1890 /* File location is passed as a D string. */
1891 if (loc.filename)
1893 unsigned len = strlen (loc.filename);
1894 tree str = build_string (len, loc.filename);
1895 TREE_TYPE (str) = make_array_type (Type::tchar, len);
1897 file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
1898 size_int (len), build_address (str));
1900 else
1901 file = null_array_node;
1902 break;
1904 case LIBCALL_ASSERTP:
1905 case LIBCALL_UNITTESTP:
1906 file = build_filename_from_loc (loc);
1907 break;
1909 default:
1910 gcc_unreachable ();
1914 if (msg != NULL_TREE)
1915 return build_libcall (libcall, Type::tvoid, 3, msg, file, line);
1916 else
1917 return build_libcall (libcall, Type::tvoid, 2, file, line);
1920 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
1921 array bounds check fails. */
1923 tree
1924 build_array_bounds_call (const Loc &loc)
1926 /* Terminate the program with a trap if no D runtime present. */
1927 if (checkaction_trap_p ())
1928 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1929 else
1931 return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
1932 build_filename_from_loc (loc),
1933 size_int (loc.linnum));
1937 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1938 in the index expression IE. The condition returns the INDEX if true, or
1939 throws a `ArrayIndexError`. */
1941 tree
1942 build_bounds_index_condition (IndexExp *ie, tree index, tree length)
1944 if (ie->indexIsInBounds || !array_bounds_check ())
1945 return index;
1947 /* Prevent multiple evaluations of the index. */
1948 index = d_save_expr (index);
1950 /* Generate INDEX >= LENGTH && throw RangeError.
1951 No need to check whether INDEX >= 0 as the front-end should
1952 have already taken care of implicit casts to unsigned. */
1953 tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length);
1954 tree boundserr;
1956 if (checkaction_trap_p ())
1957 boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1958 else
1960 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
1961 build_filename_from_loc (ie->e2->loc),
1962 size_int (ie->e2->loc.linnum), index, length);
1965 return build_condition (TREE_TYPE (index), condition, boundserr, index);
1968 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1969 the slice expression SE of the source array length LENGTH. The condition
1970 returns the new array length if true, or throws an `ArraySliceError`. */
1972 tree
1973 build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
1975 if (array_bounds_check ())
1977 tree condition = NULL_TREE;
1979 /* Enforces that `upper <= length`. */
1980 if (!se->upperIsInBounds && length != NULL_TREE)
1981 condition = fold_build2 (GT_EXPR, d_bool_type, upper, length);
1982 else
1983 length = integer_zero_node;
1985 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1986 we've already ensured that `upper <= length`. */
1987 if (!se->lowerIsLessThanUpper)
1989 tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper);
1991 if (condition != NULL_TREE)
1992 condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond);
1993 else
1994 condition = lwr_cond;
1997 if (condition != NULL_TREE)
1999 tree boundserr;
2001 if (checkaction_trap_p ())
2003 boundserr =
2004 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2006 else
2008 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
2009 Type::tvoid, 5,
2010 build_filename_from_loc (se->loc),
2011 size_int (se->loc.linnum),
2012 lower, upper, length);
2015 upper = build_condition (TREE_TYPE (upper), condition,
2016 boundserr, upper);
2020 /* Need to ensure lower always gets evaluated first, as it may be a function
2021 call. Generates (lower, upper) - lower. */
2022 return fold_build2 (MINUS_EXPR, TREE_TYPE (upper),
2023 compound_expr (lower, upper), lower);
2026 /* Returns TRUE if array bounds checking code generation is turned on. */
2028 bool
2029 array_bounds_check (void)
2031 FuncDeclaration *fd;
2033 switch (global.params.useArrayBounds)
2035 case CHECKENABLEoff:
2036 return false;
2038 case CHECKENABLEon:
2039 return true;
2041 case CHECKENABLEsafeonly:
2042 /* For D2 safe functions only. */
2043 fd = d_function_chain->function;
2044 if (fd && fd->type->ty == TY::Tfunction)
2046 if (fd->type->isTypeFunction ()->trust == TRUST::safe)
2047 return true;
2049 return false;
2051 default:
2052 gcc_unreachable ();
2056 /* Returns TRUE if we terminate the program with a trap if an array bounds or
2057 contract check fails. */
2059 bool
2060 checkaction_trap_p (void)
2062 switch (global.params.checkAction)
2064 case CHECKACTION_D:
2065 case CHECKACTION_context:
2066 return false;
2068 case CHECKACTION_C:
2069 case CHECKACTION_halt:
2070 return true;
2072 default:
2073 gcc_unreachable ();
2077 /* Returns the TypeFunction class for Type T.
2078 Assumes T is already ->toBasetype(). */
2080 TypeFunction *
2081 get_function_type (Type *t)
2083 TypeFunction *tf = NULL;
2084 if (t->ty == TY::Tpointer)
2085 t = t->nextOf ()->toBasetype ();
2086 if (t->ty == TY::Tfunction)
2087 tf = t->isTypeFunction ();
2088 else if (t->ty == TY::Tdelegate)
2089 tf = t->isTypeDelegate ()->next->isTypeFunction ();
2090 return tf;
2093 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
2094 CALLER. In which case, CALLEE is being called through an alias that was
2095 passed to CALLER. */
2097 bool
2098 call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)
2100 if (!callee->isNested ())
2101 return false;
2103 if (caller->toParent () == callee->toParent ())
2104 return false;
2106 Dsymbol *dsym = callee;
2108 while (dsym)
2110 if (dsym->isTemplateInstance ())
2111 return false;
2112 else if (dsym->isFuncDeclaration () == caller)
2113 return false;
2114 dsym = dsym->toParent ();
2117 return true;
2120 /* Entry point for call routines. Builds a function call to FD.
2121 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
2123 tree
2124 d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)
2126 return d_build_call (get_function_type (fd->type),
2127 build_address (get_symbol_decl (fd)), object, arguments);
2130 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
2131 ARGUMENTS are evaluated in left to right order, saved and promoted
2132 before passing. */
2134 tree
2135 d_build_call (TypeFunction *tf, tree callable, tree object,
2136 Expressions *arguments)
2138 tree ctype = TREE_TYPE (callable);
2139 tree callee = callable;
2141 if (POINTER_TYPE_P (ctype))
2142 ctype = TREE_TYPE (ctype);
2143 else
2144 callee = build_address (callable);
2146 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));
2147 gcc_assert (tf != NULL);
2148 gcc_assert (tf->ty == TY::Tfunction);
2150 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)
2152 /* Front-end apparently doesn't check this. */
2153 if (TREE_CODE (callable) == FUNCTION_DECL)
2155 error ("need %<this%> to access member %qE", DECL_NAME (callable));
2156 return error_mark_node;
2159 /* Probably an internal error. */
2160 gcc_unreachable ();
2163 /* Build the argument list for the call. */
2164 vec <tree, va_gc> *args = NULL;
2165 tree saved_args = NULL_TREE;
2166 bool noreturn_call = false;
2168 /* If this is a delegate call or a nested function being called as
2169 a delegate, the object should not be NULL. */
2170 if (object != NULL_TREE)
2171 vec_safe_push (args, object);
2173 if (arguments)
2175 /* First pass, evaluated expanded tuples in function arguments. */
2176 for (size_t i = 0; i < arguments->length; ++i)
2178 Lagain:
2179 Expression *arg = (*arguments)[i];
2180 gcc_assert (arg->op != EXP::tuple);
2182 if (arg->op == EXP::comma)
2184 CommaExp *ce = arg->isCommaExp ();
2185 tree tce = build_expr (ce->e1);
2186 saved_args = compound_expr (saved_args, tce);
2187 (*arguments)[i] = ce->e2;
2188 goto Lagain;
2192 const size_t nparams = tf->parameterList.length ();
2193 /* if _arguments[] is the first argument. */
2194 const size_t varargs = tf->isDstyleVariadic ();
2196 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2197 for (size_t i = 0; i < arguments->length; ++i)
2199 Expression *arg = (*arguments)[i];
2200 tree targ = build_expr (arg);
2202 if (i - varargs < nparams && i >= varargs)
2204 /* Actual arguments for declared formal arguments. */
2205 Parameter *parg = tf->parameterList[i - varargs];
2206 targ = convert_for_argument (targ, parg);
2209 /* Don't pass empty aggregates by value. */
2210 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
2211 && TREE_CODE (targ) != CONSTRUCTOR)
2213 tree t = build_constructor (TREE_TYPE (targ), NULL);
2214 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
2217 /* Parameter is a struct or array passed by invisible reference. */
2218 if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
2220 Type *t = arg->type->toBasetype ();
2221 StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
2223 /* Nested structs also have ADDRESSABLE set, but if the type has
2224 neither a copy constructor nor a destructor available, then we
2225 need to take care of copying its value before passing it. */
2226 if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor))
2227 targ = force_target_expr (targ);
2229 targ = convert (build_reference_type (TREE_TYPE (targ)),
2230 build_address (targ));
2233 /* Complex types are exposed as special types with an underlying
2234 struct representation, if we are passing the native type to a
2235 function that accepts the library-defined version, then ensure
2236 it is properly reinterpreted as the underlying struct type. */
2237 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (targ))
2238 && arg->type->isTypeStruct ())
2239 targ = underlying_complex_expr (build_ctype (arg->type), targ);
2241 /* Type `noreturn` is a terminator, as no other arguments can possibly
2242 be evaluated after it. */
2243 if (TREE_TYPE (targ) == noreturn_type_node)
2244 noreturn_call = true;
2246 vec_safe_push (args, targ);
2250 /* Evaluate the callee before calling it. */
2251 if (TREE_SIDE_EFFECTS (callee))
2253 callee = d_save_expr (callee);
2254 saved_args = compound_expr (callee, saved_args);
2257 /* If we saw a `noreturn` parameter, any unreachable argument evaluations
2258 after it are discarded, as well as the function call itself. */
2259 if (noreturn_call)
2261 if (TREE_SIDE_EFFECTS (callee))
2262 saved_args = compound_expr (callee, saved_args);
2264 tree arg;
2265 unsigned int ix;
2267 FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
2268 saved_args = compound_expr (saved_args, arg);
2270 /* Add a stub result type for the expression. */
2271 tree result = build_zero_cst (TREE_TYPE (ctype));
2272 return compound_expr (saved_args, result);
2275 tree result = build_call_vec (TREE_TYPE (ctype), callee, args);
2276 SET_EXPR_LOCATION (result, input_location);
2278 result = maybe_expand_intrinsic (result);
2280 /* Return the value in a temporary slot so that it can be evaluated
2281 multiple times by the caller. */
2282 if (TREE_CODE (result) == CALL_EXPR
2283 && AGGREGATE_TYPE_P (TREE_TYPE (result))
2284 && TREE_ADDRESSABLE (TREE_TYPE (result)))
2286 CALL_EXPR_RETURN_SLOT_OPT (result) = true;
2287 result = force_target_expr (result);
2290 return compound_expr (saved_args, result);
2293 /* Build and return the correct call to fmod depending on TYPE.
2294 ARG0 and ARG1 are the arguments pass to the function. */
2296 tree
2297 build_float_modulus (tree type, tree arg0, tree arg1)
2299 tree fmodfn = NULL_TREE;
2300 tree basetype = type;
2302 if (COMPLEX_FLOAT_TYPE_P (basetype))
2303 basetype = TREE_TYPE (basetype);
2305 if (TYPE_MAIN_VARIANT (basetype) == double_type_node
2306 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)
2307 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);
2308 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node
2309 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)
2310 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);
2311 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node
2312 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)
2313 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);
2315 if (!fmodfn)
2317 error ("tried to perform floating-point modulo division on %qT", type);
2318 return error_mark_node;
2321 if (COMPLEX_FLOAT_TYPE_P (type))
2323 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);
2324 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);
2326 return complex_expr (type, re, im);
2329 if (SCALAR_FLOAT_TYPE_P (type))
2330 return build_call_expr (fmodfn, 2, arg0, arg1);
2332 /* Should have caught this above. */
2333 gcc_unreachable ();
2336 /* Build a function type whose first argument is a pointer to BASETYPE,
2337 which is to be used for the `vthis' context parameter for TYPE.
2338 The base type may be a record for member functions, or a void for
2339 nested functions and delegates. */
2341 tree
2342 build_vthis_function (tree basetype, tree type)
2344 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
2346 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),
2347 TYPE_ARG_TYPES (type));
2348 tree fntype = build_function_type (TREE_TYPE (type), argtypes);
2350 /* Copy volatile qualifiers from the original function type. */
2351 if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE)
2352 fntype = build_qualified_type (fntype, TYPE_QUAL_VOLATILE);
2354 if (RECORD_OR_UNION_TYPE_P (basetype))
2355 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);
2356 else
2357 gcc_assert (VOID_TYPE_P (basetype));
2359 return fntype;
2362 /* Raise an error at that the context pointer of the function or object SYM is
2363 not accessible from the current scope. */
2365 tree
2366 error_no_frame_access (Dsymbol *sym)
2368 error_at (input_location, "cannot get frame pointer to %qs",
2369 sym->toPrettyChars ());
2370 return null_pointer_node;
2373 /* If SYM is a nested function, return the static chain to be
2374 used when calling that function from the current function.
2376 If SYM is a nested class or struct, return the static chain
2377 to be used when creating an instance of the class from CFUN. */
2379 tree
2380 get_frame_for_symbol (Dsymbol *sym)
2382 FuncDeclaration *thisfd
2383 = d_function_chain ? d_function_chain->function : NULL;
2384 FuncDeclaration *fd = sym->isFuncDeclaration ();
2385 FuncDeclaration *fdparent = NULL;
2386 FuncDeclaration *fdoverride = NULL;
2388 if (fd != NULL)
2390 /* Check that the nested function is properly defined. */
2391 if (!fd->fbody)
2393 /* Should instead error on line that references `fd'. */
2394 error_at (make_location_t (fd->loc), "nested function missing body");
2395 return null_pointer_node;
2398 fdparent = fd->toParent2 ()->isFuncDeclaration ();
2400 /* Special case for __ensure and __require. */
2401 if ((fd->ident == Identifier::idPool ("__ensure")
2402 || fd->ident == Identifier::idPool ("__require"))
2403 && fdparent != thisfd)
2405 fdoverride = fdparent;
2406 fdparent = thisfd;
2409 else
2411 /* It's a class (or struct). NewExp codegen has already determined its
2412 outer scope is not another class, so it must be a function. */
2413 while (sym && !sym->isFuncDeclaration ())
2414 sym = sym->toParent2 ();
2416 fdparent = (FuncDeclaration *) sym;
2419 /* Not a nested function, there is no frame pointer to pass. */
2420 if (fdparent == NULL)
2422 /* Only delegate literals report as being nested, even if they are in
2423 global scope. */
2424 gcc_assert (fd && fd->isFuncLiteralDeclaration ());
2425 return null_pointer_node;
2428 gcc_assert (thisfd != NULL);
2430 if (thisfd != fdparent)
2432 /* If no frame pointer for this function. */
2433 if (!thisfd->vthis)
2435 error_at (make_location_t (sym->loc),
2436 "%qs is a nested function and cannot be accessed from %qs",
2437 fdparent->toPrettyChars (), thisfd->toPrettyChars ());
2438 return null_pointer_node;
2441 /* Make sure we can get the frame pointer to the outer function.
2442 Go up each nesting level until we find the enclosing function. */
2443 Dsymbol *dsym = thisfd;
2445 while (fd != dsym)
2447 /* Check if enclosing function is a function. */
2448 FuncDeclaration *fdp = dsym->isFuncDeclaration ();
2449 Dsymbol *parent = dsym->toParent2 ();
2451 if (fdp != NULL)
2453 if (fdparent == parent)
2454 break;
2456 gcc_assert (fdp->isNested () || fdp->vthis);
2457 dsym = parent;
2458 continue;
2461 /* Check if enclosed by an aggregate. That means the current
2462 function must be a member function of that aggregate. */
2463 AggregateDeclaration *adp = dsym->isAggregateDeclaration ();
2465 if (adp != NULL)
2467 if ((adp->isClassDeclaration () || adp->isStructDeclaration ())
2468 && fdparent == parent)
2469 break;
2472 /* No frame to outer function found. */
2473 if (!adp || !adp->isNested () || !adp->vthis)
2474 return error_no_frame_access (sym);
2476 dsym = parent;
2480 tree ffo = get_frameinfo (fdparent);
2481 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2483 tree frame_ref = get_framedecl (thisfd, fdparent);
2485 /* If `thisfd' is a derived member function, then `fdparent' is the
2486 overridden member function in the base class. Even if there's a
2487 closure environment, we should give the original stack data as the
2488 nested function frame. */
2489 if (fdoverride)
2491 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2492 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2493 gcc_assert (cdo && cd);
2495 int offset;
2496 if (cdo->isBaseOf (cd, &offset) && offset != 0)
2498 /* Generate a new frame to pass to the overriden function that
2499 has the `this' pointer adjusted. */
2500 gcc_assert (offset != OFFSET_RUNTIME);
2502 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2503 tree fields = TYPE_FIELDS (type);
2504 /* The `this' field comes immediately after the `__chain'. */
2505 tree thisfield = chain_index (1, fields);
2506 vec <constructor_elt, va_gc> *ve = NULL;
2508 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2509 frame_ref = build_deref (frame_ref);
2511 for (tree field = fields; field; field = DECL_CHAIN (field))
2513 tree value = component_ref (frame_ref, framefields);
2514 if (field == thisfield)
2515 value = build_offset (value, size_int (offset));
2517 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2518 framefields = DECL_CHAIN (framefields);
2521 frame_ref = build_address (build_constructor (type, ve));
2525 return frame_ref;
2528 return null_pointer_node;
2531 /* Return the parent function of a nested class or struct AD. */
2533 static FuncDeclaration *
2534 get_outer_function (AggregateDeclaration *ad)
2536 FuncDeclaration *fd = NULL;
2537 while (ad && ad->isNested ())
2539 Dsymbol *dsym = ad->toParent2 ();
2540 if ((fd = dsym->isFuncDeclaration ()))
2541 return fd;
2542 else
2543 ad = dsym->isAggregateDeclaration ();
2546 return NULL;
2549 /* Starting from the current function FD, try to find a suitable value of
2550 `this' in nested function instances. A suitable `this' value is an
2551 instance of OCD or a class that has OCD as a base. */
2553 static tree
2554 find_this_tree (ClassDeclaration *ocd)
2556 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2558 while (fd)
2560 AggregateDeclaration *ad = fd->isThis ();
2561 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;
2563 if (cd != NULL)
2565 if (ocd == cd)
2566 return get_decl_tree (fd->vthis);
2567 else if (ocd->isBaseOf (cd, NULL))
2568 return convert_expr (get_decl_tree (fd->vthis),
2569 cd->type, ocd->type);
2571 fd = get_outer_function (cd);
2572 continue;
2575 if (fd->isNested ())
2577 fd = fd->toParent2 ()->isFuncDeclaration ();
2578 continue;
2581 fd = NULL;
2584 return NULL_TREE;
2587 /* Retrieve the outer class/struct `this' value of DECL from
2588 the current function. */
2590 tree
2591 build_vthis (AggregateDeclaration *decl)
2593 ClassDeclaration *cd = decl->isClassDeclaration ();
2594 StructDeclaration *sd = decl->isStructDeclaration ();
2596 /* If an aggregate nested in a function has no methods and there are no
2597 other nested functions, any static chain created here will never be
2598 translated. Use a null pointer for the link in this case. */
2599 tree vthis_value = null_pointer_node;
2601 if (cd != NULL || sd != NULL)
2603 Dsymbol *outer = decl->toParent2 ();
2605 /* If the parent is a templated struct, the outer context is instead
2606 the enclosing symbol of where the instantiation happened. */
2607 if (outer->isStructDeclaration ())
2609 gcc_assert (outer->parent && outer->parent->isTemplateInstance ());
2610 outer = ((TemplateInstance *) outer->parent)->enclosing;
2613 /* For outer classes, get a suitable `this' value.
2614 For outer functions, get a suitable frame/closure pointer. */
2615 ClassDeclaration *cdo = outer->isClassDeclaration ();
2616 FuncDeclaration *fdo = outer->isFuncDeclaration ();
2618 if (cdo)
2620 vthis_value = find_this_tree (cdo);
2621 gcc_assert (vthis_value != NULL_TREE);
2623 else if (fdo)
2625 tree ffo = get_frameinfo (fdo);
2626 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)
2627 || fdo->hasNestedFrameRefs ())
2628 vthis_value = get_frame_for_symbol (decl);
2629 else if (cd != NULL)
2631 /* Classes nested in methods are allowed to access any outer
2632 class fields, use the function chain in this case. */
2633 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)
2634 vthis_value = get_decl_tree (fdo->vthis);
2637 else
2638 gcc_unreachable ();
2641 return vthis_value;
2644 /* Build the RECORD_TYPE that describes the function frame or closure type for
2645 the function FD. FFI is the tree holding all frame information. */
2647 static tree
2648 build_frame_type (tree ffi, FuncDeclaration *fd)
2650 if (FRAMEINFO_TYPE (ffi))
2651 return FRAMEINFO_TYPE (ffi);
2653 tree frame_rec_type = make_node (RECORD_TYPE);
2654 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.",
2655 fd->toPrettyChars (), NULL);
2656 TYPE_NAME (frame_rec_type) = get_identifier (name);
2657 free (name);
2659 tree fields = NULL_TREE;
2661 /* Function is a member or nested, so must have field for outer context. */
2662 if (fd->vthis)
2664 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
2665 get_identifier ("__chain"), ptr_type_node);
2666 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;
2667 fields = chainon (NULL_TREE, ptr_field);
2668 DECL_NONADDRESSABLE_P (ptr_field) = 1;
2671 /* The __ensure and __require are called directly, so never make the outer
2672 functions closure, but nevertheless could still be referencing parameters
2673 of the calling function non-locally. So we add all parameters with nested
2674 refs to the function frame, this should also mean overriding methods will
2675 have the same frame layout when inheriting a contract. */
2676 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2677 || (global.params.useOut == CHECKENABLEon && fd->fensure))
2679 if (fd->parameters)
2681 for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++)
2683 VarDeclaration *v = (*fd->parameters)[i];
2684 /* Remove if already in closureVars so can push to front. */
2685 size_t j = fd->closureVars.find (v);
2687 if (j < fd->closureVars.length)
2688 fd->closureVars.remove (j);
2690 fd->closureVars.insert (i, v);
2694 /* Also add hidden `this' to outer context. */
2695 if (fd->vthis)
2697 size_t i = fd->closureVars.find (fd->vthis);
2699 if (i < fd->closureVars.length)
2700 fd->closureVars.remove (i);
2702 fd->closureVars.insert (0, fd->vthis);
2706 for (size_t i = 0; i < fd->closureVars.length; i++)
2708 VarDeclaration *v = fd->closureVars[i];
2709 tree vsym = get_symbol_decl (v);
2710 tree ident = v->ident
2711 ? get_identifier (v->ident->toChars ()) : NULL_TREE;
2713 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,
2714 TREE_TYPE (vsym));
2715 SET_DECL_LANG_FRAME_FIELD (vsym, field);
2716 DECL_FIELD_CONTEXT (field) = frame_rec_type;
2717 fields = chainon (fields, field);
2718 TREE_USED (vsym) = 1;
2720 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
2721 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
2722 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
2724 if (DECL_LANG_NRVO (vsym))
2726 /* Store the nrvo variable in the frame by reference. */
2727 TREE_TYPE (field) = build_reference_type (TREE_TYPE (field));
2729 /* Can't do nrvo if the variable is put in a closure, since what the
2730 return slot points to may no longer exist. */
2731 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi));
2734 if (FRAMEINFO_IS_CLOSURE (ffi))
2736 /* Because the value needs to survive the end of the scope. */
2737 if ((v->edtor && (v->storage_class & STCparameter))
2738 || v->needsScopeDtor ())
2739 error_at (make_location_t (v->loc),
2740 "has scoped destruction, cannot build closure");
2744 TYPE_FIELDS (frame_rec_type) = fields;
2745 TYPE_READONLY (frame_rec_type) = 1;
2746 TYPE_CXX_ODR_P (frame_rec_type) = 1;
2747 layout_type (frame_rec_type);
2748 d_keep (frame_rec_type);
2750 return frame_rec_type;
2753 /* Closures are implemented by taking the local variables that
2754 need to survive the scope of the function, and copying them
2755 into a GC allocated chuck of memory. That chunk, called the
2756 closure here, is inserted into the linked list of stack
2757 frames instead of the usual stack frame.
2759 If a closure is not required, but FD still needs a frame to lower
2760 nested refs, then instead build custom static chain decl on stack. */
2762 void
2763 build_closure (FuncDeclaration *fd)
2765 tree ffi = get_frameinfo (fd);
2767 if (!FRAMEINFO_CREATES_FRAME (ffi))
2768 return;
2770 tree type = FRAMEINFO_TYPE (ffi);
2771 gcc_assert (COMPLETE_TYPE_P (type));
2773 tree decl, decl_ref;
2775 if (FRAMEINFO_IS_CLOSURE (ffi))
2777 decl = build_local_temp (build_pointer_type (type));
2778 DECL_NAME (decl) = get_identifier ("__closptr");
2779 decl_ref = build_deref (decl);
2781 /* Allocate memory for closure. */
2782 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
2783 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
2785 tree init_exp = build_assign (INIT_EXPR, decl,
2786 build_nop (TREE_TYPE (decl), init));
2787 add_stmt (init_exp);
2789 else
2791 decl = build_local_temp (type);
2792 DECL_NAME (decl) = get_identifier ("__frame");
2793 decl_ref = decl;
2796 /* Set the first entry to the parent closure/frame, if any. */
2797 if (fd->vthis)
2799 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));
2800 tree chain_expr = modify_expr (chain_field,
2801 d_function_chain->static_chain);
2802 add_stmt (chain_expr);
2805 /* Copy parameters that are referenced nonlocally. */
2806 for (size_t i = 0; i < fd->closureVars.length; i++)
2808 VarDeclaration *v = fd->closureVars[i];
2809 tree vsym = get_symbol_decl (v);
2811 if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym))
2812 continue;
2814 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));
2816 /* Variable is an alias for the NRVO slot, store the reference. */
2817 if (DECL_LANG_NRVO (vsym))
2818 vsym = build_address (DECL_LANG_NRVO (vsym));
2820 tree expr = modify_expr (field, vsym);
2821 add_stmt (expr);
2824 if (!FRAMEINFO_IS_CLOSURE (ffi))
2825 decl = build_address (decl);
2827 d_function_chain->static_chain = decl;
2830 /* Return the frame of FD. This could be a static chain or a closure
2831 passed via the hidden `this' pointer. */
2833 tree
2834 get_frameinfo (FuncDeclaration *fd)
2836 tree fds = get_symbol_decl (fd);
2837 if (DECL_LANG_FRAMEINFO (fds))
2838 return DECL_LANG_FRAMEINFO (fds);
2840 tree ffi = make_node (FUNCFRAME_INFO);
2842 DECL_LANG_FRAMEINFO (fds) = ffi;
2844 if (fd->needsClosure ())
2846 /* Set-up a closure frame, this will be allocated on the heap. */
2847 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2848 FRAMEINFO_IS_CLOSURE (ffi) = 1;
2850 else if (fd->hasNestedFrameRefs ())
2852 /* Functions with nested refs must create a static frame for local
2853 variables to be referenced from. */
2854 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2856 else
2858 /* For nested functions, default to creating a frame. Even if there are
2859 no fields to populate the frame, create it anyway, as this will be
2860 used as the record type instead of `void*` for the this parameter. */
2861 if (fd->vthis && fd->vthis->type == Type::tvoidptr)
2862 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2864 /* In checkNestedReference, references from contracts are not added to the
2865 closureVars array, so assume all parameters referenced. */
2866 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2867 || (global.params.useOut == CHECKENABLEon && fd->fensure))
2868 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2870 /* If however `fd` is nested (deeply) in a function that creates a
2871 closure, then `fd` instead inherits that closure via hidden vthis
2872 pointer, and doesn't create a stack frame at all. */
2873 FuncDeclaration *ff = fd;
2875 while (ff)
2877 tree ffo = get_frameinfo (ff);
2879 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))
2881 gcc_assert (FRAMEINFO_TYPE (ffo));
2882 FRAMEINFO_CREATES_FRAME (ffi) = 0;
2883 FRAMEINFO_STATIC_CHAIN (ffi) = 1;
2884 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);
2885 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));
2886 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);
2887 break;
2890 /* Stop looking if no frame pointer for this function. */
2891 if (ff->vthis == NULL)
2892 break;
2894 AggregateDeclaration *ad = ff->isThis ();
2895 if (ad && ad->isNested ())
2897 while (ad->isNested ())
2899 Dsymbol *d = ad->toParent2 ();
2900 ad = d->isAggregateDeclaration ();
2901 ff = d->isFuncDeclaration ();
2903 if (ad == NULL)
2904 break;
2907 else
2908 ff = ff->toParent2 ()->isFuncDeclaration ();
2912 /* Build type now as may be referenced from another module. */
2913 if (FRAMEINFO_CREATES_FRAME (ffi))
2914 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);
2916 return ffi;
2919 /* Return a pointer to the frame/closure block of OUTER
2920 so can be accessed from the function INNER. */
2922 tree
2923 get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
2925 tree result = d_function_chain->static_chain;
2926 FuncDeclaration *fd = inner;
2928 while (fd && fd != outer)
2930 /* Parent frame link is the first field. */
2931 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))
2932 result = indirect_ref (ptr_type_node, result);
2934 if (fd->isNested ())
2935 fd = fd->toParent2 ()->isFuncDeclaration ();
2936 /* The frame/closure record always points to the outer function's
2937 frame, even if there are intervening nested classes or structs.
2938 So, we can just skip over these. */
2939 else
2940 fd = get_outer_function (fd->isThis ());
2943 if (fd != outer)
2944 return error_no_frame_access (outer);
2946 /* Go get our frame record. */
2947 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
2949 if (frame_type != NULL_TREE)
2951 result = build_nop (build_pointer_type (frame_type), result);
2952 return result;
2954 else
2956 error_at (make_location_t (inner->loc),
2957 "forward reference to frame of %qs", outer->toChars ());
2958 return null_pointer_node;