]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-codegen.cc
d: Build internal TypeInfo types when module name is "object"
[thirdparty/gcc.git] / gcc / d / d-codegen.cc
CommitLineData
b4c522fa 1/* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
7adcbafe 2 Copyright (C) 2006-2022 Free Software Foundation, Inc.
b4c522fa
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with GCC; see the file COPYING3. If not see
16<http://www.gnu.org/licenses/>. */
17
18#include "config.h"
19#include "system.h"
20#include "coretypes.h"
21
22#include "dmd/aggregate.h"
23#include "dmd/ctfe.h"
24#include "dmd/declaration.h"
25#include "dmd/identifier.h"
766f5f87 26#include "dmd/module.h"
b4c522fa
IB
27#include "dmd/target.h"
28#include "dmd/template.h"
29
30#include "tree.h"
31#include "tree-iterator.h"
32#include "fold-const.h"
33#include "diagnostic.h"
34#include "langhooks.h"
35#include "target.h"
36#include "stringpool.h"
37#include "varasm.h"
38#include "stor-layout.h"
39#include "attribs.h"
40#include "function.h"
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
1591/* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1592 The back-end requires this cast in many cases. */
1593
1594tree
1595indirect_ref (tree type, tree exp)
1596{
1597 if (error_operand_p (exp))
1598 return exp;
1599
1600 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1601 tree init = stabilize_expr (&exp);
1602
1603 if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
1604 exp = fold_build1 (INDIRECT_REF, type, exp);
1605 else
1606 {
1607 exp = build_nop (build_pointer_type (type), exp);
1608 exp = build_deref (exp);
1609 }
1610
1611 return compound_expr (init, exp);
1612}
1613
1614/* Returns indirect reference of EXP, which must be a pointer type. */
1615
1616tree
1617build_deref (tree exp)
1618{
1619 if (error_operand_p (exp))
1620 return exp;
1621
1622 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1623 tree init = stabilize_expr (&exp);
1624
1625 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
1626
1627 if (TREE_CODE (exp) == ADDR_EXPR)
1628 exp = TREE_OPERAND (exp, 0);
1629 else
1630 exp = build_fold_indirect_ref (exp);
1631
1632 return compound_expr (init, exp);
1633}
1634
1635/* Builds pointer offset expression PTR[INDEX]. */
1636
1637tree
8288cd63 1638build_pointer_index (tree ptr, tree index)
b4c522fa
IB
1639{
1640 if (error_operand_p (ptr) || error_operand_p (index))
1641 return error_mark_node;
1642
1643 tree ptr_type = TREE_TYPE (ptr);
1644 tree target_type = TREE_TYPE (ptr_type);
1645
1646 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1647 TYPE_UNSIGNED (sizetype));
1648
1649 /* Array element size. */
1650 tree size_exp = size_in_bytes (target_type);
1651
c936c39f 1652 if (integer_zerop (size_exp) || integer_onep (size_exp))
b4c522fa 1653 {
c936c39f 1654 /* Array of void or bytes -- No need to multiply. */
b4c522fa
IB
1655 index = fold_convert (type, index);
1656 }
1657 else
1658 {
1659 index = d_convert (type, index);
1660 index = fold_build2 (MULT_EXPR, TREE_TYPE (index),
1661 index, d_convert (TREE_TYPE (index), size_exp));
1662 index = fold_convert (type, index);
1663 }
1664
1665 if (integer_zerop (index))
1666 return ptr;
1667
1668 return fold_build2 (POINTER_PLUS_EXPR, ptr_type, ptr, index);
1669}
1670
1671/* Builds pointer offset expression *(PTR OP OFFSET)
1672 OP could be a plus or minus expression. */
1673
1674tree
1675build_offset_op (tree_code op, tree ptr, tree offset)
1676{
1677 gcc_assert (op == MINUS_EXPR || op == PLUS_EXPR);
1678
1679 tree type = lang_hooks.types.type_for_size (TYPE_PRECISION (sizetype),
1680 TYPE_UNSIGNED (sizetype));
1681 offset = fold_convert (type, offset);
1682
1683 if (op == MINUS_EXPR)
1684 offset = fold_build1 (NEGATE_EXPR, type, offset);
1685
1686 return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, offset);
1687}
1688
1689/* Builds pointer offset expression *(PTR + OFFSET). */
1690
1691tree
1692build_offset (tree ptr, tree offset)
1693{
1694 return build_offset_op (PLUS_EXPR, ptr, offset);
1695}
1696
1697tree
1698build_memref (tree type, tree ptr, tree offset)
1699{
1700 return fold_build2 (MEM_REF, type, ptr, fold_convert (type, offset));
1701}
1702
1703/* Create a tree node to set multiple elements to a single value. */
1704
1705tree
1706build_array_set (tree ptr, tree length, tree value)
1707{
1708 tree ptrtype = TREE_TYPE (ptr);
1709 tree lentype = TREE_TYPE (length);
1710
1711 push_binding_level (level_block);
1712 push_stmt_list ();
1713
1714 /* Build temporary locals for length and ptr, and maybe value. */
1715 tree t = build_local_temp (size_type_node);
1716 add_stmt (build_assign (INIT_EXPR, t, length));
1717 length = t;
1718
1719 t = build_local_temp (ptrtype);
1720 add_stmt (build_assign (INIT_EXPR, t, ptr));
1721 ptr = t;
1722
1723 if (TREE_SIDE_EFFECTS (value))
1724 {
1725 t = build_local_temp (TREE_TYPE (value));
1726 add_stmt (build_assign (INIT_EXPR, t, value));
1727 value = t;
1728 }
1729
1730 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1731 push_stmt_list ();
1732
1733 /* Exit logic for the loop.
1734 if (length == 0) break; */
1735 t = build_boolop (EQ_EXPR, length, d_convert (lentype, integer_zero_node));
1736 t = build1 (EXIT_EXPR, void_type_node, t);
1737 add_stmt (t);
1738
1739 /* Assign value to the current pointer position.
1740 *ptr = value; */
1741 t = modify_expr (build_deref (ptr), value);
1742 add_stmt (t);
1743
1744 /* Move pointer to next element position.
1745 ptr++; */
1746 tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptrtype));
1747 t = build2 (POSTINCREMENT_EXPR, ptrtype, ptr, d_convert (ptrtype, size));
1748 add_stmt (t);
1749
1750 /* Decrease loop counter.
1751 length -= 1; */
1752 t = build2 (POSTDECREMENT_EXPR, lentype, length,
1753 d_convert (lentype, integer_one_node));
1754 add_stmt (t);
1755
1756 /* Pop statements and finish loop. */
1757 tree loop_body = pop_stmt_list ();
1758 add_stmt (build1 (LOOP_EXPR, void_type_node, loop_body));
1759
1760 /* Wrap it up into a bind expression. */
1761 tree stmt_list = pop_stmt_list ();
1762 tree block = pop_binding_level ();
1763
1764 return build3 (BIND_EXPR, void_type_node,
1765 BLOCK_VARS (block), stmt_list, block);
1766}
1767
1768
1769/* Build an array of type TYPE where all the elements are VAL. */
1770
1771tree
1772build_array_from_val (Type *type, tree val)
1773{
b4c522fa
IB
1774 tree etype = build_ctype (type->nextOf ());
1775
1776 /* Initializing a multidimensional array. */
1777 if (TREE_CODE (etype) == ARRAY_TYPE && TREE_TYPE (val) != etype)
1778 val = build_array_from_val (type->nextOf (), val);
1779
89fdaf5a 1780 size_t dims = type->isTypeSArray ()->dim->toInteger ();
af3c19f0 1781 vec <constructor_elt, va_gc> *elms = NULL;
b4c522fa
IB
1782 vec_safe_reserve (elms, dims);
1783
1784 val = d_convert (etype, val);
1785
1786 for (size_t i = 0; i < dims; i++)
1787 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
1788
1789 return build_constructor (build_ctype (type), elms);
1790}
1791
7508a7e9
IB
1792/* Build a static array of type TYPE from an array of EXPS.
1793 If CONST_P is true, then all elements in EXPS are constants. */
1794
1795tree
1796build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
1797{
1798 /* Build a CONSTRUCTOR from all expressions. */
1799 vec <constructor_elt, va_gc> *elms = NULL;
1800 vec_safe_reserve (elms, exps->length);
1801
1802 Type *etype = type->nextOf ();
1803 tree satype = make_array_type (etype, exps->length);
1804
1805 for (size_t i = 0; i < exps->length; i++)
1806 {
1807 Expression *expr = (*exps)[i];
1808 tree t = build_expr (expr, const_p);
1809 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1810 convert_expr (t, expr->type, etype));
1811 }
1812
1813 /* Create a new temporary to store the array. */
1814 tree var = build_local_temp (satype);
1815
1816 /* Fill any alignment holes with zeroes. */
1817 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
1818 tree init = NULL;
1819 if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ()))
1820 init = build_memset_call (var);
1821
1822 /* Initialize the temporary. */
1823 tree assign = modify_expr (var, build_constructor (satype, elms));
1824 return compound_expr (compound_expr (init, assign), var);
1825}
1826
1827
b4c522fa
IB
1828/* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1829
1830tree
1831void_okay_p (tree t)
1832{
1833 tree type = TREE_TYPE (t);
1834
1835 if (VOID_TYPE_P (TREE_TYPE (type)))
1836 {
1837 tree totype = build_ctype (Type::tuns8->pointerTo ());
1838 return fold_convert (totype, t);
1839 }
1840
1841 return t;
1842}
1843
766f5f87
IB
1844/* Builds a STRING_CST representing the filename of location LOC. When the
1845 location is not valid, the name of the source module is used instead. */
1846
1847static tree
1848build_filename_from_loc (const Loc &loc)
1849{
1850 const char *filename = loc.filename
5fee5ec3 1851 ? loc.filename : d_function_chain->module->srcfile.toChars ();
766f5f87
IB
1852
1853 unsigned length = strlen (filename);
1854 tree str = build_string (length, filename);
1855 TREE_TYPE (str) = make_array_type (Type::tchar, length + 1);
1856
1857 return build_address (str);
1858}
1859
1860/* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1861 an assert check fails. When calling the msg variant functions, MSG is the
1862 error message supplied by the user. */
f267a310
IB
1863
1864tree
766f5f87 1865build_assert_call (const Loc &loc, libcall_fn libcall, tree msg)
f267a310 1866{
766f5f87
IB
1867 tree file;
1868 tree line = size_int (loc.linnum);
1869
1870 switch (libcall)
f267a310 1871 {
766f5f87
IB
1872 case LIBCALL_ASSERT_MSG:
1873 case LIBCALL_UNITTEST_MSG:
766f5f87
IB
1874 /* File location is passed as a D string. */
1875 if (loc.filename)
1876 {
1877 unsigned len = strlen (loc.filename);
1878 tree str = build_string (len, loc.filename);
1879 TREE_TYPE (str) = make_array_type (Type::tchar, len);
f267a310 1880
766f5f87
IB
1881 file = d_array_value (build_ctype (Type::tchar->arrayOf ()),
1882 size_int (len), build_address (str));
1883 }
1884 else
1885 file = null_array_node;
1886 break;
1887
1888 case LIBCALL_ASSERTP:
1889 case LIBCALL_UNITTESTP:
1890 file = build_filename_from_loc (loc);
1891 break;
f267a310
IB
1892
1893 default:
1894 gcc_unreachable ();
1895 }
766f5f87
IB
1896
1897
1898 if (msg != NULL_TREE)
1899 return build_libcall (libcall, Type::tvoid, 3, msg, file, line);
1900 else
1901 return build_libcall (libcall, Type::tvoid, 2, file, line);
f267a310
IB
1902}
1903
766f5f87
IB
1904/* Builds a CALL_EXPR at location LOC in the source file to execute when an
1905 array bounds check fails. */
b4c522fa
IB
1906
1907tree
766f5f87 1908build_array_bounds_call (const Loc &loc)
b4c522fa 1909{
766f5f87
IB
1910 /* Terminate the program with a trap if no D runtime present. */
1911 if (checkaction_trap_p ())
1912 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1913 else
1914 {
1915 return build_libcall (LIBCALL_ARRAYBOUNDSP, Type::tvoid, 2,
1916 build_filename_from_loc (loc),
1917 size_int (loc.linnum));
1918 }
1919}
1920
1921/* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1922 in the index expression IE. The condition returns the INDEX if true, or
5fee5ec3 1923 throws a `ArrayIndexError`. */
766f5f87
IB
1924
1925tree
1926build_bounds_index_condition (IndexExp *ie, tree index, tree length)
1927{
1928 if (ie->indexIsInBounds || !array_bounds_check ())
b4c522fa
IB
1929 return index;
1930
1931 /* Prevent multiple evaluations of the index. */
1932 index = d_save_expr (index);
1933
766f5f87 1934 /* Generate INDEX >= LENGTH && throw RangeError.
b4c522fa
IB
1935 No need to check whether INDEX >= 0 as the front-end should
1936 have already taken care of implicit casts to unsigned. */
766f5f87 1937 tree condition = fold_build2 (GE_EXPR, d_bool_type, index, length);
5fee5ec3
IB
1938 tree boundserr;
1939
1940 if (checkaction_trap_p ())
1941 boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1942 else
1943 {
1944 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, Type::tvoid, 4,
1945 build_filename_from_loc (ie->e2->loc),
1946 size_int (ie->e2->loc.linnum), index, length);
1947 }
b4c522fa
IB
1948
1949 return build_condition (TREE_TYPE (index), condition, boundserr, index);
1950}
1951
766f5f87
IB
1952/* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1953 the slice expression SE of the source array length LENGTH. The condition
1954 returns the new array length if true, or throws an `ArraySliceError`. */
1955
1956tree
1957build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
1958{
1959 if (array_bounds_check ())
1960 {
1961 tree condition = NULL_TREE;
1962
1963 /* Enforces that `upper <= length`. */
1964 if (!se->upperIsInBounds && length != NULL_TREE)
1965 condition = fold_build2 (GT_EXPR, d_bool_type, upper, length);
1966 else
1967 length = integer_zero_node;
1968
1969 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1970 we've already ensured that `upper <= length`. */
1971 if (!se->lowerIsLessThanUpper)
1972 {
1973 tree lwr_cond = fold_build2 (GT_EXPR, d_bool_type, lower, upper);
1974
1975 if (condition != NULL_TREE)
1976 condition = build_boolop (TRUTH_ORIF_EXPR, condition, lwr_cond);
1977 else
1978 condition = lwr_cond;
1979 }
1980
1981 if (condition != NULL_TREE)
1982 {
5fee5ec3
IB
1983 tree boundserr;
1984
1985 if (checkaction_trap_p ())
1986 {
1987 boundserr =
1988 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1989 }
1990 else
1991 {
1992 boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP,
1993 Type::tvoid, 5,
1994 build_filename_from_loc (se->loc),
1995 size_int (se->loc.linnum),
1996 lower, upper, length);
1997 }
1998
766f5f87
IB
1999 upper = build_condition (TREE_TYPE (upper), condition,
2000 boundserr, upper);
2001 }
2002 }
2003
2004 /* Need to ensure lower always gets evaluated first, as it may be a function
2005 call. Generates (lower, upper) - lower. */
2006 return fold_build2 (MINUS_EXPR, TREE_TYPE (upper),
2007 compound_expr (lower, upper), lower);
2008}
2009
b4c522fa
IB
2010/* Returns TRUE if array bounds checking code generation is turned on. */
2011
2012bool
2013array_bounds_check (void)
2014{
2015 FuncDeclaration *fd;
2016
2017 switch (global.params.useArrayBounds)
2018 {
0cdc55f5 2019 case CHECKENABLEoff:
b4c522fa
IB
2020 return false;
2021
0cdc55f5 2022 case CHECKENABLEon:
b4c522fa
IB
2023 return true;
2024
0cdc55f5 2025 case CHECKENABLEsafeonly:
b4c522fa
IB
2026 /* For D2 safe functions only. */
2027 fd = d_function_chain->function;
5fee5ec3 2028 if (fd && fd->type->ty == TY::Tfunction)
b4c522fa 2029 {
5fee5ec3 2030 if (fd->type->isTypeFunction ()->trust == TRUST::safe)
b4c522fa
IB
2031 return true;
2032 }
2033 return false;
2034
2035 default:
2036 gcc_unreachable ();
2037 }
2038}
2039
766f5f87
IB
2040/* Returns TRUE if we terminate the program with a trap if an array bounds or
2041 contract check fails. */
2042
2043bool
2044checkaction_trap_p (void)
2045{
2046 switch (global.params.checkAction)
2047 {
2048 case CHECKACTION_D:
5fee5ec3 2049 case CHECKACTION_context:
766f5f87
IB
2050 return false;
2051
2052 case CHECKACTION_C:
2053 case CHECKACTION_halt:
2054 return true;
2055
2056 default:
2057 gcc_unreachable ();
2058 }
2059}
2060
b4c522fa
IB
2061/* Returns the TypeFunction class for Type T.
2062 Assumes T is already ->toBasetype(). */
2063
2064TypeFunction *
2065get_function_type (Type *t)
2066{
2067 TypeFunction *tf = NULL;
5fee5ec3 2068 if (t->ty == TY::Tpointer)
b4c522fa 2069 t = t->nextOf ()->toBasetype ();
5fee5ec3 2070 if (t->ty == TY::Tfunction)
89fdaf5a 2071 tf = t->isTypeFunction ();
5fee5ec3 2072 else if (t->ty == TY::Tdelegate)
89fdaf5a 2073 tf = t->isTypeDelegate ()->next->isTypeFunction ();
b4c522fa
IB
2074 return tf;
2075}
2076
2077/* Returns TRUE if CALLEE is a plain nested function outside the scope of
2078 CALLER. In which case, CALLEE is being called through an alias that was
2079 passed to CALLER. */
2080
2081bool
2082call_by_alias_p (FuncDeclaration *caller, FuncDeclaration *callee)
2083{
2084 if (!callee->isNested ())
2085 return false;
2086
2087 if (caller->toParent () == callee->toParent ())
2088 return false;
2089
2090 Dsymbol *dsym = callee;
2091
2092 while (dsym)
2093 {
2094 if (dsym->isTemplateInstance ())
2095 return false;
2096 else if (dsym->isFuncDeclaration () == caller)
2097 return false;
2098 dsym = dsym->toParent ();
2099 }
2100
2101 return true;
2102}
2103
2104/* Entry point for call routines. Builds a function call to FD.
cdbf48be 2105 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
b4c522fa
IB
2106
2107tree
2108d_build_call_expr (FuncDeclaration *fd, tree object, Expressions *arguments)
2109{
2110 return d_build_call (get_function_type (fd->type),
2111 build_address (get_symbol_decl (fd)), object, arguments);
2112}
2113
cdbf48be 2114/* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
b4c522fa
IB
2115 ARGUMENTS are evaluated in left to right order, saved and promoted
2116 before passing. */
2117
2118tree
2119d_build_call (TypeFunction *tf, tree callable, tree object,
2120 Expressions *arguments)
2121{
2122 tree ctype = TREE_TYPE (callable);
2123 tree callee = callable;
2124
2125 if (POINTER_TYPE_P (ctype))
2126 ctype = TREE_TYPE (ctype);
2127 else
2128 callee = build_address (callable);
2129
2130 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype));
2131 gcc_assert (tf != NULL);
5fee5ec3 2132 gcc_assert (tf->ty == TY::Tfunction);
b4c522fa
IB
2133
2134 if (TREE_CODE (ctype) != FUNCTION_TYPE && object == NULL_TREE)
2135 {
2136 /* Front-end apparently doesn't check this. */
2137 if (TREE_CODE (callable) == FUNCTION_DECL)
2138 {
2139 error ("need %<this%> to access member %qE", DECL_NAME (callable));
2140 return error_mark_node;
2141 }
2142
2143 /* Probably an internal error. */
2144 gcc_unreachable ();
2145 }
2146
2147 /* Build the argument list for the call. */
af3c19f0 2148 vec <tree, va_gc> *args = NULL;
b4c522fa 2149 tree saved_args = NULL_TREE;
0fb57034 2150 bool noreturn_call = false;
b4c522fa
IB
2151
2152 /* If this is a delegate call or a nested function being called as
2153 a delegate, the object should not be NULL. */
2154 if (object != NULL_TREE)
2155 vec_safe_push (args, object);
2156
2157 if (arguments)
2158 {
2159 /* First pass, evaluated expanded tuples in function arguments. */
2cbc99d1 2160 for (size_t i = 0; i < arguments->length; ++i)
b4c522fa
IB
2161 {
2162 Lagain:
2163 Expression *arg = (*arguments)[i];
9c7d5e88 2164 gcc_assert (arg->op != EXP::tuple);
b4c522fa 2165
9c7d5e88 2166 if (arg->op == EXP::comma)
b4c522fa 2167 {
d873350a 2168 CommaExp *ce = arg->isCommaExp ();
b4c522fa
IB
2169 tree tce = build_expr (ce->e1);
2170 saved_args = compound_expr (saved_args, tce);
2171 (*arguments)[i] = ce->e2;
2172 goto Lagain;
2173 }
2174 }
2175
0fb57034 2176 const size_t nparams = tf->parameterList.length ();
b4c522fa 2177 /* if _arguments[] is the first argument. */
0fb57034 2178 const size_t varargs = tf->isDstyleVariadic ();
b4c522fa 2179
2cbc99d1
IB
2180 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2181 for (size_t i = 0; i < arguments->length; ++i)
b4c522fa
IB
2182 {
2183 Expression *arg = (*arguments)[i];
2184 tree targ = build_expr (arg);
2185
2186 if (i - varargs < nparams && i >= varargs)
2187 {
2188 /* Actual arguments for declared formal arguments. */
c3a2ba10 2189 Parameter *parg = tf->parameterList[i - varargs];
b4c522fa
IB
2190 targ = convert_for_argument (targ, parg);
2191 }
2192
2193 /* Don't pass empty aggregates by value. */
2194 if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
2195 && TREE_CODE (targ) != CONSTRUCTOR)
2196 {
2197 tree t = build_constructor (TREE_TYPE (targ), NULL);
2198 targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
2199 }
2200
312ad889 2201 /* Parameter is a struct or array passed by invisible reference. */
2370bdbb
IB
2202 if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
2203 {
2204 Type *t = arg->type->toBasetype ();
312ad889 2205 StructDeclaration *sd = t->baseElemOf ()->isTypeStruct ()->sym;
2370bdbb
IB
2206
2207 /* Nested structs also have ADDRESSABLE set, but if the type has
2208 neither a copy constructor nor a destructor available, then we
2209 need to take care of copying its value before passing it. */
9c7d5e88 2210 if (arg->op == EXP::structLiteral || (!sd->postblit && !sd->dtor))
2370bdbb
IB
2211 targ = force_target_expr (targ);
2212
2213 targ = convert (build_reference_type (TREE_TYPE (targ)),
2214 build_address (targ));
2215 }
2216
235d5a96
IB
2217 /* Type `noreturn` is a terminator, as no other arguments can possibly
2218 be evaluated after it. */
2219 if (TREE_TYPE (targ) == noreturn_type_node)
0fb57034
IB
2220 noreturn_call = true;
2221
b4c522fa
IB
2222 vec_safe_push (args, targ);
2223 }
2224 }
2225
2226 /* Evaluate the callee before calling it. */
2227 if (TREE_SIDE_EFFECTS (callee))
2228 {
2229 callee = d_save_expr (callee);
2230 saved_args = compound_expr (callee, saved_args);
2231 }
2232
0fb57034
IB
2233 /* If we saw a `noreturn` parameter, any unreachable argument evaluations
2234 after it are discarded, as well as the function call itself. */
2235 if (noreturn_call)
2236 {
2237 if (TREE_SIDE_EFFECTS (callee))
2238 saved_args = compound_expr (callee, saved_args);
2239
2240 tree arg;
2241 unsigned int ix;
2242
2243 FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
2244 saved_args = compound_expr (saved_args, arg);
2245
2246 /* Add a stub result type for the expression. */
2247 tree result = build_zero_cst (TREE_TYPE (ctype));
2248 return compound_expr (saved_args, result);
2249 }
2250
b4c522fa 2251 tree result = build_call_vec (TREE_TYPE (ctype), callee, args);
707e9159 2252 SET_EXPR_LOCATION (result, input_location);
b4c522fa 2253
b4c522fa
IB
2254 result = maybe_expand_intrinsic (result);
2255
2256 /* Return the value in a temporary slot so that it can be evaluated
2257 multiple times by the caller. */
2258 if (TREE_CODE (result) == CALL_EXPR
2259 && AGGREGATE_TYPE_P (TREE_TYPE (result))
2260 && TREE_ADDRESSABLE (TREE_TYPE (result)))
2261 {
2262 CALL_EXPR_RETURN_SLOT_OPT (result) = true;
2263 result = force_target_expr (result);
2264 }
2265
2266 return compound_expr (saved_args, result);
2267}
2268
b4c522fa
IB
2269/* Build and return the correct call to fmod depending on TYPE.
2270 ARG0 and ARG1 are the arguments pass to the function. */
2271
2272tree
2273build_float_modulus (tree type, tree arg0, tree arg1)
2274{
2275 tree fmodfn = NULL_TREE;
2276 tree basetype = type;
2277
2278 if (COMPLEX_FLOAT_TYPE_P (basetype))
2279 basetype = TREE_TYPE (basetype);
2280
2281 if (TYPE_MAIN_VARIANT (basetype) == double_type_node
2282 || TYPE_MAIN_VARIANT (basetype) == idouble_type_node)
2283 fmodfn = builtin_decl_explicit (BUILT_IN_FMOD);
2284 else if (TYPE_MAIN_VARIANT (basetype) == float_type_node
2285 || TYPE_MAIN_VARIANT (basetype) == ifloat_type_node)
2286 fmodfn = builtin_decl_explicit (BUILT_IN_FMODF);
2287 else if (TYPE_MAIN_VARIANT (basetype) == long_double_type_node
2288 || TYPE_MAIN_VARIANT (basetype) == ireal_type_node)
2289 fmodfn = builtin_decl_explicit (BUILT_IN_FMODL);
2290
2291 if (!fmodfn)
2292 {
2293 error ("tried to perform floating-point modulo division on %qT", type);
2294 return error_mark_node;
2295 }
2296
2297 if (COMPLEX_FLOAT_TYPE_P (type))
2298 {
2299 tree re = build_call_expr (fmodfn, 2, real_part (arg0), arg1);
2300 tree im = build_call_expr (fmodfn, 2, imaginary_part (arg0), arg1);
2301
2302 return complex_expr (type, re, im);
2303 }
2304
2305 if (SCALAR_FLOAT_TYPE_P (type))
2306 return build_call_expr (fmodfn, 2, arg0, arg1);
2307
2308 /* Should have caught this above. */
2309 gcc_unreachable ();
2310}
2311
2312/* Build a function type whose first argument is a pointer to BASETYPE,
cdbf48be 2313 which is to be used for the `vthis' context parameter for TYPE.
b4c522fa
IB
2314 The base type may be a record for member functions, or a void for
2315 nested functions and delegates. */
2316
2317tree
2318build_vthis_function (tree basetype, tree type)
2319{
2320 gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
2321
2322 tree argtypes = tree_cons (NULL_TREE, build_pointer_type (basetype),
2323 TYPE_ARG_TYPES (type));
2324 tree fntype = build_function_type (TREE_TYPE (type), argtypes);
2325
0fb57034
IB
2326 /* Copy volatile qualifiers from the original function type. */
2327 if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE)
2328 fntype = build_qualified_type (fntype, TYPE_QUAL_VOLATILE);
2329
b4c522fa
IB
2330 if (RECORD_OR_UNION_TYPE_P (basetype))
2331 TYPE_METHOD_BASETYPE (fntype) = TYPE_MAIN_VARIANT (basetype);
2332 else
2333 gcc_assert (VOID_TYPE_P (basetype));
2334
2335 return fntype;
2336}
2337
2b1c2a4b
IB
2338/* Raise an error at that the context pointer of the function or object SYM is
2339 not accessible from the current scope. */
2340
2341tree
2342error_no_frame_access (Dsymbol *sym)
2343{
2344 error_at (input_location, "cannot get frame pointer to %qs",
2345 sym->toPrettyChars ());
2346 return null_pointer_node;
2347}
2348
b4c522fa
IB
2349/* If SYM is a nested function, return the static chain to be
2350 used when calling that function from the current function.
2351
2352 If SYM is a nested class or struct, return the static chain
2353 to be used when creating an instance of the class from CFUN. */
2354
2355tree
2356get_frame_for_symbol (Dsymbol *sym)
2357{
2358 FuncDeclaration *thisfd
2359 = d_function_chain ? d_function_chain->function : NULL;
2360 FuncDeclaration *fd = sym->isFuncDeclaration ();
2361 FuncDeclaration *fdparent = NULL;
2362 FuncDeclaration *fdoverride = NULL;
2363
2364 if (fd != NULL)
2365 {
2366 /* Check that the nested function is properly defined. */
2367 if (!fd->fbody)
2368 {
cdbf48be 2369 /* Should instead error on line that references `fd'. */
b4c522fa
IB
2370 error_at (make_location_t (fd->loc), "nested function missing body");
2371 return null_pointer_node;
2372 }
2373
2374 fdparent = fd->toParent2 ()->isFuncDeclaration ();
2375
2376 /* Special case for __ensure and __require. */
2377 if ((fd->ident == Identifier::idPool ("__ensure")
2378 || fd->ident == Identifier::idPool ("__require"))
2379 && fdparent != thisfd)
2380 {
2381 fdoverride = fdparent;
2382 fdparent = thisfd;
2383 }
2384 }
2385 else
2386 {
2387 /* It's a class (or struct). NewExp codegen has already determined its
2388 outer scope is not another class, so it must be a function. */
2389 while (sym && !sym->isFuncDeclaration ())
2390 sym = sym->toParent2 ();
2391
2392 fdparent = (FuncDeclaration *) sym;
2393 }
2394
9fa5d5de
IB
2395 /* Not a nested function, there is no frame pointer to pass. */
2396 if (fdparent == NULL)
2397 {
2398 /* Only delegate literals report as being nested, even if they are in
2399 global scope. */
2400 gcc_assert (fd && fd->isFuncLiteralDeclaration ());
2401 return null_pointer_node;
2402 }
2403
2404 gcc_assert (thisfd != NULL);
b4c522fa
IB
2405
2406 if (thisfd != fdparent)
2407 {
2408 /* If no frame pointer for this function. */
2409 if (!thisfd->vthis)
2410 {
2411 error_at (make_location_t (sym->loc),
9fa5d5de 2412 "%qs is a nested function and cannot be accessed from %qs",
2b1c2a4b 2413 fdparent->toPrettyChars (), thisfd->toPrettyChars ());
b4c522fa
IB
2414 return null_pointer_node;
2415 }
2416
2417 /* Make sure we can get the frame pointer to the outer function.
2418 Go up each nesting level until we find the enclosing function. */
2419 Dsymbol *dsym = thisfd;
2420
2421 while (fd != dsym)
2422 {
2423 /* Check if enclosing function is a function. */
2b1c2a4b
IB
2424 FuncDeclaration *fdp = dsym->isFuncDeclaration ();
2425 Dsymbol *parent = dsym->toParent2 ();
b4c522fa 2426
2b1c2a4b 2427 if (fdp != NULL)
b4c522fa 2428 {
2b1c2a4b 2429 if (fdparent == parent)
b4c522fa
IB
2430 break;
2431
2b1c2a4b
IB
2432 gcc_assert (fdp->isNested () || fdp->vthis);
2433 dsym = parent;
b4c522fa
IB
2434 continue;
2435 }
2436
2437 /* Check if enclosed by an aggregate. That means the current
2438 function must be a member function of that aggregate. */
2b1c2a4b 2439 AggregateDeclaration *adp = dsym->isAggregateDeclaration ();
b4c522fa 2440
2b1c2a4b 2441 if (adp != NULL)
b4c522fa 2442 {
2b1c2a4b
IB
2443 if ((adp->isClassDeclaration () || adp->isStructDeclaration ())
2444 && fdparent == parent)
2445 break;
b4c522fa
IB
2446 }
2447
2b1c2a4b
IB
2448 /* No frame to outer function found. */
2449 if (!adp || !adp->isNested () || !adp->vthis)
2450 return error_no_frame_access (sym);
2451
2452 dsym = parent;
b4c522fa
IB
2453 }
2454 }
2455
2456 tree ffo = get_frameinfo (fdparent);
2457 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo))
2458 {
2459 tree frame_ref = get_framedecl (thisfd, fdparent);
2460
cdbf48be 2461 /* If `thisfd' is a derived member function, then `fdparent' is the
b4c522fa
IB
2462 overridden member function in the base class. Even if there's a
2463 closure environment, we should give the original stack data as the
2464 nested function frame. */
2465 if (fdoverride)
2466 {
2467 ClassDeclaration *cdo = fdoverride->isThis ()->isClassDeclaration ();
2468 ClassDeclaration *cd = thisfd->isThis ()->isClassDeclaration ();
2469 gcc_assert (cdo && cd);
2470
2471 int offset;
2472 if (cdo->isBaseOf (cd, &offset) && offset != 0)
2473 {
2474 /* Generate a new frame to pass to the overriden function that
cdbf48be 2475 has the `this' pointer adjusted. */
b4c522fa
IB
2476 gcc_assert (offset != OFFSET_RUNTIME);
2477
2478 tree type = FRAMEINFO_TYPE (get_frameinfo (fdoverride));
2479 tree fields = TYPE_FIELDS (type);
cdbf48be 2480 /* The `this' field comes immediately after the `__chain'. */
b4c522fa 2481 tree thisfield = chain_index (1, fields);
af3c19f0 2482 vec <constructor_elt, va_gc> *ve = NULL;
b4c522fa
IB
2483
2484 tree framefields = TYPE_FIELDS (FRAMEINFO_TYPE (ffo));
2485 frame_ref = build_deref (frame_ref);
2486
2487 for (tree field = fields; field; field = DECL_CHAIN (field))
2488 {
2489 tree value = component_ref (frame_ref, framefields);
2490 if (field == thisfield)
2491 value = build_offset (value, size_int (offset));
2492
2493 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2494 framefields = DECL_CHAIN (framefields);
2495 }
2496
2497 frame_ref = build_address (build_constructor (type, ve));
2498 }
2499 }
2500
2501 return frame_ref;
2502 }
2503
2504 return null_pointer_node;
2505}
2506
55303957 2507/* Return the parent function of a nested class or struct AD. */
b4c522fa
IB
2508
2509static FuncDeclaration *
55303957 2510get_outer_function (AggregateDeclaration *ad)
b4c522fa
IB
2511{
2512 FuncDeclaration *fd = NULL;
55303957 2513 while (ad && ad->isNested ())
b4c522fa 2514 {
55303957 2515 Dsymbol *dsym = ad->toParent2 ();
b4c522fa
IB
2516 if ((fd = dsym->isFuncDeclaration ()))
2517 return fd;
2518 else
55303957 2519 ad = dsym->isAggregateDeclaration ();
b4c522fa 2520 }
b4c522fa 2521
b4c522fa
IB
2522 return NULL;
2523}
2524
b4c522fa 2525/* Starting from the current function FD, try to find a suitable value of
cdbf48be 2526 `this' in nested function instances. A suitable `this' value is an
b4c522fa
IB
2527 instance of OCD or a class that has OCD as a base. */
2528
2529static tree
2530find_this_tree (ClassDeclaration *ocd)
2531{
2532 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2533
2534 while (fd)
2535 {
2536 AggregateDeclaration *ad = fd->isThis ();
2537 ClassDeclaration *cd = ad ? ad->isClassDeclaration () : NULL;
2538
2539 if (cd != NULL)
2540 {
2541 if (ocd == cd)
2542 return get_decl_tree (fd->vthis);
2543 else if (ocd->isBaseOf (cd, NULL))
2544 return convert_expr (get_decl_tree (fd->vthis),
2545 cd->type, ocd->type);
2546
55303957
IB
2547 fd = get_outer_function (cd);
2548 continue;
b4c522fa 2549 }
b4c522fa 2550
55303957
IB
2551 if (fd->isNested ())
2552 {
2553 fd = fd->toParent2 ()->isFuncDeclaration ();
2554 continue;
b4c522fa 2555 }
55303957
IB
2556
2557 fd = NULL;
b4c522fa
IB
2558 }
2559
2560 return NULL_TREE;
2561}
2562
cdbf48be 2563/* Retrieve the outer class/struct `this' value of DECL from
b4c522fa
IB
2564 the current function. */
2565
2566tree
2567build_vthis (AggregateDeclaration *decl)
2568{
2569 ClassDeclaration *cd = decl->isClassDeclaration ();
2570 StructDeclaration *sd = decl->isStructDeclaration ();
2571
2572 /* If an aggregate nested in a function has no methods and there are no
2573 other nested functions, any static chain created here will never be
2574 translated. Use a null pointer for the link in this case. */
2575 tree vthis_value = null_pointer_node;
2576
2577 if (cd != NULL || sd != NULL)
2578 {
2579 Dsymbol *outer = decl->toParent2 ();
2580
2581 /* If the parent is a templated struct, the outer context is instead
2582 the enclosing symbol of where the instantiation happened. */
2583 if (outer->isStructDeclaration ())
2584 {
2585 gcc_assert (outer->parent && outer->parent->isTemplateInstance ());
2586 outer = ((TemplateInstance *) outer->parent)->enclosing;
2587 }
2588
cdbf48be 2589 /* For outer classes, get a suitable `this' value.
b4c522fa
IB
2590 For outer functions, get a suitable frame/closure pointer. */
2591 ClassDeclaration *cdo = outer->isClassDeclaration ();
2592 FuncDeclaration *fdo = outer->isFuncDeclaration ();
2593
2594 if (cdo)
2595 {
2596 vthis_value = find_this_tree (cdo);
2597 gcc_assert (vthis_value != NULL_TREE);
2598 }
2599 else if (fdo)
2600 {
2601 tree ffo = get_frameinfo (fdo);
2602 if (FRAMEINFO_CREATES_FRAME (ffo) || FRAMEINFO_STATIC_CHAIN (ffo)
2603 || fdo->hasNestedFrameRefs ())
2604 vthis_value = get_frame_for_symbol (decl);
2605 else if (cd != NULL)
2606 {
2607 /* Classes nested in methods are allowed to access any outer
2608 class fields, use the function chain in this case. */
2609 if (fdo->vthis && fdo->vthis->type != Type::tvoidptr)
2610 vthis_value = get_decl_tree (fdo->vthis);
2611 }
2612 }
2613 else
2614 gcc_unreachable ();
2615 }
2616
2617 return vthis_value;
2618}
2619
2620/* Build the RECORD_TYPE that describes the function frame or closure type for
2621 the function FD. FFI is the tree holding all frame information. */
2622
2623static tree
2624build_frame_type (tree ffi, FuncDeclaration *fd)
2625{
2626 if (FRAMEINFO_TYPE (ffi))
2627 return FRAMEINFO_TYPE (ffi);
2628
2629 tree frame_rec_type = make_node (RECORD_TYPE);
2630 char *name = concat (FRAMEINFO_IS_CLOSURE (ffi) ? "CLOSURE." : "FRAME.",
2631 fd->toPrettyChars (), NULL);
2632 TYPE_NAME (frame_rec_type) = get_identifier (name);
2633 free (name);
2634
2635 tree fields = NULL_TREE;
2636
2637 /* Function is a member or nested, so must have field for outer context. */
2638 if (fd->vthis)
2639 {
2640 tree ptr_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
2641 get_identifier ("__chain"), ptr_type_node);
2642 DECL_FIELD_CONTEXT (ptr_field) = frame_rec_type;
2643 fields = chainon (NULL_TREE, ptr_field);
2644 DECL_NONADDRESSABLE_P (ptr_field) = 1;
2645 }
2646
2647 /* The __ensure and __require are called directly, so never make the outer
2648 functions closure, but nevertheless could still be referencing parameters
2649 of the calling function non-locally. So we add all parameters with nested
2650 refs to the function frame, this should also mean overriding methods will
2651 have the same frame layout when inheriting a contract. */
0cdc55f5
IB
2652 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2653 || (global.params.useOut == CHECKENABLEon && fd->fensure))
b4c522fa
IB
2654 {
2655 if (fd->parameters)
2656 {
2cbc99d1 2657 for (size_t i = 0; fd->parameters && i < fd->parameters->length; i++)
b4c522fa
IB
2658 {
2659 VarDeclaration *v = (*fd->parameters)[i];
2660 /* Remove if already in closureVars so can push to front. */
62321ab4
IB
2661 size_t j = fd->closureVars.find (v);
2662
2663 if (j < fd->closureVars.length)
2664 fd->closureVars.remove (j);
2665
b4c522fa
IB
2666 fd->closureVars.insert (i, v);
2667 }
2668 }
2669
cdbf48be 2670 /* Also add hidden `this' to outer context. */
b4c522fa
IB
2671 if (fd->vthis)
2672 {
62321ab4
IB
2673 size_t i = fd->closureVars.find (fd->vthis);
2674
2675 if (i < fd->closureVars.length)
2676 fd->closureVars.remove (i);
2677
b4c522fa
IB
2678 fd->closureVars.insert (0, fd->vthis);
2679 }
2680 }
2681
2cbc99d1 2682 for (size_t i = 0; i < fd->closureVars.length; i++)
b4c522fa
IB
2683 {
2684 VarDeclaration *v = fd->closureVars[i];
2685 tree vsym = get_symbol_decl (v);
2686 tree ident = v->ident
2687 ? get_identifier (v->ident->toChars ()) : NULL_TREE;
2688
2689 tree field = build_decl (make_location_t (v->loc), FIELD_DECL, ident,
2690 TREE_TYPE (vsym));
2691 SET_DECL_LANG_FRAME_FIELD (vsym, field);
2692 DECL_FIELD_CONTEXT (field) = frame_rec_type;
2693 fields = chainon (fields, field);
2694 TREE_USED (vsym) = 1;
2695
2696 TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (vsym);
2697 DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (vsym);
2698 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (vsym);
2699
235d5a96
IB
2700 if (DECL_LANG_NRVO (vsym))
2701 {
2702 /* Store the nrvo variable in the frame by reference. */
2703 TREE_TYPE (field) = build_reference_type (TREE_TYPE (field));
2704
2705 /* Can't do nrvo if the variable is put in a closure, since what the
2706 return slot points to may no longer exist. */
2707 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi));
2708 }
b4c522fa
IB
2709
2710 if (FRAMEINFO_IS_CLOSURE (ffi))
2711 {
2712 /* Because the value needs to survive the end of the scope. */
2713 if ((v->edtor && (v->storage_class & STCparameter))
2714 || v->needsScopeDtor ())
2715 error_at (make_location_t (v->loc),
91418c42
IB
2716 "variable %qs has scoped destruction, "
2717 "cannot build closure", v->toChars ());
2718 }
2719
2720 if (DECL_REGISTER (vsym))
2721 {
2722 /* Because the value will be in memory, not a register. */
2723 error_at (make_location_t (v->loc),
2724 "explicit register variable %qs cannot be used in nested "
2725 "function", v->toChars ());
b4c522fa
IB
2726 }
2727 }
2728
2729 TYPE_FIELDS (frame_rec_type) = fields;
2730 TYPE_READONLY (frame_rec_type) = 1;
07984707 2731 TYPE_CXX_ODR_P (frame_rec_type) = 1;
b4c522fa
IB
2732 layout_type (frame_rec_type);
2733 d_keep (frame_rec_type);
2734
2735 return frame_rec_type;
2736}
2737
2738/* Closures are implemented by taking the local variables that
2739 need to survive the scope of the function, and copying them
2740 into a GC allocated chuck of memory. That chunk, called the
2741 closure here, is inserted into the linked list of stack
2742 frames instead of the usual stack frame.
2743
2744 If a closure is not required, but FD still needs a frame to lower
2745 nested refs, then instead build custom static chain decl on stack. */
2746
2747void
2748build_closure (FuncDeclaration *fd)
2749{
2750 tree ffi = get_frameinfo (fd);
2751
2752 if (!FRAMEINFO_CREATES_FRAME (ffi))
2753 return;
2754
2755 tree type = FRAMEINFO_TYPE (ffi);
2756 gcc_assert (COMPLETE_TYPE_P (type));
2757
2758 tree decl, decl_ref;
2759
2760 if (FRAMEINFO_IS_CLOSURE (ffi))
2761 {
2762 decl = build_local_temp (build_pointer_type (type));
2763 DECL_NAME (decl) = get_identifier ("__closptr");
2764 decl_ref = build_deref (decl);
2765
2766 /* Allocate memory for closure. */
2767 tree arg = convert (build_ctype (Type::tsize_t), TYPE_SIZE_UNIT (type));
2768 tree init = build_libcall (LIBCALL_ALLOCMEMORY, Type::tvoidptr, 1, arg);
2769
2770 tree init_exp = build_assign (INIT_EXPR, decl,
2771 build_nop (TREE_TYPE (decl), init));
2772 add_stmt (init_exp);
2773 }
2774 else
2775 {
2776 decl = build_local_temp (type);
2777 DECL_NAME (decl) = get_identifier ("__frame");
2778 decl_ref = decl;
2779 }
2780
2781 /* Set the first entry to the parent closure/frame, if any. */
2782 if (fd->vthis)
2783 {
2784 tree chain_field = component_ref (decl_ref, TYPE_FIELDS (type));
2785 tree chain_expr = modify_expr (chain_field,
2786 d_function_chain->static_chain);
2787 add_stmt (chain_expr);
2788 }
2789
2790 /* Copy parameters that are referenced nonlocally. */
2cbc99d1 2791 for (size_t i = 0; i < fd->closureVars.length; i++)
b4c522fa
IB
2792 {
2793 VarDeclaration *v = fd->closureVars[i];
235d5a96 2794 tree vsym = get_symbol_decl (v);
b4c522fa 2795
235d5a96 2796 if (TREE_CODE (vsym) != PARM_DECL && !DECL_LANG_NRVO (vsym))
b4c522fa
IB
2797 continue;
2798
b4c522fa 2799 tree field = component_ref (decl_ref, DECL_LANG_FRAME_FIELD (vsym));
235d5a96
IB
2800
2801 /* Variable is an alias for the NRVO slot, store the reference. */
2802 if (DECL_LANG_NRVO (vsym))
2803 vsym = build_address (DECL_LANG_NRVO (vsym));
2804
b4c522fa
IB
2805 tree expr = modify_expr (field, vsym);
2806 add_stmt (expr);
2807 }
2808
2809 if (!FRAMEINFO_IS_CLOSURE (ffi))
2810 decl = build_address (decl);
2811
2812 d_function_chain->static_chain = decl;
2813}
2814
2815/* Return the frame of FD. This could be a static chain or a closure
cdbf48be 2816 passed via the hidden `this' pointer. */
b4c522fa
IB
2817
2818tree
2819get_frameinfo (FuncDeclaration *fd)
2820{
2821 tree fds = get_symbol_decl (fd);
2822 if (DECL_LANG_FRAMEINFO (fds))
2823 return DECL_LANG_FRAMEINFO (fds);
2824
2825 tree ffi = make_node (FUNCFRAME_INFO);
2826
2827 DECL_LANG_FRAMEINFO (fds) = ffi;
2828
b6df1132 2829 const bool requiresClosure = fd->requiresClosure;
b4c522fa
IB
2830 if (fd->needsClosure ())
2831 {
b6df1132
IB
2832 /* This can shift due to templates being expanded that access alias
2833 symbols, give it a decent error for now. */
2834 if (requiresClosure != fd->requiresClosure
2835 && (fd->nrvo_var || global.params.betterC))
2836 fd->checkClosure ();
2837
b4c522fa
IB
2838 /* Set-up a closure frame, this will be allocated on the heap. */
2839 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2840 FRAMEINFO_IS_CLOSURE (ffi) = 1;
2841 }
2842 else if (fd->hasNestedFrameRefs ())
2843 {
2844 /* Functions with nested refs must create a static frame for local
2845 variables to be referenced from. */
2846 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2847 }
2848 else
2849 {
2850 /* For nested functions, default to creating a frame. Even if there are
2851 no fields to populate the frame, create it anyway, as this will be
2852 used as the record type instead of `void*` for the this parameter. */
2853 if (fd->vthis && fd->vthis->type == Type::tvoidptr)
2854 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2855
2856 /* In checkNestedReference, references from contracts are not added to the
2857 closureVars array, so assume all parameters referenced. */
0cdc55f5
IB
2858 if ((global.params.useIn == CHECKENABLEon && fd->frequire)
2859 || (global.params.useOut == CHECKENABLEon && fd->fensure))
b4c522fa
IB
2860 FRAMEINFO_CREATES_FRAME (ffi) = 1;
2861
2862 /* If however `fd` is nested (deeply) in a function that creates a
2863 closure, then `fd` instead inherits that closure via hidden vthis
2864 pointer, and doesn't create a stack frame at all. */
2865 FuncDeclaration *ff = fd;
2866
2867 while (ff)
2868 {
2869 tree ffo = get_frameinfo (ff);
2870
2871 if (ff != fd && FRAMEINFO_CREATES_FRAME (ffo))
2872 {
2873 gcc_assert (FRAMEINFO_TYPE (ffo));
2874 FRAMEINFO_CREATES_FRAME (ffi) = 0;
2875 FRAMEINFO_STATIC_CHAIN (ffi) = 1;
2876 FRAMEINFO_IS_CLOSURE (ffi) = FRAMEINFO_IS_CLOSURE (ffo);
2877 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo)));
2878 FRAMEINFO_TYPE (ffi) = FRAMEINFO_TYPE (ffo);
2879 break;
2880 }
2881
2882 /* Stop looking if no frame pointer for this function. */
2883 if (ff->vthis == NULL)
2884 break;
2885
2886 AggregateDeclaration *ad = ff->isThis ();
2887 if (ad && ad->isNested ())
2888 {
2889 while (ad->isNested ())
2890 {
2891 Dsymbol *d = ad->toParent2 ();
2892 ad = d->isAggregateDeclaration ();
2893 ff = d->isFuncDeclaration ();
2894
2895 if (ad == NULL)
2896 break;
2897 }
2898 }
2899 else
2900 ff = ff->toParent2 ()->isFuncDeclaration ();
2901 }
2902 }
2903
2904 /* Build type now as may be referenced from another module. */
2905 if (FRAMEINFO_CREATES_FRAME (ffi))
2906 FRAMEINFO_TYPE (ffi) = build_frame_type (ffi, fd);
2907
2908 return ffi;
2909}
2910
2911/* Return a pointer to the frame/closure block of OUTER
2912 so can be accessed from the function INNER. */
2913
2914tree
2915get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
2916{
2917 tree result = d_function_chain->static_chain;
2918 FuncDeclaration *fd = inner;
2919
2920 while (fd && fd != outer)
2921 {
b4c522fa
IB
2922 /* Parent frame link is the first field. */
2923 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd)))
2924 result = indirect_ref (ptr_type_node, result);
2925
2926 if (fd->isNested ())
2927 fd = fd->toParent2 ()->isFuncDeclaration ();
2928 /* The frame/closure record always points to the outer function's
2929 frame, even if there are intervening nested classes or structs.
2930 So, we can just skip over these. */
b4c522fa 2931 else
55303957 2932 fd = get_outer_function (fd->isThis ());
b4c522fa
IB
2933 }
2934
2b1c2a4b
IB
2935 if (fd != outer)
2936 return error_no_frame_access (outer);
2937
b4c522fa 2938 /* Go get our frame record. */
b4c522fa
IB
2939 tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
2940
2941 if (frame_type != NULL_TREE)
2942 {
2943 result = build_nop (build_pointer_type (frame_type), result);
2944 return result;
2945 }
2946 else
2947 {
2948 error_at (make_location_t (inner->loc),
2949 "forward reference to frame of %qs", outer->toChars ());
2950 return null_pointer_node;
2951 }
2952}