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