]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/d-codegen.cc
1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
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)
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.
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/>. */
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
24 #include "dmd/declaration.h"
25 #include "dmd/identifier.h"
26 #include "dmd/target.h"
27 #include "dmd/template.h"
30 #include "tree-iterator.h"
31 #include "fold-const.h"
32 #include "diagnostic.h"
33 #include "langhooks.h"
35 #include "stringpool.h"
37 #include "stor-layout.h"
44 /* Return the GCC location for the D frontend location LOC. */
47 make_location_t (const Loc
& loc
)
49 location_t gcc_location
= input_location
;
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);
62 /* Return the DECL_CONTEXT for symbol DSYM. */
65 d_decl_context (Dsymbol
*dsym
)
67 Dsymbol
*parent
= dsym
;
68 Declaration
*decl
= dsym
->isDeclaration ();
70 while ((parent
= parent
->toParent ()))
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 ())
77 if (decl
!= NULL
&& decl
->linkage
!= LINKd
)
80 return build_import_decl (parent
);
83 /* Declarations marked as 'static' or '__gshared' are never
84 part of any context except at module level. */
85 if (decl
!= NULL
&& decl
->isDataseg ())
88 /* Nested functions. */
89 FuncDeclaration
*fd
= parent
->isFuncDeclaration ();
91 return get_symbol_decl (fd
);
93 /* Methods of classes or structs. */
94 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration ();
97 tree context
= build_ctype (ad
->type
);
98 /* Want the underlying RECORD_TYPE. */
99 if (ad
->isClassDeclaration ())
100 context
= TREE_TYPE (context
);
105 /* Instantiated types are given the context of their template. */
106 TemplateInstance
*ti
= parent
->isTemplateInstance ();
107 if (ti
!= NULL
&& decl
== NULL
)
108 parent
= ti
->tempdecl
;
114 /* Return a copy of record TYPE but safe to modify in any way. */
117 copy_aggregate_type (tree type
)
119 tree newtype
= build_distinct_type_copy (type
);
120 TYPE_FIELDS (newtype
) = copy_list (TYPE_FIELDS (type
));
122 for (tree f
= TYPE_FIELDS (newtype
); f
; f
= DECL_CHAIN (f
))
123 DECL_FIELD_CONTEXT (f
) = newtype
;
128 /* Return TRUE if declaration DECL is a reference type. */
131 declaration_reference_p (Declaration
*decl
)
133 Type
*tb
= decl
->type
->toBasetype ();
135 /* Declaration is a reference type. */
136 if (tb
->ty
== Treference
|| decl
->storage_class
& (STCout
| STCref
))
142 /* Returns the real type for declaration DECL. */
145 declaration_type (Declaration
*decl
)
147 /* Lazy declarations are converted to delegates. */
148 if (decl
->storage_class
& STClazy
)
150 TypeFunction
*tf
= TypeFunction::create (NULL
, decl
->type
, false, LINKd
);
151 TypeDelegate
*t
= TypeDelegate::create (tf
);
152 return build_ctype (t
->merge2 ());
155 /* Static array va_list have array->pointer conversions applied. */
156 if (decl
->isParameter () && valist_array_p (decl
->type
))
158 Type
*valist
= decl
->type
->nextOf ()->pointerTo ();
159 valist
= valist
->castMod (decl
->type
->mod
);
160 return build_ctype (valist
);
163 tree type
= build_ctype (decl
->type
);
165 /* Parameter is passed by reference. */
166 if (declaration_reference_p (decl
))
167 return build_reference_type (type
);
169 /* The 'this' parameter is always const. */
170 if (decl
->isThisDeclaration ())
171 return insert_type_modifiers (type
, MODconst
);
176 /* These should match the Declaration versions above
177 Return TRUE if parameter ARG is a reference type. */
180 argument_reference_p (Parameter
*arg
)
182 Type
*tb
= arg
->type
->toBasetype ();
184 /* Parameter is a reference type. */
185 if (tb
->ty
== Treference
|| arg
->storageClass
& (STCout
| STCref
))
188 tree type
= build_ctype (arg
->type
);
189 if (TREE_ADDRESSABLE (type
))
195 /* Returns the real type for parameter ARG. */
198 type_passed_as (Parameter
*arg
)
200 /* Lazy parameters are converted to delegates. */
201 if (arg
->storageClass
& STClazy
)
203 TypeFunction
*tf
= TypeFunction::create (NULL
, arg
->type
, false, LINKd
);
204 TypeDelegate
*t
= TypeDelegate::create (tf
);
205 return build_ctype (t
->merge2 ());
208 /* Static array va_list have array->pointer conversions applied. */
209 if (valist_array_p (arg
->type
))
211 Type
*valist
= arg
->type
->nextOf ()->pointerTo ();
212 valist
= valist
->castMod (arg
->type
->mod
);
213 return build_ctype (valist
);
216 tree type
= build_ctype (arg
->type
);
218 /* Parameter is passed by reference. */
219 if (argument_reference_p (arg
))
220 return build_reference_type (type
);
225 /* Build INTEGER_CST of type TYPE with the value VALUE. */
228 build_integer_cst (dinteger_t value
, tree type
)
230 /* The type is error_mark_node, we can't do anything. */
231 if (error_operand_p (type
))
234 return build_int_cst_type (type
, value
);
237 /* Build REAL_CST of type TOTYPE with the value VALUE. */
240 build_float_cst (const real_t
& value
, Type
*totype
)
243 TypeBasic
*tb
= totype
->isTypeBasic ();
245 gcc_assert (tb
!= NULL
);
247 tree type_node
= build_ctype (tb
);
248 real_convert (&new_value
.rv (), TYPE_MODE (type_node
), &value
.rv ());
250 return build_real (type_node
, new_value
.rv ());
253 /* Returns the .length component from the D dynamic array EXP. */
256 d_array_length (tree exp
)
258 if (error_operand_p (exp
))
261 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp
)));
263 /* Get the back-end type for the array and pick out the array
264 length field (assumed to be the first field). */
265 tree len_field
= TYPE_FIELDS (TREE_TYPE (exp
));
266 return component_ref (exp
, len_field
);
269 /* Returns the .ptr component from the D dynamic array EXP. */
272 d_array_ptr (tree exp
)
274 if (error_operand_p (exp
))
277 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp
)));
279 /* Get the back-end type for the array and pick out the array
280 data pointer field (assumed to be the second field). */
281 tree ptr_field
= TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp
)));
282 return component_ref (exp
, ptr_field
);
285 /* Returns a constructor for D dynamic array type TYPE of .length LEN
286 and .ptr pointing to DATA. */
289 d_array_value (tree type
, tree len
, tree data
)
291 tree len_field
, ptr_field
;
292 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
294 gcc_assert (TYPE_DYNAMIC_ARRAY (type
));
295 len_field
= TYPE_FIELDS (type
);
296 ptr_field
= TREE_CHAIN (len_field
);
298 len
= convert (TREE_TYPE (len_field
), len
);
299 data
= convert (TREE_TYPE (ptr_field
), data
);
301 CONSTRUCTOR_APPEND_ELT (ce
, len_field
, len
);
302 CONSTRUCTOR_APPEND_ELT (ce
, ptr_field
, data
);
304 return build_constructor (type
, ce
);
307 /* Returns value representing the array length of expression EXP.
308 TYPE could be a dynamic or static array. */
311 get_array_length (tree exp
, Type
*type
)
313 Type
*tb
= type
->toBasetype ();
318 return size_int (((TypeSArray
*) tb
)->dim
->toUInteger ());
321 return d_array_length (exp
);
324 error ("can't determine the length of a %qs", type
->toChars ());
325 return error_mark_node
;
329 /* Create BINFO for a ClassDeclaration's inheritance tree.
330 InterfaceDeclaration's are not included. */
333 build_class_binfo (tree super
, ClassDeclaration
*cd
)
335 tree binfo
= make_tree_binfo (1);
336 tree ctype
= build_ctype (cd
->type
);
338 /* Want RECORD_TYPE, not POINTER_TYPE. */
339 BINFO_TYPE (binfo
) = TREE_TYPE (ctype
);
340 BINFO_INHERITANCE_CHAIN (binfo
) = super
;
341 BINFO_OFFSET (binfo
) = integer_zero_node
;
344 BINFO_BASE_APPEND (binfo
, build_class_binfo (binfo
, cd
->baseClass
));
349 /* Create BINFO for an InterfaceDeclaration's inheritance tree.
350 In order to access all inherited methods in the debugger,
351 the entire tree must be described.
352 This function makes assumptions about interface layout. */
355 build_interface_binfo (tree super
, ClassDeclaration
*cd
, unsigned& offset
)
357 tree binfo
= make_tree_binfo (cd
->baseclasses
->dim
);
358 tree ctype
= build_ctype (cd
->type
);
360 /* Want RECORD_TYPE, not POINTER_TYPE. */
361 BINFO_TYPE (binfo
) = TREE_TYPE (ctype
);
362 BINFO_INHERITANCE_CHAIN (binfo
) = super
;
363 BINFO_OFFSET (binfo
) = size_int (offset
* Target::ptrsize
);
364 BINFO_VIRTUAL_P (binfo
) = 1;
366 for (size_t i
= 0; i
< cd
->baseclasses
->dim
; i
++, offset
++)
368 BaseClass
*bc
= (*cd
->baseclasses
)[i
];
369 BINFO_BASE_APPEND (binfo
, build_interface_binfo (binfo
, bc
->sym
, offset
));
375 /* Returns the .funcptr component from the D delegate EXP. */
378 delegate_method (tree exp
)
380 /* Get the back-end type for the delegate and pick out the funcptr field
381 (assumed to be the second field). */
382 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp
)));
383 tree method_field
= TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp
)));
384 return component_ref (exp
, method_field
);
387 /* Returns the .object component from the delegate EXP. */
390 delegate_object (tree exp
)
392 /* Get the back-end type for the delegate and pick out the object field
393 (assumed to be the first field). */
394 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp
)));
395 tree obj_field
= TYPE_FIELDS (TREE_TYPE (exp
));
396 return component_ref (exp
, obj_field
);
399 /* Build a delegate literal of type TYPE whose pointer function is
400 METHOD, and hidden object is OBJECT. */
403 build_delegate_cst (tree method
, tree object
, Type
*type
)
405 tree ctor
= make_node (CONSTRUCTOR
);
408 Type
*tb
= type
->toBasetype ();
409 if (tb
->ty
== Tdelegate
)
410 ctype
= build_ctype (type
);
413 /* Convert a function method into an anonymous delegate. */
414 ctype
= make_struct_type ("delegate()", 2,
415 get_identifier ("object"), TREE_TYPE (object
),
416 get_identifier ("func"), TREE_TYPE (method
));
417 TYPE_DELEGATE (ctype
) = 1;
420 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
421 CONSTRUCTOR_APPEND_ELT (ce
, TYPE_FIELDS (ctype
), object
);
422 CONSTRUCTOR_APPEND_ELT (ce
, TREE_CHAIN (TYPE_FIELDS (ctype
)), method
);
424 CONSTRUCTOR_ELTS (ctor
) = ce
;
425 TREE_TYPE (ctor
) = ctype
;
430 /* Builds a temporary tree to store the CALLEE and OBJECT
431 of a method call expression of type TYPE. */
434 build_method_call (tree callee
, tree object
, Type
*type
)
436 tree t
= build_delegate_cst (callee
, object
, type
);
437 METHOD_CALL_EXPR (t
) = 1;
441 /* Extract callee and object from T and return in to CALLEE and OBJECT. */
444 extract_from_method_call (tree t
, tree
& callee
, tree
& object
)
446 gcc_assert (METHOD_CALL_EXPR (t
));
447 object
= CONSTRUCTOR_ELT (t
, 0)->value
;
448 callee
= CONSTRUCTOR_ELT (t
, 1)->value
;
451 /* Build a typeof(null) constant of type TYPE. Handles certain special case
452 conversions, where the underlying type is an aggregate with a nullable
456 build_typeof_null_value (Type
*type
)
458 Type
*tb
= type
->toBasetype ();
461 /* For dynamic arrays, set length and pointer fields to zero. */
462 if (tb
->ty
== Tarray
)
463 value
= d_array_value (build_ctype (type
), size_int (0), null_pointer_node
);
465 /* For associative arrays, set the pointer field to null. */
466 else if (tb
->ty
== Taarray
)
468 tree ctype
= build_ctype (type
);
469 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype
));
471 value
= build_constructor_single (ctype
, TYPE_FIELDS (ctype
),
475 /* For delegates, set the frame and function pointer fields to null. */
476 else if (tb
->ty
== Tdelegate
)
477 value
= build_delegate_cst (null_pointer_node
, null_pointer_node
, type
);
479 /* Simple zero constant for all other types. */
481 value
= build_zero_cst (build_ctype (type
));
483 TREE_CONSTANT (value
) = 1;
487 /* Build a dereference into the virtual table for OBJECT to retrieve
488 a function pointer of type FNTYPE at position INDEX. */
491 build_vindex_ref (tree object
, tree fntype
, size_t index
)
493 /* The vtable is the first field. Interface methods are also in the class's
494 vtable, so we don't need to convert from a class to an interface. */
495 tree result
= build_deref (object
);
496 result
= component_ref (result
, TYPE_FIELDS (TREE_TYPE (result
)));
498 gcc_assert (POINTER_TYPE_P (fntype
));
500 return build_memref (fntype
, result
, size_int (Target::ptrsize
* index
));
503 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
504 made into temporaries, otherwise any assignments will be lost. */
509 const enum tree_code code
= TREE_CODE (exp
);
521 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp
));
527 return lvalue_p (TREE_OPERAND (exp
, 0));
530 return (lvalue_p (TREE_OPERAND (exp
, 1)
531 ? TREE_OPERAND (exp
, 1)
532 : TREE_OPERAND (exp
, 0))
533 && lvalue_p (TREE_OPERAND (exp
, 2)));
539 return lvalue_p (TREE_OPERAND (exp
, 1));
546 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
547 more than once in an expression. */
550 d_save_expr (tree exp
)
552 if (TREE_SIDE_EFFECTS (exp
))
555 return stabilize_reference (exp
);
557 return save_expr (exp
);
563 /* VALUEP is an expression we want to pre-evaluate or perform a computation on.
564 The expression returned by this function is the part whose value we don't
565 care about, storing the value in VALUEP. Callers must ensure that the
566 returned expression is evaluated before VALUEP. */
569 stabilize_expr (tree
*valuep
)
572 const enum tree_code code
= TREE_CODE (expr
);
579 /* Given ((e1, ...), eN):
580 Store the last RHS 'eN' expression in VALUEP. */
581 lhs
= TREE_OPERAND (expr
, 0);
582 rhs
= TREE_OPERAND (expr
, 1);
583 lhs
= compound_expr (lhs
, stabilize_expr (&rhs
));
592 /* Return a TARGET_EXPR, initializing the DECL with EXP. */
595 build_target_expr (tree decl
, tree exp
)
597 tree type
= TREE_TYPE (decl
);
598 tree result
= build4 (TARGET_EXPR
, type
, decl
, exp
, NULL_TREE
, NULL_TREE
);
600 if (EXPR_HAS_LOCATION (exp
))
601 SET_EXPR_LOCATION (result
, EXPR_LOCATION (exp
));
603 /* If decl must always reside in memory. */
604 if (TREE_ADDRESSABLE (type
))
605 d_mark_addressable (decl
);
607 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
608 TARGET_EXPR. If there really turn out to be no side effects, then the
609 optimizer should be able to remove it. */
610 TREE_SIDE_EFFECTS (result
) = 1;
615 /* Like the above function, but initializes a new temporary. */
618 force_target_expr (tree exp
)
620 tree decl
= create_temporary_var (TREE_TYPE (exp
));
622 return build_target_expr (decl
, exp
);
625 /* Returns the address of the expression EXP. */
628 build_address (tree exp
)
630 if (error_operand_p (exp
))
634 tree type
= TREE_TYPE (exp
);
636 if (TREE_CODE (exp
) == STRING_CST
)
638 /* Just convert string literals (char[]) to C-style strings (char *),
639 otherwise the latter method (char[]*) causes conversion problems
640 during gimplification. */
641 ptrtype
= build_pointer_type (TREE_TYPE (type
));
643 else if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
)
644 && TREE_CODE (TYPE_MAIN_VARIANT (type
)) == ARRAY_TYPE
)
646 /* Special case for va_list, allow arrays to decay to a pointer. */
647 ptrtype
= build_pointer_type (TREE_TYPE (type
));
650 ptrtype
= build_pointer_type (type
);
652 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
653 tree init
= stabilize_expr (&exp
);
655 /* Can't take the address of a manifest constant, instead use its value. */
656 if (TREE_CODE (exp
) == CONST_DECL
)
657 exp
= DECL_INITIAL (exp
);
659 /* Some expression lowering may request an address of a compile-time constant.
660 Make sure it is assigned to a location we can reference. */
661 if (CONSTANT_CLASS_P (exp
) && TREE_CODE (exp
) != STRING_CST
)
662 exp
= force_target_expr (exp
);
664 d_mark_addressable (exp
);
665 exp
= build_fold_addr_expr_with_type_loc (input_location
, exp
, ptrtype
);
667 if (TREE_CODE (exp
) == ADDR_EXPR
)
668 TREE_NO_TRAMPOLINE (exp
) = 1;
670 return compound_expr (init
, exp
);
673 /* Mark EXP saying that we need to be able to take the
674 address of it; it should not be allocated in a register. */
677 d_mark_addressable (tree exp
)
679 switch (TREE_CODE (exp
))
686 d_mark_addressable (TREE_OPERAND (exp
, 0));
694 TREE_ADDRESSABLE (exp
) = 1;
698 TREE_ADDRESSABLE (exp
) = 1;
702 TREE_ADDRESSABLE (exp
) = 1;
703 d_mark_addressable (TREE_OPERAND (exp
, 0));
713 /* Mark EXP as "used" in the program for the benefit of
714 -Wunused warning purposes. */
717 d_mark_used (tree exp
)
719 switch (TREE_CODE (exp
))
737 d_mark_used (TREE_OPERAND (exp
, 0));
741 d_mark_used (TREE_OPERAND (exp
, 0));
742 d_mark_used (TREE_OPERAND (exp
, 1));
751 /* Mark EXP as read, not just set, for set but not used -Wunused
755 d_mark_read (tree exp
)
757 switch (TREE_CODE (exp
))
762 DECL_READ_P (exp
) = 1;
773 d_mark_read (TREE_OPERAND (exp
, 0));
777 d_mark_read (TREE_OPERAND (exp
, 1));
786 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
787 This is because we don't guarantee that padding is zero-initialized for
788 a stack variable, so we can't use memcmp to compare struct values. */
791 identity_compare_p (StructDeclaration
*sd
)
793 if (sd
->isUnionDeclaration ())
798 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
800 VarDeclaration
*vd
= sd
->fields
[i
];
801 Type
*tb
= vd
->type
->toBasetype ();
803 /* Check inner data structures. */
804 if (tb
->ty
== Tstruct
)
806 TypeStruct
*ts
= (TypeStruct
*) tb
;
807 if (!identity_compare_p (ts
->sym
))
811 /* Check for types that may have padding. */
812 if ((tb
->ty
== Tcomplex80
|| tb
->ty
== Tfloat80
|| tb
->ty
== Timaginary80
)
813 && Target::realpad
!= 0)
816 if (offset
<= vd
->offset
)
818 /* There's a hole in the struct. */
819 if (offset
!= vd
->offset
)
822 offset
+= vd
->type
->size ();
826 /* Any trailing padding may not be zero. */
827 if (offset
< sd
->structsize
)
833 /* Build a floating-point identity comparison between T1 and T2, ignoring any
834 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
837 build_float_identity (tree_code code
, tree t1
, tree t2
)
839 tree tmemcmp
= builtin_decl_explicit (BUILT_IN_MEMCMP
);
840 tree size
= size_int (TYPE_PRECISION (TREE_TYPE (t1
)) / BITS_PER_UNIT
);
842 tree result
= build_call_expr (tmemcmp
, 3, build_address (t1
),
843 build_address (t2
), size
);
844 return build_boolop (code
, result
, integer_zero_node
);
847 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
848 CODE is the EQ_EXPR or NE_EXPR comparison. */
851 lower_struct_comparison (tree_code code
, StructDeclaration
*sd
,
854 tree_code tcode
= (code
== EQ_EXPR
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
855 tree tmemcmp
= NULL_TREE
;
857 /* We can skip the compare if the structs are empty. */
858 if (sd
->fields
.dim
== 0)
860 tmemcmp
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
861 if (TREE_SIDE_EFFECTS (t2
))
862 tmemcmp
= compound_expr (t2
, tmemcmp
);
863 if (TREE_SIDE_EFFECTS (t1
))
864 tmemcmp
= compound_expr (t1
, tmemcmp
);
869 /* Let back-end take care of union comparisons. */
870 if (sd
->isUnionDeclaration ())
872 tmemcmp
= build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP
), 3,
873 build_address (t1
), build_address (t2
),
874 size_int (sd
->structsize
));
876 return build_boolop (code
, tmemcmp
, integer_zero_node
);
879 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
881 VarDeclaration
*vd
= sd
->fields
[i
];
882 Type
*type
= vd
->type
->toBasetype ();
883 tree sfield
= get_symbol_decl (vd
);
885 tree t1ref
= component_ref (t1
, sfield
);
886 tree t2ref
= component_ref (t2
, sfield
);
889 if (type
->ty
== Tstruct
)
891 /* Compare inner data structures. */
892 StructDeclaration
*decl
= ((TypeStruct
*) type
)->sym
;
893 tcmp
= lower_struct_comparison (code
, decl
, t1ref
, t2ref
);
895 else if (type
->ty
!= Tvector
&& type
->isintegral ())
897 /* Integer comparison, no special handling required. */
898 tcmp
= build_boolop (code
, t1ref
, t2ref
);
900 else if (type
->ty
!= Tvector
&& type
->isfloating ())
902 /* Floating-point comparison, don't compare padding in type. */
903 if (!type
->iscomplex ())
904 tcmp
= build_float_identity (code
, t1ref
, t2ref
);
907 tree req
= build_float_identity (code
, real_part (t1ref
),
909 tree ieq
= build_float_identity (code
, imaginary_part (t1ref
),
910 imaginary_part (t2ref
));
912 tcmp
= build_boolop (tcode
, req
, ieq
);
917 tree stype
= build_ctype (type
);
918 opt_scalar_int_mode mode
= int_mode_for_mode (TYPE_MODE (stype
));
922 /* Compare field bits as their corresponding integer type.
923 *((T*) &t1) == *((T*) &t2) */
924 tree tmode
= lang_hooks
.types
.type_for_mode (mode
.require (), 1);
926 if (tmode
== NULL_TREE
)
927 tmode
= make_unsigned_type (GET_MODE_BITSIZE (mode
.require ()));
929 t1ref
= build_vconvert (tmode
, t1ref
);
930 t2ref
= build_vconvert (tmode
, t2ref
);
932 tcmp
= build_boolop (code
, t1ref
, t2ref
);
936 /* Simple memcmp between types. */
937 tcmp
= build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP
),
938 3, build_address (t1ref
),
939 build_address (t2ref
),
940 TYPE_SIZE_UNIT (stype
));
942 tcmp
= build_boolop (code
, tcmp
, integer_zero_node
);
946 tmemcmp
= (tmemcmp
) ? build_boolop (tcode
, tmemcmp
, tcmp
) : tcmp
;
953 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
954 If possible, use memcmp, otherwise field-by-field comparison is done.
955 CODE is the EQ_EXPR or NE_EXPR comparison. */
958 build_struct_comparison (tree_code code
, StructDeclaration
*sd
,
961 /* We can skip the compare if the structs are empty. */
962 if (sd
->fields
.dim
== 0)
964 tree exp
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
965 if (TREE_SIDE_EFFECTS (t2
))
966 exp
= compound_expr (t2
, exp
);
967 if (TREE_SIDE_EFFECTS (t1
))
968 exp
= compound_expr (t1
, exp
);
973 /* Make temporaries to prevent multiple evaluations. */
974 tree t1init
= stabilize_expr (&t1
);
975 tree t2init
= stabilize_expr (&t2
);
978 t1
= d_save_expr (t1
);
979 t2
= d_save_expr (t2
);
981 /* Bitwise comparison of structs not returned in memory may not work
982 due to data holes loosing its zero padding upon return.
983 As a heuristic, small structs are not compared using memcmp either. */
984 if (TYPE_MODE (TREE_TYPE (t1
)) != BLKmode
|| !identity_compare_p (sd
))
985 result
= lower_struct_comparison (code
, sd
, t1
, t2
);
988 /* Do bit compare of structs. */
989 tree size
= size_int (sd
->structsize
);
990 tree tmemcmp
= build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP
),
991 3, build_address (t1
),
992 build_address (t2
), size
);
994 result
= build_boolop (code
, tmemcmp
, integer_zero_node
);
997 return compound_expr (compound_expr (t1init
, t2init
), result
);
1000 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1001 The pointer references are T1 and T2, and the element type is SD.
1002 CODE is the EQ_EXPR or NE_EXPR comparison. */
1005 build_array_struct_comparison (tree_code code
, StructDeclaration
*sd
,
1006 tree length
, tree t1
, tree t2
)
1008 tree_code tcode
= (code
== EQ_EXPR
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
1010 /* Build temporary for the result of the comparison.
1011 Initialize as either 0 or 1 depending on operation. */
1012 tree result
= build_local_temp (d_bool_type
);
1013 tree init
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
1014 add_stmt (build_assign (INIT_EXPR
, result
, init
));
1016 /* Cast pointer-to-array to pointer-to-struct. */
1017 tree ptrtype
= build_ctype (sd
->type
->pointerTo ());
1018 tree lentype
= TREE_TYPE (length
);
1020 push_binding_level (level_block
);
1023 /* Build temporary locals for length and pointers. */
1024 tree t
= build_local_temp (size_type_node
);
1025 add_stmt (build_assign (INIT_EXPR
, t
, length
));
1028 t
= build_local_temp (ptrtype
);
1029 add_stmt (build_assign (INIT_EXPR
, t
, d_convert (ptrtype
, t1
)));
1032 t
= build_local_temp (ptrtype
);
1033 add_stmt (build_assign (INIT_EXPR
, t
, d_convert (ptrtype
, t2
)));
1036 /* Build loop for comparing each element. */
1039 /* Exit logic for the loop.
1040 if (length == 0 || result OP 0) break; */
1041 t
= build_boolop (EQ_EXPR
, length
, d_convert (lentype
, integer_zero_node
));
1042 t
= build_boolop (TRUTH_ORIF_EXPR
, t
, build_boolop (code
, result
,
1043 boolean_false_node
));
1044 t
= build1 (EXIT_EXPR
, void_type_node
, t
);
1047 /* Do comparison, caching the value.
1048 result = result OP (*t1 == *t2); */
1049 t
= build_struct_comparison (code
, sd
, build_deref (t1
), build_deref (t2
));
1050 t
= build_boolop (tcode
, result
, t
);
1051 t
= modify_expr (result
, t
);
1054 /* Move both pointers to next element position.
1056 tree size
= d_convert (ptrtype
, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype
)));
1057 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, t1
, size
);
1059 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, t2
, size
);
1062 /* Decrease loop counter.
1064 t
= build2 (POSTDECREMENT_EXPR
, lentype
, length
,
1065 d_convert (lentype
, integer_one_node
));
1068 /* Pop statements and finish loop. */
1069 tree body
= pop_stmt_list ();
1070 add_stmt (build1 (LOOP_EXPR
, void_type_node
, body
));
1072 /* Wrap it up into a bind expression. */
1073 tree stmt_list
= pop_stmt_list ();
1074 tree block
= pop_binding_level ();
1076 body
= build3 (BIND_EXPR
, void_type_node
,
1077 BLOCK_VARS (block
), stmt_list
, block
);
1079 return compound_expr (body
, result
);
1082 /* Create an anonymous field of type ubyte[T] at OFFSET to fill
1083 the alignment hole between OFFSET and FIELDPOS. */
1086 build_alignment_field (tree type
, HOST_WIDE_INT offset
, HOST_WIDE_INT fieldpos
)
1088 tree atype
= make_array_type (Type::tuns8
, fieldpos
- offset
);
1089 tree field
= create_field_decl (atype
, NULL
, 1, 1);
1091 SET_DECL_OFFSET_ALIGN (field
, TYPE_ALIGN (atype
));
1092 DECL_FIELD_OFFSET (field
) = size_int (offset
);
1093 DECL_FIELD_BIT_OFFSET (field
) = bitsize_zero_node
;
1094 DECL_FIELD_CONTEXT (field
) = type
;
1095 DECL_PADDING_P (field
) = 1;
1097 layout_decl (field
, 0);
1102 /* Build a constructor for a variable of aggregate type TYPE using the
1103 initializer INIT, an ordered flat list of fields and values provided
1104 by the frontend. The returned constructor should be a value that
1105 matches the layout of TYPE. */
1108 build_struct_literal (tree type
, vec
<constructor_elt
, va_gc
> *init
)
1110 /* If the initializer was empty, use default zero initialization. */
1111 if (vec_safe_is_empty (init
))
1112 return build_constructor (type
, NULL
);
1114 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
1115 HOST_WIDE_INT offset
= 0;
1116 bool constant_p
= true;
1117 bool fillholes
= true;
1118 bool finished
= false;
1120 /* Filling alignment holes this only applies to structs. */
1121 if (TREE_CODE (type
) != RECORD_TYPE
1122 || CLASS_TYPE_P (type
) || TYPE_PACKED (type
))
1125 /* Walk through each field, matching our initializer list. */
1126 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
1128 bool is_initialized
= false;
1131 if (DECL_NAME (field
) == NULL_TREE
1132 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field
))
1133 && ANON_AGGR_TYPE_P (TREE_TYPE (field
)))
1135 /* Search all nesting aggregates, if nothing is found, then
1136 this will return an empty initializer to fill the hole. */
1137 value
= build_struct_literal (TREE_TYPE (field
), init
);
1139 if (!initializer_zerop (value
))
1140 is_initialized
= true;
1144 /* Search for the value to initialize the next field. Once found,
1145 pop it from the init list so we don't look at it again. */
1146 unsigned HOST_WIDE_INT idx
;
1149 FOR_EACH_CONSTRUCTOR_ELT (init
, idx
, index
, value
)
1151 /* If the index is NULL, then just assign it to the next field.
1152 This comes from layout_typeinfo(), which generates a flat
1153 list of values that we must shape into the record type. */
1154 if (index
== field
|| index
== NULL_TREE
)
1156 init
->ordered_remove (idx
);
1158 is_initialized
= true;
1166 HOST_WIDE_INT fieldpos
= int_byte_position (field
);
1167 gcc_assert (value
!= NULL_TREE
);
1169 /* Insert anonymous fields in the constructor for padding out
1170 alignment holes in-place between fields. */
1171 if (fillholes
&& offset
< fieldpos
)
1173 tree pfield
= build_alignment_field (type
, offset
, fieldpos
);
1174 tree pvalue
= build_zero_cst (TREE_TYPE (pfield
));
1175 CONSTRUCTOR_APPEND_ELT (ve
, pfield
, pvalue
);
1178 /* Must not initialize fields that overlap. */
1179 if (fieldpos
< offset
)
1181 /* Find the nearest user defined type and field. */
1183 while (ANON_AGGR_TYPE_P (vtype
))
1184 vtype
= TYPE_CONTEXT (vtype
);
1186 tree vfield
= field
;
1187 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield
))
1188 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield
)))
1189 vfield
= TYPE_FIELDS (TREE_TYPE (vfield
));
1191 /* Must not generate errors for compiler generated fields. */
1192 gcc_assert (TYPE_NAME (vtype
) && DECL_NAME (vfield
));
1193 error ("overlapping initializer for field %qT.%qD",
1194 TYPE_NAME (vtype
), DECL_NAME (vfield
));
1197 if (!TREE_CONSTANT (value
))
1200 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
1202 /* For unions, only the first field is initialized, any other field
1203 initializers found for this union are drained and ignored. */
1204 if (TREE_CODE (type
) == UNION_TYPE
)
1208 /* Move offset to the next position in the struct. */
1209 if (TREE_CODE (type
) == RECORD_TYPE
)
1211 offset
= int_byte_position (field
)
1212 + int_size_in_bytes (TREE_TYPE (field
));
1215 /* If all initializers have been assigned, there's nothing else to do. */
1216 if (vec_safe_is_empty (init
))
1220 /* Finally pad out the end of the record. */
1221 if (fillholes
&& offset
< int_size_in_bytes (type
))
1223 tree pfield
= build_alignment_field (type
, offset
,
1224 int_size_in_bytes (type
));
1225 tree pvalue
= build_zero_cst (TREE_TYPE (pfield
));
1226 CONSTRUCTOR_APPEND_ELT (ve
, pfield
, pvalue
);
1229 /* Ensure that we have consumed all values. */
1230 gcc_assert (vec_safe_is_empty (init
) || ANON_AGGR_TYPE_P (type
));
1232 tree ctor
= build_constructor (type
, ve
);
1235 TREE_CONSTANT (ctor
) = 1;
1240 /* Given the TYPE of an anonymous field inside T, return the
1241 FIELD_DECL for the field. If not found return NULL_TREE.
1242 Because anonymous types can nest, we must also search all
1243 anonymous fields that are directly reachable. */
1246 lookup_anon_field (tree t
, tree type
)
1248 t
= TYPE_MAIN_VARIANT (t
);
1250 for (tree field
= TYPE_FIELDS (t
); field
; field
= DECL_CHAIN (field
))
1252 if (DECL_NAME (field
) == NULL_TREE
)
1254 /* If we find it directly, return the field. */
1255 if (type
== TYPE_MAIN_VARIANT (TREE_TYPE (field
)))
1258 /* Otherwise, it could be nested, search harder. */
1259 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field
))
1260 && ANON_AGGR_TYPE_P (TREE_TYPE (field
)))
1262 tree subfield
= lookup_anon_field (TREE_TYPE (field
), type
);
1272 /* Builds OBJECT.FIELD component reference. */
1275 component_ref (tree object
, tree field
)
1277 if (error_operand_p (object
) || error_operand_p (field
))
1278 return error_mark_node
;
1280 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
1282 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1283 tree init
= stabilize_expr (&object
);
1285 /* If the FIELD is from an anonymous aggregate, generate a reference
1286 to the anonymous data member, and recur to find FIELD. */
1287 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field
)))
1289 tree anonymous_field
= lookup_anon_field (TREE_TYPE (object
),
1290 DECL_CONTEXT (field
));
1291 object
= component_ref (object
, anonymous_field
);
1294 tree result
= fold_build3_loc (input_location
, COMPONENT_REF
,
1295 TREE_TYPE (field
), object
, field
, NULL_TREE
);
1297 return compound_expr (init
, result
);
1300 /* Build an assignment expression of lvalue LHS from value RHS.
1301 CODE is the code for a binary operator that we use to combine
1302 the old value of LHS with RHS to get the new value. */
1305 build_assign (tree_code code
, tree lhs
, tree rhs
)
1307 tree init
= stabilize_expr (&lhs
);
1308 init
= compound_expr (init
, stabilize_expr (&rhs
));
1310 /* If initializing the LHS using a function that returns via NRVO. */
1311 if (code
== INIT_EXPR
&& TREE_CODE (rhs
) == CALL_EXPR
1312 && AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
1313 && aggregate_value_p (TREE_TYPE (rhs
), rhs
))
1315 /* Mark as addressable here, which should ensure the return slot is the
1316 address of the LHS expression, taken care of by back-end. */
1317 d_mark_addressable (lhs
);
1318 CALL_EXPR_RETURN_SLOT_OPT (rhs
) = true;
1321 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1322 if (TREE_CODE (rhs
) == TARGET_EXPR
)
1324 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1325 since that would cause the LHS to be constructed twice.
1326 So we force the TARGET_EXPR to be expanded without a target. */
1327 if (code
!= INIT_EXPR
)
1328 rhs
= compound_expr (rhs
, TARGET_EXPR_SLOT (rhs
));
1331 d_mark_addressable (lhs
);
1332 rhs
= TARGET_EXPR_INITIAL (rhs
);
1336 tree result
= fold_build2_loc (input_location
, code
,
1337 TREE_TYPE (lhs
), lhs
, rhs
);
1338 return compound_expr (init
, result
);
1341 /* Build an assignment expression of lvalue LHS from value RHS. */
1344 modify_expr (tree lhs
, tree rhs
)
1346 return build_assign (MODIFY_EXPR
, lhs
, rhs
);
1349 /* Return EXP represented as TYPE. */
1352 build_nop (tree type
, tree exp
)
1354 if (error_operand_p (exp
))
1357 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1358 tree init
= stabilize_expr (&exp
);
1359 exp
= fold_build1_loc (input_location
, NOP_EXPR
, type
, exp
);
1361 return compound_expr (init
, exp
);
1364 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1365 except that EXP is type-punned, rather than a straight-forward cast. */
1368 build_vconvert (tree type
, tree exp
)
1370 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1371 makes sure this works for vector-to-array viewing, or if EXP ends up being
1372 used as the LHS of a MODIFY_EXPR. */
1373 return indirect_ref (type
, build_address (exp
));
1376 /* Maybe warn about ARG being an address that can never be null. */
1379 warn_for_null_address (tree arg
)
1381 if (TREE_CODE (arg
) == ADDR_EXPR
1382 && decl_with_nonnull_addr_p (TREE_OPERAND (arg
, 0)))
1383 warning (OPT_Waddress
,
1384 "the address of %qD will never be %<null%>",
1385 TREE_OPERAND (arg
, 0));
1388 /* Build a boolean ARG0 op ARG1 expression. */
1391 build_boolop (tree_code code
, tree arg0
, tree arg1
)
1393 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1394 so need to remove all side effects incase its address is taken. */
1395 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0
)))
1396 arg0
= d_save_expr (arg0
);
1397 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1
)))
1398 arg1
= d_save_expr (arg1
);
1400 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)) && VECTOR_TYPE_P (TREE_TYPE (arg1
)))
1402 /* Build a vector comparison.
1403 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1404 tree type
= TREE_TYPE (arg0
);
1405 tree cmptype
= build_same_sized_truth_vector_type (type
);
1406 tree cmp
= fold_build2_loc (input_location
, code
, cmptype
, arg0
, arg1
);
1408 return fold_build3_loc (input_location
, VEC_COND_EXPR
, type
, cmp
,
1409 build_minus_one_cst (type
),
1410 build_zero_cst (type
));
1413 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
1415 /* Check if comparing the address of a variable to null. */
1416 if (POINTER_TYPE_P (TREE_TYPE (arg0
)) && integer_zerop (arg1
))
1417 warn_for_null_address (arg0
);
1418 if (POINTER_TYPE_P (TREE_TYPE (arg1
)) && integer_zerop (arg0
))
1419 warn_for_null_address (arg1
);
1422 return fold_build2_loc (input_location
, code
, d_bool_type
,
1423 arg0
, d_convert (TREE_TYPE (arg0
), arg1
));
1426 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1427 arguments to the conditional expression. */
1430 build_condition (tree type
, tree arg0
, tree arg1
, tree arg2
)
1432 if (arg1
== void_node
)
1433 arg1
= build_empty_stmt (input_location
);
1435 if (arg2
== void_node
)
1436 arg2
= build_empty_stmt (input_location
);
1438 return fold_build3_loc (input_location
, COND_EXPR
,
1439 type
, arg0
, arg1
, arg2
);
1443 build_vcondition (tree arg0
, tree arg1
, tree arg2
)
1445 return build_condition (void_type_node
, arg0
, arg1
, arg2
);
1448 /* Build a compound expr to join ARG0 and ARG1 together. */
1451 compound_expr (tree arg0
, tree arg1
)
1453 if (arg1
== NULL_TREE
)
1456 if (arg0
== NULL_TREE
|| !TREE_SIDE_EFFECTS (arg0
))
1459 if (TREE_CODE (arg1
) == TARGET_EXPR
)
1461 /* If the rhs is a TARGET_EXPR, then build the compound expression
1462 inside the target_expr's initializer. This helps the compiler
1463 to eliminate unnecessary temporaries. */
1464 tree init
= compound_expr (arg0
, TARGET_EXPR_INITIAL (arg1
));
1465 TARGET_EXPR_INITIAL (arg1
) = init
;
1470 return fold_build2_loc (input_location
, COMPOUND_EXPR
,
1471 TREE_TYPE (arg1
), arg0
, arg1
);
1474 /* Build a return expression. */
1477 return_expr (tree ret
)
1479 return fold_build1_loc (input_location
, RETURN_EXPR
,
1480 void_type_node
, ret
);
1483 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1486 size_mult_expr (tree arg0
, tree arg1
)
1488 return fold_build2_loc (input_location
, MULT_EXPR
, size_type_node
,
1489 d_convert (size_type_node
, arg0
),
1490 d_convert (size_type_node
, arg1
));
1494 /* Return the real part of CE, which should be a complex expression. */
1499 return fold_build1_loc (input_location
, REALPART_EXPR
,
1500 TREE_TYPE (TREE_TYPE (ce
)), ce
);
1503 /* Return the imaginary part of CE, which should be a complex expression. */
1506 imaginary_part (tree ce
)
1508 return fold_build1_loc (input_location
, IMAGPART_EXPR
,
1509 TREE_TYPE (TREE_TYPE (ce
)), ce
);
1512 /* Build a complex expression of type TYPE using RE and IM. */
1515 complex_expr (tree type
, tree re
, tree im
)
1517 return fold_build2_loc (input_location
, COMPLEX_EXPR
,
1521 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1522 The back-end requires this cast in many cases. */
1525 indirect_ref (tree type
, tree exp
)
1527 if (error_operand_p (exp
))
1530 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1531 tree init
= stabilize_expr (&exp
);
1533 if (TREE_CODE (TREE_TYPE (exp
)) == REFERENCE_TYPE
)
1534 exp
= fold_build1 (INDIRECT_REF
, type
, exp
);
1537 exp
= build_nop (build_pointer_type (type
), exp
);
1538 exp
= build_deref (exp
);
1541 return compound_expr (init
, exp
);
1544 /* Returns indirect reference of EXP, which must be a pointer type. */
1547 build_deref (tree exp
)
1549 if (error_operand_p (exp
))
1552 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1553 tree init
= stabilize_expr (&exp
);
1555 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp
)));
1557 if (TREE_CODE (exp
) == ADDR_EXPR
)
1558 exp
= TREE_OPERAND (exp
, 0);
1560 exp
= build_fold_indirect_ref (exp
);
1562 return compound_expr (init
, exp
);
1565 /* Builds pointer offset expression PTR[INDEX]. */
1568 build_array_index (tree ptr
, tree index
)
1570 if (error_operand_p (ptr
) || error_operand_p (index
))
1571 return error_mark_node
;
1573 tree ptr_type
= TREE_TYPE (ptr
);
1574 tree target_type
= TREE_TYPE (ptr_type
);
1576 tree type
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (sizetype
),
1577 TYPE_UNSIGNED (sizetype
));
1579 /* Array element size. */
1580 tree size_exp
= size_in_bytes (target_type
);
1582 if (integer_zerop (size_exp
))
1584 /* Test for array of void. */
1585 if (TYPE_MODE (target_type
) == TYPE_MODE (void_type_node
))
1586 index
= fold_convert (type
, index
);
1589 /* Should catch this earlier. */
1590 error ("invalid use of incomplete type %qD", TYPE_NAME (target_type
));
1591 ptr_type
= error_mark_node
;
1594 else if (integer_onep (size_exp
))
1596 /* Array of bytes -- No need to multiply. */
1597 index
= fold_convert (type
, index
);
1601 index
= d_convert (type
, index
);
1602 index
= fold_build2 (MULT_EXPR
, TREE_TYPE (index
),
1603 index
, d_convert (TREE_TYPE (index
), size_exp
));
1604 index
= fold_convert (type
, index
);
1607 if (integer_zerop (index
))
1610 return fold_build2 (POINTER_PLUS_EXPR
, ptr_type
, ptr
, index
);
1613 /* Builds pointer offset expression *(PTR OP OFFSET)
1614 OP could be a plus or minus expression. */
1617 build_offset_op (tree_code op
, tree ptr
, tree offset
)
1619 gcc_assert (op
== MINUS_EXPR
|| op
== PLUS_EXPR
);
1621 tree type
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (sizetype
),
1622 TYPE_UNSIGNED (sizetype
));
1623 offset
= fold_convert (type
, offset
);
1625 if (op
== MINUS_EXPR
)
1626 offset
= fold_build1 (NEGATE_EXPR
, type
, offset
);
1628 return fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ptr
), ptr
, offset
);
1631 /* Builds pointer offset expression *(PTR + OFFSET). */
1634 build_offset (tree ptr
, tree offset
)
1636 return build_offset_op (PLUS_EXPR
, ptr
, offset
);
1640 build_memref (tree type
, tree ptr
, tree offset
)
1642 return fold_build2 (MEM_REF
, type
, ptr
, fold_convert (type
, offset
));
1645 /* Create a tree node to set multiple elements to a single value. */
1648 build_array_set (tree ptr
, tree length
, tree value
)
1650 tree ptrtype
= TREE_TYPE (ptr
);
1651 tree lentype
= TREE_TYPE (length
);
1653 push_binding_level (level_block
);
1656 /* Build temporary locals for length and ptr, and maybe value. */
1657 tree t
= build_local_temp (size_type_node
);
1658 add_stmt (build_assign (INIT_EXPR
, t
, length
));
1661 t
= build_local_temp (ptrtype
);
1662 add_stmt (build_assign (INIT_EXPR
, t
, ptr
));
1665 if (TREE_SIDE_EFFECTS (value
))
1667 t
= build_local_temp (TREE_TYPE (value
));
1668 add_stmt (build_assign (INIT_EXPR
, t
, value
));
1672 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1675 /* Exit logic for the loop.
1676 if (length == 0) break; */
1677 t
= build_boolop (EQ_EXPR
, length
, d_convert (lentype
, integer_zero_node
));
1678 t
= build1 (EXIT_EXPR
, void_type_node
, t
);
1681 /* Assign value to the current pointer position.
1683 t
= modify_expr (build_deref (ptr
), value
);
1686 /* Move pointer to next element position.
1688 tree size
= TYPE_SIZE_UNIT (TREE_TYPE (ptrtype
));
1689 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, ptr
, d_convert (ptrtype
, size
));
1692 /* Decrease loop counter.
1694 t
= build2 (POSTDECREMENT_EXPR
, lentype
, length
,
1695 d_convert (lentype
, integer_one_node
));
1698 /* Pop statements and finish loop. */
1699 tree loop_body
= pop_stmt_list ();
1700 add_stmt (build1 (LOOP_EXPR
, void_type_node
, loop_body
));
1702 /* Wrap it up into a bind expression. */
1703 tree stmt_list
= pop_stmt_list ();
1704 tree block
= pop_binding_level ();
1706 return build3 (BIND_EXPR
, void_type_node
,
1707 BLOCK_VARS (block
), stmt_list
, block
);
1711 /* Build an array of type TYPE where all the elements are VAL. */
1714 build_array_from_val (Type
*type
, tree val
)
1716 gcc_assert (type
->ty
== Tsarray
);
1718 tree etype
= build_ctype (type
->nextOf ());
1720 /* Initializing a multidimensional array. */
1721 if (TREE_CODE (etype
) == ARRAY_TYPE
&& TREE_TYPE (val
) != etype
)
1722 val
= build_array_from_val (type
->nextOf (), val
);
1724 size_t dims
= ((TypeSArray
*) type
)->dim
->toInteger ();
1725 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
1726 vec_safe_reserve (elms
, dims
);
1728 val
= d_convert (etype
, val
);
1730 for (size_t i
= 0; i
< dims
; i
++)
1731 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), val
);
1733 return build_constructor (build_ctype (type
), elms
);
1736 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1739 void_okay_p (tree t
)
1741 tree type
= TREE_TYPE (t
);
1743 if (VOID_TYPE_P (TREE_TYPE (type
)))
1745 tree totype
= build_ctype (Type::tuns8
->pointerTo ());
1746 return fold_convert (totype
, t
);
1752 /* Builds a bounds condition checking that INDEX is between 0 and LEN.
1753 The condition returns the INDEX if true, or throws a RangeError.
1754 If INCLUSIVE, we allow INDEX == LEN to return true also. */
1757 build_bounds_condition (const Loc
& loc
, tree index
, tree len
, bool inclusive
)
1759 if (!array_bounds_check ())
1762 /* Prevent multiple evaluations of the index. */
1763 index
= d_save_expr (index
);
1765 /* Generate INDEX >= LEN && throw RangeError.
1766 No need to check whether INDEX >= 0 as the front-end should
1767 have already taken care of implicit casts to unsigned. */
1768 tree condition
= fold_build2 (inclusive
? GT_EXPR
: GE_EXPR
,
1769 d_bool_type
, index
, len
);
1770 tree boundserr
= d_assert_call (loc
, LIBCALL_ARRAY_BOUNDS
);
1772 return build_condition (TREE_TYPE (index
), condition
, boundserr
, index
);
1775 /* Returns TRUE if array bounds checking code generation is turned on. */
1778 array_bounds_check (void)
1780 FuncDeclaration
*fd
;
1782 switch (global
.params
.useArrayBounds
)
1784 case BOUNDSCHECKoff
:
1790 case BOUNDSCHECKsafeonly
:
1791 /* For D2 safe functions only. */
1792 fd
= d_function_chain
->function
;
1793 if (fd
&& fd
->type
->ty
== Tfunction
)
1795 TypeFunction
*tf
= (TypeFunction
*) fd
->type
;
1796 if (tf
->trust
== TRUSTsafe
)
1806 /* Return an undeclared local temporary of type TYPE
1807 for use with BIND_EXPR. */
1810 create_temporary_var (tree type
)
1812 tree decl
= build_decl (input_location
, VAR_DECL
, NULL_TREE
, type
);
1814 DECL_CONTEXT (decl
) = current_function_decl
;
1815 DECL_ARTIFICIAL (decl
) = 1;
1816 DECL_IGNORED_P (decl
) = 1;
1817 layout_decl (decl
, 0);
1822 /* Return an undeclared local temporary OUT_VAR initialized
1823 with result of expression EXP. */
1826 maybe_temporary_var (tree exp
, tree
*out_var
)
1830 /* Get the base component. */
1831 while (TREE_CODE (t
) == COMPONENT_REF
)
1832 t
= TREE_OPERAND (t
, 0);
1834 if (!DECL_P (t
) && !REFERENCE_CLASS_P (t
))
1836 *out_var
= create_temporary_var (TREE_TYPE (exp
));
1837 DECL_INITIAL (*out_var
) = exp
;
1842 *out_var
= NULL_TREE
;
1847 /* Builds a BIND_EXPR around BODY for the variables VAR_CHAIN. */
1850 bind_expr (tree var_chain
, tree body
)
1852 /* Only handles one var. */
1853 gcc_assert (TREE_CHAIN (var_chain
) == NULL_TREE
);
1855 if (DECL_INITIAL (var_chain
))
1857 tree ini
= build_assign (INIT_EXPR
, var_chain
, DECL_INITIAL (var_chain
));
1858 DECL_INITIAL (var_chain
) = NULL_TREE
;
1859 body
= compound_expr (ini
, body
);
1862 return d_save_expr (build3 (BIND_EXPR
, TREE_TYPE (body
),
1863 var_chain
, body
, NULL_TREE
));
1866 /* Returns the TypeFunction class for Type T.
1867 Assumes T is already ->toBasetype(). */
1870 get_function_type (Type
*t
)
1872 TypeFunction
*tf
= NULL
;
1873 if (t
->ty
== Tpointer
)
1874 t
= t
->nextOf ()->toBasetype ();
1875 if (t
->ty
== Tfunction
)
1876 tf
= (TypeFunction
*) t
;
1877 else if (t
->ty
== Tdelegate
)
1878 tf
= (TypeFunction
*) ((TypeDelegate
*) t
)->next
;
1882 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
1883 CALLER. In which case, CALLEE is being called through an alias that was
1884 passed to CALLER. */
1887 call_by_alias_p (FuncDeclaration
*caller
, FuncDeclaration
*callee
)
1889 if (!callee
->isNested ())
1892 if (caller
->toParent () == callee
->toParent ())
1895 Dsymbol
*dsym
= callee
;
1899 if (dsym
->isTemplateInstance ())
1901 else if (dsym
->isFuncDeclaration () == caller
)
1903 dsym
= dsym
->toParent ();
1909 /* Entry point for call routines. Builds a function call to FD.
1910 OBJECT is the 'this' reference passed and ARGS are the arguments to FD. */
1913 d_build_call_expr (FuncDeclaration
*fd
, tree object
, Expressions
*arguments
)
1915 return d_build_call (get_function_type (fd
->type
),
1916 build_address (get_symbol_decl (fd
)), object
, arguments
);
1919 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the 'this' pointer,
1920 ARGUMENTS are evaluated in left to right order, saved and promoted
1924 d_build_call (TypeFunction
*tf
, tree callable
, tree object
,
1925 Expressions
*arguments
)
1927 tree ctype
= TREE_TYPE (callable
);
1928 tree callee
= callable
;
1930 if (POINTER_TYPE_P (ctype
))
1931 ctype
= TREE_TYPE (ctype
);
1933 callee
= build_address (callable
);
1935 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype
));
1936 gcc_assert (tf
!= NULL
);
1937 gcc_assert (tf
->ty
== Tfunction
);
1939 if (TREE_CODE (ctype
) != FUNCTION_TYPE
&& object
== NULL_TREE
)
1941 /* Front-end apparently doesn't check this. */
1942 if (TREE_CODE (callable
) == FUNCTION_DECL
)
1944 error ("need %<this%> to access member %qE", DECL_NAME (callable
));
1945 return error_mark_node
;
1948 /* Probably an internal error. */
1952 /* Build the argument list for the call. */
1953 vec
<tree
, va_gc
> *args
= NULL
;
1954 tree saved_args
= NULL_TREE
;
1956 /* If this is a delegate call or a nested function being called as
1957 a delegate, the object should not be NULL. */
1958 if (object
!= NULL_TREE
)
1959 vec_safe_push (args
, object
);
1963 /* First pass, evaluated expanded tuples in function arguments. */
1964 for (size_t i
= 0; i
< arguments
->dim
; ++i
)
1967 Expression
*arg
= (*arguments
)[i
];
1968 gcc_assert (arg
->op
!= TOKtuple
);
1970 if (arg
->op
== TOKcomma
)
1972 CommaExp
*ce
= (CommaExp
*) arg
;
1973 tree tce
= build_expr (ce
->e1
);
1974 saved_args
= compound_expr (saved_args
, tce
);
1975 (*arguments
)[i
] = ce
->e2
;
1980 size_t nparams
= Parameter::dim (tf
->parameters
);
1981 /* if _arguments[] is the first argument. */
1982 size_t varargs
= (tf
->linkage
== LINKd
&& tf
->varargs
== 1);
1984 /* Assumes arguments->dim <= formal_args->dim if (!tf->varargs). */
1985 for (size_t i
= 0; i
< arguments
->dim
; ++i
)
1987 Expression
*arg
= (*arguments
)[i
];
1988 tree targ
= build_expr (arg
);
1990 if (i
- varargs
< nparams
&& i
>= varargs
)
1992 /* Actual arguments for declared formal arguments. */
1993 Parameter
*parg
= Parameter::getNth (tf
->parameters
, i
- varargs
);
1994 targ
= convert_for_argument (targ
, parg
);
1997 /* Don't pass empty aggregates by value. */
1998 if (empty_aggregate_p (TREE_TYPE (targ
)) && !TREE_ADDRESSABLE (targ
)
1999 && TREE_CODE (targ
) != CONSTRUCTOR
)
2001 tree t
= build_constructor (TREE_TYPE (targ
), NULL
);
2002 targ
= build2 (COMPOUND_EXPR
, TREE_TYPE (t
), targ
, t
);
2005 vec_safe_push (args
, targ
);
2009 /* Evaluate the callee before calling it. */
2010 if (TREE_SIDE_EFFECTS (callee
))
2012 callee
= d_save_expr (callee
);
2013 saved_args
= compound_expr (callee
, saved_args
);
2016 tree result
= build_call_vec (TREE_TYPE (ctype
), callee
, args
);
2018 /* Enforce left to right evaluation. */
2019 if (tf
->linkage
== LINKd
)
2020 CALL_EXPR_ARGS_ORDERED (result
) = 1;
2022 result
= maybe_expand_intrinsic (result
);
2024 /* Return the value in a temporary slot so that it can be evaluated
2025 multiple times by the caller. */
2026 if (TREE_CODE (result
) == CALL_EXPR
2027 && AGGREGATE_TYPE_P (TREE_TYPE (result
))
2028 && TREE_ADDRESSABLE (TREE_TYPE (result
)))
2030 CALL_EXPR_RETURN_SLOT_OPT (result
) = true;
2031 result
= force_target_expr (result
);
2034 return compound_expr (saved_args
, result
);
2037 /* Builds a call to AssertError or AssertErrorMsg. */
2040 d_assert_call (const Loc
& loc
, libcall_fn libcall
, tree msg
)
2043 tree line
= size_int (loc
.linnum
);
2045 /* File location is passed as a D string. */
2048 unsigned len
= strlen (loc
.filename
);
2049 tree str
= build_string (len
, loc
.filename
);
2050 TREE_TYPE (str
) = make_array_type (Type::tchar
, len
);
2052 file
= d_array_value (build_ctype (Type::tchar
->arrayOf ()),
2053 size_int (len
), build_address (str
));
2056 file
= null_array_node
;
2059 return build_libcall (libcall
, Type::tvoid
, 3, msg
, file
, line
);
2061 return build_libcall (libcall
, Type::tvoid
, 2, file
, line
);
2064 /* Build and return the correct call to fmod depending on TYPE.
2065 ARG0 and ARG1 are the arguments pass to the function. */
2068 build_float_modulus (tree type
, tree arg0
, tree arg1
)
2070 tree fmodfn
= NULL_TREE
;
2071 tree basetype
= type
;
2073 if (COMPLEX_FLOAT_TYPE_P (basetype
))
2074 basetype
= TREE_TYPE (basetype
);
2076 if (TYPE_MAIN_VARIANT (basetype
) == double_type_node
2077 || TYPE_MAIN_VARIANT (basetype
) == idouble_type_node
)
2078 fmodfn
= builtin_decl_explicit (BUILT_IN_FMOD
);
2079 else if (TYPE_MAIN_VARIANT (basetype
) == float_type_node
2080 || TYPE_MAIN_VARIANT (basetype
) == ifloat_type_node
)
2081 fmodfn
= builtin_decl_explicit (BUILT_IN_FMODF
);
2082 else if (TYPE_MAIN_VARIANT (basetype
) == long_double_type_node
2083 || TYPE_MAIN_VARIANT (basetype
) == ireal_type_node
)
2084 fmodfn
= builtin_decl_explicit (BUILT_IN_FMODL
);
2088 error ("tried to perform floating-point modulo division on %qT", type
);
2089 return error_mark_node
;
2092 if (COMPLEX_FLOAT_TYPE_P (type
))
2094 tree re
= build_call_expr (fmodfn
, 2, real_part (arg0
), arg1
);
2095 tree im
= build_call_expr (fmodfn
, 2, imaginary_part (arg0
), arg1
);
2097 return complex_expr (type
, re
, im
);
2100 if (SCALAR_FLOAT_TYPE_P (type
))
2101 return build_call_expr (fmodfn
, 2, arg0
, arg1
);
2103 /* Should have caught this above. */
2107 /* Build a function type whose first argument is a pointer to BASETYPE,
2108 which is to be used for the 'vthis' context parameter for TYPE.
2109 The base type may be a record for member functions, or a void for
2110 nested functions and delegates. */
2113 build_vthis_function (tree basetype
, tree type
)
2115 gcc_assert (TREE_CODE (type
) == FUNCTION_TYPE
);
2117 tree argtypes
= tree_cons (NULL_TREE
, build_pointer_type (basetype
),
2118 TYPE_ARG_TYPES (type
));
2119 tree fntype
= build_function_type (TREE_TYPE (type
), argtypes
);
2121 if (RECORD_OR_UNION_TYPE_P (basetype
))
2122 TYPE_METHOD_BASETYPE (fntype
) = TYPE_MAIN_VARIANT (basetype
);
2124 gcc_assert (VOID_TYPE_P (basetype
));
2129 /* If SYM is a nested function, return the static chain to be
2130 used when calling that function from the current function.
2132 If SYM is a nested class or struct, return the static chain
2133 to be used when creating an instance of the class from CFUN. */
2136 get_frame_for_symbol (Dsymbol
*sym
)
2138 FuncDeclaration
*thisfd
2139 = d_function_chain
? d_function_chain
->function
: NULL
;
2140 FuncDeclaration
*fd
= sym
->isFuncDeclaration ();
2141 FuncDeclaration
*fdparent
= NULL
;
2142 FuncDeclaration
*fdoverride
= NULL
;
2146 /* Check that the nested function is properly defined. */
2149 /* Should instead error on line that references 'fd'. */
2150 error_at (make_location_t (fd
->loc
), "nested function missing body");
2151 return null_pointer_node
;
2154 fdparent
= fd
->toParent2 ()->isFuncDeclaration ();
2156 /* Special case for __ensure and __require. */
2157 if ((fd
->ident
== Identifier::idPool ("__ensure")
2158 || fd
->ident
== Identifier::idPool ("__require"))
2159 && fdparent
!= thisfd
)
2161 fdoverride
= fdparent
;
2167 /* It's a class (or struct). NewExp codegen has already determined its
2168 outer scope is not another class, so it must be a function. */
2169 while (sym
&& !sym
->isFuncDeclaration ())
2170 sym
= sym
->toParent2 ();
2172 fdparent
= (FuncDeclaration
*) sym
;
2175 /* Not a nested function, there is no frame pointer to pass. */
2176 if (fdparent
== NULL
)
2178 /* Only delegate literals report as being nested, even if they are in
2180 gcc_assert (fd
&& fd
->isFuncLiteralDeclaration ());
2181 return null_pointer_node
;
2184 gcc_assert (thisfd
!= NULL
);
2186 if (thisfd
!= fdparent
)
2188 /* If no frame pointer for this function. */
2191 error_at (make_location_t (sym
->loc
),
2192 "%qs is a nested function and cannot be accessed from %qs",
2193 fd
->toPrettyChars (), thisfd
->toPrettyChars ());
2194 return null_pointer_node
;
2197 /* Make sure we can get the frame pointer to the outer function.
2198 Go up each nesting level until we find the enclosing function. */
2199 Dsymbol
*dsym
= thisfd
;
2203 /* Check if enclosing function is a function. */
2204 FuncDeclaration
*fd
= dsym
->isFuncDeclaration ();
2208 if (fdparent
== fd
->toParent2 ())
2211 gcc_assert (fd
->isNested () || fd
->vthis
);
2212 dsym
= dsym
->toParent2 ();
2216 /* Check if enclosed by an aggregate. That means the current
2217 function must be a member function of that aggregate. */
2218 AggregateDeclaration
*ad
= dsym
->isAggregateDeclaration ();
2222 if (ad
->isClassDeclaration () && fdparent
== ad
->toParent2 ())
2224 if (ad
->isStructDeclaration () && fdparent
== ad
->toParent2 ())
2227 if (!ad
->isNested () || !ad
->vthis
)
2230 error_at (make_location_t (thisfd
->loc
),
2231 "cannot get frame pointer to %qs",
2232 sym
->toPrettyChars ());
2233 return null_pointer_node
;
2236 dsym
= dsym
->toParent2 ();
2240 tree ffo
= get_frameinfo (fdparent
);
2241 if (FRAMEINFO_CREATES_FRAME (ffo
) || FRAMEINFO_STATIC_CHAIN (ffo
))
2243 tree frame_ref
= get_framedecl (thisfd
, fdparent
);
2245 /* If 'thisfd' is a derived member function, then 'fdparent' is the
2246 overridden member function in the base class. Even if there's a
2247 closure environment, we should give the original stack data as the
2248 nested function frame. */
2251 ClassDeclaration
*cdo
= fdoverride
->isThis ()->isClassDeclaration ();
2252 ClassDeclaration
*cd
= thisfd
->isThis ()->isClassDeclaration ();
2253 gcc_assert (cdo
&& cd
);
2256 if (cdo
->isBaseOf (cd
, &offset
) && offset
!= 0)
2258 /* Generate a new frame to pass to the overriden function that
2259 has the 'this' pointer adjusted. */
2260 gcc_assert (offset
!= OFFSET_RUNTIME
);
2262 tree type
= FRAMEINFO_TYPE (get_frameinfo (fdoverride
));
2263 tree fields
= TYPE_FIELDS (type
);
2264 /* The 'this' field comes immediately after the '__chain'. */
2265 tree thisfield
= chain_index (1, fields
);
2266 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
2268 tree framefields
= TYPE_FIELDS (FRAMEINFO_TYPE (ffo
));
2269 frame_ref
= build_deref (frame_ref
);
2271 for (tree field
= fields
; field
; field
= DECL_CHAIN (field
))
2273 tree value
= component_ref (frame_ref
, framefields
);
2274 if (field
== thisfield
)
2275 value
= build_offset (value
, size_int (offset
));
2277 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
2278 framefields
= DECL_CHAIN (framefields
);
2281 frame_ref
= build_address (build_constructor (type
, ve
));
2288 return null_pointer_node
;
2291 /* Return the parent function of a nested class CD. */
2293 static FuncDeclaration
*
2294 d_nested_class (ClassDeclaration
*cd
)
2296 FuncDeclaration
*fd
= NULL
;
2297 while (cd
&& cd
->isNested ())
2299 Dsymbol
*dsym
= cd
->toParent2 ();
2300 if ((fd
= dsym
->isFuncDeclaration ()))
2303 cd
= dsym
->isClassDeclaration ();
2308 /* Return the parent function of a nested struct SD. */
2310 static FuncDeclaration
*
2311 d_nested_struct (StructDeclaration
*sd
)
2313 FuncDeclaration
*fd
= NULL
;
2314 while (sd
&& sd
->isNested ())
2316 Dsymbol
*dsym
= sd
->toParent2 ();
2317 if ((fd
= dsym
->isFuncDeclaration ()))
2320 sd
= dsym
->isStructDeclaration ();
2326 /* Starting from the current function FD, try to find a suitable value of
2327 'this' in nested function instances. A suitable 'this' value is an
2328 instance of OCD or a class that has OCD as a base. */
2331 find_this_tree (ClassDeclaration
*ocd
)
2333 FuncDeclaration
*fd
= d_function_chain
? d_function_chain
->function
: NULL
;
2337 AggregateDeclaration
*ad
= fd
->isThis ();
2338 ClassDeclaration
*cd
= ad
? ad
->isClassDeclaration () : NULL
;
2343 return get_decl_tree (fd
->vthis
);
2344 else if (ocd
->isBaseOf (cd
, NULL
))
2345 return convert_expr (get_decl_tree (fd
->vthis
),
2346 cd
->type
, ocd
->type
);
2348 fd
= d_nested_class (cd
);
2352 if (fd
->isNested ())
2354 fd
= fd
->toParent2 ()->isFuncDeclaration ();
2365 /* Retrieve the outer class/struct 'this' value of DECL from
2366 the current function. */
2369 build_vthis (AggregateDeclaration
*decl
)
2371 ClassDeclaration
*cd
= decl
->isClassDeclaration ();
2372 StructDeclaration
*sd
= decl
->isStructDeclaration ();
2374 /* If an aggregate nested in a function has no methods and there are no
2375 other nested functions, any static chain created here will never be
2376 translated. Use a null pointer for the link in this case. */
2377 tree vthis_value
= null_pointer_node
;
2379 if (cd
!= NULL
|| sd
!= NULL
)
2381 Dsymbol
*outer
= decl
->toParent2 ();
2383 /* If the parent is a templated struct, the outer context is instead
2384 the enclosing symbol of where the instantiation happened. */
2385 if (outer
->isStructDeclaration ())
2387 gcc_assert (outer
->parent
&& outer
->parent
->isTemplateInstance ());
2388 outer
= ((TemplateInstance
*) outer
->parent
)->enclosing
;
2391 /* For outer classes, get a suitable 'this' value.
2392 For outer functions, get a suitable frame/closure pointer. */
2393 ClassDeclaration
*cdo
= outer
->isClassDeclaration ();
2394 FuncDeclaration
*fdo
= outer
->isFuncDeclaration ();
2398 vthis_value
= find_this_tree (cdo
);
2399 gcc_assert (vthis_value
!= NULL_TREE
);
2403 tree ffo
= get_frameinfo (fdo
);
2404 if (FRAMEINFO_CREATES_FRAME (ffo
) || FRAMEINFO_STATIC_CHAIN (ffo
)
2405 || fdo
->hasNestedFrameRefs ())
2406 vthis_value
= get_frame_for_symbol (decl
);
2407 else if (cd
!= NULL
)
2409 /* Classes nested in methods are allowed to access any outer
2410 class fields, use the function chain in this case. */
2411 if (fdo
->vthis
&& fdo
->vthis
->type
!= Type::tvoidptr
)
2412 vthis_value
= get_decl_tree (fdo
->vthis
);
2422 /* Build the RECORD_TYPE that describes the function frame or closure type for
2423 the function FD. FFI is the tree holding all frame information. */
2426 build_frame_type (tree ffi
, FuncDeclaration
*fd
)
2428 if (FRAMEINFO_TYPE (ffi
))
2429 return FRAMEINFO_TYPE (ffi
);
2431 tree frame_rec_type
= make_node (RECORD_TYPE
);
2432 char *name
= concat (FRAMEINFO_IS_CLOSURE (ffi
) ? "CLOSURE." : "FRAME.",
2433 fd
->toPrettyChars (), NULL
);
2434 TYPE_NAME (frame_rec_type
) = get_identifier (name
);
2437 tree fields
= NULL_TREE
;
2439 /* Function is a member or nested, so must have field for outer context. */
2442 tree ptr_field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
2443 get_identifier ("__chain"), ptr_type_node
);
2444 DECL_FIELD_CONTEXT (ptr_field
) = frame_rec_type
;
2445 fields
= chainon (NULL_TREE
, ptr_field
);
2446 DECL_NONADDRESSABLE_P (ptr_field
) = 1;
2449 /* The __ensure and __require are called directly, so never make the outer
2450 functions closure, but nevertheless could still be referencing parameters
2451 of the calling function non-locally. So we add all parameters with nested
2452 refs to the function frame, this should also mean overriding methods will
2453 have the same frame layout when inheriting a contract. */
2454 if ((global
.params
.useIn
&& fd
->frequire
)
2455 || (global
.params
.useOut
&& fd
->fensure
))
2459 for (size_t i
= 0; fd
->parameters
&& i
< fd
->parameters
->dim
; i
++)
2461 VarDeclaration
*v
= (*fd
->parameters
)[i
];
2462 /* Remove if already in closureVars so can push to front. */
2463 for (size_t j
= i
; j
< fd
->closureVars
.dim
; j
++)
2465 Dsymbol
*s
= fd
->closureVars
[j
];
2468 fd
->closureVars
.remove (j
);
2472 fd
->closureVars
.insert (i
, v
);
2476 /* Also add hidden 'this' to outer context. */
2479 for (size_t i
= 0; i
< fd
->closureVars
.dim
; i
++)
2481 Dsymbol
*s
= fd
->closureVars
[i
];
2484 fd
->closureVars
.remove (i
);
2488 fd
->closureVars
.insert (0, fd
->vthis
);
2492 for (size_t i
= 0; i
< fd
->closureVars
.dim
; i
++)
2494 VarDeclaration
*v
= fd
->closureVars
[i
];
2495 tree vsym
= get_symbol_decl (v
);
2496 tree ident
= v
->ident
2497 ? get_identifier (v
->ident
->toChars ()) : NULL_TREE
;
2499 tree field
= build_decl (make_location_t (v
->loc
), FIELD_DECL
, ident
,
2501 SET_DECL_LANG_FRAME_FIELD (vsym
, field
);
2502 DECL_FIELD_CONTEXT (field
) = frame_rec_type
;
2503 fields
= chainon (fields
, field
);
2504 TREE_USED (vsym
) = 1;
2506 TREE_ADDRESSABLE (field
) = TREE_ADDRESSABLE (vsym
);
2507 DECL_NONADDRESSABLE_P (field
) = !TREE_ADDRESSABLE (vsym
);
2508 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (vsym
);
2510 /* Can't do nrvo if the variable is put in a frame. */
2511 if (fd
->nrvo_can
&& fd
->nrvo_var
== v
)
2514 if (FRAMEINFO_IS_CLOSURE (ffi
))
2516 /* Because the value needs to survive the end of the scope. */
2517 if ((v
->edtor
&& (v
->storage_class
& STCparameter
))
2518 || v
->needsScopeDtor ())
2519 error_at (make_location_t (v
->loc
),
2520 "has scoped destruction, cannot build closure");
2524 TYPE_FIELDS (frame_rec_type
) = fields
;
2525 TYPE_READONLY (frame_rec_type
) = 1;
2526 layout_type (frame_rec_type
);
2527 d_keep (frame_rec_type
);
2529 return frame_rec_type
;
2532 /* Closures are implemented by taking the local variables that
2533 need to survive the scope of the function, and copying them
2534 into a GC allocated chuck of memory. That chunk, called the
2535 closure here, is inserted into the linked list of stack
2536 frames instead of the usual stack frame.
2538 If a closure is not required, but FD still needs a frame to lower
2539 nested refs, then instead build custom static chain decl on stack. */
2542 build_closure (FuncDeclaration
*fd
)
2544 tree ffi
= get_frameinfo (fd
);
2546 if (!FRAMEINFO_CREATES_FRAME (ffi
))
2549 tree type
= FRAMEINFO_TYPE (ffi
);
2550 gcc_assert (COMPLETE_TYPE_P (type
));
2552 tree decl
, decl_ref
;
2554 if (FRAMEINFO_IS_CLOSURE (ffi
))
2556 decl
= build_local_temp (build_pointer_type (type
));
2557 DECL_NAME (decl
) = get_identifier ("__closptr");
2558 decl_ref
= build_deref (decl
);
2560 /* Allocate memory for closure. */
2561 tree arg
= convert (build_ctype (Type::tsize_t
), TYPE_SIZE_UNIT (type
));
2562 tree init
= build_libcall (LIBCALL_ALLOCMEMORY
, Type::tvoidptr
, 1, arg
);
2564 tree init_exp
= build_assign (INIT_EXPR
, decl
,
2565 build_nop (TREE_TYPE (decl
), init
));
2566 add_stmt (init_exp
);
2570 decl
= build_local_temp (type
);
2571 DECL_NAME (decl
) = get_identifier ("__frame");
2575 /* Set the first entry to the parent closure/frame, if any. */
2578 tree chain_field
= component_ref (decl_ref
, TYPE_FIELDS (type
));
2579 tree chain_expr
= modify_expr (chain_field
,
2580 d_function_chain
->static_chain
);
2581 add_stmt (chain_expr
);
2584 /* Copy parameters that are referenced nonlocally. */
2585 for (size_t i
= 0; i
< fd
->closureVars
.dim
; i
++)
2587 VarDeclaration
*v
= fd
->closureVars
[i
];
2589 if (!v
->isParameter ())
2592 tree vsym
= get_symbol_decl (v
);
2594 tree field
= component_ref (decl_ref
, DECL_LANG_FRAME_FIELD (vsym
));
2595 tree expr
= modify_expr (field
, vsym
);
2599 if (!FRAMEINFO_IS_CLOSURE (ffi
))
2600 decl
= build_address (decl
);
2602 d_function_chain
->static_chain
= decl
;
2605 /* Return the frame of FD. This could be a static chain or a closure
2606 passed via the hidden 'this' pointer. */
2609 get_frameinfo (FuncDeclaration
*fd
)
2611 tree fds
= get_symbol_decl (fd
);
2612 if (DECL_LANG_FRAMEINFO (fds
))
2613 return DECL_LANG_FRAMEINFO (fds
);
2615 tree ffi
= make_node (FUNCFRAME_INFO
);
2617 DECL_LANG_FRAMEINFO (fds
) = ffi
;
2619 if (fd
->needsClosure ())
2621 /* Set-up a closure frame, this will be allocated on the heap. */
2622 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2623 FRAMEINFO_IS_CLOSURE (ffi
) = 1;
2625 else if (fd
->hasNestedFrameRefs ())
2627 /* Functions with nested refs must create a static frame for local
2628 variables to be referenced from. */
2629 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2633 /* For nested functions, default to creating a frame. Even if there are
2634 no fields to populate the frame, create it anyway, as this will be
2635 used as the record type instead of `void*` for the this parameter. */
2636 if (fd
->vthis
&& fd
->vthis
->type
== Type::tvoidptr
)
2637 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2639 /* In checkNestedReference, references from contracts are not added to the
2640 closureVars array, so assume all parameters referenced. */
2641 if ((global
.params
.useIn
&& fd
->frequire
)
2642 || (global
.params
.useOut
&& fd
->fensure
))
2643 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2645 /* If however `fd` is nested (deeply) in a function that creates a
2646 closure, then `fd` instead inherits that closure via hidden vthis
2647 pointer, and doesn't create a stack frame at all. */
2648 FuncDeclaration
*ff
= fd
;
2652 tree ffo
= get_frameinfo (ff
);
2654 if (ff
!= fd
&& FRAMEINFO_CREATES_FRAME (ffo
))
2656 gcc_assert (FRAMEINFO_TYPE (ffo
));
2657 FRAMEINFO_CREATES_FRAME (ffi
) = 0;
2658 FRAMEINFO_STATIC_CHAIN (ffi
) = 1;
2659 FRAMEINFO_IS_CLOSURE (ffi
) = FRAMEINFO_IS_CLOSURE (ffo
);
2660 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo
)));
2661 FRAMEINFO_TYPE (ffi
) = FRAMEINFO_TYPE (ffo
);
2665 /* Stop looking if no frame pointer for this function. */
2666 if (ff
->vthis
== NULL
)
2669 AggregateDeclaration
*ad
= ff
->isThis ();
2670 if (ad
&& ad
->isNested ())
2672 while (ad
->isNested ())
2674 Dsymbol
*d
= ad
->toParent2 ();
2675 ad
= d
->isAggregateDeclaration ();
2676 ff
= d
->isFuncDeclaration ();
2683 ff
= ff
->toParent2 ()->isFuncDeclaration ();
2687 /* Build type now as may be referenced from another module. */
2688 if (FRAMEINFO_CREATES_FRAME (ffi
))
2689 FRAMEINFO_TYPE (ffi
) = build_frame_type (ffi
, fd
);
2694 /* Return a pointer to the frame/closure block of OUTER
2695 so can be accessed from the function INNER. */
2698 get_framedecl (FuncDeclaration
*inner
, FuncDeclaration
*outer
)
2700 tree result
= d_function_chain
->static_chain
;
2701 FuncDeclaration
*fd
= inner
;
2703 while (fd
&& fd
!= outer
)
2705 AggregateDeclaration
*ad
;
2706 ClassDeclaration
*cd
;
2707 StructDeclaration
*sd
;
2709 /* Parent frame link is the first field. */
2710 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd
)))
2711 result
= indirect_ref (ptr_type_node
, result
);
2713 if (fd
->isNested ())
2714 fd
= fd
->toParent2 ()->isFuncDeclaration ();
2715 /* The frame/closure record always points to the outer function's
2716 frame, even if there are intervening nested classes or structs.
2717 So, we can just skip over these. */
2718 else if ((ad
= fd
->isThis ()) && (cd
= ad
->isClassDeclaration ()))
2719 fd
= d_nested_class (cd
);
2720 else if ((ad
= fd
->isThis ()) && (sd
= ad
->isStructDeclaration ()))
2721 fd
= d_nested_struct (sd
);
2726 /* Go get our frame record. */
2727 gcc_assert (fd
== outer
);
2728 tree frame_type
= FRAMEINFO_TYPE (get_frameinfo (outer
));
2730 if (frame_type
!= NULL_TREE
)
2732 result
= build_nop (build_pointer_type (frame_type
), result
);
2737 error_at (make_location_t (inner
->loc
),
2738 "forward reference to frame of %qs", outer
->toChars ());
2739 return null_pointer_node
;