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