1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
2 Copyright (C) 2006-2023 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/module.h"
27 #include "dmd/target.h"
28 #include "dmd/template.h"
31 #include "tree-iterator.h"
32 #include "fold-const.h"
33 #include "diagnostic.h"
34 #include "langhooks.h"
36 #include "stringpool.h"
38 #include "stor-layout.h"
41 #include "gimple-expr.h"
46 /* Return the GCC location for the D frontend location LOC. */
49 make_location_t (const Loc
&loc
)
51 location_t gcc_location
= input_location
;
55 linemap_add (line_table
, LC_ENTER
, 0, loc
.filename
, loc
.linnum
);
56 linemap_line_start (line_table
, loc
.linnum
, 0);
57 gcc_location
= linemap_position_for_column (line_table
, loc
.charnum
);
58 linemap_add (line_table
, LC_LEAVE
, 0, NULL
, 0);
64 /* Return the DECL_CONTEXT for symbol DSYM. */
67 d_decl_context (Dsymbol
*dsym
)
69 Dsymbol
*parent
= dsym
;
70 Declaration
*decl
= dsym
->isDeclaration ();
71 AggregateDeclaration
*ad
= dsym
->isAggregateDeclaration ();
73 while ((parent
= parent
->toParent2 ()))
75 /* We've reached the top-level module namespace.
76 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,
77 but only for extern(D) symbols. */
78 if (parent
->isModule ())
80 if ((decl
!= NULL
&& decl
->resolvedLinkage () != LINK::d
)
81 || (ad
!= NULL
&& ad
->classKind
!= ClassKind::d
))
84 return build_import_decl (parent
);
87 /* Declarations marked as `static' or `__gshared' are never
88 part of any context except at module level. */
89 if (decl
!= NULL
&& decl
->isDataseg ())
92 /* Nested functions. */
93 FuncDeclaration
*fd
= parent
->isFuncDeclaration ();
95 return get_symbol_decl (fd
);
97 /* Methods of classes or structs. */
98 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration ();
101 tree context
= build_ctype (ad
->type
);
102 /* Want the underlying RECORD_TYPE. */
103 if (ad
->isClassDeclaration ())
104 context
= TREE_TYPE (context
);
113 /* Return a copy of record TYPE but safe to modify in any way. */
116 copy_aggregate_type (tree type
)
118 tree newtype
= build_distinct_type_copy (type
);
119 TYPE_STUB_DECL (newtype
) = TYPE_NAME (newtype
);
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
== 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
,
151 VARARGnone
, LINK::d
);
152 TypeDelegate
*t
= TypeDelegate::create (tf
);
153 return build_ctype (t
->merge2 ());
156 /* Static array va_list have array->pointer conversions applied. */
157 if (decl
->isParameter () && valist_array_p (decl
->type
))
159 Type
*valist
= decl
->type
->nextOf ()->pointerTo ();
160 valist
= valist
->castMod (decl
->type
->mod
);
161 return build_ctype (valist
);
164 tree type
= build_ctype (decl
->type
);
166 /* Parameter is passed by reference. */
167 if (declaration_reference_p (decl
))
168 return build_reference_type (type
);
170 /* The `this' parameter is always const. */
171 if (decl
->isThisDeclaration ())
172 return insert_type_modifiers (type
, MODconst
);
177 /* These should match the Declaration versions above
178 Return TRUE if parameter ARG is a reference type. */
181 parameter_reference_p (Parameter
*arg
)
183 Type
*tb
= arg
->type
->toBasetype ();
185 /* Parameter is a reference type. */
186 if (tb
->ty
== TY::Treference
|| arg
->storageClass
& (STCout
| STCref
))
192 /* Returns the real type for parameter ARG. */
195 parameter_type (Parameter
*arg
)
197 /* Lazy parameters are converted to delegates. */
198 if (arg
->storageClass
& STClazy
)
200 TypeFunction
*tf
= TypeFunction::create (NULL
, arg
->type
,
201 VARARGnone
, LINK::d
);
202 TypeDelegate
*t
= TypeDelegate::create (tf
);
203 return build_ctype (t
->merge2 ());
206 /* Static array va_list have array->pointer conversions applied. */
207 if (valist_array_p (arg
->type
))
209 Type
*valist
= arg
->type
->nextOf ()->pointerTo ();
210 valist
= valist
->castMod (arg
->type
->mod
);
211 return build_ctype (valist
);
214 tree type
= build_ctype (arg
->type
);
216 /* Parameter is passed by reference. */
217 if (parameter_reference_p (arg
))
218 return build_reference_type (type
);
220 /* Pass non-POD structs by invisible reference. */
221 if (TREE_ADDRESSABLE (type
))
223 type
= build_reference_type (type
);
224 /* There are no other pointer to this temporary. */
225 type
= build_qualified_type (type
, TYPE_QUAL_RESTRICT
);
228 /* Front-end has already taken care of type promotions. */
232 /* Build INTEGER_CST of type TYPE with the value VALUE. */
235 build_integer_cst (dinteger_t value
, tree type
)
237 /* The type is error_mark_node, we can't do anything. */
238 if (error_operand_p (type
))
241 return build_int_cst_type (type
, value
);
244 /* Build REAL_CST of type TOTYPE with the value VALUE. */
247 build_float_cst (const real_t
&value
, Type
*totype
)
250 TypeBasic
*tb
= totype
->isTypeBasic ();
252 gcc_assert (tb
!= NULL
);
254 tree type_node
= build_ctype (tb
);
255 real_convert (&new_value
.rv (), TYPE_MODE (type_node
), &value
.rv ());
257 return build_real (type_node
, new_value
.rv ());
260 /* Returns the .length component from the D dynamic array EXP. */
263 d_array_length (tree exp
)
265 if (error_operand_p (exp
))
268 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp
)));
270 /* Get the back-end type for the array and pick out the array
271 length field (assumed to be the first field). */
272 tree len_field
= TYPE_FIELDS (TREE_TYPE (exp
));
273 return component_ref (exp
, len_field
);
276 /* Returns the .ptr component from the D dynamic array EXP. */
279 d_array_ptr (tree exp
)
281 if (error_operand_p (exp
))
284 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp
)));
286 /* Get the back-end type for the array and pick out the array
287 data pointer field (assumed to be the second field). */
288 tree ptr_field
= TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp
)));
289 return component_ref (exp
, ptr_field
);
292 /* Returns a constructor for D dynamic array type TYPE of .length LEN
293 and .ptr pointing to DATA. */
296 d_array_value (tree type
, tree len
, tree data
)
298 tree len_field
, ptr_field
;
299 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
301 gcc_assert (TYPE_DYNAMIC_ARRAY (type
));
302 len_field
= TYPE_FIELDS (type
);
303 ptr_field
= TREE_CHAIN (len_field
);
305 len
= convert (TREE_TYPE (len_field
), len
);
306 data
= convert (TREE_TYPE (ptr_field
), data
);
308 CONSTRUCTOR_APPEND_ELT (ce
, len_field
, len
);
309 CONSTRUCTOR_APPEND_ELT (ce
, ptr_field
, data
);
311 return build_constructor (type
, ce
);
314 /* Returns value representing the array length of expression EXP.
315 TYPE could be a dynamic or static array. */
318 get_array_length (tree exp
, Type
*type
)
320 Type
*tb
= type
->toBasetype ();
325 return size_int (tb
->isTypeSArray ()->dim
->toUInteger ());
328 return d_array_length (exp
);
331 error ("cannot determine the length of a %qs", type
->toChars ());
332 return error_mark_node
;
336 /* Create BINFO for a ClassDeclaration's inheritance tree.
337 InterfaceDeclaration's are not included. */
340 build_class_binfo (tree super
, ClassDeclaration
*cd
)
342 tree binfo
= make_tree_binfo (1);
343 tree ctype
= build_ctype (cd
->type
);
345 /* Want RECORD_TYPE, not POINTER_TYPE. */
346 BINFO_TYPE (binfo
) = TREE_TYPE (ctype
);
347 BINFO_INHERITANCE_CHAIN (binfo
) = super
;
348 BINFO_OFFSET (binfo
) = integer_zero_node
;
351 BINFO_BASE_APPEND (binfo
, build_class_binfo (binfo
, cd
->baseClass
));
356 /* Create BINFO for an InterfaceDeclaration's inheritance tree.
357 In order to access all inherited methods in the debugger,
358 the entire tree must be described.
359 This function makes assumptions about interface layout. */
362 build_interface_binfo (tree super
, ClassDeclaration
*cd
, unsigned &offset
)
364 tree binfo
= make_tree_binfo (cd
->baseclasses
->length
);
365 tree ctype
= build_ctype (cd
->type
);
367 /* Want RECORD_TYPE, not POINTER_TYPE. */
368 BINFO_TYPE (binfo
) = TREE_TYPE (ctype
);
369 BINFO_INHERITANCE_CHAIN (binfo
) = super
;
370 BINFO_OFFSET (binfo
) = size_int (offset
* target
.ptrsize
);
371 BINFO_VIRTUAL_P (binfo
) = 1;
373 for (size_t i
= 0; i
< cd
->baseclasses
->length
; i
++, offset
++)
375 BaseClass
*bc
= (*cd
->baseclasses
)[i
];
376 BINFO_BASE_APPEND (binfo
, build_interface_binfo (binfo
, bc
->sym
, offset
));
382 /* Returns the .funcptr component from the D delegate EXP. */
385 delegate_method (tree exp
)
387 /* Get the back-end type for the delegate and pick out the funcptr field
388 (assumed to be the second field). */
389 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp
)));
390 tree method_field
= TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp
)));
391 return component_ref (exp
, method_field
);
394 /* Returns the .object component from the delegate EXP. */
397 delegate_object (tree exp
)
399 /* Get the back-end type for the delegate and pick out the object field
400 (assumed to be the first field). */
401 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp
)));
402 tree obj_field
= TYPE_FIELDS (TREE_TYPE (exp
));
403 return component_ref (exp
, obj_field
);
406 /* Build a delegate literal of type TYPE whose pointer function is
407 METHOD, and hidden object is OBJECT. */
410 build_delegate_cst (tree method
, tree object
, Type
*type
)
412 tree ctor
= make_node (CONSTRUCTOR
);
415 Type
*tb
= type
->toBasetype ();
416 if (tb
->ty
== TY::Tdelegate
)
417 ctype
= build_ctype (type
);
420 /* Convert a function method into an anonymous delegate. */
421 ctype
= make_struct_type ("delegate()", 2,
422 get_identifier ("ptr"), TREE_TYPE (object
),
423 get_identifier ("funcptr"), TREE_TYPE (method
));
424 TYPE_DELEGATE (ctype
) = 1;
427 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
428 CONSTRUCTOR_APPEND_ELT (ce
, TYPE_FIELDS (ctype
), object
);
429 CONSTRUCTOR_APPEND_ELT (ce
, TREE_CHAIN (TYPE_FIELDS (ctype
)), method
);
431 CONSTRUCTOR_ELTS (ctor
) = ce
;
432 TREE_TYPE (ctor
) = ctype
;
437 /* Builds a temporary tree to store the CALLEE and OBJECT
438 of a method call expression of type TYPE. */
441 build_method_call (tree callee
, tree object
, Type
*type
)
443 tree t
= build_delegate_cst (callee
, object
, type
);
444 METHOD_CALL_EXPR (t
) = 1;
448 /* Extract callee and object from T and return in to CALLEE and OBJECT. */
451 extract_from_method_call (tree t
, tree
&callee
, tree
&object
)
453 gcc_assert (METHOD_CALL_EXPR (t
));
454 object
= CONSTRUCTOR_ELT (t
, 0)->value
;
455 callee
= CONSTRUCTOR_ELT (t
, 1)->value
;
458 /* Build a typeof(null) constant of type TYPE. Handles certain special case
459 conversions, where the underlying type is an aggregate with a nullable
463 build_typeof_null_value (Type
*type
)
465 Type
*tb
= type
->toBasetype ();
468 /* For dynamic arrays, set length and pointer fields to zero. */
469 if (tb
->ty
== TY::Tarray
)
470 value
= d_array_value (build_ctype (type
), size_int (0), null_pointer_node
);
472 /* For associative arrays, set the pointer field to null. */
473 else if (tb
->ty
== TY::Taarray
)
475 tree ctype
= build_ctype (type
);
476 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype
));
478 value
= build_constructor_single (ctype
, TYPE_FIELDS (ctype
),
482 /* For delegates, set the frame and function pointer fields to null. */
483 else if (tb
->ty
== TY::Tdelegate
)
484 value
= build_delegate_cst (null_pointer_node
, null_pointer_node
, type
);
486 /* Simple zero constant for all other types. */
488 value
= build_zero_cst (build_ctype (type
));
490 TREE_CONSTANT (value
) = 1;
494 /* Build a dereference into the virtual table for OBJECT to retrieve
495 a function pointer of type FNTYPE at position INDEX. */
498 build_vindex_ref (tree object
, tree fntype
, size_t index
)
500 /* The vtable is the first field. Interface methods are also in the class's
501 vtable, so we don't need to convert from a class to an interface. */
502 tree result
= build_deref (object
);
503 result
= component_ref (result
, TYPE_FIELDS (TREE_TYPE (result
)));
505 gcc_assert (POINTER_TYPE_P (fntype
));
507 return build_memref (fntype
, result
, size_int (target
.ptrsize
* index
));
510 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
511 made into temporaries, otherwise any assignments will be lost. */
516 const enum tree_code code
= TREE_CODE (exp
);
528 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp
));
534 return lvalue_p (TREE_OPERAND (exp
, 0));
537 return (lvalue_p (TREE_OPERAND (exp
, 1)
538 ? TREE_OPERAND (exp
, 1)
539 : TREE_OPERAND (exp
, 0))
540 && lvalue_p (TREE_OPERAND (exp
, 2)));
546 return lvalue_p (TREE_OPERAND (exp
, 1));
553 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
554 more than once in an expression. */
557 d_save_expr (tree exp
)
559 if (TREE_SIDE_EFFECTS (exp
))
562 return stabilize_reference (exp
);
564 return save_expr (exp
);
570 /* VALUEP is an expression we want to pre-evaluate or perform a computation on.
571 The expression returned by this function is the part whose value we don't
572 care about, storing the value in VALUEP. Callers must ensure that the
573 returned expression is evaluated before VALUEP. */
576 stabilize_expr (tree
*valuep
)
579 const enum tree_code code
= TREE_CODE (expr
);
586 /* Given ((e1, ...), eN):
587 Store the last RHS 'eN' expression in VALUEP. */
588 lhs
= TREE_OPERAND (expr
, 0);
589 rhs
= TREE_OPERAND (expr
, 1);
590 lhs
= compound_expr (lhs
, stabilize_expr (&rhs
));
599 /* Return a TARGET_EXPR, initializing the DECL with EXP. */
602 build_target_expr (tree decl
, tree exp
)
604 tree type
= TREE_TYPE (decl
);
605 tree result
= build4 (TARGET_EXPR
, type
, decl
, exp
, NULL_TREE
, NULL_TREE
);
607 if (EXPR_HAS_LOCATION (exp
))
608 SET_EXPR_LOCATION (result
, EXPR_LOCATION (exp
));
610 /* If decl must always reside in memory. */
611 if (TREE_ADDRESSABLE (type
))
612 d_mark_addressable (decl
);
614 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
615 TARGET_EXPR. If there really turn out to be no side effects, then the
616 optimizer should be able to remove it. */
617 TREE_SIDE_EFFECTS (result
) = 1;
622 /* Like the above function, but initializes a new temporary. */
625 force_target_expr (tree exp
)
627 tree decl
= create_tmp_var_raw (TREE_TYPE (exp
));
628 DECL_CONTEXT (decl
) = current_function_decl
;
629 layout_decl (decl
, 0);
631 return build_target_expr (decl
, exp
);
634 /* Returns the address of the expression EXP. */
637 build_address (tree exp
)
639 if (error_operand_p (exp
))
643 tree type
= TREE_TYPE (exp
);
645 if (TREE_CODE (exp
) == STRING_CST
)
647 /* Just convert string literals (char[]) to C-style strings (char *),
648 otherwise the latter method (char[]*) causes conversion problems
649 during gimplification. */
650 ptrtype
= build_pointer_type (TREE_TYPE (type
));
652 else if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
)
653 && TREE_CODE (TYPE_MAIN_VARIANT (type
)) == ARRAY_TYPE
)
655 /* Special case for va_list, allow arrays to decay to a pointer. */
656 ptrtype
= build_pointer_type (TREE_TYPE (type
));
659 ptrtype
= build_pointer_type (type
);
661 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
662 tree init
= stabilize_expr (&exp
);
664 /* Can't take the address of a manifest constant, instead use its value. */
665 if (TREE_CODE (exp
) == CONST_DECL
)
666 exp
= DECL_INITIAL (exp
);
668 /* Some expression lowering may request an address of a compile-time constant,
669 or other non-lvalue expression. Make sure it is assigned to a location we
671 if (CONSTANT_CLASS_P (exp
) && TREE_CODE (exp
) != STRING_CST
)
672 exp
= force_target_expr (exp
);
673 else if (TREE_CODE (exp
) == CALL_EXPR
)
675 /* When a struct or array is returned in registers, we need to again fill
676 in all alignment holes. */
677 if (AGGREGATE_TYPE_P (TREE_TYPE (exp
))
678 && !aggregate_value_p (TREE_TYPE (exp
), exp
))
680 tree tmp
= build_local_temp (TREE_TYPE (exp
));
681 init
= compound_expr (init
, build_memset_call (tmp
));
682 init
= compound_expr (init
, modify_expr (tmp
, exp
));
686 exp
= force_target_expr (exp
);
689 d_mark_addressable (exp
);
690 exp
= build_fold_addr_expr_with_type_loc (input_location
, exp
, ptrtype
);
692 if (TREE_CODE (exp
) == ADDR_EXPR
)
693 TREE_NO_TRAMPOLINE (exp
) = 1;
695 return compound_expr (init
, exp
);
698 /* Mark EXP saying that we need to be able to take the address of it; it should
699 not be allocated in a register. When COMPLAIN is true, issue an error if we
700 are marking a register variable. */
703 d_mark_addressable (tree exp
, bool complain
)
705 switch (TREE_CODE (exp
))
712 d_mark_addressable (TREE_OPERAND (exp
, 0));
716 if (complain
&& DECL_REGISTER (exp
))
718 if (DECL_HARD_REGISTER (exp
) || DECL_EXTERNAL (exp
))
719 error ("address of explicit register variable %qD requested", exp
);
721 error ("address of register variable %qD requested", exp
);
729 if (!VAR_P (exp
) || !DECL_HARD_REGISTER (exp
))
730 TREE_ADDRESSABLE (exp
) = 1;
734 TREE_ADDRESSABLE (exp
) = 1;
738 TREE_ADDRESSABLE (exp
) = 1;
739 d_mark_addressable (TREE_OPERAND (exp
, 0));
749 /* Mark EXP as "used" in the program for the benefit of
750 -Wunused warning purposes. */
753 d_mark_used (tree exp
)
755 switch (TREE_CODE (exp
))
773 d_mark_used (TREE_OPERAND (exp
, 0));
777 d_mark_used (TREE_OPERAND (exp
, 0));
778 d_mark_used (TREE_OPERAND (exp
, 1));
787 /* Mark EXP as read, not just set, for set but not used -Wunused
791 d_mark_read (tree exp
)
793 switch (TREE_CODE (exp
))
798 DECL_READ_P (exp
) = 1;
809 d_mark_read (TREE_OPERAND (exp
, 0));
813 d_mark_read (TREE_OPERAND (exp
, 1));
822 /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */
825 build_memcmp_call (tree ptr1
, tree ptr2
, tree num
)
827 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP
), 3,
831 /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */
834 build_memcpy_call (tree dst
, tree src
, tree num
)
836 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY
), 3,
840 /* Build a call to memset(), fills the first NUM bytes of PTR with zeros.
841 If NUM is NULL, then we expect PTR to be object that requires filling. */
844 build_memset_call (tree ptr
, tree num
)
846 if (num
== NULL_TREE
)
848 gcc_assert (TREE_CODE (ptr
) != ADDR_EXPR
);
849 num
= TYPE_SIZE_UNIT (TREE_TYPE (ptr
));
850 ptr
= build_address (ptr
);
853 /* Use a zero constant to fill the destination if setting the entire object.
854 For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
855 which can then be merged with other stores to the object. */
856 tree valtype
= TREE_TYPE (TREE_TYPE (ptr
));
857 if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype
), num
))
859 tree cst
= build_zero_cst (valtype
);
860 if (TREE_CODE (cst
) == CONSTRUCTOR
)
861 return build_memcpy_call (ptr
, build_address (cst
), num
);
863 return modify_expr (build_deref (ptr
), cst
);
866 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET
), 3,
867 ptr
, integer_zero_node
, num
);
870 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
871 This is because we don't guarantee that padding is zero-initialized for
872 a stack variable, so we can't use memcmp to compare struct values. */
875 identity_compare_p (StructDeclaration
*sd
)
877 if (sd
->isUnionDeclaration ())
882 for (size_t i
= 0; i
< sd
->fields
.length
; i
++)
884 VarDeclaration
*vd
= sd
->fields
[i
];
885 Type
*tb
= vd
->type
->toBasetype ();
887 /* Check inner data structures. */
888 if (TypeStruct
*ts
= tb
->isTypeStruct ())
890 if (!identity_compare_p (ts
->sym
))
894 /* Check for types that may have padding. */
895 if ((tb
->ty
== TY::Tcomplex80
896 || tb
->ty
== TY::Tfloat80
897 || tb
->ty
== TY::Timaginary80
)
898 && target
.realpad
!= 0)
901 if (offset
<= vd
->offset
)
903 /* There's a hole in the struct. */
904 if (offset
!= vd
->offset
)
907 offset
+= vd
->type
->size ();
911 /* Any trailing padding may not be zero. */
912 if (offset
< sd
->structsize
)
918 /* Build a floating-point identity comparison between T1 and T2, ignoring any
919 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
922 build_float_identity (tree_code code
, tree t1
, tree t2
)
924 tree size
= size_int (TYPE_PRECISION (TREE_TYPE (t1
)) / BITS_PER_UNIT
);
925 tree result
= build_memcmp_call (build_address (t1
),
926 build_address (t2
), size
);
927 return build_boolop (code
, result
, integer_zero_node
);
930 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
931 CODE is the EQ_EXPR or NE_EXPR comparison. */
934 lower_struct_comparison (tree_code code
, StructDeclaration
*sd
,
937 tree_code tcode
= (code
== EQ_EXPR
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
938 tree tmemcmp
= NULL_TREE
;
940 /* We can skip the compare if the structs are empty. */
941 if (sd
->fields
.length
== 0)
943 tmemcmp
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
944 if (TREE_SIDE_EFFECTS (t2
))
945 tmemcmp
= compound_expr (t2
, tmemcmp
);
946 if (TREE_SIDE_EFFECTS (t1
))
947 tmemcmp
= compound_expr (t1
, tmemcmp
);
952 /* Let back-end take care of union comparisons. */
953 if (sd
->isUnionDeclaration ())
955 tmemcmp
= build_memcmp_call (build_address (t1
), build_address (t2
),
956 size_int (sd
->structsize
));
957 return build_boolop (code
, tmemcmp
, integer_zero_node
);
960 for (size_t i
= 0; i
< sd
->fields
.length
; i
++)
962 VarDeclaration
*vd
= sd
->fields
[i
];
963 Type
*type
= vd
->type
->toBasetype ();
964 tree sfield
= get_symbol_decl (vd
);
966 tree t1ref
= component_ref (t1
, sfield
);
967 tree t2ref
= component_ref (t2
, sfield
);
970 if (TypeStruct
*ts
= type
->isTypeStruct ())
972 /* Compare inner data structures. */
973 tcmp
= lower_struct_comparison (code
, ts
->sym
, t1ref
, t2ref
);
975 else if (type
->ty
!= TY::Tvector
&& type
->isintegral ())
977 /* Integer comparison, no special handling required. */
978 tcmp
= build_boolop (code
, t1ref
, t2ref
);
980 else if (type
->ty
!= TY::Tvector
&& type
->isfloating ())
982 /* Floating-point comparison, don't compare padding in type. */
983 if (!type
->iscomplex ())
984 tcmp
= build_float_identity (code
, t1ref
, t2ref
);
987 tree req
= build_float_identity (code
, real_part (t1ref
),
989 tree ieq
= build_float_identity (code
, imaginary_part (t1ref
),
990 imaginary_part (t2ref
));
992 tcmp
= build_boolop (tcode
, req
, ieq
);
997 tree stype
= build_ctype (type
);
998 opt_scalar_int_mode mode
= int_mode_for_mode (TYPE_MODE (stype
));
1002 /* Compare field bits as their corresponding integer type.
1003 *((T*) &t1) == *((T*) &t2) */
1004 tree tmode
= lang_hooks
.types
.type_for_mode (mode
.require (), 1);
1006 if (tmode
== NULL_TREE
)
1007 tmode
= make_unsigned_type (GET_MODE_BITSIZE (mode
.require ()));
1009 t1ref
= build_vconvert (tmode
, t1ref
);
1010 t2ref
= build_vconvert (tmode
, t2ref
);
1012 tcmp
= build_boolop (code
, t1ref
, t2ref
);
1016 /* Simple memcmp between types. */
1017 tcmp
= build_memcmp_call (build_address (t1ref
),
1018 build_address (t2ref
),
1019 TYPE_SIZE_UNIT (stype
));
1020 tcmp
= build_boolop (code
, tcmp
, integer_zero_node
);
1024 tmemcmp
= (tmemcmp
) ? build_boolop (tcode
, tmemcmp
, tcmp
) : tcmp
;
1031 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
1032 If possible, use memcmp, otherwise field-by-field comparison is done.
1033 CODE is the EQ_EXPR or NE_EXPR comparison. */
1036 build_struct_comparison (tree_code code
, StructDeclaration
*sd
,
1039 /* We can skip the compare if the structs are empty. */
1040 if (sd
->fields
.length
== 0)
1042 tree exp
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
1043 if (TREE_SIDE_EFFECTS (t2
))
1044 exp
= compound_expr (t2
, exp
);
1045 if (TREE_SIDE_EFFECTS (t1
))
1046 exp
= compound_expr (t1
, exp
);
1051 /* Make temporaries to prevent multiple evaluations. */
1052 tree t1init
= stabilize_expr (&t1
);
1053 tree t2init
= stabilize_expr (&t2
);
1056 t1
= d_save_expr (t1
);
1057 t2
= d_save_expr (t2
);
1059 /* Bitwise comparison of structs not returned in memory may not work
1060 due to data holes loosing its zero padding upon return.
1061 As a heuristic, small structs are not compared using memcmp either. */
1062 if (TYPE_MODE (TREE_TYPE (t1
)) != BLKmode
|| !identity_compare_p (sd
))
1063 result
= lower_struct_comparison (code
, sd
, t1
, t2
);
1066 /* Do bit compare of structs. */
1067 tree tmemcmp
= build_memcmp_call (build_address (t1
), build_address (t2
),
1068 size_int (sd
->structsize
));
1069 result
= build_boolop (code
, tmemcmp
, integer_zero_node
);
1072 return compound_expr (compound_expr (t1init
, t2init
), result
);
1075 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1076 The pointer references are T1 and T2, and the element type is SD.
1077 CODE is the EQ_EXPR or NE_EXPR comparison. */
1080 build_array_struct_comparison (tree_code code
, StructDeclaration
*sd
,
1081 tree length
, tree t1
, tree t2
)
1083 tree_code tcode
= (code
== EQ_EXPR
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
1085 /* Build temporary for the result of the comparison.
1086 Initialize as either 0 or 1 depending on operation. */
1087 tree result
= build_local_temp (d_bool_type
);
1088 tree init
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
1089 add_stmt (build_assign (INIT_EXPR
, result
, init
));
1091 /* Cast pointer-to-array to pointer-to-struct. */
1092 tree ptrtype
= build_ctype (sd
->type
->pointerTo ());
1093 tree lentype
= TREE_TYPE (length
);
1095 push_binding_level (level_block
);
1098 /* Build temporary locals for length and pointers. */
1099 tree t
= build_local_temp (size_type_node
);
1100 add_stmt (build_assign (INIT_EXPR
, t
, length
));
1103 t
= build_local_temp (ptrtype
);
1104 add_stmt (build_assign (INIT_EXPR
, t
, d_convert (ptrtype
, t1
)));
1107 t
= build_local_temp (ptrtype
);
1108 add_stmt (build_assign (INIT_EXPR
, t
, d_convert (ptrtype
, t2
)));
1111 /* Build loop for comparing each element. */
1114 /* Exit logic for the loop.
1115 if (length == 0 || result OP 0) break; */
1116 t
= build_boolop (EQ_EXPR
, length
, d_convert (lentype
, integer_zero_node
));
1117 t
= build_boolop (TRUTH_ORIF_EXPR
, t
, build_boolop (code
, result
,
1118 boolean_false_node
));
1119 t
= build1 (EXIT_EXPR
, void_type_node
, t
);
1122 /* Do comparison, caching the value.
1123 result = result OP (*t1 == *t2); */
1124 t
= build_struct_comparison (code
, sd
, build_deref (t1
), build_deref (t2
));
1125 t
= build_boolop (tcode
, result
, t
);
1126 t
= modify_expr (result
, t
);
1129 /* Move both pointers to next element position.
1131 tree size
= d_convert (ptrtype
, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype
)));
1132 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, t1
, size
);
1134 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, t2
, size
);
1137 /* Decrease loop counter.
1139 t
= build2 (POSTDECREMENT_EXPR
, lentype
, length
,
1140 d_convert (lentype
, integer_one_node
));
1143 /* Pop statements and finish loop. */
1144 tree body
= pop_stmt_list ();
1145 add_stmt (build1 (LOOP_EXPR
, void_type_node
, body
));
1147 /* Wrap it up into a bind expression. */
1148 tree stmt_list
= pop_stmt_list ();
1149 tree block
= pop_binding_level ();
1151 body
= build3 (BIND_EXPR
, void_type_node
,
1152 BLOCK_VARS (block
), stmt_list
, block
);
1154 return compound_expr (body
, result
);
1157 /* Build a constructor for a variable of aggregate type TYPE using the
1158 initializer INIT, an ordered flat list of fields and values provided
1159 by the frontend. The returned constructor should be a value that
1160 matches the layout of TYPE. */
1163 build_struct_literal (tree type
, vec
<constructor_elt
, va_gc
> *init
)
1165 /* If the initializer was empty, use default zero initialization. */
1166 if (vec_safe_is_empty (init
))
1167 return build_constructor (type
, NULL
);
1169 /* Struct literals can be seen for special enums representing `_Complex',
1170 make sure to reinterpret the literal as the correct type. */
1171 if (COMPLEX_FLOAT_TYPE_P (type
))
1173 gcc_assert (vec_safe_length (init
) == 2);
1174 return complex_expr (type
, (*init
)[0].value
, (*init
)[1].value
);
1177 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
1178 HOST_WIDE_INT bitoffset
= 0;
1179 bool constant_p
= true;
1180 bool finished
= false;
1182 /* Walk through each field, matching our initializer list. */
1183 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
1185 bool is_initialized
= false;
1188 if (DECL_NAME (field
) == NULL_TREE
1189 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field
))
1190 && ANON_AGGR_TYPE_P (TREE_TYPE (field
)))
1192 /* Search all nesting aggregates, if nothing is found, then
1193 this will return an empty initializer to fill the hole. */
1194 value
= build_struct_literal (TREE_TYPE (field
), init
);
1196 if (!initializer_zerop (value
))
1197 is_initialized
= true;
1201 /* Search for the value to initialize the next field. Once found,
1202 pop it from the init list so we don't look at it again. */
1203 unsigned HOST_WIDE_INT idx
;
1206 FOR_EACH_CONSTRUCTOR_ELT (init
, idx
, index
, value
)
1208 /* If the index is NULL, then just assign it to the next field.
1209 This comes from layout_typeinfo(), which generates a flat
1210 list of values that we must shape into the record type. */
1211 if (index
== field
|| index
== NULL_TREE
)
1213 init
->ordered_remove (idx
);
1215 is_initialized
= true;
1223 HOST_WIDE_INT fieldpos
= int_bit_position (field
);
1224 gcc_assert (value
!= NULL_TREE
);
1226 /* Must not initialize fields that overlap. */
1227 if (fieldpos
< bitoffset
)
1229 /* Find the nearest user defined type and field. */
1231 while (ANON_AGGR_TYPE_P (vtype
))
1232 vtype
= TYPE_CONTEXT (vtype
);
1234 tree vfield
= field
;
1235 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield
))
1236 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield
)))
1237 vfield
= TYPE_FIELDS (TREE_TYPE (vfield
));
1239 /* Must not generate errors for compiler generated fields. */
1240 gcc_assert (TYPE_NAME (vtype
) && DECL_NAME (vfield
));
1241 error ("overlapping initializer for field %qT.%qD",
1242 TYPE_NAME (vtype
), DECL_NAME (vfield
));
1245 if (!TREE_CONSTANT (value
))
1248 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
1250 /* For unions, only the first field is initialized, any other field
1251 initializers found for this union are drained and ignored. */
1252 if (TREE_CODE (type
) == UNION_TYPE
)
1256 /* Move bit offset to the next position in the struct. */
1257 if (TREE_CODE (type
) == RECORD_TYPE
&& DECL_SIZE (field
))
1258 bitoffset
= int_bit_position (field
) + tree_to_shwi (DECL_SIZE (field
));
1260 /* If all initializers have been assigned, there's nothing else to do. */
1261 if (vec_safe_is_empty (init
))
1265 /* Ensure that we have consumed all values. */
1266 gcc_assert (vec_safe_is_empty (init
) || ANON_AGGR_TYPE_P (type
));
1268 tree ctor
= build_constructor (type
, ve
);
1271 TREE_CONSTANT (ctor
) = 1;
1276 /* Given the TYPE of an anonymous field inside T, return the
1277 FIELD_DECL for the field. If not found return NULL_TREE.
1278 Because anonymous types can nest, we must also search all
1279 anonymous fields that are directly reachable. */
1282 lookup_anon_field (tree t
, tree type
)
1284 t
= TYPE_MAIN_VARIANT (t
);
1286 for (tree field
= TYPE_FIELDS (t
); field
; field
= DECL_CHAIN (field
))
1288 if (DECL_NAME (field
) == NULL_TREE
)
1290 /* If we find it directly, return the field. */
1291 if (type
== TYPE_MAIN_VARIANT (TREE_TYPE (field
)))
1294 /* Otherwise, it could be nested, search harder. */
1295 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field
))
1296 && ANON_AGGR_TYPE_P (TREE_TYPE (field
)))
1298 tree subfield
= lookup_anon_field (TREE_TYPE (field
), type
);
1308 /* Builds OBJECT.FIELD component reference. */
1311 component_ref (tree object
, tree field
)
1313 if (error_operand_p (object
) || error_operand_p (field
))
1314 return error_mark_node
;
1316 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
1318 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1319 tree init
= stabilize_expr (&object
);
1321 /* If the FIELD is from an anonymous aggregate, generate a reference
1322 to the anonymous data member, and recur to find FIELD. */
1323 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field
)))
1325 tree anonymous_field
= lookup_anon_field (TREE_TYPE (object
),
1326 DECL_CONTEXT (field
));
1327 object
= component_ref (object
, anonymous_field
);
1330 tree result
= fold_build3_loc (input_location
, COMPONENT_REF
,
1331 TREE_TYPE (field
), object
, field
, NULL_TREE
);
1333 return compound_expr (init
, result
);
1336 /* Build an assignment expression of lvalue LHS from value RHS.
1337 CODE is the code for a binary operator that we use to combine
1338 the old value of LHS with RHS to get the new value. */
1341 build_assign (tree_code code
, tree lhs
, tree rhs
)
1344 tree init
= stabilize_expr (&lhs
);
1345 init
= compound_expr (init
, stabilize_expr (&rhs
));
1347 /* If initializing the LHS using a function that returns via NRVO. */
1348 if (code
== INIT_EXPR
&& TREE_CODE (rhs
) == CALL_EXPR
1349 && AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
1350 && aggregate_value_p (TREE_TYPE (rhs
), rhs
))
1352 /* Mark as addressable here, which should ensure the return slot is the
1353 address of the LHS expression, taken care of by back-end. */
1354 d_mark_addressable (lhs
);
1355 CALL_EXPR_RETURN_SLOT_OPT (rhs
) = true;
1357 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
1358 else if (code
== MODIFY_EXPR
&& TREE_ADDRESSABLE (TREE_TYPE (lhs
))
1359 && TREE_SIDE_EFFECTS (rhs
) && TREE_CODE (rhs
) != TARGET_EXPR
)
1361 /* LHS may be referenced by the RHS expression, so force a temporary. */
1362 rhs
= force_target_expr (rhs
);
1365 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1366 if (TREE_CODE (rhs
) == TARGET_EXPR
)
1368 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1369 since that would cause the LHS to be constructed twice. */
1370 if (code
!= INIT_EXPR
)
1372 init
= compound_expr (init
, rhs
);
1373 result
= build_assign (code
, lhs
, TARGET_EXPR_SLOT (rhs
));
1377 d_mark_addressable (lhs
);
1378 TARGET_EXPR_INITIAL (rhs
) = build_assign (code
, lhs
,
1379 TARGET_EXPR_INITIAL (rhs
));
1385 /* Simple assignment. */
1386 result
= fold_build2_loc (input_location
, code
,
1387 TREE_TYPE (lhs
), lhs
, rhs
);
1390 return compound_expr (init
, result
);
1393 /* Build an assignment expression of lvalue LHS from value RHS. */
1396 modify_expr (tree lhs
, tree rhs
)
1398 return build_assign (MODIFY_EXPR
, lhs
, rhs
);
1401 /* Return EXP represented as TYPE. */
1404 build_nop (tree type
, tree exp
)
1406 if (error_operand_p (exp
))
1409 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1410 tree init
= stabilize_expr (&exp
);
1411 exp
= fold_build1_loc (input_location
, NOP_EXPR
, type
, exp
);
1413 return compound_expr (init
, exp
);
1416 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1417 except that EXP is type-punned, rather than a straight-forward cast. */
1420 build_vconvert (tree type
, tree exp
)
1422 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1423 makes sure this works for vector-to-array viewing, or if EXP ends up being
1424 used as the LHS of a MODIFY_EXPR. */
1425 return indirect_ref (type
, build_address (exp
));
1428 /* Maybe warn about ARG being an address that can never be null. */
1431 warn_for_null_address (tree arg
)
1433 if (TREE_CODE (arg
) == ADDR_EXPR
1434 && decl_with_nonnull_addr_p (TREE_OPERAND (arg
, 0)))
1435 warning (OPT_Waddress
,
1436 "the address of %qD will never be %<null%>",
1437 TREE_OPERAND (arg
, 0));
1440 /* Build a boolean ARG0 op ARG1 expression. */
1443 build_boolop (tree_code code
, tree arg0
, tree arg1
)
1445 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1446 so need to remove all side effects incase its address is taken. */
1447 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0
)))
1448 arg0
= d_save_expr (arg0
);
1449 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1
)))
1450 arg1
= d_save_expr (arg1
);
1452 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)) && VECTOR_TYPE_P (TREE_TYPE (arg1
)))
1454 /* Build a vector comparison.
1455 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1456 tree type
= TREE_TYPE (arg0
);
1457 tree cmptype
= truth_type_for (type
);
1458 tree cmp
= fold_build2_loc (input_location
, code
, cmptype
, arg0
, arg1
);
1460 return fold_build3_loc (input_location
, VEC_COND_EXPR
, type
, cmp
,
1461 build_minus_one_cst (type
),
1462 build_zero_cst (type
));
1465 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
1467 /* Check if comparing the address of a variable to null. */
1468 if (POINTER_TYPE_P (TREE_TYPE (arg0
)) && integer_zerop (arg1
))
1469 warn_for_null_address (arg0
);
1470 if (POINTER_TYPE_P (TREE_TYPE (arg1
)) && integer_zerop (arg0
))
1471 warn_for_null_address (arg1
);
1474 return fold_build2_loc (input_location
, code
, d_bool_type
,
1475 arg0
, d_convert (TREE_TYPE (arg0
), arg1
));
1478 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1479 arguments to the conditional expression. */
1482 build_condition (tree type
, tree arg0
, tree arg1
, tree arg2
)
1484 if (arg1
== void_node
)
1485 arg1
= build_empty_stmt (input_location
);
1487 if (arg2
== void_node
)
1488 arg2
= build_empty_stmt (input_location
);
1490 return fold_build3_loc (input_location
, COND_EXPR
,
1491 type
, arg0
, arg1
, arg2
);
1495 build_vcondition (tree arg0
, tree arg1
, tree arg2
)
1497 return build_condition (void_type_node
, arg0
, arg1
, arg2
);
1500 /* Build a compound expr to join ARG0 and ARG1 together. */
1503 compound_expr (tree arg0
, tree arg1
)
1505 if (arg1
== NULL_TREE
)
1508 if (arg0
== NULL_TREE
|| !TREE_SIDE_EFFECTS (arg0
))
1511 /* Remove intermediate expressions that have no side-effects. */
1512 while (TREE_CODE (arg0
) == COMPOUND_EXPR
1513 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0
, 1)))
1514 arg0
= TREE_OPERAND (arg0
, 0);
1516 if (TREE_CODE (arg1
) == TARGET_EXPR
)
1518 /* If the rhs is a TARGET_EXPR, then build the compound expression
1519 inside the target_expr's initializer. This helps the compiler
1520 to eliminate unnecessary temporaries. */
1521 tree init
= compound_expr (arg0
, TARGET_EXPR_INITIAL (arg1
));
1522 TARGET_EXPR_INITIAL (arg1
) = init
;
1527 return fold_build2_loc (input_location
, COMPOUND_EXPR
,
1528 TREE_TYPE (arg1
), arg0
, arg1
);
1531 /* Build a return expression. */
1534 return_expr (tree ret
)
1536 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary
1537 in TARGET_EXPR_SLOT. */
1538 if (ret
!= NULL_TREE
&& TREE_CODE (ret
) == TARGET_EXPR
)
1540 tree exp
= TARGET_EXPR_INITIAL (ret
);
1541 tree init
= stabilize_expr (&exp
);
1543 exp
= fold_build1_loc (input_location
, RETURN_EXPR
, void_type_node
, exp
);
1544 TARGET_EXPR_INITIAL (ret
) = compound_expr (init
, exp
);
1549 return fold_build1_loc (input_location
, RETURN_EXPR
,
1550 void_type_node
, ret
);
1553 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1556 size_mult_expr (tree arg0
, tree arg1
)
1558 return fold_build2_loc (input_location
, MULT_EXPR
, size_type_node
,
1559 d_convert (size_type_node
, arg0
),
1560 d_convert (size_type_node
, arg1
));
1564 /* Return the real part of CE, which should be a complex expression. */
1569 return fold_build1_loc (input_location
, REALPART_EXPR
,
1570 TREE_TYPE (TREE_TYPE (ce
)), ce
);
1573 /* Return the imaginary part of CE, which should be a complex expression. */
1576 imaginary_part (tree ce
)
1578 return fold_build1_loc (input_location
, IMAGPART_EXPR
,
1579 TREE_TYPE (TREE_TYPE (ce
)), ce
);
1582 /* Build a complex expression of type TYPE using RE and IM. */
1585 complex_expr (tree type
, tree re
, tree im
)
1587 return fold_build2_loc (input_location
, COMPLEX_EXPR
,
1591 /* Build a two-field record TYPE representing the complex expression EXPR. */
1594 underlying_complex_expr (tree type
, tree expr
)
1596 gcc_assert (list_length (TYPE_FIELDS (type
)) == 2);
1598 expr
= d_save_expr (expr
);
1600 /* Build a constructor from the real and imaginary parts. */
1601 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (expr
)) &&
1602 (!INDIRECT_REF_P (expr
)
1603 || !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr
, 0)))))
1605 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
1606 CONSTRUCTOR_APPEND_ELT (ve
, TYPE_FIELDS (type
),
1608 CONSTRUCTOR_APPEND_ELT (ve
, TREE_CHAIN (TYPE_FIELDS (type
)),
1609 imaginary_part (expr
));
1610 return build_constructor (type
, ve
);
1613 /* Replace type in the reinterpret cast with a cast to the record type. */
1614 return build_vconvert (type
, expr
);
1617 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1618 The back-end requires this cast in many cases. */
1621 indirect_ref (tree type
, tree exp
)
1623 if (error_operand_p (exp
))
1626 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1627 tree init
= stabilize_expr (&exp
);
1629 if (TREE_CODE (TREE_TYPE (exp
)) == REFERENCE_TYPE
)
1630 exp
= fold_build1 (INDIRECT_REF
, type
, exp
);
1633 exp
= build_nop (build_pointer_type (type
), exp
);
1634 exp
= build_deref (exp
);
1637 return compound_expr (init
, exp
);
1640 /* Returns indirect reference of EXP, which must be a pointer type. */
1643 build_deref (tree exp
)
1645 if (error_operand_p (exp
))
1648 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1649 tree init
= stabilize_expr (&exp
);
1651 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp
)));
1653 if (TREE_CODE (exp
) == ADDR_EXPR
)
1654 exp
= TREE_OPERAND (exp
, 0);
1656 exp
= build_fold_indirect_ref (exp
);
1658 return compound_expr (init
, exp
);
1661 /* Builds pointer offset expression PTR[INDEX]. */
1664 build_pointer_index (tree ptr
, tree index
)
1666 if (error_operand_p (ptr
) || error_operand_p (index
))
1667 return error_mark_node
;
1669 tree ptr_type
= TREE_TYPE (ptr
);
1670 tree target_type
= TREE_TYPE (ptr_type
);
1672 tree type
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (sizetype
),
1673 TYPE_UNSIGNED (sizetype
));
1675 /* Array element size. */
1676 tree size_exp
= size_in_bytes (target_type
);
1678 if (integer_zerop (size_exp
) || integer_onep (size_exp
))
1680 /* Array of void or bytes -- No need to multiply. */
1681 index
= fold_convert (type
, index
);
1685 index
= d_convert (type
, index
);
1686 index
= fold_build2 (MULT_EXPR
, TREE_TYPE (index
),
1687 index
, d_convert (TREE_TYPE (index
), size_exp
));
1688 index
= fold_convert (type
, index
);
1691 if (integer_zerop (index
))
1694 return fold_build2 (POINTER_PLUS_EXPR
, ptr_type
, ptr
, index
);
1697 /* Builds pointer offset expression *(PTR OP OFFSET)
1698 OP could be a plus or minus expression. */
1701 build_offset_op (tree_code op
, tree ptr
, tree offset
)
1703 gcc_assert (op
== MINUS_EXPR
|| op
== PLUS_EXPR
);
1705 tree type
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (sizetype
),
1706 TYPE_UNSIGNED (sizetype
));
1707 offset
= fold_convert (type
, offset
);
1709 if (op
== MINUS_EXPR
)
1710 offset
= fold_build1 (NEGATE_EXPR
, type
, offset
);
1712 return fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ptr
), ptr
, offset
);
1715 /* Builds pointer offset expression *(PTR + OFFSET). */
1718 build_offset (tree ptr
, tree offset
)
1720 return build_offset_op (PLUS_EXPR
, ptr
, offset
);
1724 build_memref (tree type
, tree ptr
, tree offset
)
1726 return fold_build2 (MEM_REF
, type
, ptr
, fold_convert (type
, offset
));
1729 /* Create a tree node to set multiple elements to a single value. */
1732 build_array_set (tree ptr
, tree length
, tree value
)
1734 tree ptrtype
= TREE_TYPE (ptr
);
1735 tree lentype
= TREE_TYPE (length
);
1737 push_binding_level (level_block
);
1740 /* Build temporary locals for length and ptr, and maybe value. */
1741 tree t
= build_local_temp (size_type_node
);
1742 add_stmt (build_assign (INIT_EXPR
, t
, length
));
1745 t
= build_local_temp (ptrtype
);
1746 add_stmt (build_assign (INIT_EXPR
, t
, ptr
));
1749 if (TREE_SIDE_EFFECTS (value
))
1751 t
= build_local_temp (TREE_TYPE (value
));
1752 add_stmt (build_assign (INIT_EXPR
, t
, value
));
1756 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1759 /* Exit logic for the loop.
1760 if (length == 0) break; */
1761 t
= build_boolop (EQ_EXPR
, length
, d_convert (lentype
, integer_zero_node
));
1762 t
= build1 (EXIT_EXPR
, void_type_node
, t
);
1765 /* Assign value to the current pointer position.
1767 t
= modify_expr (build_deref (ptr
), value
);
1770 /* Move pointer to next element position.
1772 tree size
= TYPE_SIZE_UNIT (TREE_TYPE (ptrtype
));
1773 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, ptr
, d_convert (ptrtype
, size
));
1776 /* Decrease loop counter.
1778 t
= build2 (POSTDECREMENT_EXPR
, lentype
, length
,
1779 d_convert (lentype
, integer_one_node
));
1782 /* Pop statements and finish loop. */
1783 tree loop_body
= pop_stmt_list ();
1784 add_stmt (build1 (LOOP_EXPR
, void_type_node
, loop_body
));
1786 /* Wrap it up into a bind expression. */
1787 tree stmt_list
= pop_stmt_list ();
1788 tree block
= pop_binding_level ();
1790 return build3 (BIND_EXPR
, void_type_node
,
1791 BLOCK_VARS (block
), stmt_list
, block
);
1795 /* Build an array of type TYPE where all the elements are VAL. */
1798 build_array_from_val (Type
*type
, tree val
)
1800 tree etype
= build_ctype (type
->nextOf ());
1802 /* Initializing a multidimensional array. */
1803 if (TREE_CODE (etype
) == ARRAY_TYPE
&& TREE_TYPE (val
) != etype
)
1804 val
= build_array_from_val (type
->nextOf (), val
);
1806 size_t dims
= type
->isTypeSArray ()->dim
->toInteger ();
1807 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
1808 vec_safe_reserve (elms
, dims
);
1810 val
= d_convert (etype
, val
);
1812 for (size_t i
= 0; i
< dims
; i
++)
1813 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), val
);
1815 return build_constructor (build_ctype (type
), elms
);
1818 /* Build a static array of type TYPE from an array of EXPS.
1819 If CONST_P is true, then all elements in EXPS are constants. */
1822 build_array_from_exprs (Type
*type
, Expressions
*exps
, bool const_p
)
1824 /* Build a CONSTRUCTOR from all expressions. */
1825 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
1826 vec_safe_reserve (elms
, exps
->length
);
1828 Type
*etype
= type
->nextOf ();
1829 tree satype
= make_array_type (etype
, exps
->length
);
1831 for (size_t i
= 0; i
< exps
->length
; i
++)
1833 Expression
*expr
= (*exps
)[i
];
1834 tree t
= build_expr (expr
, const_p
);
1835 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
),
1836 convert_expr (t
, expr
->type
, etype
));
1839 /* Create a new temporary to store the array. */
1840 tree var
= build_local_temp (satype
);
1842 /* Fill any alignment holes with zeroes. */
1843 TypeStruct
*ts
= etype
->baseElemOf ()->isTypeStruct ();
1845 if (ts
&& (!identity_compare_p (ts
->sym
) || ts
->sym
->isUnionDeclaration ()))
1846 init
= build_memset_call (var
);
1848 /* Initialize the temporary. */
1849 tree assign
= modify_expr (var
, build_constructor (satype
, elms
));
1850 return compound_expr (compound_expr (init
, assign
), var
);
1854 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1857 void_okay_p (tree t
)
1859 tree type
= TREE_TYPE (t
);
1861 if (VOID_TYPE_P (TREE_TYPE (type
)))
1863 tree totype
= build_ctype (Type::tuns8
->pointerTo ());
1864 return fold_convert (totype
, t
);
1870 /* Builds a STRING_CST representing the filename of location LOC. When the
1871 location is not valid, the name of the source module is used instead. */
1874 build_filename_from_loc (const Loc
&loc
)
1876 const char *filename
= loc
.filename
1877 ? loc
.filename
: d_function_chain
->module
->srcfile
.toChars ();
1879 unsigned length
= strlen (filename
);
1880 tree str
= build_string (length
, filename
);
1881 TREE_TYPE (str
) = make_array_type (Type::tchar
, length
+ 1);
1883 return build_address (str
);
1886 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1887 an assert check fails. When calling the msg variant functions, MSG is the
1888 error message supplied by the user. */
1891 build_assert_call (const Loc
&loc
, libcall_fn libcall
, tree msg
)
1894 tree line
= size_int (loc
.linnum
);
1898 case LIBCALL_ASSERT_MSG
:
1899 case LIBCALL_UNITTEST_MSG
:
1900 /* File location is passed as a D string. */
1903 unsigned len
= strlen (loc
.filename
);
1904 tree str
= build_string (len
, loc
.filename
);
1905 TREE_TYPE (str
) = make_array_type (Type::tchar
, len
);
1907 file
= d_array_value (build_ctype (Type::tchar
->arrayOf ()),
1908 size_int (len
), build_address (str
));
1911 file
= null_array_node
;
1914 case LIBCALL_ASSERTP
:
1915 case LIBCALL_UNITTESTP
:
1916 file
= build_filename_from_loc (loc
);
1924 if (msg
!= NULL_TREE
)
1925 return build_libcall (libcall
, Type::tvoid
, 3, msg
, file
, line
);
1927 return build_libcall (libcall
, Type::tvoid
, 2, file
, line
);
1930 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
1931 array bounds check fails. */
1934 build_array_bounds_call (const Loc
&loc
)
1936 /* Terminate the program with a trap if no D runtime present. */
1937 if (checkaction_trap_p ())
1938 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1941 return build_libcall (LIBCALL_ARRAYBOUNDSP
, Type::tvoid
, 2,
1942 build_filename_from_loc (loc
),
1943 size_int (loc
.linnum
));
1947 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1948 in the index expression IE. The condition returns the INDEX if true, or
1949 throws a `ArrayIndexError`. */
1952 build_bounds_index_condition (IndexExp
*ie
, tree index
, tree length
)
1954 if (ie
->indexIsInBounds
|| !array_bounds_check ())
1957 /* Prevent multiple evaluations of the index. */
1958 index
= d_save_expr (index
);
1960 /* Generate INDEX >= LENGTH && throw RangeError.
1961 No need to check whether INDEX >= 0 as the front-end should
1962 have already taken care of implicit casts to unsigned. */
1963 tree condition
= fold_build2 (GE_EXPR
, d_bool_type
, index
, length
);
1966 if (checkaction_trap_p ())
1967 boundserr
= build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1970 boundserr
= build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP
, Type::tvoid
, 4,
1971 build_filename_from_loc (ie
->e2
->loc
),
1972 size_int (ie
->e2
->loc
.linnum
), index
, length
);
1975 return build_condition (TREE_TYPE (index
), condition
, boundserr
, index
);
1978 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1979 the slice expression SE of the source array length LENGTH. The condition
1980 returns the new array length if true, or throws an `ArraySliceError`. */
1983 build_bounds_slice_condition (SliceExp
*se
, tree lower
, tree upper
, tree length
)
1985 if (array_bounds_check ())
1987 tree condition
= NULL_TREE
;
1989 /* Enforces that `upper <= length`. */
1990 if (!se
->upperIsInBounds
&& length
!= NULL_TREE
)
1991 condition
= fold_build2 (GT_EXPR
, d_bool_type
, upper
, length
);
1993 length
= integer_zero_node
;
1995 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1996 we've already ensured that `upper <= length`. */
1997 if (!se
->lowerIsLessThanUpper
)
1999 tree lwr_cond
= fold_build2 (GT_EXPR
, d_bool_type
, lower
, upper
);
2001 if (condition
!= NULL_TREE
)
2002 condition
= build_boolop (TRUTH_ORIF_EXPR
, condition
, lwr_cond
);
2004 condition
= lwr_cond
;
2007 if (condition
!= NULL_TREE
)
2011 if (checkaction_trap_p ())
2014 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
2018 boundserr
= build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP
,
2020 build_filename_from_loc (se
->loc
),
2021 size_int (se
->loc
.linnum
),
2022 lower
, upper
, length
);
2025 upper
= build_condition (TREE_TYPE (upper
), condition
,
2030 /* Need to ensure lower always gets evaluated first, as it may be a function
2031 call. Generates (lower, upper) - lower. */
2032 return fold_build2 (MINUS_EXPR
, TREE_TYPE (upper
),
2033 compound_expr (lower
, upper
), lower
);
2036 /* Returns TRUE if array bounds checking code generation is turned on. */
2039 array_bounds_check (void)
2041 FuncDeclaration
*fd
;
2043 switch (global
.params
.useArrayBounds
)
2045 case CHECKENABLEoff
:
2051 case CHECKENABLEsafeonly
:
2052 /* For D2 safe functions only. */
2053 fd
= d_function_chain
->function
;
2054 if (fd
&& fd
->type
->ty
== TY::Tfunction
)
2056 if (fd
->type
->isTypeFunction ()->trust
== TRUST::safe
)
2066 /* Returns TRUE if we terminate the program with a trap if an array bounds or
2067 contract check fails. */
2070 checkaction_trap_p (void)
2072 switch (global
.params
.checkAction
)
2075 case CHECKACTION_context
:
2079 case CHECKACTION_halt
:
2087 /* Returns the TypeFunction class for Type T.
2088 Assumes T is already ->toBasetype(). */
2091 get_function_type (Type
*t
)
2093 TypeFunction
*tf
= NULL
;
2094 if (t
->ty
== TY::Tpointer
)
2095 t
= t
->nextOf ()->toBasetype ();
2096 if (t
->ty
== TY::Tfunction
)
2097 tf
= t
->isTypeFunction ();
2098 else if (t
->ty
== TY::Tdelegate
)
2099 tf
= t
->isTypeDelegate ()->next
->isTypeFunction ();
2103 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
2104 CALLER. In which case, CALLEE is being called through an alias that was
2105 passed to CALLER. */
2108 call_by_alias_p (FuncDeclaration
*caller
, FuncDeclaration
*callee
)
2110 if (!callee
->isNested ())
2113 if (caller
->toParent () == callee
->toParent ())
2116 Dsymbol
*dsym
= callee
;
2120 if (dsym
->isTemplateInstance ())
2122 else if (dsym
->isFuncDeclaration () == caller
)
2124 dsym
= dsym
->toParent ();
2130 /* Entry point for call routines. Builds a function call to FD.
2131 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
2134 d_build_call_expr (FuncDeclaration
*fd
, tree object
, Expressions
*arguments
)
2136 return d_build_call (get_function_type (fd
->type
),
2137 build_address (get_symbol_decl (fd
)), object
, arguments
);
2140 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
2141 ARGUMENTS are evaluated in left to right order, saved and promoted
2145 d_build_call (TypeFunction
*tf
, tree callable
, tree object
,
2146 Expressions
*arguments
)
2148 tree ctype
= TREE_TYPE (callable
);
2149 tree callee
= callable
;
2151 if (POINTER_TYPE_P (ctype
))
2152 ctype
= TREE_TYPE (ctype
);
2154 callee
= build_address (callable
);
2156 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype
));
2157 gcc_assert (tf
!= NULL
);
2158 gcc_assert (tf
->ty
== TY::Tfunction
);
2160 if (TREE_CODE (ctype
) != FUNCTION_TYPE
&& object
== NULL_TREE
)
2162 /* Front-end apparently doesn't check this. */
2163 if (TREE_CODE (callable
) == FUNCTION_DECL
)
2165 error ("need %<this%> to access member %qE", DECL_NAME (callable
));
2166 return error_mark_node
;
2169 /* Probably an internal error. */
2173 /* Build the argument list for the call. */
2174 vec
<tree
, va_gc
> *args
= NULL
;
2175 bool noreturn_call
= false;
2177 /* If this is a delegate call or a nested function being called as
2178 a delegate, the object should not be NULL. */
2179 if (object
!= NULL_TREE
)
2180 vec_safe_push (args
, object
);
2184 const size_t nparams
= tf
->parameterList
.length ();
2185 /* if _arguments[] is the first argument. */
2186 const size_t varargs
= tf
->isDstyleVariadic ();
2188 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2189 for (size_t i
= 0; i
< arguments
->length
; ++i
)
2191 Expression
*arg
= (*arguments
)[i
];
2192 tree targ
= build_expr (arg
);
2194 if (i
- varargs
< nparams
&& i
>= varargs
)
2196 /* Actual arguments for declared formal arguments. */
2197 Parameter
*parg
= tf
->parameterList
[i
- varargs
];
2198 targ
= convert_for_argument (targ
, parg
);
2201 /* Don't pass empty aggregates by value. */
2202 if (empty_aggregate_p (TREE_TYPE (targ
)) && !TREE_ADDRESSABLE (targ
)
2203 && TREE_CODE (targ
) != CONSTRUCTOR
)
2205 tree t
= build_constructor (TREE_TYPE (targ
), NULL
);
2206 targ
= build2 (COMPOUND_EXPR
, TREE_TYPE (t
), targ
, t
);
2209 /* Parameter is a struct or array passed by invisible reference. */
2210 if (TREE_ADDRESSABLE (TREE_TYPE (targ
)))
2212 Type
*t
= arg
->type
->toBasetype ();
2213 StructDeclaration
*sd
= t
->baseElemOf ()->isTypeStruct ()->sym
;
2215 /* Nested structs also have ADDRESSABLE set, but if the type has
2216 neither a copy constructor nor a destructor available, then we
2217 need to take care of copying its value before passing it. */
2218 if (arg
->op
== EXP::structLiteral
|| (!sd
->postblit
&& !sd
->dtor
))
2219 targ
= force_target_expr (targ
);
2221 targ
= convert (build_reference_type (TREE_TYPE (targ
)),
2222 build_address (targ
));
2225 /* Complex types are exposed as special types with an underlying
2226 struct representation, if we are passing the native type to a
2227 function that accepts the library-defined version, then ensure
2228 it is properly reinterpreted as the underlying struct type. */
2229 if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (targ
))
2230 && arg
->type
->isTypeStruct ())
2231 targ
= underlying_complex_expr (build_ctype (arg
->type
), targ
);
2233 /* Type `noreturn` is a terminator, as no other arguments can possibly
2234 be evaluated after it. */
2235 if (TREE_TYPE (targ
) == noreturn_type_node
)
2236 noreturn_call
= true;
2238 vec_safe_push (args
, targ
);
2242 /* If we saw a `noreturn` parameter, any unreachable argument evaluations
2243 after it are discarded, as well as the function call itself. */
2246 tree saved_args
= NULL_TREE
;
2248 if (TREE_SIDE_EFFECTS (callee
))
2249 saved_args
= compound_expr (callee
, saved_args
);
2254 FOR_EACH_VEC_SAFE_ELT (args
, ix
, arg
)
2255 saved_args
= compound_expr (saved_args
, arg
);
2257 /* Add a stub result type for the expression. */
2258 tree result
= build_zero_cst (TREE_TYPE (ctype
));
2259 return compound_expr (saved_args
, result
);
2262 tree result
= build_call_vec (TREE_TYPE (ctype
), callee
, args
);
2263 SET_EXPR_LOCATION (result
, input_location
);
2265 result
= maybe_expand_intrinsic (result
);
2267 /* Return the value in a temporary slot so that it can be evaluated
2268 multiple times by the caller. */
2269 if (TREE_CODE (result
) == CALL_EXPR
2270 && AGGREGATE_TYPE_P (TREE_TYPE (result
))
2271 && TREE_ADDRESSABLE (TREE_TYPE (result
)))
2273 CALL_EXPR_RETURN_SLOT_OPT (result
) = true;
2274 result
= force_target_expr (result
);
2280 /* Build and return the correct call to fmod depending on TYPE.
2281 ARG0 and ARG1 are the arguments pass to the function. */
2284 build_float_modulus (tree type
, tree arg0
, tree arg1
)
2286 tree fmodfn
= NULL_TREE
;
2287 tree basetype
= type
;
2289 if (COMPLEX_FLOAT_TYPE_P (basetype
))
2290 basetype
= TREE_TYPE (basetype
);
2292 if (TYPE_MAIN_VARIANT (basetype
) == double_type_node
2293 || TYPE_MAIN_VARIANT (basetype
) == idouble_type_node
)
2294 fmodfn
= builtin_decl_explicit (BUILT_IN_FMOD
);
2295 else if (TYPE_MAIN_VARIANT (basetype
) == float_type_node
2296 || TYPE_MAIN_VARIANT (basetype
) == ifloat_type_node
)
2297 fmodfn
= builtin_decl_explicit (BUILT_IN_FMODF
);
2298 else if (TYPE_MAIN_VARIANT (basetype
) == long_double_type_node
2299 || TYPE_MAIN_VARIANT (basetype
) == ireal_type_node
)
2300 fmodfn
= builtin_decl_explicit (BUILT_IN_FMODL
);
2304 error ("tried to perform floating-point modulo division on %qT", type
);
2305 return error_mark_node
;
2308 if (COMPLEX_FLOAT_TYPE_P (type
))
2310 tree re
= build_call_expr (fmodfn
, 2, real_part (arg0
), arg1
);
2311 tree im
= build_call_expr (fmodfn
, 2, imaginary_part (arg0
), arg1
);
2313 return complex_expr (type
, re
, im
);
2316 if (SCALAR_FLOAT_TYPE_P (type
))
2317 return build_call_expr (fmodfn
, 2, arg0
, arg1
);
2319 /* Should have caught this above. */
2323 /* Build a function type whose first argument is a pointer to BASETYPE,
2324 which is to be used for the `vthis' context parameter for TYPE.
2325 The base type may be a record for member functions, or a void for
2326 nested functions and delegates. */
2329 build_vthis_function (tree basetype
, tree type
)
2331 gcc_assert (TREE_CODE (type
) == FUNCTION_TYPE
);
2333 tree argtypes
= tree_cons (NULL_TREE
, build_pointer_type (basetype
),
2334 TYPE_ARG_TYPES (type
));
2335 tree fntype
= build_function_type (TREE_TYPE (type
), argtypes
);
2337 /* Copy volatile qualifiers from the original function type. */
2338 if (TYPE_QUALS (type
) & TYPE_QUAL_VOLATILE
)
2339 fntype
= build_qualified_type (fntype
, TYPE_QUAL_VOLATILE
);
2341 if (RECORD_OR_UNION_TYPE_P (basetype
))
2342 TYPE_METHOD_BASETYPE (fntype
) = TYPE_MAIN_VARIANT (basetype
);
2344 gcc_assert (VOID_TYPE_P (basetype
));
2349 /* Raise an error at that the context pointer of the function or object SYM is
2350 not accessible from the current scope. */
2353 error_no_frame_access (Dsymbol
*sym
)
2355 error_at (input_location
, "cannot get frame pointer to %qs",
2356 sym
->toPrettyChars ());
2357 return null_pointer_node
;
2360 /* If SYM is a nested function, return the static chain to be
2361 used when calling that function from the current function.
2363 If SYM is a nested class or struct, return the static chain
2364 to be used when creating an instance of the class from CFUN. */
2367 get_frame_for_symbol (Dsymbol
*sym
)
2369 FuncDeclaration
*thisfd
2370 = d_function_chain
? d_function_chain
->function
: NULL
;
2371 FuncDeclaration
*fd
= sym
->isFuncDeclaration ();
2372 FuncDeclaration
*fdparent
= NULL
;
2373 FuncDeclaration
*fdoverride
= NULL
;
2377 /* Check that the nested function is properly defined. */
2380 /* Should instead error on line that references `fd'. */
2381 error_at (make_location_t (fd
->loc
), "nested function missing body");
2382 return null_pointer_node
;
2385 fdparent
= fd
->toParent2 ()->isFuncDeclaration ();
2387 /* Special case for __ensure and __require. */
2388 if ((fd
->ident
== Identifier::idPool ("__ensure")
2389 || fd
->ident
== Identifier::idPool ("__require"))
2390 && fdparent
!= thisfd
)
2392 fdoverride
= fdparent
;
2398 /* It's a class (or struct). NewExp codegen has already determined its
2399 outer scope is not another class, so it must be a function. */
2400 while (sym
&& !sym
->isFuncDeclaration ())
2401 sym
= sym
->toParent2 ();
2403 fdparent
= (FuncDeclaration
*) sym
;
2406 /* Not a nested function, there is no frame pointer to pass. */
2407 if (fdparent
== NULL
)
2409 /* Only delegate literals report as being nested, even if they are in
2411 gcc_assert (fd
&& fd
->isFuncLiteralDeclaration ());
2412 return null_pointer_node
;
2415 gcc_assert (thisfd
!= NULL
);
2417 if (thisfd
!= fdparent
)
2419 /* If no frame pointer for this function. */
2422 error_at (make_location_t (sym
->loc
),
2423 "%qs is a nested function and cannot be accessed from %qs",
2424 fdparent
->toPrettyChars (), thisfd
->toPrettyChars ());
2425 return null_pointer_node
;
2428 /* Make sure we can get the frame pointer to the outer function.
2429 Go up each nesting level until we find the enclosing function. */
2430 Dsymbol
*dsym
= thisfd
;
2434 /* Check if enclosing function is a function. */
2435 FuncDeclaration
*fdp
= dsym
->isFuncDeclaration ();
2436 Dsymbol
*parent
= dsym
->toParent2 ();
2440 if (fdparent
== parent
)
2443 gcc_assert (fdp
->isNested () || fdp
->vthis
);
2448 /* Check if enclosed by an aggregate. That means the current
2449 function must be a member function of that aggregate. */
2450 AggregateDeclaration
*adp
= dsym
->isAggregateDeclaration ();
2454 if ((adp
->isClassDeclaration () || adp
->isStructDeclaration ())
2455 && fdparent
== parent
)
2459 /* No frame to outer function found. */
2460 if (!adp
|| !adp
->isNested () || !adp
->vthis
)
2461 return error_no_frame_access (sym
);
2467 tree ffo
= get_frameinfo (fdparent
);
2468 if (FRAMEINFO_CREATES_FRAME (ffo
) || FRAMEINFO_STATIC_CHAIN (ffo
))
2470 tree frame_ref
= get_framedecl (thisfd
, fdparent
);
2472 /* If `thisfd' is a derived member function, then `fdparent' is the
2473 overridden member function in the base class. Even if there's a
2474 closure environment, we should give the original stack data as the
2475 nested function frame. */
2478 ClassDeclaration
*cdo
= fdoverride
->isThis ()->isClassDeclaration ();
2479 ClassDeclaration
*cd
= thisfd
->isThis ()->isClassDeclaration ();
2480 gcc_assert (cdo
&& cd
);
2483 if (cdo
->isBaseOf (cd
, &offset
) && offset
!= 0)
2485 /* Generate a new frame to pass to the overriden function that
2486 has the `this' pointer adjusted. */
2487 gcc_assert (offset
!= OFFSET_RUNTIME
);
2489 tree type
= FRAMEINFO_TYPE (get_frameinfo (fdoverride
));
2490 tree fields
= TYPE_FIELDS (type
);
2491 /* The `this' field comes immediately after the `__chain'. */
2492 tree thisfield
= chain_index (1, fields
);
2493 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
2495 tree framefields
= TYPE_FIELDS (FRAMEINFO_TYPE (ffo
));
2496 frame_ref
= build_deref (frame_ref
);
2498 for (tree field
= fields
; field
; field
= DECL_CHAIN (field
))
2500 tree value
= component_ref (frame_ref
, framefields
);
2501 if (field
== thisfield
)
2502 value
= build_offset (value
, size_int (offset
));
2504 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
2505 framefields
= DECL_CHAIN (framefields
);
2508 frame_ref
= build_address (build_constructor (type
, ve
));
2515 return null_pointer_node
;
2518 /* Return the parent function of a nested class or struct AD. */
2520 static FuncDeclaration
*
2521 get_outer_function (AggregateDeclaration
*ad
)
2523 FuncDeclaration
*fd
= NULL
;
2524 while (ad
&& ad
->isNested ())
2526 Dsymbol
*dsym
= ad
->toParent2 ();
2527 if ((fd
= dsym
->isFuncDeclaration ()))
2530 ad
= dsym
->isAggregateDeclaration ();
2536 /* Starting from the current function FD, try to find a suitable value of
2537 `this' in nested function instances. A suitable `this' value is an
2538 instance of OCD or a class that has OCD as a base. */
2541 find_this_tree (ClassDeclaration
*ocd
)
2543 FuncDeclaration
*fd
= d_function_chain
? d_function_chain
->function
: NULL
;
2547 AggregateDeclaration
*ad
= fd
->isThis ();
2548 ClassDeclaration
*cd
= ad
? ad
->isClassDeclaration () : NULL
;
2553 return get_decl_tree (fd
->vthis
);
2554 else if (ocd
->isBaseOf (cd
, NULL
))
2555 return convert_expr (get_decl_tree (fd
->vthis
),
2556 cd
->type
, ocd
->type
);
2558 fd
= get_outer_function (cd
);
2562 if (fd
->isNested ())
2564 fd
= fd
->toParent2 ()->isFuncDeclaration ();
2574 /* Retrieve the outer class/struct `this' value of DECL from
2575 the current function. */
2578 build_vthis (AggregateDeclaration
*decl
)
2580 ClassDeclaration
*cd
= decl
->isClassDeclaration ();
2581 StructDeclaration
*sd
= decl
->isStructDeclaration ();
2583 /* If an aggregate nested in a function has no methods and there are no
2584 other nested functions, any static chain created here will never be
2585 translated. Use a null pointer for the link in this case. */
2586 tree vthis_value
= null_pointer_node
;
2588 if (cd
!= NULL
|| sd
!= NULL
)
2590 Dsymbol
*outer
= decl
->toParent2 ();
2592 /* If the parent is a templated struct, the outer context is instead
2593 the enclosing symbol of where the instantiation happened. */
2594 if (outer
->isStructDeclaration ())
2596 gcc_assert (outer
->parent
&& outer
->parent
->isTemplateInstance ());
2597 outer
= ((TemplateInstance
*) outer
->parent
)->enclosing
;
2600 /* For outer classes, get a suitable `this' value.
2601 For outer functions, get a suitable frame/closure pointer. */
2602 ClassDeclaration
*cdo
= outer
->isClassDeclaration ();
2603 FuncDeclaration
*fdo
= outer
->isFuncDeclaration ();
2607 vthis_value
= find_this_tree (cdo
);
2608 gcc_assert (vthis_value
!= NULL_TREE
);
2612 tree ffo
= get_frameinfo (fdo
);
2613 if (FRAMEINFO_CREATES_FRAME (ffo
) || FRAMEINFO_STATIC_CHAIN (ffo
)
2614 || fdo
->hasNestedFrameRefs ())
2615 vthis_value
= get_frame_for_symbol (decl
);
2616 else if (cd
!= NULL
)
2618 /* Classes nested in methods are allowed to access any outer
2619 class fields, use the function chain in this case. */
2620 if (fdo
->vthis
&& fdo
->vthis
->type
!= Type::tvoidptr
)
2621 vthis_value
= get_decl_tree (fdo
->vthis
);
2631 /* Build the RECORD_TYPE that describes the function frame or closure type for
2632 the function FD. FFI is the tree holding all frame information. */
2635 build_frame_type (tree ffi
, FuncDeclaration
*fd
)
2637 if (FRAMEINFO_TYPE (ffi
))
2638 return FRAMEINFO_TYPE (ffi
);
2640 tree frame_rec_type
= make_node (RECORD_TYPE
);
2641 char *name
= concat (FRAMEINFO_IS_CLOSURE (ffi
) ? "CLOSURE." : "FRAME.",
2642 fd
->toPrettyChars (), NULL
);
2643 TYPE_NAME (frame_rec_type
) = get_identifier (name
);
2646 tree fields
= NULL_TREE
;
2648 /* Function is a member or nested, so must have field for outer context. */
2651 tree ptr_field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
2652 get_identifier ("__chain"), ptr_type_node
);
2653 DECL_FIELD_CONTEXT (ptr_field
) = frame_rec_type
;
2654 fields
= chainon (NULL_TREE
, ptr_field
);
2655 DECL_NONADDRESSABLE_P (ptr_field
) = 1;
2658 /* The __ensure and __require are called directly, so never make the outer
2659 functions closure, but nevertheless could still be referencing parameters
2660 of the calling function non-locally. So we add all parameters with nested
2661 refs to the function frame, this should also mean overriding methods will
2662 have the same frame layout when inheriting a contract. */
2663 if ((global
.params
.useIn
== CHECKENABLEon
&& fd
->frequire
)
2664 || (global
.params
.useOut
== CHECKENABLEon
&& fd
->fensure
))
2668 for (size_t i
= 0; fd
->parameters
&& i
< fd
->parameters
->length
; i
++)
2670 VarDeclaration
*v
= (*fd
->parameters
)[i
];
2671 /* Remove if already in closureVars so can push to front. */
2672 size_t j
= fd
->closureVars
.find (v
);
2674 if (j
< fd
->closureVars
.length
)
2675 fd
->closureVars
.remove (j
);
2677 fd
->closureVars
.insert (i
, v
);
2681 /* Also add hidden `this' to outer context. */
2684 size_t i
= fd
->closureVars
.find (fd
->vthis
);
2686 if (i
< fd
->closureVars
.length
)
2687 fd
->closureVars
.remove (i
);
2689 fd
->closureVars
.insert (0, fd
->vthis
);
2693 for (size_t i
= 0; i
< fd
->closureVars
.length
; i
++)
2695 VarDeclaration
*v
= fd
->closureVars
[i
];
2696 tree vsym
= get_symbol_decl (v
);
2697 tree ident
= v
->ident
2698 ? get_identifier (v
->ident
->toChars ()) : NULL_TREE
;
2700 tree field
= build_decl (make_location_t (v
->loc
), FIELD_DECL
, ident
,
2702 SET_DECL_LANG_FRAME_FIELD (vsym
, field
);
2703 DECL_FIELD_CONTEXT (field
) = frame_rec_type
;
2704 fields
= chainon (fields
, field
);
2705 TREE_USED (vsym
) = 1;
2707 TREE_ADDRESSABLE (field
) = TREE_ADDRESSABLE (vsym
);
2708 DECL_NONADDRESSABLE_P (field
) = !TREE_ADDRESSABLE (vsym
);
2709 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (vsym
);
2711 if (DECL_LANG_NRVO (vsym
))
2713 /* Store the nrvo variable in the frame by reference. */
2714 TREE_TYPE (field
) = build_reference_type (TREE_TYPE (field
));
2716 /* Can't do nrvo if the variable is put in a closure, since what the
2717 return slot points to may no longer exist. */
2718 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi
));
2721 if (FRAMEINFO_IS_CLOSURE (ffi
))
2723 /* Because the value needs to survive the end of the scope. */
2724 if ((v
->edtor
&& (v
->storage_class
& STCparameter
))
2725 || v
->needsScopeDtor ())
2726 error_at (make_location_t (v
->loc
),
2727 "variable %qs has scoped destruction, "
2728 "cannot build closure", v
->toChars ());
2731 if (DECL_REGISTER (vsym
))
2733 /* Because the value will be in memory, not a register. */
2734 error_at (make_location_t (v
->loc
),
2735 "explicit register variable %qs cannot be used in nested "
2736 "function", v
->toChars ());
2740 TYPE_FIELDS (frame_rec_type
) = fields
;
2741 TYPE_READONLY (frame_rec_type
) = 1;
2742 TYPE_CXX_ODR_P (frame_rec_type
) = 1;
2743 layout_type (frame_rec_type
);
2744 d_keep (frame_rec_type
);
2746 return frame_rec_type
;
2749 /* Closures are implemented by taking the local variables that
2750 need to survive the scope of the function, and copying them
2751 into a GC allocated chuck of memory. That chunk, called the
2752 closure here, is inserted into the linked list of stack
2753 frames instead of the usual stack frame.
2755 If a closure is not required, but FD still needs a frame to lower
2756 nested refs, then instead build custom static chain decl on stack. */
2759 build_closure (FuncDeclaration
*fd
)
2761 tree ffi
= get_frameinfo (fd
);
2763 if (!FRAMEINFO_CREATES_FRAME (ffi
))
2766 tree type
= FRAMEINFO_TYPE (ffi
);
2767 gcc_assert (COMPLETE_TYPE_P (type
));
2769 tree decl
, decl_ref
;
2771 if (FRAMEINFO_IS_CLOSURE (ffi
))
2773 decl
= build_local_temp (build_pointer_type (type
));
2774 DECL_NAME (decl
) = get_identifier ("__closptr");
2775 decl_ref
= build_deref (decl
);
2777 /* Allocate memory for closure. */
2778 tree arg
= convert (build_ctype (Type::tsize_t
), TYPE_SIZE_UNIT (type
));
2779 tree init
= build_libcall (LIBCALL_ALLOCMEMORY
, Type::tvoidptr
, 1, arg
);
2781 tree init_exp
= build_assign (INIT_EXPR
, decl
,
2782 build_nop (TREE_TYPE (decl
), init
));
2783 add_stmt (init_exp
);
2787 decl
= build_local_temp (type
);
2788 DECL_NAME (decl
) = get_identifier ("__frame");
2792 /* Set the first entry to the parent closure/frame, if any. */
2795 tree chain_field
= component_ref (decl_ref
, TYPE_FIELDS (type
));
2796 tree chain_expr
= modify_expr (chain_field
,
2797 d_function_chain
->static_chain
);
2798 add_stmt (chain_expr
);
2801 /* Copy parameters that are referenced nonlocally. */
2802 for (size_t i
= 0; i
< fd
->closureVars
.length
; i
++)
2804 VarDeclaration
*v
= fd
->closureVars
[i
];
2805 tree vsym
= get_symbol_decl (v
);
2807 if (TREE_CODE (vsym
) != PARM_DECL
&& !DECL_LANG_NRVO (vsym
))
2810 tree field
= component_ref (decl_ref
, DECL_LANG_FRAME_FIELD (vsym
));
2812 /* Variable is an alias for the NRVO slot, store the reference. */
2813 if (DECL_LANG_NRVO (vsym
))
2814 vsym
= build_address (DECL_LANG_NRVO (vsym
));
2816 tree expr
= modify_expr (field
, vsym
);
2820 if (!FRAMEINFO_IS_CLOSURE (ffi
))
2821 decl
= build_address (decl
);
2823 d_function_chain
->static_chain
= decl
;
2826 /* Return the frame of FD. This could be a static chain or a closure
2827 passed via the hidden `this' pointer. */
2830 get_frameinfo (FuncDeclaration
*fd
)
2832 tree fds
= get_symbol_decl (fd
);
2833 if (DECL_LANG_FRAMEINFO (fds
))
2834 return DECL_LANG_FRAMEINFO (fds
);
2836 tree ffi
= make_node (FUNCFRAME_INFO
);
2838 DECL_LANG_FRAMEINFO (fds
) = ffi
;
2840 const bool requiresClosure
= fd
->requiresClosure
;
2841 if (fd
->needsClosure ())
2843 /* This can shift due to templates being expanded that access alias
2844 symbols, give it a decent error for now. */
2845 if (requiresClosure
!= fd
->requiresClosure
2846 && (fd
->nrvo_var
|| global
.params
.betterC
))
2847 fd
->checkClosure ();
2849 /* Set-up a closure frame, this will be allocated on the heap. */
2850 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2851 FRAMEINFO_IS_CLOSURE (ffi
) = 1;
2853 else if (fd
->hasNestedFrameRefs ())
2855 /* Functions with nested refs must create a static frame for local
2856 variables to be referenced from. */
2857 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2861 /* For nested functions, default to creating a frame. Even if there are
2862 no fields to populate the frame, create it anyway, as this will be
2863 used as the record type instead of `void*` for the this parameter. */
2864 if (fd
->vthis
&& fd
->vthis
->type
== Type::tvoidptr
)
2865 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2867 /* In checkNestedReference, references from contracts are not added to the
2868 closureVars array, so assume all parameters referenced. */
2869 if ((global
.params
.useIn
== CHECKENABLEon
&& fd
->frequire
)
2870 || (global
.params
.useOut
== CHECKENABLEon
&& fd
->fensure
))
2871 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2873 /* If however `fd` is nested (deeply) in a function that creates a
2874 closure, then `fd` instead inherits that closure via hidden vthis
2875 pointer, and doesn't create a stack frame at all. */
2876 FuncDeclaration
*ff
= fd
;
2880 tree ffo
= get_frameinfo (ff
);
2882 if (ff
!= fd
&& FRAMEINFO_CREATES_FRAME (ffo
))
2884 gcc_assert (FRAMEINFO_TYPE (ffo
));
2885 FRAMEINFO_CREATES_FRAME (ffi
) = 0;
2886 FRAMEINFO_STATIC_CHAIN (ffi
) = 1;
2887 FRAMEINFO_IS_CLOSURE (ffi
) = FRAMEINFO_IS_CLOSURE (ffo
);
2888 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo
)));
2889 FRAMEINFO_TYPE (ffi
) = FRAMEINFO_TYPE (ffo
);
2893 /* Stop looking if no frame pointer for this function. */
2894 if (ff
->vthis
== NULL
)
2897 AggregateDeclaration
*ad
= ff
->isThis ();
2898 if (ad
&& ad
->isNested ())
2900 while (ad
->isNested ())
2902 Dsymbol
*d
= ad
->toParent2 ();
2903 ad
= d
->isAggregateDeclaration ();
2904 ff
= d
->isFuncDeclaration ();
2911 ff
= ff
->toParent2 ()->isFuncDeclaration ();
2915 /* Build type now as may be referenced from another module. */
2916 if (FRAMEINFO_CREATES_FRAME (ffi
))
2917 FRAMEINFO_TYPE (ffi
) = build_frame_type (ffi
, fd
);
2922 /* Return a pointer to the frame/closure block of OUTER
2923 so can be accessed from the function INNER. */
2926 get_framedecl (FuncDeclaration
*inner
, FuncDeclaration
*outer
)
2928 tree result
= d_function_chain
->static_chain
;
2929 FuncDeclaration
*fd
= inner
;
2931 while (fd
&& fd
!= outer
)
2933 /* Parent frame link is the first field. */
2934 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd
)))
2935 result
= indirect_ref (ptr_type_node
, result
);
2937 if (fd
->isNested ())
2938 fd
= fd
->toParent2 ()->isFuncDeclaration ();
2939 /* The frame/closure record always points to the outer function's
2940 frame, even if there are intervening nested classes or structs.
2941 So, we can just skip over these. */
2943 fd
= get_outer_function (fd
->isThis ());
2947 return error_no_frame_access (outer
);
2949 /* Go get our frame record. */
2950 tree frame_type
= FRAMEINFO_TYPE (get_frameinfo (outer
));
2952 if (frame_type
!= NULL_TREE
)
2954 result
= build_nop (build_pointer_type (frame_type
), result
);
2959 error_at (make_location_t (inner
->loc
),
2960 "forward reference to frame of %qs", outer
->toChars ());
2961 return null_pointer_node
;