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