comparison gcc/d/d-codegen.cc @ 145:1830386684a0

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