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