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