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