]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-codegen.cc
Daily bump.
[thirdparty/gcc.git] / gcc / d / d-codegen.cc
CommitLineData
b4c522fa 1/* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
8d9254fc 2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
b4c522fa
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with GCC; see the file COPYING3. If not see
16<http://www.gnu.org/licenses/>. */
17
18#include "config.h"
19#include "system.h"
20#include "coretypes.h"
21
22#include "dmd/aggregate.h"
23#include "dmd/ctfe.h"
24#include "dmd/declaration.h"
25#include "dmd/identifier.h"
26#include "dmd/target.h"
27#include "dmd/template.h"
28
29#include "tree.h"
30#include "tree-iterator.h"
31#include "fold-const.h"
32#include "diagnostic.h"
33#include "langhooks.h"
34#include "target.h"
35#include "stringpool.h"
36#include "varasm.h"
37#include "stor-layout.h"
38#include "attribs.h"
39#include "function.h"
40
41#include "d-tree.h"
42
43
44/* Return the GCC location for the D frontend location LOC. */
45
46location_t
47make_location_t (const Loc& loc)
48{
49 location_t gcc_location = input_location;
50
51 if (loc.filename)
52 {
53 linemap_add (line_table, LC_ENTER, 0, loc.filename, loc.linnum);
54 linemap_line_start (line_table, loc.linnum, 0);
55 gcc_location = linemap_position_for_column (line_table, loc.charnum);
56 linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
57 }
58
59 return gcc_location;
60}
61
62/* Return the DECL_CONTEXT for symbol DSYM. */
63
64tree
65d_decl_context (Dsymbol *dsym)
66{
67 Dsymbol *parent = dsym;
68 Declaration *decl = dsym->isDeclaration ();
69
9dddefef 70 while ((parent = parent->toParent2 ()))
b4c522fa
IB
71 {
72 /* We've reached the top-level module namespace.
73 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,
74 but only for extern(D) symbols. */
75 if (parent->isModule ())
76 {
77 if (decl != NULL && decl->linkage != LINKd)
78 return NULL_TREE;
79
80 return build_import_decl (parent);
81 }
82
83 /* Declarations marked as 'static' or '__gshared' are never
84 part of any context except at module level. */
85 if (decl != NULL && decl->isDataseg ())
86 continue;
87
88 /* Nested functions. */
89 FuncDeclaration *fd = parent->isFuncDeclaration ();
90 if (fd != NULL)
91 return get_symbol_decl (fd);
92
93 /* Methods of classes or structs. */
94 AggregateDeclaration *ad = parent->isAggregateDeclaration ();
95 if (ad != NULL)
96 {
97 tree context = build_ctype (ad->type);
98 /* Want the underlying RECORD_TYPE. */
99 if (ad->isClassDeclaration ())
100 context = TREE_TYPE (context);
101
102 return context;
103 }
b4c522fa
IB
104 }
105
106 return NULL_TREE;
107}
108
109/* Return a copy of record TYPE but safe to modify in any way. */
110
111tree
112copy_aggregate_type (tree type)
113{
114 tree newtype = build_distinct_type_copy (type);
115 TYPE_FIELDS (newtype) = copy_list (TYPE_FIELDS (type));
116
117 for (tree f = TYPE_FIELDS (newtype); f; f = DECL_CHAIN (f))
118 DECL_FIELD_CONTEXT (f) = newtype;
119
120 return newtype;
121}
122
123/* Return TRUE if declaration DECL is a reference type. */
124
125bool
126declaration_reference_p (Declaration *decl)
127{
128 Type *tb = decl->type->toBasetype ();
129
130 /* Declaration is a reference type. */
131 if (tb->ty == Treference || decl->storage_class & (STCout | STCref))
132 return true;
133
134 return false;
135}
136
137/* Returns the real type for declaration DECL. */
138
139tree
140declaration_type (Declaration *decl)
141{
142 /* Lazy declarations are converted to delegates. */
143 if (decl->storage_class & STClazy)
144 {
145 TypeFunction *tf = TypeFunction::create (NULL, decl->type, false, LINKd);
146 TypeDelegate *t = TypeDelegate::create (tf);
147 return build_ctype (t->merge2 ());
148 }
149
150 /* Static array va_list have array->pointer conversions applied. */
151 if (decl->isParameter () && valist_array_p (decl->type))
152 {
153 Type *valist = decl->type->nextOf ()->pointerTo ();
154 valist = valist->castMod (decl->type->mod);
155 return build_ctype (valist);
156 }
157
158 tree type = build_ctype (decl->type);
159
160 /* Parameter is passed by reference. */
161 if (declaration_reference_p (decl))
162 return build_reference_type (type);
163
164 /* The 'this' parameter is always const. */
165 if (decl->isThisDeclaration ())
166 return insert_type_modifiers (type, MODconst);
167
168 return type;
169}
170
171/* These should match the Declaration versions above
172 Return TRUE if parameter ARG is a reference type. */
173
174bool
175argument_reference_p (Parameter *arg)
176{
177 Type *tb = arg->type->toBasetype ();
178
179 /* Parameter is a reference type. */
180 if (tb->ty == Treference || arg->storageClass & (STCout | STCref))
181 return true;
182
b4c522fa
IB
183 return false;
184}
185
186/* Returns the real type for parameter ARG. */
187
188tree
189type_passed_as (Parameter *arg)
190{
191 /* Lazy parameters are converted to delegates. */
192 if (arg->storageClass & STClazy)
193 {
194 TypeFunction *tf = TypeFunction::create (NULL, arg->type, false, LINKd);
195 TypeDelegate *t = TypeDelegate::create (tf);
196 return build_ctype (t->merge2 ());
197 }
198
199 /* Static array va_list have array->pointer conversions applied. */
200 if (valist_array_p (arg->type))
201 {
202 Type *valist = arg->type->nextOf ()->pointerTo ();
203 valist = valist->castMod (arg->type->mod);
204 return build_ctype (valist);
205 }
206
207 tree type = build_ctype (arg->type);
208
209 /* Parameter is passed by reference. */
8a9ce39f 210 if (TREE_ADDRESSABLE (type) || argument_reference_p (arg))
b4c522fa
IB
211 return build_reference_type (type);
212
213 return type;
214}
215
216/* Build INTEGER_CST of type TYPE with the value VALUE. */
217
218tree
219build_integer_cst (dinteger_t value, tree type)
220{
221 /* The type is error_mark_node, we can't do anything. */
222 if (error_operand_p (type))
223 return type;
224
225 return build_int_cst_type (type, value);
226}
227
228/* Build REAL_CST of type TOTYPE with the value VALUE. */
229
230tree
231build_float_cst (const real_t& value, Type *totype)
232{
233 real_t new_value;
234 TypeBasic *tb = totype->isTypeBasic ();
235
236 gcc_assert (tb != NULL);
237
238 tree type_node = build_ctype (tb);
239 real_convert (&new_value.rv (), TYPE_MODE (type_node), &value.rv ());
240
241 return build_real (type_node, new_value.rv ());
242}
243
244/* Returns the .length component from the D dynamic array EXP. */
245
246tree
247d_array_length (tree exp)
248{
249 if (error_operand_p (exp))
250 return exp;
251
252 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
253
254 /* Get the back-end type for the array and pick out the array
255 length field (assumed to be the first field). */
256 tree len_field = TYPE_FIELDS (TREE_TYPE (exp));
257 return component_ref (exp, len_field);
258}
259
260/* Returns the .ptr component from the D dynamic array EXP. */
261
262tree
263d_array_ptr (tree exp)
264{
265 if (error_operand_p (exp))
266 return exp;
267
268 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp)));
269
270 /* Get the back-end type for the array and pick out the array
271 data pointer field (assumed to be the second field). */
272 tree ptr_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
273 return component_ref (exp, ptr_field);
274}
275
276/* Returns a constructor for D dynamic array type TYPE of .length LEN
277 and .ptr pointing to DATA. */
278
279tree
280d_array_value (tree type, tree len, tree data)
281{
282 tree len_field, ptr_field;
283 vec<constructor_elt, va_gc> *ce = NULL;
284
285 gcc_assert (TYPE_DYNAMIC_ARRAY (type));
286 len_field = TYPE_FIELDS (type);
287 ptr_field = TREE_CHAIN (len_field);
288
289 len = convert (TREE_TYPE (len_field), len);
290 data = convert (TREE_TYPE (ptr_field), data);
291
292 CONSTRUCTOR_APPEND_ELT (ce, len_field, len);
293 CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);
294
295 return build_constructor (type, ce);
296}
297
298/* Returns value representing the array length of expression EXP.
299 TYPE could be a dynamic or static array. */
300
301tree
302get_array_length (tree exp, Type *type)
303{
304 Type *tb = type->toBasetype ();
305
306 switch (tb->ty)
307 {
308 case Tsarray:
309 return size_int (((TypeSArray *) tb)->dim->toUInteger ());
310
311 case Tarray:
312 return d_array_length (exp);
313
314 default:
a9c697b8 315 error ("cannot determine the length of a %qs", type->toChars ());
b4c522fa
IB
316 return error_mark_node;
317 }
318}
319
320/* Create BINFO for a ClassDeclaration's inheritance tree.
321 InterfaceDeclaration's are not included. */
322
323tree
324build_class_binfo (tree super, ClassDeclaration *cd)
325{
326 tree binfo = make_tree_binfo (1);
327 tree ctype = build_ctype (cd->type);
328
329 /* Want RECORD_TYPE, not POINTER_TYPE. */
330 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
331 BINFO_INHERITANCE_CHAIN (binfo) = super;
332 BINFO_OFFSET (binfo) = integer_zero_node;
333
334 if (cd->baseClass)
335 BINFO_BASE_APPEND (binfo, build_class_binfo (binfo, cd->baseClass));
336
337 return binfo;
338}
339
340/* Create BINFO for an InterfaceDeclaration's inheritance tree.
341 In order to access all inherited methods in the debugger,
342 the entire tree must be described.
343 This function makes assumptions about interface layout. */
344
345tree
346build_interface_binfo (tree super, ClassDeclaration *cd, unsigned& offset)
347{
348 tree binfo = make_tree_binfo (cd->baseclasses->dim);
349 tree ctype = build_ctype (cd->type);
350
351 /* Want RECORD_TYPE, not POINTER_TYPE. */
352 BINFO_TYPE (binfo) = TREE_TYPE (ctype);
353 BINFO_INHERITANCE_CHAIN (binfo) = super;
354 BINFO_OFFSET (binfo) = size_int (offset * Target::ptrsize);
355 BINFO_VIRTUAL_P (binfo) = 1;
356
357 for (size_t i = 0; i < cd->baseclasses->dim; i++, offset++)
358 {
359 BaseClass *bc = (*cd->baseclasses)[i];
360 BINFO_BASE_APPEND (binfo, build_interface_binfo (binfo, bc->sym, offset));
361 }
362
363 return binfo;
364}
365
366/* Returns the .funcptr component from the D delegate EXP. */
367
368tree
369delegate_method (tree exp)
370{
371 /* Get the back-end type for the delegate and pick out the funcptr field
372 (assumed to be the second field). */
373 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
374 tree method_field = TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp)));
375 return component_ref (exp, method_field);
376}
377
378/* Returns the .object component from the delegate EXP. */
379
380tree
381delegate_object (tree exp)
382{
383 /* Get the back-end type for the delegate and pick out the object field
384 (assumed to be the first field). */
385 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp)));
386 tree obj_field = TYPE_FIELDS (TREE_TYPE (exp));
387 return component_ref (exp, obj_field);
388}
389
390/* Build a delegate literal of type TYPE whose pointer function is
391 METHOD, and hidden object is OBJECT. */
392
393tree
394build_delegate_cst (tree method, tree object, Type *type)
395{
396 tree ctor = make_node (CONSTRUCTOR);
397 tree ctype;
398
399 Type *tb = type->toBasetype ();
400 if (tb->ty == Tdelegate)
401 ctype = build_ctype (type);
402 else
403 {
404 /* Convert a function method into an anonymous delegate. */
405 ctype = make_struct_type ("delegate()", 2,
406 get_identifier ("object"), TREE_TYPE (object),
407 get_identifier ("func"), TREE_TYPE (method));
408 TYPE_DELEGATE (ctype) = 1;
409 }
410
411 vec<constructor_elt, va_gc> *ce = NULL;
412 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (ctype), object);
413 CONSTRUCTOR_APPEND_ELT (ce, TREE_CHAIN (TYPE_FIELDS (ctype)), method);
414
415 CONSTRUCTOR_ELTS (ctor) = ce;
416 TREE_TYPE (ctor) = ctype;
417
418 return ctor;
419}
420
421/* Builds a temporary tree to store the CALLEE and OBJECT
422 of a method call expression of type TYPE. */
423
424tree
425build_method_call (tree callee, tree object, Type *type)
426{
427 tree t = build_delegate_cst (callee, object, type);
428 METHOD_CALL_EXPR (t) = 1;
429 return t;
430}
431
432/* Extract callee and object from T and return in to CALLEE and OBJECT. */
433
434void
435extract_from_method_call (tree t, tree& callee, tree& object)
436{
437 gcc_assert (METHOD_CALL_EXPR (t));
438 object = CONSTRUCTOR_ELT (t, 0)->value;
439 callee = CONSTRUCTOR_ELT (t, 1)->value;
440}
441
5e95646e
IB
442/* Build a typeof(null) constant of type TYPE. Handles certain special case
443 conversions, where the underlying type is an aggregate with a nullable
444 interior pointer. */
445
446tree
447build_typeof_null_value (Type *type)
448{
449 Type *tb = type->toBasetype ();
450 tree value;
451
452 /* For dynamic arrays, set length and pointer fields to zero. */
453 if (tb->ty == Tarray)
454 value = d_array_value (build_ctype (type), size_int (0), null_pointer_node);
455
456 /* For associative arrays, set the pointer field to null. */
457 else if (tb->ty == Taarray)
458 {
459 tree ctype = build_ctype (type);
460 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype));
461
462 value = build_constructor_single (ctype, TYPE_FIELDS (ctype),
463 null_pointer_node);
464 }
465
466 /* For delegates, set the frame and function pointer fields to null. */
467 else if (tb->ty == Tdelegate)
468 value = build_delegate_cst (null_pointer_node, null_pointer_node, type);
469
470 /* Simple zero constant for all other types. */
471 else
472 value = build_zero_cst (build_ctype (type));
473
474 TREE_CONSTANT (value) = 1;
475 return value;
476}
477
b4c522fa
IB
478/* Build a dereference into the virtual table for OBJECT to retrieve
479 a function pointer of type FNTYPE at position INDEX. */
480
481tree
482build_vindex_ref (tree object, tree fntype, size_t index)
483{
484 /* The vtable is the first field. Interface methods are also in the class's
485 vtable, so we don't need to convert from a class to an interface. */
486 tree result = build_deref (object);
487 result = component_ref (result, TYPE_FIELDS (TREE_TYPE (result)));
488
489 gcc_assert (POINTER_TYPE_P (fntype));
490
491 return build_memref (fntype, result, size_int (Target::ptrsize * index));
492}
493
494/* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
495 made into temporaries, otherwise any assignments will be lost. */
496
497static bool
498lvalue_p (tree exp)
499{
500 const enum tree_code code = TREE_CODE (exp);
501
502 switch (code)
503 {
504 case SAVE_EXPR:
505 return false;
506
507 case ARRAY_REF:
508 case INDIRECT_REF:
509 case VAR_DECL:
510 case PARM_DECL:
511 case RESULT_DECL:
512 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp));
513
514 case IMAGPART_EXPR:
515 case REALPART_EXPR:
516 case COMPONENT_REF:
517 CASE_CONVERT:
518 return lvalue_p (TREE_OPERAND (exp, 0));
519
520 case COND_EXPR:
521 return (lvalue_p (TREE_OPERAND (exp, 1)
522 ? TREE_OPERAND (exp, 1)
523 : TREE_OPERAND (exp, 0))
524 && lvalue_p (TREE_OPERAND (exp, 2)));
525
526 case TARGET_EXPR:
527 return true;
528
529 case COMPOUND_EXPR:
530 return lvalue_p (TREE_OPERAND (exp, 1));
531
532 default:
533 return false;
534 }
535}
536
537/* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
538 more than once in an expression. */
539
540tree
541d_save_expr (tree exp)
542{
543 if (TREE_SIDE_EFFECTS (exp))
544 {
545 if (lvalue_p (exp))
546 return stabilize_reference (exp);
547
548 return save_expr (exp);
549 }
550
551 return exp;
552}
553
554/* VALUEP is an expression we want to pre-evaluate or perform a computation on.
555 The expression returned by this function is the part whose value we don't
556 care about, storing the value in VALUEP. Callers must ensure that the
557 returned expression is evaluated before VALUEP. */
558
559tree
560stabilize_expr (tree *valuep)
561{
562 tree expr = *valuep;
563 const enum tree_code code = TREE_CODE (expr);
564 tree lhs;
565 tree rhs;
566
567 switch (code)
568 {
569 case COMPOUND_EXPR:
570 /* Given ((e1, ...), eN):
571 Store the last RHS 'eN' expression in VALUEP. */
572 lhs = TREE_OPERAND (expr, 0);
573 rhs = TREE_OPERAND (expr, 1);
574 lhs = compound_expr (lhs, stabilize_expr (&rhs));
575 *valuep = rhs;
576 return lhs;
577
578 default:
579 return NULL_TREE;
580 }
581}
582
583/* Return a TARGET_EXPR, initializing the DECL with EXP. */
584
585tree
586build_target_expr (tree decl, tree exp)
587{
588 tree type = TREE_TYPE (decl);
589 tree result = build4 (TARGET_EXPR, type, decl, exp, NULL_TREE, NULL_TREE);
590
591 if (EXPR_HAS_LOCATION (exp))
592 SET_EXPR_LOCATION (result, EXPR_LOCATION (exp));
593
594 /* If decl must always reside in memory. */
595 if (TREE_ADDRESSABLE (type))
596 d_mark_addressable (decl);
597
598 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
599 TARGET_EXPR. If there really turn out to be no side effects, then the
600 optimizer should be able to remove it. */
601 TREE_SIDE_EFFECTS (result) = 1;
602
603 return result;
604}
605
606/* Like the above function, but initializes a new temporary. */
607
608tree
609force_target_expr (tree exp)
610{
611 tree decl = create_temporary_var (TREE_TYPE (exp));
612
613 return build_target_expr (decl, exp);
614}
615
616/* Returns the address of the expression EXP. */
617
618tree
619build_address (tree exp)
620{
621 if (error_operand_p (exp))
622 return exp;
623
624 tree ptrtype;
625 tree type = TREE_TYPE (exp);
626
627 if (TREE_CODE (exp) == STRING_CST)
628 {
629 /* Just convert string literals (char[]) to C-style strings (char *),
630 otherwise the latter method (char[]*) causes conversion problems
631 during gimplification. */
632 ptrtype = build_pointer_type (TREE_TYPE (type));
633 }
634 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (va_list_type_node)
635 && TREE_CODE (TYPE_MAIN_VARIANT (type)) == ARRAY_TYPE)
636 {
637 /* Special case for va_list, allow arrays to decay to a pointer. */
638 ptrtype = build_pointer_type (TREE_TYPE (type));
639 }
640 else
641 ptrtype = build_pointer_type (type);
642
643 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
644 tree init = stabilize_expr (&exp);
645
646 /* Can't take the address of a manifest constant, instead use its value. */
647 if (TREE_CODE (exp) == CONST_DECL)
648 exp = DECL_INITIAL (exp);
649
884efbd5
IB
650 /* Some expression lowering may request an address of a compile-time constant,
651 or other non-lvalue expression. Make sure it is assigned to a location we
652 can reference. */
653 if ((CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
654 || TREE_CODE (exp) == CALL_EXPR)
b4c522fa
IB
655 exp = force_target_expr (exp);
656
657 d_mark_addressable (exp);
658 exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype);
659
660 if (TREE_CODE (exp) == ADDR_EXPR)
661 TREE_NO_TRAMPOLINE (exp) = 1;
662
663 return compound_expr (init, exp);
664}
665
666/* Mark EXP saying that we need to be able to take the
667 address of it; it should not be allocated in a register. */
668
669tree
670d_mark_addressable (tree exp)
671{
672 switch (TREE_CODE (exp))
673 {
674 case ADDR_EXPR:
675 case COMPONENT_REF:
676 case ARRAY_REF:
677 case REALPART_EXPR:
678 case IMAGPART_EXPR:
679 d_mark_addressable (TREE_OPERAND (exp, 0));
680 break;
681
682 case PARM_DECL:
683 case VAR_DECL:
684 case RESULT_DECL:
685 case CONST_DECL:
686 case FUNCTION_DECL:
687 TREE_ADDRESSABLE (exp) = 1;
688 break;
689
690 case CONSTRUCTOR:
691 TREE_ADDRESSABLE (exp) = 1;
692 break;
693
694 case TARGET_EXPR:
695 TREE_ADDRESSABLE (exp) = 1;
696 d_mark_addressable (TREE_OPERAND (exp, 0));
697 break;
698
699 default:
700 break;
701 }
702
703 return exp;
704}
705
706/* Mark EXP as "used" in the program for the benefit of
707 -Wunused warning purposes. */
708
709tree
710d_mark_used (tree exp)
711{
712 switch (TREE_CODE (exp))
713 {
714 case VAR_DECL:
715 case CONST_DECL:
716 case PARM_DECL:
717 case RESULT_DECL:
718 case FUNCTION_DECL:
719 TREE_USED (exp) = 1;
720 break;
721
722 case ARRAY_REF:
723 case COMPONENT_REF:
724 case MODIFY_EXPR:
725 case REALPART_EXPR:
726 case IMAGPART_EXPR:
727 case NOP_EXPR:
728 case CONVERT_EXPR:
729 case ADDR_EXPR:
730 d_mark_used (TREE_OPERAND (exp, 0));
731 break;
732
733 case COMPOUND_EXPR:
734 d_mark_used (TREE_OPERAND (exp, 0));
735 d_mark_used (TREE_OPERAND (exp, 1));
736 break;
737
738 default:
739 break;
740 }
741 return exp;
742}
743
744/* Mark EXP as read, not just set, for set but not used -Wunused
745 warning purposes. */
746
747tree
748d_mark_read (tree exp)
749{
750 switch (TREE_CODE (exp))
751 {
752 case VAR_DECL:
753 case PARM_DECL:
754 TREE_USED (exp) = 1;
755 DECL_READ_P (exp) = 1;
756 break;
757
758 case ARRAY_REF:
759 case COMPONENT_REF:
760 case MODIFY_EXPR:
761 case REALPART_EXPR:
762 case IMAGPART_EXPR:
763 case NOP_EXPR:
764 case CONVERT_EXPR:
765 case ADDR_EXPR:
766 d_mark_read (TREE_OPERAND (exp, 0));
767 break;
768
769 case COMPOUND_EXPR:
770 d_mark_read (TREE_OPERAND (exp, 1));
771 break;
772
773 default:
774 break;
775 }
776 return exp;
777}
778
779/* Return TRUE if the struct SD is suitable for comparison using memcmp.
780 This is because we don't guarantee that padding is zero-initialized for
781 a stack variable, so we can't use memcmp to compare struct values. */
782
783bool
784identity_compare_p (StructDeclaration *sd)
785{
786 if (sd->isUnionDeclaration ())
787 return true;
788
789 unsigned offset = 0;
790
791 for (size_t i = 0; i < sd->fields.dim; i++)
792 {
793 VarDeclaration *vd = sd->fields[i];
5bdebb51 794 Type *tb = vd->type->toBasetype ();
b4c522fa
IB
795
796 /* Check inner data structures. */
5bdebb51 797 if (tb->ty == Tstruct)
b4c522fa 798 {
5bdebb51 799 TypeStruct *ts = (TypeStruct *) tb;
b4c522fa
IB
800 if (!identity_compare_p (ts->sym))
801 return false;
802 }
803
5bdebb51
IB
804 /* Check for types that may have padding. */
805 if ((tb->ty == Tcomplex80 || tb->ty == Tfloat80 || tb->ty == Timaginary80)
806 && Target::realpad != 0)
807 return false;
808
b4c522fa
IB
809 if (offset <= vd->offset)
810 {
811 /* There's a hole in the struct. */
812 if (offset != vd->offset)
813 return false;
814
815 offset += vd->type->size ();
816 }
817 }
818
819 /* Any trailing padding may not be zero. */
820 if (offset < sd->structsize)
821 return false;
822
823 return true;
824}
825
5bdebb51
IB
826/* Build a floating-point identity comparison between T1 and T2, ignoring any
827 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
828
829tree
830build_float_identity (tree_code code, tree t1, tree t2)
831{
832 tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
833 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
834
835 tree result = build_call_expr (tmemcmp, 3, build_address (t1),
836 build_address (t2), size);
837 return build_boolop (code, result, integer_zero_node);
838}
839
b4c522fa
IB
840/* Lower a field-by-field equality expression between T1 and T2 of type SD.
841 CODE is the EQ_EXPR or NE_EXPR comparison. */
842
843static tree
844lower_struct_comparison (tree_code code, StructDeclaration *sd,
845 tree t1, tree t2)
846{
847 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
848 tree tmemcmp = NULL_TREE;
849
850 /* We can skip the compare if the structs are empty. */
851 if (sd->fields.dim == 0)
852 {
853 tmemcmp = build_boolop (code, integer_zero_node, integer_zero_node);
854 if (TREE_SIDE_EFFECTS (t2))
855 tmemcmp = compound_expr (t2, tmemcmp);
856 if (TREE_SIDE_EFFECTS (t1))
857 tmemcmp = compound_expr (t1, tmemcmp);
858
859 return tmemcmp;
860 }
861
862 /* Let back-end take care of union comparisons. */
863 if (sd->isUnionDeclaration ())
864 {
865 tmemcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,
866 build_address (t1), build_address (t2),
867 size_int (sd->structsize));
868
869 return build_boolop (code, tmemcmp, integer_zero_node);
870 }
871
872 for (size_t i = 0; i < sd->fields.dim; i++)
873 {
874 VarDeclaration *vd = sd->fields[i];
5bdebb51 875 Type *type = vd->type->toBasetype ();
b4c522fa
IB
876 tree sfield = get_symbol_decl (vd);
877
878 tree t1ref = component_ref (t1, sfield);
879 tree t2ref = component_ref (t2, sfield);
880 tree tcmp;
881
5bdebb51 882 if (type->ty == Tstruct)
b4c522fa
IB
883 {
884 /* Compare inner data structures. */
5bdebb51 885 StructDeclaration *decl = ((TypeStruct *) type)->sym;
b4c522fa
IB
886 tcmp = lower_struct_comparison (code, decl, t1ref, t2ref);
887 }
5bdebb51
IB
888 else if (type->ty != Tvector && type->isintegral ())
889 {
890 /* Integer comparison, no special handling required. */
891 tcmp = build_boolop (code, t1ref, t2ref);
892 }
893 else if (type->ty != Tvector && type->isfloating ())
894 {
895 /* Floating-point comparison, don't compare padding in type. */
896 if (!type->iscomplex ())
897 tcmp = build_float_identity (code, t1ref, t2ref);
898 else
899 {
900 tree req = build_float_identity (code, real_part (t1ref),
901 real_part (t2ref));
902 tree ieq = build_float_identity (code, imaginary_part (t1ref),
903 imaginary_part (t2ref));
904
905 tcmp = build_boolop (tcode, req, ieq);
906 }
907 }
b4c522fa
IB
908 else
909 {
5bdebb51 910 tree stype = build_ctype (type);
b4c522fa
IB
911 opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));
912
5bdebb51 913 if (mode.exists ())
b4c522fa
IB
914 {
915 /* Compare field bits as their corresponding integer type.
916 *((T*) &t1) == *((T*) &t2) */
917 tree tmode = lang_hooks.types.type_for_mode (mode.require (), 1);
918
919 if (tmode == NULL_TREE)
920 tmode = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
921
922 t1ref = build_vconvert (tmode, t1ref);
923 t2ref = build_vconvert (tmode, t2ref);
924
925 tcmp = build_boolop (code, t1ref, t2ref);
926 }
927 else
928 {
929 /* Simple memcmp between types. */
930 tcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP),
931 3, build_address (t1ref),
932 build_address (t2ref),
933 TYPE_SIZE_UNIT (stype));
934
935 tcmp = build_boolop (code, tcmp, integer_zero_node);
936 }
937 }
938
939 tmemcmp = (tmemcmp) ? build_boolop (tcode, tmemcmp, tcmp) : tcmp;
940 }
941
942 return tmemcmp;
943}
944
945
946/* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
947 If possible, use memcmp, otherwise field-by-field comparison is done.
948 CODE is the EQ_EXPR or NE_EXPR comparison. */
949
950tree
951build_struct_comparison (tree_code code, StructDeclaration *sd,
952 tree t1, tree t2)
953{
954 /* We can skip the compare if the structs are empty. */
955 if (sd->fields.dim == 0)
956 {
957 tree exp = build_boolop (code, integer_zero_node, integer_zero_node);
958 if (TREE_SIDE_EFFECTS (t2))
959 exp = compound_expr (t2, exp);
960 if (TREE_SIDE_EFFECTS (t1))
961 exp = compound_expr (t1, exp);
962
963 return exp;
964 }
965
966 /* Make temporaries to prevent multiple evaluations. */
967 tree t1init = stabilize_expr (&t1);
968 tree t2init = stabilize_expr (&t2);
969 tree result;
970
971 t1 = d_save_expr (t1);
972 t2 = d_save_expr (t2);
973
974 /* Bitwise comparison of structs not returned in memory may not work
975 due to data holes loosing its zero padding upon return.
976 As a heuristic, small structs are not compared using memcmp either. */
977 if (TYPE_MODE (TREE_TYPE (t1)) != BLKmode || !identity_compare_p (sd))
978 result = lower_struct_comparison (code, sd, t1, t2);
979 else
980 {
981 /* Do bit compare of structs. */
982 tree size = size_int (sd->structsize);
983 tree tmemcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP),
984 3, build_address (t1),
985 build_address (t2), size);
986
987 result = build_boolop (code, tmemcmp, integer_zero_node);
988 }
989
990 return compound_expr (compound_expr (t1init, t2init), result);
991}
992
993/* Build an equality expression between two ARRAY_TYPES of size LENGTH.
994 The pointer references are T1 and T2, and the element type is SD.
995 CODE is the EQ_EXPR or NE_EXPR comparison. */
996
997tree
998build_array_struct_comparison (tree_code code, StructDeclaration *sd,
999 tree length, tree t1, tree t2)
1000{
1001 tree_code tcode = (code == EQ_EXPR) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
1002
1003 /* Build temporary for the result of the comparison.
1004 Initialize as either 0 or 1 depending on operation. */
1005 tree result = build_local_temp (d_bool_type);
1006 tree init = build_boolop (code, integer_zero_node, integer_zero_node);
1007 add_stmt (build_assign (INIT_EXPR, result, init));
1008
1009 /* Cast pointer-to-array to pointer-to-struct. */
1010 tree ptrtype = build_ctype (sd->type->pointerTo ());
1011 tree lentype = TREE_TYPE (length);
1012
1013 push_binding_level (level_block);
1014 push_stmt_list ();
1015
1016 /* Build temporary locals for length and pointers. */
1017 tree t = build_local_temp (size_type_node);
1018 add_stmt (build_assign (INIT_EXPR, t, length));
1019 length = t;
1020
1021 t = build_local_temp (ptrtype);
1022 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t1)));
1023 t1 = t;
1024
1025 t = build_local_temp (ptrtype);
1026 add_stmt (build_assign (INIT_EXPR, t, d_convert (ptrtype, t2)));
1027 t2 = t;
1028
1029 /* Build loop for comparing each element. */
1030 push_stmt_list ();
1031
1032 /* Exit logic for the loop.
1033 if (length == 0 || result OP 0) break; */
1034 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1035 t = build_boolop (TRUTH_ORIF_EXPR, t, build_boolop (code, result,
1036 boolean_false_node));
1037 t = build1 (EXIT_EXPR, void_type_node, t);
1038 add_stmt (t);
1039
1040 /* Do comparison, caching the value.
1041 result = result OP (*t1 == *t2); */
1042 t = build_struct_comparison (code, sd, build_deref (t1), build_deref (t2));
1043 t = build_boolop (tcode, result, t);
1044 t = modify_expr (result, t);
1045 add_stmt (t);
1046
1047 /* Move both pointers to next element position.
1048 t1++, t2++; */
1049 tree size = d_convert (ptrtype, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype)));
1050 t = build2 (POSTINCREMENT_EXPR, ptrtype, t1, size);
1051 add_stmt (t);
1052 t = build2 (POSTINCREMENT_EXPR, ptrtype, t2, size);
1053 add_stmt (t);
1054
1055 /* Decrease loop counter.
1056 length -= 1; */
1057 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1058 d_convert (lentype, integer_one_node));
1059 add_stmt (t);
1060
1061 /* Pop statements and finish loop. */
1062 tree body = pop_stmt_list ();
1063 add_stmt (build1 (LOOP_EXPR, void_type_node, body));
1064
1065 /* Wrap it up into a bind expression. */
1066 tree stmt_list = pop_stmt_list ();
1067 tree block = pop_binding_level ();
1068
1069 body = build3 (BIND_EXPR, void_type_node,
1070 BLOCK_VARS (block), stmt_list, block);
1071
1072 return compound_expr (body, result);
1073}
1074
b4c522fa
IB
1075/* Build a constructor for a variable of aggregate type TYPE using the
1076 initializer INIT, an ordered flat list of fields and values provided
1077 by the frontend. The returned constructor should be a value that
1078 matches the layout of TYPE. */
1079
1080tree
1081build_struct_literal (tree type, vec<constructor_elt, va_gc> *init)
1082{
1083 /* If the initializer was empty, use default zero initialization. */
1084 if (vec_safe_is_empty (init))
1085 return build_constructor (type, NULL);
1086
1087 vec<constructor_elt, va_gc> *ve = NULL;
1088 HOST_WIDE_INT offset = 0;
1089 bool constant_p = true;
b4c522fa
IB
1090 bool finished = false;
1091
b4c522fa
IB
1092 /* Walk through each field, matching our initializer list. */
1093 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
1094 {
1095 bool is_initialized = false;
1096 tree value;
1097
1098 if (DECL_NAME (field) == NULL_TREE
1099 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1100 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1101 {
1102 /* Search all nesting aggregates, if nothing is found, then
1103 this will return an empty initializer to fill the hole. */
1104 value = build_struct_literal (TREE_TYPE (field), init);
1105
1106 if (!initializer_zerop (value))
1107 is_initialized = true;
1108 }
1109 else
1110 {
1111 /* Search for the value to initialize the next field. Once found,
1112 pop it from the init list so we don't look at it again. */
1113 unsigned HOST_WIDE_INT idx;
1114 tree index;
1115
1116 FOR_EACH_CONSTRUCTOR_ELT (init, idx, index, value)
1117 {
1118 /* If the index is NULL, then just assign it to the next field.
1119 This comes from layout_typeinfo(), which generates a flat
1120 list of values that we must shape into the record type. */
1121 if (index == field || index == NULL_TREE)
1122 {
1123 init->ordered_remove (idx);
1124 if (!finished)
1125 is_initialized = true;
1126 break;
1127 }
1128 }
1129 }
1130
1131 if (is_initialized)
1132 {
1133 HOST_WIDE_INT fieldpos = int_byte_position (field);
1134 gcc_assert (value != NULL_TREE);
1135
b4c522fa
IB
1136 /* Must not initialize fields that overlap. */
1137 if (fieldpos < offset)
1138 {
1139 /* Find the nearest user defined type and field. */
1140 tree vtype = type;
1141 while (ANON_AGGR_TYPE_P (vtype))
1142 vtype = TYPE_CONTEXT (vtype);
1143
1144 tree vfield = field;
1145 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield))
1146 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield)))
1147 vfield = TYPE_FIELDS (TREE_TYPE (vfield));
1148
1149 /* Must not generate errors for compiler generated fields. */
1150 gcc_assert (TYPE_NAME (vtype) && DECL_NAME (vfield));
1151 error ("overlapping initializer for field %qT.%qD",
1152 TYPE_NAME (vtype), DECL_NAME (vfield));
1153 }
1154
1155 if (!TREE_CONSTANT (value))
1156 constant_p = false;
1157
1158 CONSTRUCTOR_APPEND_ELT (ve, field, value);
1159
1160 /* For unions, only the first field is initialized, any other field
1161 initializers found for this union are drained and ignored. */
1162 if (TREE_CODE (type) == UNION_TYPE)
1163 finished = true;
1164 }
1165
1166 /* Move offset to the next position in the struct. */
1167 if (TREE_CODE (type) == RECORD_TYPE)
1168 {
1169 offset = int_byte_position (field)
1170 + int_size_in_bytes (TREE_TYPE (field));
1171 }
1172
1173 /* If all initializers have been assigned, there's nothing else to do. */
1174 if (vec_safe_is_empty (init))
1175 break;
1176 }
1177
b4c522fa
IB
1178 /* Ensure that we have consumed all values. */
1179 gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
1180
1181 tree ctor = build_constructor (type, ve);
1182
1183 if (constant_p)
1184 TREE_CONSTANT (ctor) = 1;
1185
1186 return ctor;
1187}
1188
1189/* Given the TYPE of an anonymous field inside T, return the
1190 FIELD_DECL for the field. If not found return NULL_TREE.
1191 Because anonymous types can nest, we must also search all
1192 anonymous fields that are directly reachable. */
1193
1194static tree
1195lookup_anon_field (tree t, tree type)
1196{
1197 t = TYPE_MAIN_VARIANT (t);
1198
1199 for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
1200 {
1201 if (DECL_NAME (field) == NULL_TREE)
1202 {
1203 /* If we find it directly, return the field. */
1204 if (type == TYPE_MAIN_VARIANT (TREE_TYPE (field)))
1205 return field;
1206
1207 /* Otherwise, it could be nested, search harder. */
1208 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
1209 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
1210 {
1211 tree subfield = lookup_anon_field (TREE_TYPE (field), type);
1212 if (subfield)
1213 return subfield;
1214 }
1215 }
1216 }
1217
1218 return NULL_TREE;
1219}
1220
1221/* Builds OBJECT.FIELD component reference. */
1222
1223tree
1224component_ref (tree object, tree field)
1225{
1226 if (error_operand_p (object) || error_operand_p (field))
1227 return error_mark_node;
1228
1229 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1230
1231 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1232 tree init = stabilize_expr (&object);
1233
1234 /* If the FIELD is from an anonymous aggregate, generate a reference
1235 to the anonymous data member, and recur to find FIELD. */
1236 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field)))
1237 {
1238 tree anonymous_field = lookup_anon_field (TREE_TYPE (object),
1239 DECL_CONTEXT (field));
1240 object = component_ref (object, anonymous_field);
1241 }
1242
1243 tree result = fold_build3_loc (input_location, COMPONENT_REF,
1244 TREE_TYPE (field), object, field, NULL_TREE);
1245
1246 return compound_expr (init, result);
1247}
1248
1249/* Build an assignment expression of lvalue LHS from value RHS.
1250 CODE is the code for a binary operator that we use to combine
1251 the old value of LHS with RHS to get the new value. */
1252
1253tree
1254build_assign (tree_code code, tree lhs, tree rhs)
1255{
1256 tree init = stabilize_expr (&lhs);
1257 init = compound_expr (init, stabilize_expr (&rhs));
1258
1259 /* If initializing the LHS using a function that returns via NRVO. */
1260 if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
1261 && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
1262 && aggregate_value_p (TREE_TYPE (rhs), rhs))
1263 {
1264 /* Mark as addressable here, which should ensure the return slot is the
1265 address of the LHS expression, taken care of by back-end. */
1266 d_mark_addressable (lhs);
1267 CALL_EXPR_RETURN_SLOT_OPT (rhs) = true;
1268 }
1269
1270 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1271 if (TREE_CODE (rhs) == TARGET_EXPR)
1272 {
1273 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1274 since that would cause the LHS to be constructed twice.
1275 So we force the TARGET_EXPR to be expanded without a target. */
1276 if (code != INIT_EXPR)
1277 rhs = compound_expr (rhs, TARGET_EXPR_SLOT (rhs));
1278 else
1279 {
1280 d_mark_addressable (lhs);
1281 rhs = TARGET_EXPR_INITIAL (rhs);
1282 }
1283 }
1284
1285 tree result = fold_build2_loc (input_location, code,
1286 TREE_TYPE (lhs), lhs, rhs);
1287 return compound_expr (init, result);
1288}
1289
1290/* Build an assignment expression of lvalue LHS from value RHS. */
1291
1292tree
1293modify_expr (tree lhs, tree rhs)
1294{
1295 return build_assign (MODIFY_EXPR, lhs, rhs);
1296}
1297
1298/* Return EXP represented as TYPE. */
1299
1300tree
1301build_nop (tree type, tree exp)
1302{
1303 if (error_operand_p (exp))
1304 return exp;
1305
1306 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1307 tree init = stabilize_expr (&exp);
1308 exp = fold_build1_loc (input_location, NOP_EXPR, type, exp);
1309
1310 return compound_expr (init, exp);
1311}
1312
1313/* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1314 except that EXP is type-punned, rather than a straight-forward cast. */
1315
1316tree
1317build_vconvert (tree type, tree exp)
1318{
1319 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1320 makes sure this works for vector-to-array viewing, or if EXP ends up being
1321 used as the LHS of a MODIFY_EXPR. */
1322 return indirect_ref (type, build_address (exp));
1323}
1324
1325/* Maybe warn about ARG being an address that can never be null. */
1326
1327static void
1328warn_for_null_address (tree arg)
1329{
1330 if (TREE_CODE (arg) == ADDR_EXPR
1331 && decl_with_nonnull_addr_p (TREE_OPERAND (arg, 0)))
1332 warning (OPT_Waddress,
1333 "the address of %qD will never be %<null%>",
1334 TREE_OPERAND (arg, 0));
1335}
1336
1337/* Build a boolean ARG0 op ARG1 expression. */
1338
1339tree
1340build_boolop (tree_code code, tree arg0, tree arg1)
1341{
1342 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1343 so need to remove all side effects incase its address is taken. */
1344 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0)))
1345 arg0 = d_save_expr (arg0);
1346 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1)))
1347 arg1 = d_save_expr (arg1);
1348
1349 if (VECTOR_TYPE_P (TREE_TYPE (arg0)) && VECTOR_TYPE_P (TREE_TYPE (arg1)))
1350 {
1351 /* Build a vector comparison.
1352 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1353 tree type = TREE_TYPE (arg0);
e8738f4e 1354 tree cmptype = truth_type_for (type);
b4c522fa
IB
1355 tree cmp = fold_build2_loc (input_location, code, cmptype, arg0, arg1);
1356
1357 return fold_build3_loc (input_location, VEC_COND_EXPR, type, cmp,
1358 build_minus_one_cst (type),
1359 build_zero_cst (type));
1360 }
1361
1362 if (code == EQ_EXPR || code == NE_EXPR)
1363 {
1364 /* Check if comparing the address of a variable to null. */
1365 if (POINTER_TYPE_P (TREE_TYPE (arg0)) && integer_zerop (arg1))
1366 warn_for_null_address (arg0);
1367 if (POINTER_TYPE_P (TREE_TYPE (arg1)) && integer_zerop (arg0))
1368 warn_for_null_address (arg1);
1369 }
1370
1371 return fold_build2_loc (input_location, code, d_bool_type,
1372 arg0, d_convert (TREE_TYPE (arg0), arg1));
1373}
1374
1375/* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1376 arguments to the conditional expression. */
1377
1378tree
1379build_condition (tree type, tree arg0, tree arg1, tree arg2)
1380{
1381 if (arg1 == void_node)
1382 arg1 = build_empty_stmt (input_location);
1383
1384 if (arg2 == void_node)
1385 arg2 = build_empty_stmt (input_location);
1386
1387 return fold_build3_loc (input_location, COND_EXPR,
1388 type, arg0, arg1, arg2);
1389}
1390
1391tree
1392build_vcondition (tree arg0, tree arg1, tree arg2)
1393{
1394 return build_condition (void_type_node, arg0, arg1, arg2);
1395}
1396
1397/* Build a compound expr to join ARG0 and ARG1 together. */
1398
1399tree
1400compound_expr (tree arg0, tree arg1)
1401{
1402 if (arg1 == NULL_TREE)
1403 return arg0;
1404
1405 if (arg0 == NULL_TREE || !TREE_SIDE_EFFECTS (arg0))
1406 return arg1;
1407
1408 if (TREE_CODE (arg1) == TARGET_EXPR)
1409 {
1410 /* If the rhs is a TARGET_EXPR, then build the compound expression
1411 inside the target_expr's initializer. This helps the compiler
1412 to eliminate unnecessary temporaries. */
1413 tree init = compound_expr (arg0, TARGET_EXPR_INITIAL (arg1));
1414 TARGET_EXPR_INITIAL (arg1) = init;
1415
1416 return arg1;
1417 }
1418
1419 return fold_build2_loc (input_location, COMPOUND_EXPR,
1420 TREE_TYPE (arg1), arg0, arg1);
1421}
1422
1423/* Build a return expression. */
1424
1425tree
1426return_expr (tree ret)
1427{
1428 return fold_build1_loc (input_location, RETURN_EXPR,
1429 void_type_node, ret);
1430}
1431
1432/* Return the product of ARG0 and ARG1 as a size_type_node. */
1433
1434tree
1435size_mult_expr (tree arg0, tree arg1)
1436{
1437 return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1438 d_convert (size_type_node, arg0),
1439 d_convert (size_type_node, arg1));
1440
1441}
1442
1443/* Return the real part of CE, which should be a complex expression. */
1444
1445tree
1446real_part (tree ce)
1447{
1448 return fold_build1_loc (input_location, REALPART_EXPR,
1449 TREE_TYPE (TREE_TYPE (ce)), ce);
1450}
1451
1452/* Return the imaginary part of CE, which should be a complex expression. */
1453
1454tree
1455imaginary_part (tree ce)
1456{
1457 return fold_build1_loc (input_location, IMAGPART_EXPR,
1458 TREE_TYPE (TREE_TYPE (ce)), ce);
1459}
1460
1461/* Build a complex expression of type TYPE using RE and IM. */
1462
1463tree
1464complex_expr (tree type, tree re, tree im)
1465{
1466 return fold_build2_loc (input_location, COMPLEX_EXPR,
1467 type, re, im);
1468}
1469
1470/* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1471 The back-end requires this cast in many cases. */
1472
1473tree
1474indirect_ref (tree type, tree exp)
1475{
1476 if (error_operand_p (exp))
1477 return exp;
1478
1479 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1480 tree init = stabilize_expr (&exp);
1481
1482 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
1483 exp = fold_build1 (INDIRECT_REF, type, exp);
1484 else
1485 {
1486 exp = build_nop (build_pointer_type (type), exp);
1487 exp = build_deref (exp);
1488 }
1489
1490 return compound_expr (init, exp);
1491}
1492
1493/* Returns indirect reference of EXP, which must be a pointer type. */
1494
1495tree
1496build_deref (tree exp)
1497{
1498 if (error_operand_p (exp))
1499 return exp;
1500
1501 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1502 tree init = stabilize_expr (&exp);
1503
1504 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
1505
1506 if (TREE_CODE (exp) == ADDR_EXPR)
1507 exp = TREE_OPERAND (exp, 0);
1508 else
1509 exp = build_fold_indirect_ref (exp);
1510
1511 return compound_expr (init, exp);
1512}
1513
1514/* Builds pointer offset expression PTR[INDEX]. */
1515
1516tree
1517build_array_index (tree ptr, tree index)
1518{
1519 if (error_operand_p (ptr) || error_operand_p (index))
1520 return error_mark_node;
1521
1522 tree ptr_type = TREE_TYPE (ptr);
1523 tree target_type = TREE_TYPE (ptr_type);
1524
1525 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1526 TYPE_UNSIGNED (sizetype));
1527
1528 /* Array element size. */
1529 tree size_exp = size_in_bytes (target_type);
1530
1531 if (integer_zerop (size_exp))
1532 {
1533 /* Test for array of void. */
1534 if (TYPE_MODE (target_type) == TYPE_MODE (void_type_node))
1535 index = fold_convert (type, index);
1536 else
1537 {
1538 /* Should catch this earlier. */
1539 error ("invalid use of incomplete type %qD", TYPE_NAME (target_type));
1540 ptr_type = error_mark_node;
1541 }
1542 }
1543 else if (integer_onep (size_exp))
1544 {
1545 /* Array of bytes -- No need to multiply. */
1546 index = fold_convert (type, index);
1547 }
1548 else
1549 {
1550 index = d_convert (type, index);
1551 index = fold_build2 (MULT_EXPR, TREE_TYPE (index),
1552 index, d_convert (TREE_TYPE (index), size_exp));
1553 index = fold_convert (type, index);
1554 }
1555
1556 if (integer_zerop (index))
1557 return ptr;
1558
1559 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);
1560}
1561
1562/* Builds pointer offset expression *(PTR OP OFFSET)
1563 OP could be a plus or minus expression. */
1564
1565tree
1566build_offset_op (tree_code op, tree ptr, tree offset)
1567{
1568 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);
1569
1570 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1571 TYPE_UNSIGNED (sizetype));
1572 offset = fold_convert (type, offset);
1573
1574 if (op == MINUS_EXPR)
1575 offset = fold_build1 (NEGATE_EXPR, type, offset);
1576
1577 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);
1578}
1579
1580/* Builds pointer offset expression *(PTR + OFFSET). */
1581
1582tree
1583build_offset (tree ptr, tree offset)
1584{
1585 return build_offset_op (PLUS_EXPR, ptr, offset);
1586}
1587
1588tree
1589build_memref (tree type, tree ptr, tree offset)
1590{
1591 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));
1592}
1593
1594/* Create a tree node to set multiple elements to a single value. */
1595
1596tree
1597build_array_set (tree ptr, tree length, tree value)
1598{
1599 tree ptrtype = TREE_TYPE (ptr);
1600 tree lentype = TREE_TYPE (length);
1601
1602 push_binding_level (level_block);
1603 push_stmt_list ();
1604
1605 /* Build temporary locals for length and ptr, and maybe value. */
1606 tree t = build_local_temp (size_type_node);
1607 add_stmt (build_assign (INIT_EXPR, t, length));
1608 length = t;
1609
1610 t = build_local_temp (ptrtype);
1611 add_stmt (build_assign (INIT_EXPR, t, ptr));
1612 ptr = t;
1613
1614 if (TREE_SIDE_EFFECTS (value))
1615 {
1616 t = build_local_temp (TREE_TYPE (value));
1617 add_stmt (build_assign (INIT_EXPR, t, value));
1618 value = t;
1619 }
1620
1621 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1622 push_stmt_list ();
1623
1624 /* Exit logic for the loop.
1625 if (length == 0) break; */
1626 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1627 t = build1 (EXIT_EXPR, void_type_node, t);
1628 add_stmt (t);
1629
1630 /* Assign value to the current pointer position.
1631 *ptr = value; */
1632 t = modify_expr (build_deref (ptr), value);
1633 add_stmt (t);
1634
1635 /* Move pointer to next element position.
1636 ptr++; */
1637 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));
1638 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));
1639 add_stmt (t);
1640
1641 /* Decrease loop counter.
1642 length -= 1; */
1643 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1644 d_convert (lentype, integer_one_node));
1645 add_stmt (t);
1646
1647 /* Pop statements and finish loop. */
1648 tree loop_body = pop_stmt_list ();
1649 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));
1650
1651 /* Wrap it up into a bind expression. */
1652 tree stmt_list = pop_stmt_list ();
1653 tree block = pop_binding_level ();
1654
1655 return build3 (BIND_EXPR, void_type_node,
1656 BLOCK_VARS (block), stmt_list, block);
1657}
1658
1659
1660/* Build an array of type TYPE where all the elements are VAL. */
1661
1662tree
1663build_array_from_val (Type *type, tree val)
1664{
1665 gcc_assert (type->ty == Tsarray);
1666
1667 tree etype = build_ctype (type->nextOf ());
1668
1669 /* Initializing a multidimensional array. */
1670 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)
1671 val = build_array_from_val (type->nextOf (), val);
1672
1673 size_t dims = ((TypeSArray *) type)->dim->toInteger ();
1674 vec<constructor_elt, va_gc> *elms = NULL;
1675 vec_safe_reserve (elms, dims);
1676
1677 val = d_convert (etype, val);
1678
1679 for (size_t i = 0; i < dims; i++)
1680 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
1681
1682 return build_constructor (build_ctype (type), elms);
1683}
1684
1685/* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1686
1687tree
1688void_okay_p (tree t)
1689{
1690 tree type = TREE_TYPE (t);
1691
1692 if (VOID_TYPE_P (TREE_TYPE (type)))
1693 {
1694 tree totype = build_ctype (Type::tuns8->pointerTo ());
1695 return fold_convert (totype, t);
1696 }
1697
1698 return t;
1699}
1700
1701/* Builds a bounds condition checking that INDEX is between 0 and LEN.
1702 The condition returns the INDEX if true, or throws a RangeError.
1703 If INCLUSIVE, we allow INDEX == LEN to return true also. */
1704
1705tree
1706build_bounds_condition (const Loc& loc, tree index, tree len, bool inclusive)
1707{
1708 if (!array_bounds_check ())
1709 return index;
1710
1711 /* Prevent multiple evaluations of the index. */
1712 index = d_save_expr (index);
1713
1714 /* Generate INDEX >= LEN && throw RangeError.
1715 No need to check whether INDEX >= 0 as the front-end should
1716 have already taken care of implicit casts to unsigned. */
1717 tree condition = fold_build2 (inclusive ? GT_EXPR : GE_EXPR,
1718 d_bool_type, index, len);
c0aebc60
IB
1719 /* Terminate the program with a trap if no D runtime present. */
1720 tree boundserr = (global.params.checkAction == CHECKACTION_D)
1721 ? d_assert_call (loc, LIBCALL_ARRAY_BOUNDS)
1722 : build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
b4c522fa
IB
1723
1724 return build_condition (TREE_TYPE (index), condition, boundserr, index);
1725}
1726
1727/* Returns TRUE if array bounds checking code generation is turned on. */
1728
1729bool
1730array_bounds_check (void)
1731{
1732 FuncDeclaration *fd;
1733
1734 switch (global.params.useArrayBounds)
1735 {
1736 case BOUNDSCHECKoff:
1737 return false;
1738
1739 case BOUNDSCHECKon:
1740 return true;
1741
1742 case BOUNDSCHECKsafeonly:
1743 /* For D2 safe functions only. */
1744 fd = d_function_chain->function;
1745 if (fd && fd->type->ty == Tfunction)
1746 {
1747 TypeFunction *tf = (TypeFunction *) fd->type;
1748 if (tf->trust == TRUSTsafe)
1749 return true;
1750 }
1751 return false;
1752
1753 default:
1754 gcc_unreachable ();
1755 }
1756}
1757
1758/* Return an undeclared local temporary of type TYPE
1759 for use with BIND_EXPR. */
1760
1761tree
1762create_temporary_var (tree type)
1763{
1764 tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, type);
1765
1766 DECL_CONTEXT (decl) = current_function_decl;
1767 DECL_ARTIFICIAL (decl) = 1;
1768 DECL_IGNORED_P (decl) = 1;
1769 layout_decl (decl, 0);
1770
1771 return decl;
1772}
1773
1774/* Return an undeclared local temporary OUT_VAR initialized
1775 with result of expression EXP. */
1776
1777tree
1778maybe_temporary_var (tree exp, tree *out_var)
1779{
1780 tree t = exp;
1781
1782 /* Get the base component. */
1783 while (TREE_CODE (t) == COMPONENT_REF)
1784 t = TREE_OPERAND (t, 0);
1785
1786 if (!DECL_P (t) && !REFERENCE_CLASS_P (t))
1787 {
1788 *out_var = create_temporary_var (TREE_TYPE (exp));
1789 DECL_INITIAL (*out_var) = exp;
1790 return *out_var;
1791 }
1792 else
1793 {
1794 *out_var = NULL_TREE;
1795 return exp;
1796 }
1797}
1798
1799/* Builds a BIND_EXPR around BODY for the variables VAR_CHAIN. */
1800
1801tree
1802bind_expr (tree var_chain, tree body)
1803{
1804 /* Only handles one var. */
1805 gcc_assert (TREE_CHAIN (var_chain) == NULL_TREE);
1806
1807 if (DECL_INITIAL (var_chain))
1808 {
1809 tree ini = build_assign (INIT_EXPR, var_chain, DECL_INITIAL (var_chain));
1810 DECL_INITIAL (var_chain) = NULL_TREE;
1811 body = compound_expr (ini, body);
1812 }
1813
1814 return d_save_expr (build3 (BIND_EXPR, TREE_TYPE (body),
1815 var_chain, body, NULL_TREE));
1816}
1817
1818/* Returns the TypeFunction class for Type T.
1819 Assumes T is already ->toBasetype(). */
1820
1821TypeFunction *
1822get_function_type (Type *t)
1823{
1824 TypeFunction *tf = NULL;
1825 if (t->ty == Tpointer)
1826 t = t->nextOf ()->toBasetype ();
1827 if (t->ty == Tfunction)
1828 tf = (TypeFunction *) t;
1829 else if (t->ty == Tdelegate)
1830 tf = (TypeFunction *) ((TypeDelegate *) t)->next;
1831 return tf;
1832}
1833
1834/* Returns TRUE if CALLEE is a plain nested function outside the scope of
1835 CALLER. In which case, CALLEE is being called through an alias that was
1836 passed to CALLER. */
1837
1838bool
1839call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)
1840{
1841 if (!callee->isNested ())
1842 return false;
1843
1844 if (caller->toParent () == callee->toParent ())
1845 return false;
1846
1847 Dsymbol *dsym = callee;
1848
1849 while (dsym)
1850 {
1851 if (dsym->isTemplateInstance ())
1852 return false;
1853 else if (dsym->isFuncDeclaration () == caller)
1854 return false;
1855 dsym = dsym->toParent ();
1856 }
1857
1858 return true;
1859}
1860
1861/* Entry point for call routines. Builds a function call to FD.
1862 OBJECT is the 'this' reference passed and ARGS are the arguments to FD. */
1863
1864tree
1865d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)
1866{
1867 return d_build_call (get_function_type (fd->type),
1868 build_address (get_symbol_decl (fd)), object, arguments);
1869}
1870
1871/* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the 'this' pointer,
1872 ARGUMENTS are evaluated in left to right order, saved and promoted
1873 before passing. */
1874
1875tree
1876d_build_call (TypeFunction *tf, tree callable, tree object,
1877 Expressions *arguments)
1878{
1879 tree ctype = TREE_TYPE (callable);
1880 tree callee = callable;
1881
1882 if (POINTER_TYPE_P (ctype))
1883 ctype = TREE_TYPE (ctype);
1884 else
1885 callee = build_address (callable);
1886
1887 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));
1888 gcc_assert (tf != NULL);
1889 gcc_assert (tf->ty == Tfunction);
1890
1891 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)
1892 {
1893 /* Front-end apparently doesn't check this. */
1894 if (TREE_CODE (callable) == FUNCTION_DECL)
1895 {
1896 error ("need %<this%> to access member %qE", DECL_NAME (callable));
1897 return error_mark_node;
1898 }
1899
1900 /* Probably an internal error. */
1901 gcc_unreachable ();
1902 }
1903
1904 /* Build the argument list for the call. */
1905 vec<tree, va_gc> *args = NULL;
1906 tree saved_args = NULL_TREE;
1907
1908 /* If this is a delegate call or a nested function being called as
1909 a delegate, the object should not be NULL. */
1910 if (object != NULL_TREE)
1911 vec_safe_push (args, object);
1912
1913 if (arguments)
1914 {
1915 /* First pass, evaluated expanded tuples in function arguments. */
1916 for (size_t i = 0; i < arguments->dim; ++i)
1917 {
1918 Lagain:
1919 Expression *arg = (*arguments)[i];
1920 gcc_assert (arg->op != TOKtuple);
1921
1922 if (arg->op == TOKcomma)
1923 {
1924 CommaExp *ce = (CommaExp *) arg;
1925 tree tce = build_expr (ce->e1);
1926 saved_args = compound_expr (saved_args, tce);
1927 (*arguments)[i] = ce->e2;
1928 goto Lagain;
1929 }
1930 }
1931
1932 size_t nparams = Parameter::dim (tf->parameters);
1933 /* if _arguments[] is the first argument. */
1934 size_t varargs = (tf->linkage == LINKd && tf->varargs == 1);
1935
1936 /* Assumes arguments->dim <= formal_args->dim if (!tf->varargs). */
1937 for (size_t i = 0; i < arguments->dim; ++i)
1938 {
1939 Expression *arg = (*arguments)[i];
1940 tree targ = build_expr (arg);
1941
1942 if (i - varargs < nparams && i >= varargs)
1943 {
1944 /* Actual arguments for declared formal arguments. */
1945 Parameter *parg = Parameter::getNth (tf->parameters, i - varargs);
1946 targ = convert_for_argument (targ, parg);
1947 }
1948
1949 /* Don't pass empty aggregates by value. */
1950 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
1951 && TREE_CODE (targ) != CONSTRUCTOR)
1952 {
1953 tree t = build_constructor (TREE_TYPE (targ), NULL);
1954 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
1955 }
1956
1957 vec_safe_push (args, targ);
1958 }
1959 }
1960
1961 /* Evaluate the callee before calling it. */
1962 if (TREE_SIDE_EFFECTS (callee))
1963 {
1964 callee = d_save_expr (callee);
1965 saved_args = compound_expr (callee, saved_args);
1966 }
1967
1968 tree result = build_call_vec (TREE_TYPE (ctype), callee, args);
1969
1970 /* Enforce left to right evaluation. */
1971 if (tf->linkage == LINKd)
1972 CALL_EXPR_ARGS_ORDERED (result) = 1;
1973
1974 result = maybe_expand_intrinsic (result);
1975
1976 /* Return the value in a temporary slot so that it can be evaluated
1977 multiple times by the caller. */
1978 if (TREE_CODE (result) == CALL_EXPR
1979 && AGGREGATE_TYPE_P (TREE_TYPE (result))
1980 && TREE_ADDRESSABLE (TREE_TYPE (result)))
1981 {
1982 CALL_EXPR_RETURN_SLOT_OPT (result) = true;
1983 result = force_target_expr (result);
1984 }
1985
1986 return compound_expr (saved_args, result);
1987}
1988
1989/* Builds a call to AssertError or AssertErrorMsg. */
1990
1991tree
1992d_assert_call (const Loc& loc, libcall_fn libcall, tree msg)
1993{
1994 tree file;
1995 tree line = size_int (loc.linnum);
1996
1997 /* File location is passed as a D string. */
1998 if (loc.filename)
1999 {
2000 unsigned len = strlen (loc.filename);
2001 tree str = build_string (len, loc.filename);
2002 TREE_TYPE (str) = make_array_type (Type::tchar, len);
2003
2004 file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
2005 size_int (len), build_address (str));
2006 }
2007 else
2008 file = null_array_node;
2009
2010 if (msg != NULL)
2011 return build_libcall (libcall, Type::tvoid, 3, msg, file, line);
2012 else
2013 return build_libcall (libcall, Type::tvoid, 2, file, line);
2014}
2015
2016/* Build and return the correct call to fmod depending on TYPE.
2017 ARG0 and ARG1 are the arguments pass to the function. */
2018
2019tree
2020build_float_modulus (tree type, tree arg0, tree arg1)
2021{
2022 tree fmodfn = NULL_TREE;
2023 tree basetype = type;
2024
2025 if (COMPLEX_FLOAT_TYPE_P (basetype))
2026 basetype = TREE_TYPE (basetype);
2027
2028 if (TYPE_MAIN_VARIANT (basetype) == double_type_node
2029 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)
2030 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);
2031 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node
2032 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)
2033 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);
2034 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node
2035 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)
2036 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);
2037
2038 if (!fmodfn)
2039 {
2040 error ("tried to perform floating-point modulo division on %qT", type);
2041 return error_mark_node;
2042 }
2043
2044 if (COMPLEX_FLOAT_TYPE_P (type))
2045 {
2046 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);
2047 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);
2048
2049 return complex_expr (type, re, im);
2050 }
2051
2052 if (SCALAR_FLOAT_TYPE_P (type))
2053 return build_call_expr (fmodfn, 2, arg0, arg1);
2054
2055 /* Should have caught this above. */
2056 gcc_unreachable ();
2057}
2058
2059/* Build a function type whose first argument is a pointer to BASETYPE,
2060 which is to be used for the 'vthis' context parameter for TYPE.
2061 The base type may be a record for member functions, or a void for
2062 nested functions and delegates. */
2063
2064tree
2065build_vthis_function (tree basetype, tree type)
2066{
2067 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
2068
2069 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),
2070 TYPE_ARG_TYPES (type));
2071 tree fntype = build_function_type (TREE_TYPE (type), argtypes);
2072
2073 if (RECORD_OR_UNION_TYPE_P (basetype))
2074 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);
2075 else
2076 gcc_assert (VOID_TYPE_P (basetype));
2077
2078 return fntype;
2079}
2080
2081/* If SYM is a nested function, return the static chain to be
2082 used when calling that function from the current function.
2083
2084 If SYM is a nested class or struct, return the static chain
2085 to be used when creating an instance of the class from CFUN. */
2086
2087tree
2088get_frame_for_symbol (Dsymbol *sym)
2089{
2090 FuncDeclaration *thisfd
2091 = d_function_chain ? d_function_chain->function : NULL;
2092 FuncDeclaration *fd = sym->isFuncDeclaration ();
2093 FuncDeclaration *fdparent = NULL;
2094 FuncDeclaration *fdoverride = NULL;
2095
2096 if (fd != NULL)
2097 {
2098 /* Check that the nested function is properly defined. */
2099 if (!fd->fbody)
2100 {
2101 /* Should instead error on line that references 'fd'. */
2102 error_at (make_location_t (fd->loc), "nested function missing body");
2103 return null_pointer_node;
2104 }
2105
2106 fdparent = fd->toParent2 ()->isFuncDeclaration ();
2107
2108 /* Special case for __ensure and __require. */
2109 if ((fd->ident == Identifier::idPool ("__ensure")
2110 || fd->ident == Identifier::idPool ("__require"))
2111 && fdparent != thisfd)
2112 {
2113 fdoverride = fdparent;
2114 fdparent = thisfd;
2115 }
2116 }
2117 else
2118 {
2119 /* It's a class (or struct). NewExp codegen has already determined its
2120 outer scope is not another class, so it must be a function. */
2121 while (sym && !sym->isFuncDeclaration ())
2122 sym = sym->toParent2 ();
2123
2124 fdparent = (FuncDeclaration *) sym;
2125 }
2126
9fa5d5de
IB
2127 /* Not a nested function, there is no frame pointer to pass. */
2128 if (fdparent == NULL)
2129 {
2130 /* Only delegate literals report as being nested, even if they are in
2131 global scope. */
2132 gcc_assert (fd && fd->isFuncLiteralDeclaration ());
2133 return null_pointer_node;
2134 }
2135
2136 gcc_assert (thisfd != NULL);
b4c522fa
IB
2137
2138 if (thisfd != fdparent)
2139 {
2140 /* If no frame pointer for this function. */
2141 if (!thisfd->vthis)
2142 {
2143 error_at (make_location_t (sym->loc),
9fa5d5de
IB
2144 "%qs is a nested function and cannot be accessed from %qs",
2145 fd->toPrettyChars (), thisfd->toPrettyChars ());
b4c522fa
IB
2146 return null_pointer_node;
2147 }
2148
2149 /* Make sure we can get the frame pointer to the outer function.
2150 Go up each nesting level until we find the enclosing function. */
2151 Dsymbol *dsym = thisfd;
2152
2153 while (fd != dsym)
2154 {
2155 /* Check if enclosing function is a function. */
2156 FuncDeclaration *fd = dsym->isFuncDeclaration ();
2157
2158 if (fd != NULL)
2159 {
2160 if (fdparent == fd->toParent2 ())
2161 break;
2162
2163 gcc_assert (fd->isNested () || fd->vthis);
2164 dsym = dsym->toParent2 ();
2165 continue;
2166 }
2167
2168 /* Check if enclosed by an aggregate. That means the current
2169 function must be a member function of that aggregate. */
2170 AggregateDeclaration *ad = dsym->isAggregateDeclaration ();
2171
2172 if (ad == NULL)
2173 goto Lnoframe;
2174 if (ad->isClassDeclaration () && fdparent == ad->toParent2 ())
2175 break;
2176 if (ad->isStructDeclaration () && fdparent == ad->toParent2 ())
2177 break;
2178
2179 if (!ad->isNested () || !ad->vthis)
2180 {
2181 Lnoframe:
2182 error_at (make_location_t (thisfd->loc),
2183 "cannot get frame pointer to %qs",
2184 sym->toPrettyChars ());
2185 return null_pointer_node;
2186 }
2187
2188 dsym = dsym->toParent2 ();
2189 }
2190 }
2191
2192 tree ffo = get_frameinfo (fdparent);
2193 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2194 {
2195 tree frame_ref = get_framedecl (thisfd, fdparent);
2196
2197 /* If 'thisfd' is a derived member function, then 'fdparent' is the
2198 overridden member function in the base class. Even if there's a
2199 closure environment, we should give the original stack data as the
2200 nested function frame. */
2201 if (fdoverride)
2202 {
2203 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2204 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2205 gcc_assert (cdo && cd);
2206
2207 int offset;
2208 if (cdo->isBaseOf (cd, &offset) && offset != 0)
2209 {
2210 /* Generate a new frame to pass to the overriden function that
2211 has the 'this' pointer adjusted. */
2212 gcc_assert (offset != OFFSET_RUNTIME);
2213
2214 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2215 tree fields = TYPE_FIELDS (type);
2216 /* The 'this' field comes immediately after the '__chain'. */
2217 tree thisfield = chain_index (1, fields);
2218 vec<constructor_elt, va_gc> *ve = NULL;
2219
2220 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2221 frame_ref = build_deref (frame_ref);
2222
2223 for (tree field = fields; field; field = DECL_CHAIN (field))
2224 {
2225 tree value = component_ref (frame_ref, framefields);
2226 if (field == thisfield)
2227 value = build_offset (value, size_int (offset));
2228
2229 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2230 framefields = DECL_CHAIN (framefields);
2231 }
2232
2233 frame_ref = build_address (build_constructor (type, ve));
2234 }
2235 }
2236
2237 return frame_ref;
2238 }
2239
2240 return null_pointer_node;
2241}
2242
2243/* Return the parent function of a nested class CD. */
2244
2245static FuncDeclaration *
2246d_nested_class (ClassDeclaration *cd)
2247{
2248 FuncDeclaration *fd = NULL;
2249 while (cd && cd->isNested ())
2250 {
2251 Dsymbol *dsym = cd->toParent2 ();
2252 if ((fd = dsym->isFuncDeclaration ()))
2253 return fd;
2254 else
2255 cd = dsym->isClassDeclaration ();
2256 }
2257 return NULL;
2258}
2259
2260/* Return the parent function of a nested struct SD. */
2261
2262static FuncDeclaration *
2263d_nested_struct (StructDeclaration *sd)
2264{
2265 FuncDeclaration *fd = NULL;
2266 while (sd && sd->isNested ())
2267 {
2268 Dsymbol *dsym = sd->toParent2 ();
2269 if ((fd = dsym->isFuncDeclaration ()))
2270 return fd;
2271 else
2272 sd = dsym->isStructDeclaration ();
2273 }
2274 return NULL;
2275}
2276
2277
2278/* Starting from the current function FD, try to find a suitable value of
2279 'this' in nested function instances. A suitable 'this' value is an
2280 instance of OCD or a class that has OCD as a base. */
2281
2282static tree
2283find_this_tree (ClassDeclaration *ocd)
2284{
2285 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2286
2287 while (fd)
2288 {
2289 AggregateDeclaration *ad = fd->isThis ();
2290 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;
2291
2292 if (cd != NULL)
2293 {
2294 if (ocd == cd)
2295 return get_decl_tree (fd->vthis);
2296 else if (ocd->isBaseOf (cd, NULL))
2297 return convert_expr (get_decl_tree (fd->vthis),
2298 cd->type, ocd->type);
2299
2300 fd = d_nested_class (cd);
2301 }
2302 else
2303 {
2304 if (fd->isNested ())
2305 {
2306 fd = fd->toParent2 ()->isFuncDeclaration ();
2307 continue;
2308 }
2309
2310 fd = NULL;
2311 }
2312 }
2313
2314 return NULL_TREE;
2315}
2316
2317/* Retrieve the outer class/struct 'this' value of DECL from
2318 the current function. */
2319
2320tree
2321build_vthis (AggregateDeclaration *decl)
2322{
2323 ClassDeclaration *cd = decl->isClassDeclaration ();
2324 StructDeclaration *sd = decl->isStructDeclaration ();
2325
2326 /* If an aggregate nested in a function has no methods and there are no
2327 other nested functions, any static chain created here will never be
2328 translated. Use a null pointer for the link in this case. */
2329 tree vthis_value = null_pointer_node;
2330
2331 if (cd != NULL || sd != NULL)
2332 {
2333 Dsymbol *outer = decl->toParent2 ();
2334
2335 /* If the parent is a templated struct, the outer context is instead
2336 the enclosing symbol of where the instantiation happened. */
2337 if (outer->isStructDeclaration ())
2338 {
2339 gcc_assert (outer->parent && outer->parent->isTemplateInstance ());
2340 outer = ((TemplateInstance *) outer->parent)->enclosing;
2341 }
2342
2343 /* For outer classes, get a suitable 'this' value.
2344 For outer functions, get a suitable frame/closure pointer. */
2345 ClassDeclaration *cdo = outer->isClassDeclaration ();
2346 FuncDeclaration *fdo = outer->isFuncDeclaration ();
2347
2348 if (cdo)
2349 {
2350 vthis_value = find_this_tree (cdo);
2351 gcc_assert (vthis_value != NULL_TREE);
2352 }
2353 else if (fdo)
2354 {
2355 tree ffo = get_frameinfo (fdo);
2356 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)
2357 || fdo->hasNestedFrameRefs ())
2358 vthis_value = get_frame_for_symbol (decl);
2359 else if (cd != NULL)
2360 {
2361 /* Classes nested in methods are allowed to access any outer
2362 class fields, use the function chain in this case. */
2363 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)
2364 vthis_value = get_decl_tree (fdo->vthis);
2365 }
2366 }
2367 else
2368 gcc_unreachable ();
2369 }
2370
2371 return vthis_value;
2372}
2373
2374/* Build the RECORD_TYPE that describes the function frame or closure type for
2375 the function FD. FFI is the tree holding all frame information. */
2376
2377static tree
2378build_frame_type (tree ffi, FuncDeclaration *fd)
2379{
2380 if (FRAMEINFO_TYPE (ffi))
2381 return FRAMEINFO_TYPE (ffi);
2382
2383 tree frame_rec_type = make_node (RECORD_TYPE);
2384 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.",
2385 fd->toPrettyChars (), NULL);
2386 TYPE_NAME (frame_rec_type) = get_identifier (name);
2387 free (name);
2388
2389 tree fields = NULL_TREE;
2390
2391 /* Function is a member or nested, so must have field for outer context. */
2392 if (fd->vthis)
2393 {
2394 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
2395 get_identifier ("__chain"), ptr_type_node);
2396 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;
2397 fields = chainon (NULL_TREE, ptr_field);
2398 DECL_NONADDRESSABLE_P (ptr_field) = 1;
2399 }
2400
2401 /* The __ensure and __require are called directly, so never make the outer
2402 functions closure, but nevertheless could still be referencing parameters
2403 of the calling function non-locally. So we add all parameters with nested
2404 refs to the function frame, this should also mean overriding methods will
2405 have the same frame layout when inheriting a contract. */
2406 if ((global.params.useIn && fd->frequire)
2407 || (global.params.useOut && fd->fensure))
2408 {
2409 if (fd->parameters)
2410 {
2411 for (size_t i = 0; fd->parameters && i < fd->parameters->dim; i++)
2412 {
2413 VarDeclaration *v = (*fd->parameters)[i];
2414 /* Remove if already in closureVars so can push to front. */
2415 for (size_t j = i; j < fd->closureVars.dim; j++)
2416 {
2417 Dsymbol *s = fd->closureVars[j];
2418 if (s == v)
2419 {
2420 fd->closureVars.remove (j);
2421 break;
2422 }
2423 }
2424 fd->closureVars.insert (i, v);
2425 }
2426 }
2427
2428 /* Also add hidden 'this' to outer context. */
2429 if (fd->vthis)
2430 {
2431 for (size_t i = 0; i < fd->closureVars.dim; i++)
2432 {
2433 Dsymbol *s = fd->closureVars[i];
2434 if (s == fd->vthis)
2435 {
2436 fd->closureVars.remove (i);
2437 break;
2438 }
2439 }
2440 fd->closureVars.insert (0, fd->vthis);
2441 }
2442 }
2443
2444 for (size_t i = 0; i < fd->closureVars.dim; i++)
2445 {
2446 VarDeclaration *v = fd->closureVars[i];
2447 tree vsym = get_symbol_decl (v);
2448 tree ident = v->ident
2449 ? get_identifier (v->ident->toChars ()) : NULL_TREE;
2450
2451 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,
2452 TREE_TYPE (vsym));
2453 SET_DECL_LANG_FRAME_FIELD (vsym, field);
2454 DECL_FIELD_CONTEXT (field) = frame_rec_type;
2455 fields = chainon (fields, field);
2456 TREE_USED (vsym) = 1;
2457
2458 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
2459 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
2460 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
2461
2462 /* Can't do nrvo if the variable is put in a frame. */
2463 if (fd->nrvo_can && fd->nrvo_var == v)
2464 fd->nrvo_can = 0;
2465
2466 if (FRAMEINFO_IS_CLOSURE (ffi))
2467 {
2468 /* Because the value needs to survive the end of the scope. */
2469 if ((v->edtor && (v->storage_class & STCparameter))
2470 || v->needsScopeDtor ())
2471 error_at (make_location_t (v->loc),
2472 "has scoped destruction, cannot build closure");
2473 }
2474 }
2475
2476 TYPE_FIELDS (frame_rec_type) = fields;
2477 TYPE_READONLY (frame_rec_type) = 1;
2478 layout_type (frame_rec_type);
2479 d_keep (frame_rec_type);
2480
2481 return frame_rec_type;
2482}
2483
2484/* Closures are implemented by taking the local variables that
2485 need to survive the scope of the function, and copying them
2486 into a GC allocated chuck of memory. That chunk, called the
2487 closure here, is inserted into the linked list of stack
2488 frames instead of the usual stack frame.
2489
2490 If a closure is not required, but FD still needs a frame to lower
2491 nested refs, then instead build custom static chain decl on stack. */
2492
2493void
2494build_closure (FuncDeclaration *fd)
2495{
2496 tree ffi = get_frameinfo (fd);
2497
2498 if (!FRAMEINFO_CREATES_FRAME (ffi))
2499 return;
2500
2501 tree type = FRAMEINFO_TYPE (ffi);
2502 gcc_assert (COMPLETE_TYPE_P (type));
2503
2504 tree decl, decl_ref;
2505
2506 if (FRAMEINFO_IS_CLOSURE (ffi))
2507 {
2508 decl = build_local_temp (build_pointer_type (type));
2509 DECL_NAME (decl) = get_identifier ("__closptr");
2510 decl_ref = build_deref (decl);
2511
2512 /* Allocate memory for closure. */
2513 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
2514 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
2515
2516 tree init_exp = build_assign (INIT_EXPR, decl,
2517 build_nop (TREE_TYPE (decl), init));
2518 add_stmt (init_exp);
2519 }
2520 else
2521 {
2522 decl = build_local_temp (type);
2523 DECL_NAME (decl) = get_identifier ("__frame");
2524 decl_ref = decl;
2525 }
2526
2527 /* Set the first entry to the parent closure/frame, if any. */
2528 if (fd->vthis)
2529 {
2530 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));
2531 tree chain_expr = modify_expr (chain_field,
2532 d_function_chain->static_chain);
2533 add_stmt (chain_expr);
2534 }
2535
2536 /* Copy parameters that are referenced nonlocally. */
2537 for (size_t i = 0; i < fd->closureVars.dim; i++)
2538 {
2539 VarDeclaration *v = fd->closureVars[i];
2540
2541 if (!v->isParameter ())
2542 continue;
2543
2544 tree vsym = get_symbol_decl (v);
2545
2546 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));
2547 tree expr = modify_expr (field, vsym);
2548 add_stmt (expr);
2549 }
2550
2551 if (!FRAMEINFO_IS_CLOSURE (ffi))
2552 decl = build_address (decl);
2553
2554 d_function_chain->static_chain = decl;
2555}
2556
2557/* Return the frame of FD. This could be a static chain or a closure
2558 passed via the hidden 'this' pointer. */
2559
2560tree
2561get_frameinfo (FuncDeclaration *fd)
2562{
2563 tree fds = get_symbol_decl (fd);
2564 if (DECL_LANG_FRAMEINFO (fds))
2565 return DECL_LANG_FRAMEINFO (fds);
2566
2567 tree ffi = make_node (FUNCFRAME_INFO);
2568
2569 DECL_LANG_FRAMEINFO (fds) = ffi;
2570
2571 if (fd->needsClosure ())
2572 {
2573 /* Set-up a closure frame, this will be allocated on the heap. */
2574 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2575 FRAMEINFO_IS_CLOSURE (ffi) = 1;
2576 }
2577 else if (fd->hasNestedFrameRefs ())
2578 {
2579 /* Functions with nested refs must create a static frame for local
2580 variables to be referenced from. */
2581 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2582 }
2583 else
2584 {
2585 /* For nested functions, default to creating a frame. Even if there are
2586 no fields to populate the frame, create it anyway, as this will be
2587 used as the record type instead of `void*` for the this parameter. */
2588 if (fd->vthis && fd->vthis->type == Type::tvoidptr)
2589 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2590
2591 /* In checkNestedReference, references from contracts are not added to the
2592 closureVars array, so assume all parameters referenced. */
2593 if ((global.params.useIn && fd->frequire)
2594 || (global.params.useOut && fd->fensure))
2595 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2596
2597 /* If however `fd` is nested (deeply) in a function that creates a
2598 closure, then `fd` instead inherits that closure via hidden vthis
2599 pointer, and doesn't create a stack frame at all. */
2600 FuncDeclaration *ff = fd;
2601
2602 while (ff)
2603 {
2604 tree ffo = get_frameinfo (ff);
2605
2606 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))
2607 {
2608 gcc_assert (FRAMEINFO_TYPE (ffo));
2609 FRAMEINFO_CREATES_FRAME (ffi) = 0;
2610 FRAMEINFO_STATIC_CHAIN (ffi) = 1;
2611 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);
2612 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));
2613 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);
2614 break;
2615 }
2616
2617 /* Stop looking if no frame pointer for this function. */
2618 if (ff->vthis == NULL)
2619 break;
2620
2621 AggregateDeclaration *ad = ff->isThis ();
2622 if (ad && ad->isNested ())
2623 {
2624 while (ad->isNested ())
2625 {
2626 Dsymbol *d = ad->toParent2 ();
2627 ad = d->isAggregateDeclaration ();
2628 ff = d->isFuncDeclaration ();
2629
2630 if (ad == NULL)
2631 break;
2632 }
2633 }
2634 else
2635 ff = ff->toParent2 ()->isFuncDeclaration ();
2636 }
2637 }
2638
2639 /* Build type now as may be referenced from another module. */
2640 if (FRAMEINFO_CREATES_FRAME (ffi))
2641 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);
2642
2643 return ffi;
2644}
2645
2646/* Return a pointer to the frame/closure block of OUTER
2647 so can be accessed from the function INNER. */
2648
2649tree
2650get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
2651{
2652 tree result = d_function_chain->static_chain;
2653 FuncDeclaration *fd = inner;
2654
2655 while (fd && fd != outer)
2656 {
2657 AggregateDeclaration *ad;
2658 ClassDeclaration *cd;
2659 StructDeclaration *sd;
2660
2661 /* Parent frame link is the first field. */
2662 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))
2663 result = indirect_ref (ptr_type_node, result);
2664
2665 if (fd->isNested ())
2666 fd = fd->toParent2 ()->isFuncDeclaration ();
2667 /* The frame/closure record always points to the outer function's
2668 frame, even if there are intervening nested classes or structs.
2669 So, we can just skip over these. */
2670 else if ((ad = fd->isThis ()) && (cd = ad->isClassDeclaration ()))
2671 fd = d_nested_class (cd);
2672 else if ((ad = fd->isThis ()) && (sd = ad->isStructDeclaration ()))
2673 fd = d_nested_struct (sd);
2674 else
2675 break;
2676 }
2677
2678 /* Go get our frame record. */
2679 gcc_assert (fd == outer);
2680 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
2681
2682 if (frame_type != NULL_TREE)
2683 {
2684 result = build_nop (build_pointer_type (frame_type), result);
2685 return result;
2686 }
2687 else
2688 {
2689 error_at (make_location_t (inner->loc),
2690 "forward reference to frame of %qs", outer->toChars ());
2691 return null_pointer_node;
2692 }
2693}