1 /* d-codegen.cc -- Code generation and routines for manipulation of GCC trees.
2 Copyright (C) 2006-2022 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"
45 /* Return the GCC location for the D frontend location LOC. */
48 make_location_t (const Loc
&loc
)
50 location_t gcc_location
= input_location
;
54 linemap_add (line_table
, LC_ENTER
, 0, loc
.filename
, loc
.linnum
);
55 linemap_line_start (line_table
, loc
.linnum
, 0);
56 gcc_location
= linemap_position_for_column (line_table
, loc
.charnum
);
57 linemap_add (line_table
, LC_LEAVE
, 0, NULL
, 0);
63 /* Return the DECL_CONTEXT for symbol DSYM. */
66 d_decl_context (Dsymbol
*dsym
)
68 Dsymbol
*parent
= dsym
;
69 Declaration
*decl
= dsym
->isDeclaration ();
70 AggregateDeclaration
*ad
= dsym
->isAggregateDeclaration ();
72 while ((parent
= parent
->toParent2 ()))
74 /* We've reached the top-level module namespace.
75 Set DECL_CONTEXT as the NAMESPACE_DECL of the enclosing module,
76 but only for extern(D) symbols. */
77 if (parent
->isModule ())
79 if ((decl
!= NULL
&& decl
->linkage
!= LINK::d
)
80 || (ad
!= NULL
&& ad
->classKind
!= ClassKind::d
))
83 return build_import_decl (parent
);
86 /* Declarations marked as `static' or `__gshared' are never
87 part of any context except at module level. */
88 if (decl
!= NULL
&& decl
->isDataseg ())
91 /* Nested functions. */
92 FuncDeclaration
*fd
= parent
->isFuncDeclaration ();
94 return get_symbol_decl (fd
);
96 /* Methods of classes or structs. */
97 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration ();
100 tree context
= build_ctype (ad
->type
);
101 /* Want the underlying RECORD_TYPE. */
102 if (ad
->isClassDeclaration ())
103 context
= TREE_TYPE (context
);
112 /* Return a copy of record TYPE but safe to modify in any way. */
115 copy_aggregate_type (tree type
)
117 tree newtype
= build_distinct_type_copy (type
);
118 TYPE_FIELDS (newtype
) = copy_list (TYPE_FIELDS (type
));
120 for (tree f
= TYPE_FIELDS (newtype
); f
; f
= DECL_CHAIN (f
))
121 DECL_FIELD_CONTEXT (f
) = newtype
;
126 /* Return TRUE if declaration DECL is a reference type. */
129 declaration_reference_p (Declaration
*decl
)
131 Type
*tb
= decl
->type
->toBasetype ();
133 /* Declaration is a reference type. */
134 if (tb
->ty
== TY::Treference
|| decl
->storage_class
& (STCout
| STCref
))
140 /* Returns the real type for declaration DECL. */
143 declaration_type (Declaration
*decl
)
145 /* Lazy declarations are converted to delegates. */
146 if (decl
->storage_class
& STClazy
)
148 TypeFunction
*tf
= TypeFunction::create (NULL
, decl
->type
,
149 VARARGnone
, LINK::d
);
150 TypeDelegate
*t
= TypeDelegate::create (tf
);
151 return build_ctype (t
->merge2 ());
154 /* Static array va_list have array->pointer conversions applied. */
155 if (decl
->isParameter () && valist_array_p (decl
->type
))
157 Type
*valist
= decl
->type
->nextOf ()->pointerTo ();
158 valist
= valist
->castMod (decl
->type
->mod
);
159 return build_ctype (valist
);
162 tree type
= build_ctype (decl
->type
);
164 /* Parameter is passed by reference. */
165 if (declaration_reference_p (decl
))
166 return build_reference_type (type
);
168 /* The `this' parameter is always const. */
169 if (decl
->isThisDeclaration ())
170 return insert_type_modifiers (type
, MODconst
);
175 /* These should match the Declaration versions above
176 Return TRUE if parameter ARG is a reference type. */
179 parameter_reference_p (Parameter
*arg
)
181 Type
*tb
= arg
->type
->toBasetype ();
183 /* Parameter is a reference type. */
184 if (tb
->ty
== TY::Treference
|| arg
->storageClass
& (STCout
| STCref
))
190 /* Returns the real type for parameter ARG. */
193 parameter_type (Parameter
*arg
)
195 /* Lazy parameters are converted to delegates. */
196 if (arg
->storageClass
& STClazy
)
198 TypeFunction
*tf
= TypeFunction::create (NULL
, arg
->type
,
199 VARARGnone
, LINK::d
);
200 TypeDelegate
*t
= TypeDelegate::create (tf
);
201 return build_ctype (t
->merge2 ());
204 /* Static array va_list have array->pointer conversions applied. */
205 if (valist_array_p (arg
->type
))
207 Type
*valist
= arg
->type
->nextOf ()->pointerTo ();
208 valist
= valist
->castMod (arg
->type
->mod
);
209 return build_ctype (valist
);
212 tree type
= build_ctype (arg
->type
);
214 /* Parameter is passed by reference. */
215 if (parameter_reference_p (arg
))
216 return build_reference_type (type
);
218 /* Pass non-POD structs by invisible reference. */
219 if (TREE_ADDRESSABLE (type
))
221 type
= build_reference_type (type
);
222 /* There are no other pointer to this temporary. */
223 type
= build_qualified_type (type
, TYPE_QUAL_RESTRICT
);
226 /* Front-end has already taken care of type promotions. */
230 /* Build INTEGER_CST of type TYPE with the value VALUE. */
233 build_integer_cst (dinteger_t value
, tree type
)
235 /* The type is error_mark_node, we can't do anything. */
236 if (error_operand_p (type
))
239 return build_int_cst_type (type
, value
);
242 /* Build REAL_CST of type TOTYPE with the value VALUE. */
245 build_float_cst (const real_t
&value
, Type
*totype
)
248 TypeBasic
*tb
= totype
->isTypeBasic ();
250 gcc_assert (tb
!= NULL
);
252 tree type_node
= build_ctype (tb
);
253 real_convert (&new_value
.rv (), TYPE_MODE (type_node
), &value
.rv ());
255 return build_real (type_node
, new_value
.rv ());
258 /* Returns the .length component from the D dynamic array EXP. */
261 d_array_length (tree exp
)
263 if (error_operand_p (exp
))
266 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp
)));
268 /* Get the back-end type for the array and pick out the array
269 length field (assumed to be the first field). */
270 tree len_field
= TYPE_FIELDS (TREE_TYPE (exp
));
271 return component_ref (exp
, len_field
);
274 /* Returns the .ptr component from the D dynamic array EXP. */
277 d_array_ptr (tree exp
)
279 if (error_operand_p (exp
))
282 gcc_assert (TYPE_DYNAMIC_ARRAY (TREE_TYPE (exp
)));
284 /* Get the back-end type for the array and pick out the array
285 data pointer field (assumed to be the second field). */
286 tree ptr_field
= TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp
)));
287 return component_ref (exp
, ptr_field
);
290 /* Returns a constructor for D dynamic array type TYPE of .length LEN
291 and .ptr pointing to DATA. */
294 d_array_value (tree type
, tree len
, tree data
)
296 tree len_field
, ptr_field
;
297 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
299 gcc_assert (TYPE_DYNAMIC_ARRAY (type
));
300 len_field
= TYPE_FIELDS (type
);
301 ptr_field
= TREE_CHAIN (len_field
);
303 len
= convert (TREE_TYPE (len_field
), len
);
304 data
= convert (TREE_TYPE (ptr_field
), data
);
306 CONSTRUCTOR_APPEND_ELT (ce
, len_field
, len
);
307 CONSTRUCTOR_APPEND_ELT (ce
, ptr_field
, data
);
309 return build_constructor (type
, ce
);
312 /* Returns value representing the array length of expression EXP.
313 TYPE could be a dynamic or static array. */
316 get_array_length (tree exp
, Type
*type
)
318 Type
*tb
= type
->toBasetype ();
323 return size_int (tb
->isTypeSArray ()->dim
->toUInteger ());
326 return d_array_length (exp
);
329 error ("cannot determine the length of a %qs", type
->toChars ());
330 return error_mark_node
;
334 /* Create BINFO for a ClassDeclaration's inheritance tree.
335 InterfaceDeclaration's are not included. */
338 build_class_binfo (tree super
, ClassDeclaration
*cd
)
340 tree binfo
= make_tree_binfo (1);
341 tree ctype
= build_ctype (cd
->type
);
343 /* Want RECORD_TYPE, not POINTER_TYPE. */
344 BINFO_TYPE (binfo
) = TREE_TYPE (ctype
);
345 BINFO_INHERITANCE_CHAIN (binfo
) = super
;
346 BINFO_OFFSET (binfo
) = integer_zero_node
;
349 BINFO_BASE_APPEND (binfo
, build_class_binfo (binfo
, cd
->baseClass
));
354 /* Create BINFO for an InterfaceDeclaration's inheritance tree.
355 In order to access all inherited methods in the debugger,
356 the entire tree must be described.
357 This function makes assumptions about interface layout. */
360 build_interface_binfo (tree super
, ClassDeclaration
*cd
, unsigned &offset
)
362 tree binfo
= make_tree_binfo (cd
->baseclasses
->length
);
363 tree ctype
= build_ctype (cd
->type
);
365 /* Want RECORD_TYPE, not POINTER_TYPE. */
366 BINFO_TYPE (binfo
) = TREE_TYPE (ctype
);
367 BINFO_INHERITANCE_CHAIN (binfo
) = super
;
368 BINFO_OFFSET (binfo
) = size_int (offset
* target
.ptrsize
);
369 BINFO_VIRTUAL_P (binfo
) = 1;
371 for (size_t i
= 0; i
< cd
->baseclasses
->length
; i
++, offset
++)
373 BaseClass
*bc
= (*cd
->baseclasses
)[i
];
374 BINFO_BASE_APPEND (binfo
, build_interface_binfo (binfo
, bc
->sym
, offset
));
380 /* Returns the .funcptr component from the D delegate EXP. */
383 delegate_method (tree exp
)
385 /* Get the back-end type for the delegate and pick out the funcptr field
386 (assumed to be the second field). */
387 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp
)));
388 tree method_field
= TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp
)));
389 return component_ref (exp
, method_field
);
392 /* Returns the .object component from the delegate EXP. */
395 delegate_object (tree exp
)
397 /* Get the back-end type for the delegate and pick out the object field
398 (assumed to be the first field). */
399 gcc_assert (TYPE_DELEGATE (TREE_TYPE (exp
)));
400 tree obj_field
= TYPE_FIELDS (TREE_TYPE (exp
));
401 return component_ref (exp
, obj_field
);
404 /* Build a delegate literal of type TYPE whose pointer function is
405 METHOD, and hidden object is OBJECT. */
408 build_delegate_cst (tree method
, tree object
, Type
*type
)
410 tree ctor
= make_node (CONSTRUCTOR
);
413 Type
*tb
= type
->toBasetype ();
414 if (tb
->ty
== TY::Tdelegate
)
415 ctype
= build_ctype (type
);
418 /* Convert a function method into an anonymous delegate. */
419 ctype
= make_struct_type ("delegate()", 2,
420 get_identifier ("object"), TREE_TYPE (object
),
421 get_identifier ("func"), TREE_TYPE (method
));
422 TYPE_DELEGATE (ctype
) = 1;
425 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
426 CONSTRUCTOR_APPEND_ELT (ce
, TYPE_FIELDS (ctype
), object
);
427 CONSTRUCTOR_APPEND_ELT (ce
, TREE_CHAIN (TYPE_FIELDS (ctype
)), method
);
429 CONSTRUCTOR_ELTS (ctor
) = ce
;
430 TREE_TYPE (ctor
) = ctype
;
435 /* Builds a temporary tree to store the CALLEE and OBJECT
436 of a method call expression of type TYPE. */
439 build_method_call (tree callee
, tree object
, Type
*type
)
441 tree t
= build_delegate_cst (callee
, object
, type
);
442 METHOD_CALL_EXPR (t
) = 1;
446 /* Extract callee and object from T and return in to CALLEE and OBJECT. */
449 extract_from_method_call (tree t
, tree
&callee
, tree
&object
)
451 gcc_assert (METHOD_CALL_EXPR (t
));
452 object
= CONSTRUCTOR_ELT (t
, 0)->value
;
453 callee
= CONSTRUCTOR_ELT (t
, 1)->value
;
456 /* Build a typeof(null) constant of type TYPE. Handles certain special case
457 conversions, where the underlying type is an aggregate with a nullable
461 build_typeof_null_value (Type
*type
)
463 Type
*tb
= type
->toBasetype ();
466 /* For dynamic arrays, set length and pointer fields to zero. */
467 if (tb
->ty
== TY::Tarray
)
468 value
= d_array_value (build_ctype (type
), size_int (0), null_pointer_node
);
470 /* For associative arrays, set the pointer field to null. */
471 else if (tb
->ty
== TY::Taarray
)
473 tree ctype
= build_ctype (type
);
474 gcc_assert (TYPE_ASSOCIATIVE_ARRAY (ctype
));
476 value
= build_constructor_single (ctype
, TYPE_FIELDS (ctype
),
480 /* For delegates, set the frame and function pointer fields to null. */
481 else if (tb
->ty
== TY::Tdelegate
)
482 value
= build_delegate_cst (null_pointer_node
, null_pointer_node
, type
);
484 /* Simple zero constant for all other types. */
486 value
= build_zero_cst (build_ctype (type
));
488 TREE_CONSTANT (value
) = 1;
492 /* Build a dereference into the virtual table for OBJECT to retrieve
493 a function pointer of type FNTYPE at position INDEX. */
496 build_vindex_ref (tree object
, tree fntype
, size_t index
)
498 /* The vtable is the first field. Interface methods are also in the class's
499 vtable, so we don't need to convert from a class to an interface. */
500 tree result
= build_deref (object
);
501 result
= component_ref (result
, TYPE_FIELDS (TREE_TYPE (result
)));
503 gcc_assert (POINTER_TYPE_P (fntype
));
505 return build_memref (fntype
, result
, size_int (target
.ptrsize
* index
));
508 /* Return TRUE if EXP is a valid lvalue. Lvalue references cannot be
509 made into temporaries, otherwise any assignments will be lost. */
514 const enum tree_code code
= TREE_CODE (exp
);
526 return !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (exp
));
532 return lvalue_p (TREE_OPERAND (exp
, 0));
535 return (lvalue_p (TREE_OPERAND (exp
, 1)
536 ? TREE_OPERAND (exp
, 1)
537 : TREE_OPERAND (exp
, 0))
538 && lvalue_p (TREE_OPERAND (exp
, 2)));
544 return lvalue_p (TREE_OPERAND (exp
, 1));
551 /* Create a SAVE_EXPR if EXP might have unwanted side effects if referenced
552 more than once in an expression. */
555 d_save_expr (tree exp
)
557 if (TREE_SIDE_EFFECTS (exp
))
560 return stabilize_reference (exp
);
562 return save_expr (exp
);
568 /* VALUEP is an expression we want to pre-evaluate or perform a computation on.
569 The expression returned by this function is the part whose value we don't
570 care about, storing the value in VALUEP. Callers must ensure that the
571 returned expression is evaluated before VALUEP. */
574 stabilize_expr (tree
*valuep
)
577 const enum tree_code code
= TREE_CODE (expr
);
584 /* Given ((e1, ...), eN):
585 Store the last RHS 'eN' expression in VALUEP. */
586 lhs
= TREE_OPERAND (expr
, 0);
587 rhs
= TREE_OPERAND (expr
, 1);
588 lhs
= compound_expr (lhs
, stabilize_expr (&rhs
));
597 /* Return a TARGET_EXPR, initializing the DECL with EXP. */
600 build_target_expr (tree decl
, tree exp
)
602 tree type
= TREE_TYPE (decl
);
603 tree result
= build4 (TARGET_EXPR
, type
, decl
, exp
, NULL_TREE
, NULL_TREE
);
605 if (EXPR_HAS_LOCATION (exp
))
606 SET_EXPR_LOCATION (result
, EXPR_LOCATION (exp
));
608 /* If decl must always reside in memory. */
609 if (TREE_ADDRESSABLE (type
))
610 d_mark_addressable (decl
);
612 /* Always set TREE_SIDE_EFFECTS so that expand_expr does not ignore the
613 TARGET_EXPR. If there really turn out to be no side effects, then the
614 optimizer should be able to remove it. */
615 TREE_SIDE_EFFECTS (result
) = 1;
620 /* Like the above function, but initializes a new temporary. */
623 force_target_expr (tree exp
)
625 tree decl
= build_decl (input_location
, VAR_DECL
, NULL_TREE
,
627 DECL_CONTEXT (decl
) = current_function_decl
;
628 DECL_ARTIFICIAL (decl
) = 1;
629 DECL_IGNORED_P (decl
) = 1;
630 layout_decl (decl
, 0);
632 return build_target_expr (decl
, exp
);
635 /* Returns the address of the expression EXP. */
638 build_address (tree exp
)
640 if (error_operand_p (exp
))
644 tree type
= TREE_TYPE (exp
);
646 if (TREE_CODE (exp
) == STRING_CST
)
648 /* Just convert string literals (char[]) to C-style strings (char *),
649 otherwise the latter method (char[]*) causes conversion problems
650 during gimplification. */
651 ptrtype
= build_pointer_type (TREE_TYPE (type
));
653 else if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (va_list_type_node
)
654 && TREE_CODE (TYPE_MAIN_VARIANT (type
)) == ARRAY_TYPE
)
656 /* Special case for va_list, allow arrays to decay to a pointer. */
657 ptrtype
= build_pointer_type (TREE_TYPE (type
));
660 ptrtype
= build_pointer_type (type
);
662 /* Maybe rewrite: &(e1, e2) => (e1, &e2). */
663 tree init
= stabilize_expr (&exp
);
665 /* Can't take the address of a manifest constant, instead use its value. */
666 if (TREE_CODE (exp
) == CONST_DECL
)
667 exp
= DECL_INITIAL (exp
);
669 /* Some expression lowering may request an address of a compile-time constant,
670 or other non-lvalue expression. Make sure it is assigned to a location we
672 if (CONSTANT_CLASS_P (exp
) && TREE_CODE (exp
) != STRING_CST
)
673 exp
= force_target_expr (exp
);
674 else if (TREE_CODE (exp
) == CALL_EXPR
)
676 /* When a struct or array is returned in registers, we need to again fill
677 in all alignment holes. */
678 if (AGGREGATE_TYPE_P (TREE_TYPE (exp
))
679 && !aggregate_value_p (TREE_TYPE (exp
), exp
))
681 tree tmp
= build_local_temp (TREE_TYPE (exp
));
682 init
= compound_expr (init
, build_memset_call (tmp
));
683 init
= compound_expr (init
, modify_expr (tmp
, exp
));
687 exp
= force_target_expr (exp
);
690 d_mark_addressable (exp
);
691 exp
= build_fold_addr_expr_with_type_loc (input_location
, exp
, ptrtype
);
693 if (TREE_CODE (exp
) == ADDR_EXPR
)
694 TREE_NO_TRAMPOLINE (exp
) = 1;
696 return compound_expr (init
, exp
);
699 /* Mark EXP saying that we need to be able to take the
700 address of it; it should not be allocated in a register. */
703 d_mark_addressable (tree exp
)
705 switch (TREE_CODE (exp
))
712 d_mark_addressable (TREE_OPERAND (exp
, 0));
720 TREE_ADDRESSABLE (exp
) = 1;
724 TREE_ADDRESSABLE (exp
) = 1;
728 TREE_ADDRESSABLE (exp
) = 1;
729 d_mark_addressable (TREE_OPERAND (exp
, 0));
739 /* Mark EXP as "used" in the program for the benefit of
740 -Wunused warning purposes. */
743 d_mark_used (tree exp
)
745 switch (TREE_CODE (exp
))
763 d_mark_used (TREE_OPERAND (exp
, 0));
767 d_mark_used (TREE_OPERAND (exp
, 0));
768 d_mark_used (TREE_OPERAND (exp
, 1));
777 /* Mark EXP as read, not just set, for set but not used -Wunused
781 d_mark_read (tree exp
)
783 switch (TREE_CODE (exp
))
788 DECL_READ_P (exp
) = 1;
799 d_mark_read (TREE_OPERAND (exp
, 0));
803 d_mark_read (TREE_OPERAND (exp
, 1));
812 /* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2. */
815 build_memcmp_call (tree ptr1
, tree ptr2
, tree num
)
817 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP
), 3,
821 /* Build a call to memcpy(), copies the first NUM bytes of SRC into DST. */
824 build_memcpy_call (tree dst
, tree src
, tree num
)
826 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY
), 3,
830 /* Build a call to memset(), fills the first NUM bytes of PTR with zeros.
831 If NUM is NULL, then we expect PTR to be object that requires filling. */
834 build_memset_call (tree ptr
, tree num
)
836 if (num
== NULL_TREE
)
838 gcc_assert (TREE_CODE (ptr
) != ADDR_EXPR
);
839 num
= TYPE_SIZE_UNIT (TREE_TYPE (ptr
));
840 ptr
= build_address (ptr
);
843 /* Use a zero constant to fill the destination if setting the entire object.
844 For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
845 which can then be merged with other stores to the object. */
846 tree valtype
= TREE_TYPE (TREE_TYPE (ptr
));
847 if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype
), num
))
849 tree cst
= build_zero_cst (valtype
);
850 if (TREE_CODE (cst
) == CONSTRUCTOR
)
851 return build_memcpy_call (ptr
, build_address (cst
), num
);
853 return modify_expr (build_deref (ptr
), cst
);
856 return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET
), 3,
857 ptr
, integer_zero_node
, num
);
860 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
861 This is because we don't guarantee that padding is zero-initialized for
862 a stack variable, so we can't use memcmp to compare struct values. */
865 identity_compare_p (StructDeclaration
*sd
)
867 if (sd
->isUnionDeclaration ())
872 for (size_t i
= 0; i
< sd
->fields
.length
; i
++)
874 VarDeclaration
*vd
= sd
->fields
[i
];
875 Type
*tb
= vd
->type
->toBasetype ();
877 /* Check inner data structures. */
878 if (TypeStruct
*ts
= tb
->isTypeStruct ())
880 if (!identity_compare_p (ts
->sym
))
884 /* Check for types that may have padding. */
885 if ((tb
->ty
== TY::Tcomplex80
886 || tb
->ty
== TY::Tfloat80
887 || tb
->ty
== TY::Timaginary80
)
888 && target
.realpad
!= 0)
891 if (offset
<= vd
->offset
)
893 /* There's a hole in the struct. */
894 if (offset
!= vd
->offset
)
897 offset
+= vd
->type
->size ();
901 /* Any trailing padding may not be zero. */
902 if (offset
< sd
->structsize
)
908 /* Build a floating-point identity comparison between T1 and T2, ignoring any
909 excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */
912 build_float_identity (tree_code code
, tree t1
, tree t2
)
914 tree size
= size_int (TYPE_PRECISION (TREE_TYPE (t1
)) / BITS_PER_UNIT
);
915 tree result
= build_memcmp_call (build_address (t1
),
916 build_address (t2
), size
);
917 return build_boolop (code
, result
, integer_zero_node
);
920 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
921 CODE is the EQ_EXPR or NE_EXPR comparison. */
924 lower_struct_comparison (tree_code code
, StructDeclaration
*sd
,
927 tree_code tcode
= (code
== EQ_EXPR
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
928 tree tmemcmp
= NULL_TREE
;
930 /* We can skip the compare if the structs are empty. */
931 if (sd
->fields
.length
== 0)
933 tmemcmp
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
934 if (TREE_SIDE_EFFECTS (t2
))
935 tmemcmp
= compound_expr (t2
, tmemcmp
);
936 if (TREE_SIDE_EFFECTS (t1
))
937 tmemcmp
= compound_expr (t1
, tmemcmp
);
942 /* Let back-end take care of union comparisons. */
943 if (sd
->isUnionDeclaration ())
945 tmemcmp
= build_memcmp_call (build_address (t1
), build_address (t2
),
946 size_int (sd
->structsize
));
947 return build_boolop (code
, tmemcmp
, integer_zero_node
);
950 for (size_t i
= 0; i
< sd
->fields
.length
; i
++)
952 VarDeclaration
*vd
= sd
->fields
[i
];
953 Type
*type
= vd
->type
->toBasetype ();
954 tree sfield
= get_symbol_decl (vd
);
956 tree t1ref
= component_ref (t1
, sfield
);
957 tree t2ref
= component_ref (t2
, sfield
);
960 if (TypeStruct
*ts
= type
->isTypeStruct ())
962 /* Compare inner data structures. */
963 tcmp
= lower_struct_comparison (code
, ts
->sym
, t1ref
, t2ref
);
965 else if (type
->ty
!= TY::Tvector
&& type
->isintegral ())
967 /* Integer comparison, no special handling required. */
968 tcmp
= build_boolop (code
, t1ref
, t2ref
);
970 else if (type
->ty
!= TY::Tvector
&& type
->isfloating ())
972 /* Floating-point comparison, don't compare padding in type. */
973 if (!type
->iscomplex ())
974 tcmp
= build_float_identity (code
, t1ref
, t2ref
);
977 tree req
= build_float_identity (code
, real_part (t1ref
),
979 tree ieq
= build_float_identity (code
, imaginary_part (t1ref
),
980 imaginary_part (t2ref
));
982 tcmp
= build_boolop (tcode
, req
, ieq
);
987 tree stype
= build_ctype (type
);
988 opt_scalar_int_mode mode
= int_mode_for_mode (TYPE_MODE (stype
));
992 /* Compare field bits as their corresponding integer type.
993 *((T*) &t1) == *((T*) &t2) */
994 tree tmode
= lang_hooks
.types
.type_for_mode (mode
.require (), 1);
996 if (tmode
== NULL_TREE
)
997 tmode
= make_unsigned_type (GET_MODE_BITSIZE (mode
.require ()));
999 t1ref
= build_vconvert (tmode
, t1ref
);
1000 t2ref
= build_vconvert (tmode
, t2ref
);
1002 tcmp
= build_boolop (code
, t1ref
, t2ref
);
1006 /* Simple memcmp between types. */
1007 tcmp
= build_memcmp_call (build_address (t1ref
),
1008 build_address (t2ref
),
1009 TYPE_SIZE_UNIT (stype
));
1010 tcmp
= build_boolop (code
, tcmp
, integer_zero_node
);
1014 tmemcmp
= (tmemcmp
) ? build_boolop (tcode
, tmemcmp
, tcmp
) : tcmp
;
1021 /* Build an equality expression between two RECORD_TYPES T1 and T2 of type SD.
1022 If possible, use memcmp, otherwise field-by-field comparison is done.
1023 CODE is the EQ_EXPR or NE_EXPR comparison. */
1026 build_struct_comparison (tree_code code
, StructDeclaration
*sd
,
1029 /* We can skip the compare if the structs are empty. */
1030 if (sd
->fields
.length
== 0)
1032 tree exp
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
1033 if (TREE_SIDE_EFFECTS (t2
))
1034 exp
= compound_expr (t2
, exp
);
1035 if (TREE_SIDE_EFFECTS (t1
))
1036 exp
= compound_expr (t1
, exp
);
1041 /* Make temporaries to prevent multiple evaluations. */
1042 tree t1init
= stabilize_expr (&t1
);
1043 tree t2init
= stabilize_expr (&t2
);
1046 t1
= d_save_expr (t1
);
1047 t2
= d_save_expr (t2
);
1049 /* Bitwise comparison of structs not returned in memory may not work
1050 due to data holes loosing its zero padding upon return.
1051 As a heuristic, small structs are not compared using memcmp either. */
1052 if (TYPE_MODE (TREE_TYPE (t1
)) != BLKmode
|| !identity_compare_p (sd
))
1053 result
= lower_struct_comparison (code
, sd
, t1
, t2
);
1056 /* Do bit compare of structs. */
1057 tree tmemcmp
= build_memcmp_call (build_address (t1
), build_address (t2
),
1058 size_int (sd
->structsize
));
1059 result
= build_boolop (code
, tmemcmp
, integer_zero_node
);
1062 return compound_expr (compound_expr (t1init
, t2init
), result
);
1065 /* Build an equality expression between two ARRAY_TYPES of size LENGTH.
1066 The pointer references are T1 and T2, and the element type is SD.
1067 CODE is the EQ_EXPR or NE_EXPR comparison. */
1070 build_array_struct_comparison (tree_code code
, StructDeclaration
*sd
,
1071 tree length
, tree t1
, tree t2
)
1073 tree_code tcode
= (code
== EQ_EXPR
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
1075 /* Build temporary for the result of the comparison.
1076 Initialize as either 0 or 1 depending on operation. */
1077 tree result
= build_local_temp (d_bool_type
);
1078 tree init
= build_boolop (code
, integer_zero_node
, integer_zero_node
);
1079 add_stmt (build_assign (INIT_EXPR
, result
, init
));
1081 /* Cast pointer-to-array to pointer-to-struct. */
1082 tree ptrtype
= build_ctype (sd
->type
->pointerTo ());
1083 tree lentype
= TREE_TYPE (length
);
1085 push_binding_level (level_block
);
1088 /* Build temporary locals for length and pointers. */
1089 tree t
= build_local_temp (size_type_node
);
1090 add_stmt (build_assign (INIT_EXPR
, t
, length
));
1093 t
= build_local_temp (ptrtype
);
1094 add_stmt (build_assign (INIT_EXPR
, t
, d_convert (ptrtype
, t1
)));
1097 t
= build_local_temp (ptrtype
);
1098 add_stmt (build_assign (INIT_EXPR
, t
, d_convert (ptrtype
, t2
)));
1101 /* Build loop for comparing each element. */
1104 /* Exit logic for the loop.
1105 if (length == 0 || result OP 0) break; */
1106 t
= build_boolop (EQ_EXPR
, length
, d_convert (lentype
, integer_zero_node
));
1107 t
= build_boolop (TRUTH_ORIF_EXPR
, t
, build_boolop (code
, result
,
1108 boolean_false_node
));
1109 t
= build1 (EXIT_EXPR
, void_type_node
, t
);
1112 /* Do comparison, caching the value.
1113 result = result OP (*t1 == *t2); */
1114 t
= build_struct_comparison (code
, sd
, build_deref (t1
), build_deref (t2
));
1115 t
= build_boolop (tcode
, result
, t
);
1116 t
= modify_expr (result
, t
);
1119 /* Move both pointers to next element position.
1121 tree size
= d_convert (ptrtype
, TYPE_SIZE_UNIT (TREE_TYPE (ptrtype
)));
1122 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, t1
, size
);
1124 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, t2
, size
);
1127 /* Decrease loop counter.
1129 t
= build2 (POSTDECREMENT_EXPR
, lentype
, length
,
1130 d_convert (lentype
, integer_one_node
));
1133 /* Pop statements and finish loop. */
1134 tree body
= pop_stmt_list ();
1135 add_stmt (build1 (LOOP_EXPR
, void_type_node
, body
));
1137 /* Wrap it up into a bind expression. */
1138 tree stmt_list
= pop_stmt_list ();
1139 tree block
= pop_binding_level ();
1141 body
= build3 (BIND_EXPR
, void_type_node
,
1142 BLOCK_VARS (block
), stmt_list
, block
);
1144 return compound_expr (body
, result
);
1147 /* Build a constructor for a variable of aggregate type TYPE using the
1148 initializer INIT, an ordered flat list of fields and values provided
1149 by the frontend. The returned constructor should be a value that
1150 matches the layout of TYPE. */
1153 build_struct_literal (tree type
, vec
<constructor_elt
, va_gc
> *init
)
1155 /* If the initializer was empty, use default zero initialization. */
1156 if (vec_safe_is_empty (init
))
1157 return build_constructor (type
, NULL
);
1159 /* Struct literals can be seen for special enums representing `_Complex',
1160 make sure to reinterpret the literal as the correct type. */
1161 if (COMPLEX_FLOAT_TYPE_P (type
))
1163 gcc_assert (vec_safe_length (init
) == 2);
1164 return complex_expr (type
, (*init
)[0].value
, (*init
)[1].value
);
1167 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
1168 HOST_WIDE_INT offset
= 0;
1169 bool constant_p
= true;
1170 bool finished
= false;
1172 /* Walk through each field, matching our initializer list. */
1173 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
1175 bool is_initialized
= false;
1178 if (DECL_NAME (field
) == NULL_TREE
1179 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field
))
1180 && ANON_AGGR_TYPE_P (TREE_TYPE (field
)))
1182 /* Search all nesting aggregates, if nothing is found, then
1183 this will return an empty initializer to fill the hole. */
1184 value
= build_struct_literal (TREE_TYPE (field
), init
);
1186 if (!initializer_zerop (value
))
1187 is_initialized
= true;
1191 /* Search for the value to initialize the next field. Once found,
1192 pop it from the init list so we don't look at it again. */
1193 unsigned HOST_WIDE_INT idx
;
1196 FOR_EACH_CONSTRUCTOR_ELT (init
, idx
, index
, value
)
1198 /* If the index is NULL, then just assign it to the next field.
1199 This comes from layout_typeinfo(), which generates a flat
1200 list of values that we must shape into the record type. */
1201 if (index
== field
|| index
== NULL_TREE
)
1203 init
->ordered_remove (idx
);
1205 is_initialized
= true;
1213 HOST_WIDE_INT fieldpos
= int_byte_position (field
);
1214 gcc_assert (value
!= NULL_TREE
);
1216 /* Must not initialize fields that overlap. */
1217 if (fieldpos
< offset
)
1219 /* Find the nearest user defined type and field. */
1221 while (ANON_AGGR_TYPE_P (vtype
))
1222 vtype
= TYPE_CONTEXT (vtype
);
1224 tree vfield
= field
;
1225 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (vfield
))
1226 && ANON_AGGR_TYPE_P (TREE_TYPE (vfield
)))
1227 vfield
= TYPE_FIELDS (TREE_TYPE (vfield
));
1229 /* Must not generate errors for compiler generated fields. */
1230 gcc_assert (TYPE_NAME (vtype
) && DECL_NAME (vfield
));
1231 error ("overlapping initializer for field %qT.%qD",
1232 TYPE_NAME (vtype
), DECL_NAME (vfield
));
1235 if (!TREE_CONSTANT (value
))
1238 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
1240 /* For unions, only the first field is initialized, any other field
1241 initializers found for this union are drained and ignored. */
1242 if (TREE_CODE (type
) == UNION_TYPE
)
1246 /* Move offset to the next position in the struct. */
1247 if (TREE_CODE (type
) == RECORD_TYPE
)
1249 offset
= int_byte_position (field
)
1250 + int_size_in_bytes (TREE_TYPE (field
));
1253 /* If all initializers have been assigned, there's nothing else to do. */
1254 if (vec_safe_is_empty (init
))
1258 /* Ensure that we have consumed all values. */
1259 gcc_assert (vec_safe_is_empty (init
) || ANON_AGGR_TYPE_P (type
));
1261 tree ctor
= build_constructor (type
, ve
);
1264 TREE_CONSTANT (ctor
) = 1;
1269 /* Given the TYPE of an anonymous field inside T, return the
1270 FIELD_DECL for the field. If not found return NULL_TREE.
1271 Because anonymous types can nest, we must also search all
1272 anonymous fields that are directly reachable. */
1275 lookup_anon_field (tree t
, tree type
)
1277 t
= TYPE_MAIN_VARIANT (t
);
1279 for (tree field
= TYPE_FIELDS (t
); field
; field
= DECL_CHAIN (field
))
1281 if (DECL_NAME (field
) == NULL_TREE
)
1283 /* If we find it directly, return the field. */
1284 if (type
== TYPE_MAIN_VARIANT (TREE_TYPE (field
)))
1287 /* Otherwise, it could be nested, search harder. */
1288 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field
))
1289 && ANON_AGGR_TYPE_P (TREE_TYPE (field
)))
1291 tree subfield
= lookup_anon_field (TREE_TYPE (field
), type
);
1301 /* Builds OBJECT.FIELD component reference. */
1304 component_ref (tree object
, tree field
)
1306 if (error_operand_p (object
) || error_operand_p (field
))
1307 return error_mark_node
;
1309 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
1311 /* Maybe rewrite: (e1, e2).field => (e1, e2.field) */
1312 tree init
= stabilize_expr (&object
);
1314 /* If the FIELD is from an anonymous aggregate, generate a reference
1315 to the anonymous data member, and recur to find FIELD. */
1316 if (ANON_AGGR_TYPE_P (DECL_CONTEXT (field
)))
1318 tree anonymous_field
= lookup_anon_field (TREE_TYPE (object
),
1319 DECL_CONTEXT (field
));
1320 object
= component_ref (object
, anonymous_field
);
1323 tree result
= fold_build3_loc (input_location
, COMPONENT_REF
,
1324 TREE_TYPE (field
), object
, field
, NULL_TREE
);
1326 return compound_expr (init
, result
);
1329 /* Build an assignment expression of lvalue LHS from value RHS.
1330 CODE is the code for a binary operator that we use to combine
1331 the old value of LHS with RHS to get the new value. */
1334 build_assign (tree_code code
, tree lhs
, tree rhs
)
1337 tree init
= stabilize_expr (&lhs
);
1338 init
= compound_expr (init
, stabilize_expr (&rhs
));
1340 /* If initializing the LHS using a function that returns via NRVO. */
1341 if (code
== INIT_EXPR
&& TREE_CODE (rhs
) == CALL_EXPR
1342 && AGGREGATE_TYPE_P (TREE_TYPE (rhs
))
1343 && aggregate_value_p (TREE_TYPE (rhs
), rhs
))
1345 /* Mark as addressable here, which should ensure the return slot is the
1346 address of the LHS expression, taken care of by back-end. */
1347 d_mark_addressable (lhs
);
1348 CALL_EXPR_RETURN_SLOT_OPT (rhs
) = true;
1350 /* If modifying an LHS whose type is marked TREE_ADDRESSABLE. */
1351 else if (code
== MODIFY_EXPR
&& TREE_ADDRESSABLE (TREE_TYPE (lhs
))
1352 && TREE_SIDE_EFFECTS (rhs
) && TREE_CODE (rhs
) != TARGET_EXPR
)
1354 /* LHS may be referenced by the RHS expression, so force a temporary. */
1355 rhs
= force_target_expr (rhs
);
1358 /* The LHS assignment replaces the temporary in TARGET_EXPR_SLOT. */
1359 if (TREE_CODE (rhs
) == TARGET_EXPR
)
1361 /* If CODE is not INIT_EXPR, can't initialize LHS directly,
1362 since that would cause the LHS to be constructed twice. */
1363 if (code
!= INIT_EXPR
)
1365 init
= compound_expr (init
, rhs
);
1366 result
= build_assign (code
, lhs
, TARGET_EXPR_SLOT (rhs
));
1370 d_mark_addressable (lhs
);
1371 TARGET_EXPR_INITIAL (rhs
) = build_assign (code
, lhs
,
1372 TARGET_EXPR_INITIAL (rhs
));
1378 /* Simple assignment. */
1379 result
= fold_build2_loc (input_location
, code
,
1380 TREE_TYPE (lhs
), lhs
, rhs
);
1383 return compound_expr (init
, result
);
1386 /* Build an assignment expression of lvalue LHS from value RHS. */
1389 modify_expr (tree lhs
, tree rhs
)
1391 return build_assign (MODIFY_EXPR
, lhs
, rhs
);
1394 /* Return EXP represented as TYPE. */
1397 build_nop (tree type
, tree exp
)
1399 if (error_operand_p (exp
))
1402 /* Maybe rewrite: cast(TYPE)(e1, e2) => (e1, cast(TYPE) e2) */
1403 tree init
= stabilize_expr (&exp
);
1404 exp
= fold_build1_loc (input_location
, NOP_EXPR
, type
, exp
);
1406 return compound_expr (init
, exp
);
1409 /* Return EXP to be viewed as being another type TYPE. Same as build_nop,
1410 except that EXP is type-punned, rather than a straight-forward cast. */
1413 build_vconvert (tree type
, tree exp
)
1415 /* Building *(cast(TYPE *)&e1) directly rather then using VIEW_CONVERT_EXPR
1416 makes sure this works for vector-to-array viewing, or if EXP ends up being
1417 used as the LHS of a MODIFY_EXPR. */
1418 return indirect_ref (type
, build_address (exp
));
1421 /* Maybe warn about ARG being an address that can never be null. */
1424 warn_for_null_address (tree arg
)
1426 if (TREE_CODE (arg
) == ADDR_EXPR
1427 && decl_with_nonnull_addr_p (TREE_OPERAND (arg
, 0)))
1428 warning (OPT_Waddress
,
1429 "the address of %qD will never be %<null%>",
1430 TREE_OPERAND (arg
, 0));
1433 /* Build a boolean ARG0 op ARG1 expression. */
1436 build_boolop (tree_code code
, tree arg0
, tree arg1
)
1438 /* Aggregate comparisons may get lowered to a call to builtin memcmp,
1439 so need to remove all side effects incase its address is taken. */
1440 if (AGGREGATE_TYPE_P (TREE_TYPE (arg0
)))
1441 arg0
= d_save_expr (arg0
);
1442 if (AGGREGATE_TYPE_P (TREE_TYPE (arg1
)))
1443 arg1
= d_save_expr (arg1
);
1445 if (VECTOR_TYPE_P (TREE_TYPE (arg0
)) && VECTOR_TYPE_P (TREE_TYPE (arg1
)))
1447 /* Build a vector comparison.
1448 VEC_COND_EXPR <e1 op e2, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
1449 tree type
= TREE_TYPE (arg0
);
1450 tree cmptype
= truth_type_for (type
);
1451 tree cmp
= fold_build2_loc (input_location
, code
, cmptype
, arg0
, arg1
);
1453 return fold_build3_loc (input_location
, VEC_COND_EXPR
, type
, cmp
,
1454 build_minus_one_cst (type
),
1455 build_zero_cst (type
));
1458 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
1460 /* Check if comparing the address of a variable to null. */
1461 if (POINTER_TYPE_P (TREE_TYPE (arg0
)) && integer_zerop (arg1
))
1462 warn_for_null_address (arg0
);
1463 if (POINTER_TYPE_P (TREE_TYPE (arg1
)) && integer_zerop (arg0
))
1464 warn_for_null_address (arg1
);
1467 return fold_build2_loc (input_location
, code
, d_bool_type
,
1468 arg0
, d_convert (TREE_TYPE (arg0
), arg1
));
1471 /* Return a COND_EXPR. ARG0, ARG1, and ARG2 are the three
1472 arguments to the conditional expression. */
1475 build_condition (tree type
, tree arg0
, tree arg1
, tree arg2
)
1477 if (arg1
== void_node
)
1478 arg1
= build_empty_stmt (input_location
);
1480 if (arg2
== void_node
)
1481 arg2
= build_empty_stmt (input_location
);
1483 return fold_build3_loc (input_location
, COND_EXPR
,
1484 type
, arg0
, arg1
, arg2
);
1488 build_vcondition (tree arg0
, tree arg1
, tree arg2
)
1490 return build_condition (void_type_node
, arg0
, arg1
, arg2
);
1493 /* Build a compound expr to join ARG0 and ARG1 together. */
1496 compound_expr (tree arg0
, tree arg1
)
1498 if (arg1
== NULL_TREE
)
1501 if (arg0
== NULL_TREE
|| !TREE_SIDE_EFFECTS (arg0
))
1504 /* Remove intermediate expressions that have no side-effects. */
1505 while (TREE_CODE (arg0
) == COMPOUND_EXPR
1506 && !TREE_SIDE_EFFECTS (TREE_OPERAND (arg0
, 1)))
1507 arg0
= TREE_OPERAND (arg0
, 0);
1509 if (TREE_CODE (arg1
) == TARGET_EXPR
)
1511 /* If the rhs is a TARGET_EXPR, then build the compound expression
1512 inside the target_expr's initializer. This helps the compiler
1513 to eliminate unnecessary temporaries. */
1514 tree init
= compound_expr (arg0
, TARGET_EXPR_INITIAL (arg1
));
1515 TARGET_EXPR_INITIAL (arg1
) = init
;
1520 return fold_build2_loc (input_location
, COMPOUND_EXPR
,
1521 TREE_TYPE (arg1
), arg0
, arg1
);
1524 /* Build a return expression. */
1527 return_expr (tree ret
)
1529 /* Same as build_assign, the DECL_RESULT assignment replaces the temporary
1530 in TARGET_EXPR_SLOT. */
1531 if (ret
!= NULL_TREE
&& TREE_CODE (ret
) == TARGET_EXPR
)
1533 tree exp
= TARGET_EXPR_INITIAL (ret
);
1534 tree init
= stabilize_expr (&exp
);
1536 exp
= fold_build1_loc (input_location
, RETURN_EXPR
, void_type_node
, exp
);
1537 TARGET_EXPR_INITIAL (ret
) = compound_expr (init
, exp
);
1542 return fold_build1_loc (input_location
, RETURN_EXPR
,
1543 void_type_node
, ret
);
1546 /* Return the product of ARG0 and ARG1 as a size_type_node. */
1549 size_mult_expr (tree arg0
, tree arg1
)
1551 return fold_build2_loc (input_location
, MULT_EXPR
, size_type_node
,
1552 d_convert (size_type_node
, arg0
),
1553 d_convert (size_type_node
, arg1
));
1557 /* Return the real part of CE, which should be a complex expression. */
1562 return fold_build1_loc (input_location
, REALPART_EXPR
,
1563 TREE_TYPE (TREE_TYPE (ce
)), ce
);
1566 /* Return the imaginary part of CE, which should be a complex expression. */
1569 imaginary_part (tree ce
)
1571 return fold_build1_loc (input_location
, IMAGPART_EXPR
,
1572 TREE_TYPE (TREE_TYPE (ce
)), ce
);
1575 /* Build a complex expression of type TYPE using RE and IM. */
1578 complex_expr (tree type
, tree re
, tree im
)
1580 return fold_build2_loc (input_location
, COMPLEX_EXPR
,
1584 /* Cast EXP (which should be a pointer) to TYPE* and then indirect.
1585 The back-end requires this cast in many cases. */
1588 indirect_ref (tree type
, tree exp
)
1590 if (error_operand_p (exp
))
1593 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1594 tree init
= stabilize_expr (&exp
);
1596 if (TREE_CODE (TREE_TYPE (exp
)) == REFERENCE_TYPE
)
1597 exp
= fold_build1 (INDIRECT_REF
, type
, exp
);
1600 exp
= build_nop (build_pointer_type (type
), exp
);
1601 exp
= build_deref (exp
);
1604 return compound_expr (init
, exp
);
1607 /* Returns indirect reference of EXP, which must be a pointer type. */
1610 build_deref (tree exp
)
1612 if (error_operand_p (exp
))
1615 /* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1616 tree init
= stabilize_expr (&exp
);
1618 gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp
)));
1620 if (TREE_CODE (exp
) == ADDR_EXPR
)
1621 exp
= TREE_OPERAND (exp
, 0);
1623 exp
= build_fold_indirect_ref (exp
);
1625 return compound_expr (init
, exp
);
1628 /* Builds pointer offset expression PTR[INDEX]. */
1631 build_array_index (tree ptr
, tree index
)
1633 if (error_operand_p (ptr
) || error_operand_p (index
))
1634 return error_mark_node
;
1636 tree ptr_type
= TREE_TYPE (ptr
);
1637 tree target_type
= TREE_TYPE (ptr_type
);
1639 tree type
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (sizetype
),
1640 TYPE_UNSIGNED (sizetype
));
1642 /* Array element size. */
1643 tree size_exp
= size_in_bytes (target_type
);
1645 if (integer_zerop (size_exp
) || integer_onep (size_exp
))
1647 /* Array of void or bytes -- No need to multiply. */
1648 index
= fold_convert (type
, index
);
1652 index
= d_convert (type
, index
);
1653 index
= fold_build2 (MULT_EXPR
, TREE_TYPE (index
),
1654 index
, d_convert (TREE_TYPE (index
), size_exp
));
1655 index
= fold_convert (type
, index
);
1658 if (integer_zerop (index
))
1661 return fold_build2 (POINTER_PLUS_EXPR
, ptr_type
, ptr
, index
);
1664 /* Builds pointer offset expression *(PTR OP OFFSET)
1665 OP could be a plus or minus expression. */
1668 build_offset_op (tree_code op
, tree ptr
, tree offset
)
1670 gcc_assert (op
== MINUS_EXPR
|| op
== PLUS_EXPR
);
1672 tree type
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (sizetype
),
1673 TYPE_UNSIGNED (sizetype
));
1674 offset
= fold_convert (type
, offset
);
1676 if (op
== MINUS_EXPR
)
1677 offset
= fold_build1 (NEGATE_EXPR
, type
, offset
);
1679 return fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ptr
), ptr
, offset
);
1682 /* Builds pointer offset expression *(PTR + OFFSET). */
1685 build_offset (tree ptr
, tree offset
)
1687 return build_offset_op (PLUS_EXPR
, ptr
, offset
);
1691 build_memref (tree type
, tree ptr
, tree offset
)
1693 return fold_build2 (MEM_REF
, type
, ptr
, fold_convert (type
, offset
));
1696 /* Create a tree node to set multiple elements to a single value. */
1699 build_array_set (tree ptr
, tree length
, tree value
)
1701 tree ptrtype
= TREE_TYPE (ptr
);
1702 tree lentype
= TREE_TYPE (length
);
1704 push_binding_level (level_block
);
1707 /* Build temporary locals for length and ptr, and maybe value. */
1708 tree t
= build_local_temp (size_type_node
);
1709 add_stmt (build_assign (INIT_EXPR
, t
, length
));
1712 t
= build_local_temp (ptrtype
);
1713 add_stmt (build_assign (INIT_EXPR
, t
, ptr
));
1716 if (TREE_SIDE_EFFECTS (value
))
1718 t
= build_local_temp (TREE_TYPE (value
));
1719 add_stmt (build_assign (INIT_EXPR
, t
, value
));
1723 /* Build loop to initialize { .length=length, .ptr=ptr } with value. */
1726 /* Exit logic for the loop.
1727 if (length == 0) break; */
1728 t
= build_boolop (EQ_EXPR
, length
, d_convert (lentype
, integer_zero_node
));
1729 t
= build1 (EXIT_EXPR
, void_type_node
, t
);
1732 /* Assign value to the current pointer position.
1734 t
= modify_expr (build_deref (ptr
), value
);
1737 /* Move pointer to next element position.
1739 tree size
= TYPE_SIZE_UNIT (TREE_TYPE (ptrtype
));
1740 t
= build2 (POSTINCREMENT_EXPR
, ptrtype
, ptr
, d_convert (ptrtype
, size
));
1743 /* Decrease loop counter.
1745 t
= build2 (POSTDECREMENT_EXPR
, lentype
, length
,
1746 d_convert (lentype
, integer_one_node
));
1749 /* Pop statements and finish loop. */
1750 tree loop_body
= pop_stmt_list ();
1751 add_stmt (build1 (LOOP_EXPR
, void_type_node
, loop_body
));
1753 /* Wrap it up into a bind expression. */
1754 tree stmt_list
= pop_stmt_list ();
1755 tree block
= pop_binding_level ();
1757 return build3 (BIND_EXPR
, void_type_node
,
1758 BLOCK_VARS (block
), stmt_list
, block
);
1762 /* Build an array of type TYPE where all the elements are VAL. */
1765 build_array_from_val (Type
*type
, tree val
)
1767 tree etype
= build_ctype (type
->nextOf ());
1769 /* Initializing a multidimensional array. */
1770 if (TREE_CODE (etype
) == ARRAY_TYPE
&& TREE_TYPE (val
) != etype
)
1771 val
= build_array_from_val (type
->nextOf (), val
);
1773 size_t dims
= type
->isTypeSArray ()->dim
->toInteger ();
1774 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
1775 vec_safe_reserve (elms
, dims
);
1777 val
= d_convert (etype
, val
);
1779 for (size_t i
= 0; i
< dims
; i
++)
1780 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), val
);
1782 return build_constructor (build_ctype (type
), elms
);
1785 /* Build a static array of type TYPE from an array of EXPS.
1786 If CONST_P is true, then all elements in EXPS are constants. */
1789 build_array_from_exprs (Type
*type
, Expressions
*exps
, bool const_p
)
1791 /* Build a CONSTRUCTOR from all expressions. */
1792 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
1793 vec_safe_reserve (elms
, exps
->length
);
1795 Type
*etype
= type
->nextOf ();
1796 tree satype
= make_array_type (etype
, exps
->length
);
1798 for (size_t i
= 0; i
< exps
->length
; i
++)
1800 Expression
*expr
= (*exps
)[i
];
1801 tree t
= build_expr (expr
, const_p
);
1802 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
),
1803 convert_expr (t
, expr
->type
, etype
));
1806 /* Create a new temporary to store the array. */
1807 tree var
= build_local_temp (satype
);
1809 /* Fill any alignment holes with zeroes. */
1810 TypeStruct
*ts
= etype
->baseElemOf ()->isTypeStruct ();
1812 if (ts
&& (!identity_compare_p (ts
->sym
) || ts
->sym
->isUnionDeclaration ()))
1813 init
= build_memset_call (var
);
1815 /* Initialize the temporary. */
1816 tree assign
= modify_expr (var
, build_constructor (satype
, elms
));
1817 return compound_expr (compound_expr (init
, assign
), var
);
1821 /* Implicitly converts void* T to byte* as D allows { void[] a; &a[3]; } */
1824 void_okay_p (tree t
)
1826 tree type
= TREE_TYPE (t
);
1828 if (VOID_TYPE_P (TREE_TYPE (type
)))
1830 tree totype
= build_ctype (Type::tuns8
->pointerTo ());
1831 return fold_convert (totype
, t
);
1837 /* Builds a STRING_CST representing the filename of location LOC. When the
1838 location is not valid, the name of the source module is used instead. */
1841 build_filename_from_loc (const Loc
&loc
)
1843 const char *filename
= loc
.filename
1844 ? loc
.filename
: d_function_chain
->module
->srcfile
.toChars ();
1846 unsigned length
= strlen (filename
);
1847 tree str
= build_string (length
, filename
);
1848 TREE_TYPE (str
) = make_array_type (Type::tchar
, length
+ 1);
1850 return build_address (str
);
1853 /* Builds a CALL_EXPR at location LOC in the source file to call LIBCALL when
1854 an assert check fails. When calling the msg variant functions, MSG is the
1855 error message supplied by the user. */
1858 build_assert_call (const Loc
&loc
, libcall_fn libcall
, tree msg
)
1861 tree line
= size_int (loc
.linnum
);
1865 case LIBCALL_ASSERT_MSG
:
1866 case LIBCALL_UNITTEST_MSG
:
1867 /* File location is passed as a D string. */
1870 unsigned len
= strlen (loc
.filename
);
1871 tree str
= build_string (len
, loc
.filename
);
1872 TREE_TYPE (str
) = make_array_type (Type::tchar
, len
);
1874 file
= d_array_value (build_ctype (Type::tchar
->arrayOf ()),
1875 size_int (len
), build_address (str
));
1878 file
= null_array_node
;
1881 case LIBCALL_ASSERTP
:
1882 case LIBCALL_UNITTESTP
:
1883 file
= build_filename_from_loc (loc
);
1891 if (msg
!= NULL_TREE
)
1892 return build_libcall (libcall
, Type::tvoid
, 3, msg
, file
, line
);
1894 return build_libcall (libcall
, Type::tvoid
, 2, file
, line
);
1897 /* Builds a CALL_EXPR at location LOC in the source file to execute when an
1898 array bounds check fails. */
1901 build_array_bounds_call (const Loc
&loc
)
1903 /* Terminate the program with a trap if no D runtime present. */
1904 if (checkaction_trap_p ())
1905 return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1908 return build_libcall (LIBCALL_ARRAYBOUNDSP
, Type::tvoid
, 2,
1909 build_filename_from_loc (loc
),
1910 size_int (loc
.linnum
));
1914 /* Builds a bounds condition checking that INDEX is between 0 and LENGTH
1915 in the index expression IE. The condition returns the INDEX if true, or
1916 throws a `ArrayIndexError`. */
1919 build_bounds_index_condition (IndexExp
*ie
, tree index
, tree length
)
1921 if (ie
->indexIsInBounds
|| !array_bounds_check ())
1924 /* Prevent multiple evaluations of the index. */
1925 index
= d_save_expr (index
);
1927 /* Generate INDEX >= LENGTH && throw RangeError.
1928 No need to check whether INDEX >= 0 as the front-end should
1929 have already taken care of implicit casts to unsigned. */
1930 tree condition
= fold_build2 (GE_EXPR
, d_bool_type
, index
, length
);
1933 if (checkaction_trap_p ())
1934 boundserr
= build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1937 boundserr
= build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP
, Type::tvoid
, 4,
1938 build_filename_from_loc (ie
->e2
->loc
),
1939 size_int (ie
->e2
->loc
.linnum
), index
, length
);
1942 return build_condition (TREE_TYPE (index
), condition
, boundserr
, index
);
1945 /* Builds a bounds condition checking that the range LOWER..UPPER do not overlap
1946 the slice expression SE of the source array length LENGTH. The condition
1947 returns the new array length if true, or throws an `ArraySliceError`. */
1950 build_bounds_slice_condition (SliceExp
*se
, tree lower
, tree upper
, tree length
)
1952 if (array_bounds_check ())
1954 tree condition
= NULL_TREE
;
1956 /* Enforces that `upper <= length`. */
1957 if (!se
->upperIsInBounds
&& length
!= NULL_TREE
)
1958 condition
= fold_build2 (GT_EXPR
, d_bool_type
, upper
, length
);
1960 length
= integer_zero_node
;
1962 /* Enforces that `lower <= upper`. No need to check `lower <= length` as
1963 we've already ensured that `upper <= length`. */
1964 if (!se
->lowerIsLessThanUpper
)
1966 tree lwr_cond
= fold_build2 (GT_EXPR
, d_bool_type
, lower
, upper
);
1968 if (condition
!= NULL_TREE
)
1969 condition
= build_boolop (TRUTH_ORIF_EXPR
, condition
, lwr_cond
);
1971 condition
= lwr_cond
;
1974 if (condition
!= NULL_TREE
)
1978 if (checkaction_trap_p ())
1981 build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1985 boundserr
= build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP
,
1987 build_filename_from_loc (se
->loc
),
1988 size_int (se
->loc
.linnum
),
1989 lower
, upper
, length
);
1992 upper
= build_condition (TREE_TYPE (upper
), condition
,
1997 /* Need to ensure lower always gets evaluated first, as it may be a function
1998 call. Generates (lower, upper) - lower. */
1999 return fold_build2 (MINUS_EXPR
, TREE_TYPE (upper
),
2000 compound_expr (lower
, upper
), lower
);
2003 /* Returns TRUE if array bounds checking code generation is turned on. */
2006 array_bounds_check (void)
2008 FuncDeclaration
*fd
;
2010 switch (global
.params
.useArrayBounds
)
2012 case CHECKENABLEoff
:
2018 case CHECKENABLEsafeonly
:
2019 /* For D2 safe functions only. */
2020 fd
= d_function_chain
->function
;
2021 if (fd
&& fd
->type
->ty
== TY::Tfunction
)
2023 if (fd
->type
->isTypeFunction ()->trust
== TRUST::safe
)
2033 /* Returns TRUE if we terminate the program with a trap if an array bounds or
2034 contract check fails. */
2037 checkaction_trap_p (void)
2039 switch (global
.params
.checkAction
)
2042 case CHECKACTION_context
:
2046 case CHECKACTION_halt
:
2054 /* Returns the TypeFunction class for Type T.
2055 Assumes T is already ->toBasetype(). */
2058 get_function_type (Type
*t
)
2060 TypeFunction
*tf
= NULL
;
2061 if (t
->ty
== TY::Tpointer
)
2062 t
= t
->nextOf ()->toBasetype ();
2063 if (t
->ty
== TY::Tfunction
)
2064 tf
= t
->isTypeFunction ();
2065 else if (t
->ty
== TY::Tdelegate
)
2066 tf
= t
->isTypeDelegate ()->next
->isTypeFunction ();
2070 /* Returns TRUE if CALLEE is a plain nested function outside the scope of
2071 CALLER. In which case, CALLEE is being called through an alias that was
2072 passed to CALLER. */
2075 call_by_alias_p (FuncDeclaration
*caller
, FuncDeclaration
*callee
)
2077 if (!callee
->isNested ())
2080 if (caller
->toParent () == callee
->toParent ())
2083 Dsymbol
*dsym
= callee
;
2087 if (dsym
->isTemplateInstance ())
2089 else if (dsym
->isFuncDeclaration () == caller
)
2091 dsym
= dsym
->toParent ();
2097 /* Entry point for call routines. Builds a function call to FD.
2098 OBJECT is the `this' reference passed and ARGS are the arguments to FD. */
2101 d_build_call_expr (FuncDeclaration
*fd
, tree object
, Expressions
*arguments
)
2103 return d_build_call (get_function_type (fd
->type
),
2104 build_address (get_symbol_decl (fd
)), object
, arguments
);
2107 /* Builds a CALL_EXPR of type TF to CALLABLE. OBJECT holds the `this' pointer,
2108 ARGUMENTS are evaluated in left to right order, saved and promoted
2112 d_build_call (TypeFunction
*tf
, tree callable
, tree object
,
2113 Expressions
*arguments
)
2115 tree ctype
= TREE_TYPE (callable
);
2116 tree callee
= callable
;
2118 if (POINTER_TYPE_P (ctype
))
2119 ctype
= TREE_TYPE (ctype
);
2121 callee
= build_address (callable
);
2123 gcc_assert (FUNC_OR_METHOD_TYPE_P (ctype
));
2124 gcc_assert (tf
!= NULL
);
2125 gcc_assert (tf
->ty
== TY::Tfunction
);
2127 if (TREE_CODE (ctype
) != FUNCTION_TYPE
&& object
== NULL_TREE
)
2129 /* Front-end apparently doesn't check this. */
2130 if (TREE_CODE (callable
) == FUNCTION_DECL
)
2132 error ("need %<this%> to access member %qE", DECL_NAME (callable
));
2133 return error_mark_node
;
2136 /* Probably an internal error. */
2140 /* Build the argument list for the call. */
2141 vec
<tree
, va_gc
> *args
= NULL
;
2142 tree saved_args
= NULL_TREE
;
2143 bool noreturn_call
= false;
2145 /* If this is a delegate call or a nested function being called as
2146 a delegate, the object should not be NULL. */
2147 if (object
!= NULL_TREE
)
2148 vec_safe_push (args
, object
);
2152 /* First pass, evaluated expanded tuples in function arguments. */
2153 for (size_t i
= 0; i
< arguments
->length
; ++i
)
2156 Expression
*arg
= (*arguments
)[i
];
2157 gcc_assert (arg
->op
!= EXP::tuple
);
2159 if (arg
->op
== EXP::comma
)
2161 CommaExp
*ce
= arg
->isCommaExp ();
2162 tree tce
= build_expr (ce
->e1
);
2163 saved_args
= compound_expr (saved_args
, tce
);
2164 (*arguments
)[i
] = ce
->e2
;
2169 const size_t nparams
= tf
->parameterList
.length ();
2170 /* if _arguments[] is the first argument. */
2171 const size_t varargs
= tf
->isDstyleVariadic ();
2173 /* Assumes arguments->length <= formal_args->length if (!tf->varargs). */
2174 for (size_t i
= 0; i
< arguments
->length
; ++i
)
2176 Expression
*arg
= (*arguments
)[i
];
2177 tree targ
= build_expr (arg
);
2179 if (i
- varargs
< nparams
&& i
>= varargs
)
2181 /* Actual arguments for declared formal arguments. */
2182 Parameter
*parg
= tf
->parameterList
[i
- varargs
];
2183 targ
= convert_for_argument (targ
, parg
);
2186 /* Don't pass empty aggregates by value. */
2187 if (empty_aggregate_p (TREE_TYPE (targ
)) && !TREE_ADDRESSABLE (targ
)
2188 && TREE_CODE (targ
) != CONSTRUCTOR
)
2190 tree t
= build_constructor (TREE_TYPE (targ
), NULL
);
2191 targ
= build2 (COMPOUND_EXPR
, TREE_TYPE (t
), targ
, t
);
2194 /* Parameter is a struct or array passed by invisible reference. */
2195 if (TREE_ADDRESSABLE (TREE_TYPE (targ
)))
2197 Type
*t
= arg
->type
->toBasetype ();
2198 StructDeclaration
*sd
= t
->baseElemOf ()->isTypeStruct ()->sym
;
2200 /* Nested structs also have ADDRESSABLE set, but if the type has
2201 neither a copy constructor nor a destructor available, then we
2202 need to take care of copying its value before passing it. */
2203 if (arg
->op
== EXP::structLiteral
|| (!sd
->postblit
&& !sd
->dtor
))
2204 targ
= force_target_expr (targ
);
2206 targ
= convert (build_reference_type (TREE_TYPE (targ
)),
2207 build_address (targ
));
2210 /* Type `noreturn` is a terminator, as no other arguments can possibly
2211 be evaluated after it. */
2212 if (TREE_TYPE (targ
) == noreturn_type_node
)
2213 noreturn_call
= true;
2215 vec_safe_push (args
, targ
);
2219 /* Evaluate the callee before calling it. */
2220 if (TREE_SIDE_EFFECTS (callee
))
2222 callee
= d_save_expr (callee
);
2223 saved_args
= compound_expr (callee
, saved_args
);
2226 /* If we saw a `noreturn` parameter, any unreachable argument evaluations
2227 after it are discarded, as well as the function call itself. */
2230 if (TREE_SIDE_EFFECTS (callee
))
2231 saved_args
= compound_expr (callee
, saved_args
);
2236 FOR_EACH_VEC_SAFE_ELT (args
, ix
, arg
)
2237 saved_args
= compound_expr (saved_args
, arg
);
2239 /* Add a stub result type for the expression. */
2240 tree result
= build_zero_cst (TREE_TYPE (ctype
));
2241 return compound_expr (saved_args
, result
);
2244 tree result
= build_call_vec (TREE_TYPE (ctype
), callee
, args
);
2245 SET_EXPR_LOCATION (result
, input_location
);
2247 result
= maybe_expand_intrinsic (result
);
2249 /* Return the value in a temporary slot so that it can be evaluated
2250 multiple times by the caller. */
2251 if (TREE_CODE (result
) == CALL_EXPR
2252 && AGGREGATE_TYPE_P (TREE_TYPE (result
))
2253 && TREE_ADDRESSABLE (TREE_TYPE (result
)))
2255 CALL_EXPR_RETURN_SLOT_OPT (result
) = true;
2256 result
= force_target_expr (result
);
2259 return compound_expr (saved_args
, result
);
2262 /* Build and return the correct call to fmod depending on TYPE.
2263 ARG0 and ARG1 are the arguments pass to the function. */
2266 build_float_modulus (tree type
, tree arg0
, tree arg1
)
2268 tree fmodfn
= NULL_TREE
;
2269 tree basetype
= type
;
2271 if (COMPLEX_FLOAT_TYPE_P (basetype
))
2272 basetype
= TREE_TYPE (basetype
);
2274 if (TYPE_MAIN_VARIANT (basetype
) == double_type_node
2275 || TYPE_MAIN_VARIANT (basetype
) == idouble_type_node
)
2276 fmodfn
= builtin_decl_explicit (BUILT_IN_FMOD
);
2277 else if (TYPE_MAIN_VARIANT (basetype
) == float_type_node
2278 || TYPE_MAIN_VARIANT (basetype
) == ifloat_type_node
)
2279 fmodfn
= builtin_decl_explicit (BUILT_IN_FMODF
);
2280 else if (TYPE_MAIN_VARIANT (basetype
) == long_double_type_node
2281 || TYPE_MAIN_VARIANT (basetype
) == ireal_type_node
)
2282 fmodfn
= builtin_decl_explicit (BUILT_IN_FMODL
);
2286 error ("tried to perform floating-point modulo division on %qT", type
);
2287 return error_mark_node
;
2290 if (COMPLEX_FLOAT_TYPE_P (type
))
2292 tree re
= build_call_expr (fmodfn
, 2, real_part (arg0
), arg1
);
2293 tree im
= build_call_expr (fmodfn
, 2, imaginary_part (arg0
), arg1
);
2295 return complex_expr (type
, re
, im
);
2298 if (SCALAR_FLOAT_TYPE_P (type
))
2299 return build_call_expr (fmodfn
, 2, arg0
, arg1
);
2301 /* Should have caught this above. */
2305 /* Build a function type whose first argument is a pointer to BASETYPE,
2306 which is to be used for the `vthis' context parameter for TYPE.
2307 The base type may be a record for member functions, or a void for
2308 nested functions and delegates. */
2311 build_vthis_function (tree basetype
, tree type
)
2313 gcc_assert (TREE_CODE (type
) == FUNCTION_TYPE
);
2315 tree argtypes
= tree_cons (NULL_TREE
, build_pointer_type (basetype
),
2316 TYPE_ARG_TYPES (type
));
2317 tree fntype
= build_function_type (TREE_TYPE (type
), argtypes
);
2319 /* Copy volatile qualifiers from the original function type. */
2320 if (TYPE_QUALS (type
) & TYPE_QUAL_VOLATILE
)
2321 fntype
= build_qualified_type (fntype
, TYPE_QUAL_VOLATILE
);
2323 if (RECORD_OR_UNION_TYPE_P (basetype
))
2324 TYPE_METHOD_BASETYPE (fntype
) = TYPE_MAIN_VARIANT (basetype
);
2326 gcc_assert (VOID_TYPE_P (basetype
));
2331 /* Raise an error at that the context pointer of the function or object SYM is
2332 not accessible from the current scope. */
2335 error_no_frame_access (Dsymbol
*sym
)
2337 error_at (input_location
, "cannot get frame pointer to %qs",
2338 sym
->toPrettyChars ());
2339 return null_pointer_node
;
2342 /* If SYM is a nested function, return the static chain to be
2343 used when calling that function from the current function.
2345 If SYM is a nested class or struct, return the static chain
2346 to be used when creating an instance of the class from CFUN. */
2349 get_frame_for_symbol (Dsymbol
*sym
)
2351 FuncDeclaration
*thisfd
2352 = d_function_chain
? d_function_chain
->function
: NULL
;
2353 FuncDeclaration
*fd
= sym
->isFuncDeclaration ();
2354 FuncDeclaration
*fdparent
= NULL
;
2355 FuncDeclaration
*fdoverride
= NULL
;
2359 /* Check that the nested function is properly defined. */
2362 /* Should instead error on line that references `fd'. */
2363 error_at (make_location_t (fd
->loc
), "nested function missing body");
2364 return null_pointer_node
;
2367 fdparent
= fd
->toParent2 ()->isFuncDeclaration ();
2369 /* Special case for __ensure and __require. */
2370 if ((fd
->ident
== Identifier::idPool ("__ensure")
2371 || fd
->ident
== Identifier::idPool ("__require"))
2372 && fdparent
!= thisfd
)
2374 fdoverride
= fdparent
;
2380 /* It's a class (or struct). NewExp codegen has already determined its
2381 outer scope is not another class, so it must be a function. */
2382 while (sym
&& !sym
->isFuncDeclaration ())
2383 sym
= sym
->toParent2 ();
2385 fdparent
= (FuncDeclaration
*) sym
;
2388 /* Not a nested function, there is no frame pointer to pass. */
2389 if (fdparent
== NULL
)
2391 /* Only delegate literals report as being nested, even if they are in
2393 gcc_assert (fd
&& fd
->isFuncLiteralDeclaration ());
2394 return null_pointer_node
;
2397 gcc_assert (thisfd
!= NULL
);
2399 if (thisfd
!= fdparent
)
2401 /* If no frame pointer for this function. */
2404 error_at (make_location_t (sym
->loc
),
2405 "%qs is a nested function and cannot be accessed from %qs",
2406 fdparent
->toPrettyChars (), thisfd
->toPrettyChars ());
2407 return null_pointer_node
;
2410 /* Make sure we can get the frame pointer to the outer function.
2411 Go up each nesting level until we find the enclosing function. */
2412 Dsymbol
*dsym
= thisfd
;
2416 /* Check if enclosing function is a function. */
2417 FuncDeclaration
*fdp
= dsym
->isFuncDeclaration ();
2418 Dsymbol
*parent
= dsym
->toParent2 ();
2422 if (fdparent
== parent
)
2425 gcc_assert (fdp
->isNested () || fdp
->vthis
);
2430 /* Check if enclosed by an aggregate. That means the current
2431 function must be a member function of that aggregate. */
2432 AggregateDeclaration
*adp
= dsym
->isAggregateDeclaration ();
2436 if ((adp
->isClassDeclaration () || adp
->isStructDeclaration ())
2437 && fdparent
== parent
)
2441 /* No frame to outer function found. */
2442 if (!adp
|| !adp
->isNested () || !adp
->vthis
)
2443 return error_no_frame_access (sym
);
2449 tree ffo
= get_frameinfo (fdparent
);
2450 if (FRAMEINFO_CREATES_FRAME (ffo
) || FRAMEINFO_STATIC_CHAIN (ffo
))
2452 tree frame_ref
= get_framedecl (thisfd
, fdparent
);
2454 /* If `thisfd' is a derived member function, then `fdparent' is the
2455 overridden member function in the base class. Even if there's a
2456 closure environment, we should give the original stack data as the
2457 nested function frame. */
2460 ClassDeclaration
*cdo
= fdoverride
->isThis ()->isClassDeclaration ();
2461 ClassDeclaration
*cd
= thisfd
->isThis ()->isClassDeclaration ();
2462 gcc_assert (cdo
&& cd
);
2465 if (cdo
->isBaseOf (cd
, &offset
) && offset
!= 0)
2467 /* Generate a new frame to pass to the overriden function that
2468 has the `this' pointer adjusted. */
2469 gcc_assert (offset
!= OFFSET_RUNTIME
);
2471 tree type
= FRAMEINFO_TYPE (get_frameinfo (fdoverride
));
2472 tree fields
= TYPE_FIELDS (type
);
2473 /* The `this' field comes immediately after the `__chain'. */
2474 tree thisfield
= chain_index (1, fields
);
2475 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
2477 tree framefields
= TYPE_FIELDS (FRAMEINFO_TYPE (ffo
));
2478 frame_ref
= build_deref (frame_ref
);
2480 for (tree field
= fields
; field
; field
= DECL_CHAIN (field
))
2482 tree value
= component_ref (frame_ref
, framefields
);
2483 if (field
== thisfield
)
2484 value
= build_offset (value
, size_int (offset
));
2486 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
2487 framefields
= DECL_CHAIN (framefields
);
2490 frame_ref
= build_address (build_constructor (type
, ve
));
2497 return null_pointer_node
;
2500 /* Return the parent function of a nested class or struct AD. */
2502 static FuncDeclaration
*
2503 get_outer_function (AggregateDeclaration
*ad
)
2505 FuncDeclaration
*fd
= NULL
;
2506 while (ad
&& ad
->isNested ())
2508 Dsymbol
*dsym
= ad
->toParent2 ();
2509 if ((fd
= dsym
->isFuncDeclaration ()))
2512 ad
= dsym
->isAggregateDeclaration ();
2518 /* Starting from the current function FD, try to find a suitable value of
2519 `this' in nested function instances. A suitable `this' value is an
2520 instance of OCD or a class that has OCD as a base. */
2523 find_this_tree (ClassDeclaration
*ocd
)
2525 FuncDeclaration
*fd
= d_function_chain
? d_function_chain
->function
: NULL
;
2529 AggregateDeclaration
*ad
= fd
->isThis ();
2530 ClassDeclaration
*cd
= ad
? ad
->isClassDeclaration () : NULL
;
2535 return get_decl_tree (fd
->vthis
);
2536 else if (ocd
->isBaseOf (cd
, NULL
))
2537 return convert_expr (get_decl_tree (fd
->vthis
),
2538 cd
->type
, ocd
->type
);
2540 fd
= get_outer_function (cd
);
2544 if (fd
->isNested ())
2546 fd
= fd
->toParent2 ()->isFuncDeclaration ();
2556 /* Retrieve the outer class/struct `this' value of DECL from
2557 the current function. */
2560 build_vthis (AggregateDeclaration
*decl
)
2562 ClassDeclaration
*cd
= decl
->isClassDeclaration ();
2563 StructDeclaration
*sd
= decl
->isStructDeclaration ();
2565 /* If an aggregate nested in a function has no methods and there are no
2566 other nested functions, any static chain created here will never be
2567 translated. Use a null pointer for the link in this case. */
2568 tree vthis_value
= null_pointer_node
;
2570 if (cd
!= NULL
|| sd
!= NULL
)
2572 Dsymbol
*outer
= decl
->toParent2 ();
2574 /* If the parent is a templated struct, the outer context is instead
2575 the enclosing symbol of where the instantiation happened. */
2576 if (outer
->isStructDeclaration ())
2578 gcc_assert (outer
->parent
&& outer
->parent
->isTemplateInstance ());
2579 outer
= ((TemplateInstance
*) outer
->parent
)->enclosing
;
2582 /* For outer classes, get a suitable `this' value.
2583 For outer functions, get a suitable frame/closure pointer. */
2584 ClassDeclaration
*cdo
= outer
->isClassDeclaration ();
2585 FuncDeclaration
*fdo
= outer
->isFuncDeclaration ();
2589 vthis_value
= find_this_tree (cdo
);
2590 gcc_assert (vthis_value
!= NULL_TREE
);
2594 tree ffo
= get_frameinfo (fdo
);
2595 if (FRAMEINFO_CREATES_FRAME (ffo
) || FRAMEINFO_STATIC_CHAIN (ffo
)
2596 || fdo
->hasNestedFrameRefs ())
2597 vthis_value
= get_frame_for_symbol (decl
);
2598 else if (cd
!= NULL
)
2600 /* Classes nested in methods are allowed to access any outer
2601 class fields, use the function chain in this case. */
2602 if (fdo
->vthis
&& fdo
->vthis
->type
!= Type::tvoidptr
)
2603 vthis_value
= get_decl_tree (fdo
->vthis
);
2613 /* Build the RECORD_TYPE that describes the function frame or closure type for
2614 the function FD. FFI is the tree holding all frame information. */
2617 build_frame_type (tree ffi
, FuncDeclaration
*fd
)
2619 if (FRAMEINFO_TYPE (ffi
))
2620 return FRAMEINFO_TYPE (ffi
);
2622 tree frame_rec_type
= make_node (RECORD_TYPE
);
2623 char *name
= concat (FRAMEINFO_IS_CLOSURE (ffi
) ? "CLOSURE." : "FRAME.",
2624 fd
->toPrettyChars (), NULL
);
2625 TYPE_NAME (frame_rec_type
) = get_identifier (name
);
2628 tree fields
= NULL_TREE
;
2630 /* Function is a member or nested, so must have field for outer context. */
2633 tree ptr_field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
2634 get_identifier ("__chain"), ptr_type_node
);
2635 DECL_FIELD_CONTEXT (ptr_field
) = frame_rec_type
;
2636 fields
= chainon (NULL_TREE
, ptr_field
);
2637 DECL_NONADDRESSABLE_P (ptr_field
) = 1;
2640 /* The __ensure and __require are called directly, so never make the outer
2641 functions closure, but nevertheless could still be referencing parameters
2642 of the calling function non-locally. So we add all parameters with nested
2643 refs to the function frame, this should also mean overriding methods will
2644 have the same frame layout when inheriting a contract. */
2645 if ((global
.params
.useIn
== CHECKENABLEon
&& fd
->frequire
)
2646 || (global
.params
.useOut
== CHECKENABLEon
&& fd
->fensure
))
2650 for (size_t i
= 0; fd
->parameters
&& i
< fd
->parameters
->length
; i
++)
2652 VarDeclaration
*v
= (*fd
->parameters
)[i
];
2653 /* Remove if already in closureVars so can push to front. */
2654 size_t j
= fd
->closureVars
.find (v
);
2656 if (j
< fd
->closureVars
.length
)
2657 fd
->closureVars
.remove (j
);
2659 fd
->closureVars
.insert (i
, v
);
2663 /* Also add hidden `this' to outer context. */
2666 size_t i
= fd
->closureVars
.find (fd
->vthis
);
2668 if (i
< fd
->closureVars
.length
)
2669 fd
->closureVars
.remove (i
);
2671 fd
->closureVars
.insert (0, fd
->vthis
);
2675 for (size_t i
= 0; i
< fd
->closureVars
.length
; i
++)
2677 VarDeclaration
*v
= fd
->closureVars
[i
];
2678 tree vsym
= get_symbol_decl (v
);
2679 tree ident
= v
->ident
2680 ? get_identifier (v
->ident
->toChars ()) : NULL_TREE
;
2682 tree field
= build_decl (make_location_t (v
->loc
), FIELD_DECL
, ident
,
2684 SET_DECL_LANG_FRAME_FIELD (vsym
, field
);
2685 DECL_FIELD_CONTEXT (field
) = frame_rec_type
;
2686 fields
= chainon (fields
, field
);
2687 TREE_USED (vsym
) = 1;
2689 TREE_ADDRESSABLE (field
) = TREE_ADDRESSABLE (vsym
);
2690 DECL_NONADDRESSABLE_P (field
) = !TREE_ADDRESSABLE (vsym
);
2691 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (vsym
);
2693 if (DECL_LANG_NRVO (vsym
))
2695 /* Store the nrvo variable in the frame by reference. */
2696 TREE_TYPE (field
) = build_reference_type (TREE_TYPE (field
));
2698 /* Can't do nrvo if the variable is put in a closure, since what the
2699 return slot points to may no longer exist. */
2700 gcc_assert (!FRAMEINFO_IS_CLOSURE (ffi
));
2703 if (FRAMEINFO_IS_CLOSURE (ffi
))
2705 /* Because the value needs to survive the end of the scope. */
2706 if ((v
->edtor
&& (v
->storage_class
& STCparameter
))
2707 || v
->needsScopeDtor ())
2708 error_at (make_location_t (v
->loc
),
2709 "has scoped destruction, cannot build closure");
2713 TYPE_FIELDS (frame_rec_type
) = fields
;
2714 TYPE_READONLY (frame_rec_type
) = 1;
2715 TYPE_CXX_ODR_P (frame_rec_type
) = 1;
2716 layout_type (frame_rec_type
);
2717 d_keep (frame_rec_type
);
2719 return frame_rec_type
;
2722 /* Closures are implemented by taking the local variables that
2723 need to survive the scope of the function, and copying them
2724 into a GC allocated chuck of memory. That chunk, called the
2725 closure here, is inserted into the linked list of stack
2726 frames instead of the usual stack frame.
2728 If a closure is not required, but FD still needs a frame to lower
2729 nested refs, then instead build custom static chain decl on stack. */
2732 build_closure (FuncDeclaration
*fd
)
2734 tree ffi
= get_frameinfo (fd
);
2736 if (!FRAMEINFO_CREATES_FRAME (ffi
))
2739 tree type
= FRAMEINFO_TYPE (ffi
);
2740 gcc_assert (COMPLETE_TYPE_P (type
));
2742 tree decl
, decl_ref
;
2744 if (FRAMEINFO_IS_CLOSURE (ffi
))
2746 decl
= build_local_temp (build_pointer_type (type
));
2747 DECL_NAME (decl
) = get_identifier ("__closptr");
2748 decl_ref
= build_deref (decl
);
2750 /* Allocate memory for closure. */
2751 tree arg
= convert (build_ctype (Type::tsize_t
), TYPE_SIZE_UNIT (type
));
2752 tree init
= build_libcall (LIBCALL_ALLOCMEMORY
, Type::tvoidptr
, 1, arg
);
2754 tree init_exp
= build_assign (INIT_EXPR
, decl
,
2755 build_nop (TREE_TYPE (decl
), init
));
2756 add_stmt (init_exp
);
2760 decl
= build_local_temp (type
);
2761 DECL_NAME (decl
) = get_identifier ("__frame");
2765 /* Set the first entry to the parent closure/frame, if any. */
2768 tree chain_field
= component_ref (decl_ref
, TYPE_FIELDS (type
));
2769 tree chain_expr
= modify_expr (chain_field
,
2770 d_function_chain
->static_chain
);
2771 add_stmt (chain_expr
);
2774 /* Copy parameters that are referenced nonlocally. */
2775 for (size_t i
= 0; i
< fd
->closureVars
.length
; i
++)
2777 VarDeclaration
*v
= fd
->closureVars
[i
];
2778 tree vsym
= get_symbol_decl (v
);
2780 if (TREE_CODE (vsym
) != PARM_DECL
&& !DECL_LANG_NRVO (vsym
))
2783 tree field
= component_ref (decl_ref
, DECL_LANG_FRAME_FIELD (vsym
));
2785 /* Variable is an alias for the NRVO slot, store the reference. */
2786 if (DECL_LANG_NRVO (vsym
))
2787 vsym
= build_address (DECL_LANG_NRVO (vsym
));
2789 tree expr
= modify_expr (field
, vsym
);
2793 if (!FRAMEINFO_IS_CLOSURE (ffi
))
2794 decl
= build_address (decl
);
2796 d_function_chain
->static_chain
= decl
;
2799 /* Return the frame of FD. This could be a static chain or a closure
2800 passed via the hidden `this' pointer. */
2803 get_frameinfo (FuncDeclaration
*fd
)
2805 tree fds
= get_symbol_decl (fd
);
2806 if (DECL_LANG_FRAMEINFO (fds
))
2807 return DECL_LANG_FRAMEINFO (fds
);
2809 tree ffi
= make_node (FUNCFRAME_INFO
);
2811 DECL_LANG_FRAMEINFO (fds
) = ffi
;
2813 if (fd
->needsClosure ())
2815 /* Set-up a closure frame, this will be allocated on the heap. */
2816 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2817 FRAMEINFO_IS_CLOSURE (ffi
) = 1;
2819 else if (fd
->hasNestedFrameRefs ())
2821 /* Functions with nested refs must create a static frame for local
2822 variables to be referenced from. */
2823 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2827 /* For nested functions, default to creating a frame. Even if there are
2828 no fields to populate the frame, create it anyway, as this will be
2829 used as the record type instead of `void*` for the this parameter. */
2830 if (fd
->vthis
&& fd
->vthis
->type
== Type::tvoidptr
)
2831 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2833 /* In checkNestedReference, references from contracts are not added to the
2834 closureVars array, so assume all parameters referenced. */
2835 if ((global
.params
.useIn
== CHECKENABLEon
&& fd
->frequire
)
2836 || (global
.params
.useOut
== CHECKENABLEon
&& fd
->fensure
))
2837 FRAMEINFO_CREATES_FRAME (ffi
) = 1;
2839 /* If however `fd` is nested (deeply) in a function that creates a
2840 closure, then `fd` instead inherits that closure via hidden vthis
2841 pointer, and doesn't create a stack frame at all. */
2842 FuncDeclaration
*ff
= fd
;
2846 tree ffo
= get_frameinfo (ff
);
2848 if (ff
!= fd
&& FRAMEINFO_CREATES_FRAME (ffo
))
2850 gcc_assert (FRAMEINFO_TYPE (ffo
));
2851 FRAMEINFO_CREATES_FRAME (ffi
) = 0;
2852 FRAMEINFO_STATIC_CHAIN (ffi
) = 1;
2853 FRAMEINFO_IS_CLOSURE (ffi
) = FRAMEINFO_IS_CLOSURE (ffo
);
2854 gcc_assert (COMPLETE_TYPE_P (FRAMEINFO_TYPE (ffo
)));
2855 FRAMEINFO_TYPE (ffi
) = FRAMEINFO_TYPE (ffo
);
2859 /* Stop looking if no frame pointer for this function. */
2860 if (ff
->vthis
== NULL
)
2863 AggregateDeclaration
*ad
= ff
->isThis ();
2864 if (ad
&& ad
->isNested ())
2866 while (ad
->isNested ())
2868 Dsymbol
*d
= ad
->toParent2 ();
2869 ad
= d
->isAggregateDeclaration ();
2870 ff
= d
->isFuncDeclaration ();
2877 ff
= ff
->toParent2 ()->isFuncDeclaration ();
2881 /* Build type now as may be referenced from another module. */
2882 if (FRAMEINFO_CREATES_FRAME (ffi
))
2883 FRAMEINFO_TYPE (ffi
) = build_frame_type (ffi
, fd
);
2888 /* Return a pointer to the frame/closure block of OUTER
2889 so can be accessed from the function INNER. */
2892 get_framedecl (FuncDeclaration
*inner
, FuncDeclaration
*outer
)
2894 tree result
= d_function_chain
->static_chain
;
2895 FuncDeclaration
*fd
= inner
;
2897 while (fd
&& fd
!= outer
)
2899 /* Parent frame link is the first field. */
2900 if (FRAMEINFO_CREATES_FRAME (get_frameinfo (fd
)))
2901 result
= indirect_ref (ptr_type_node
, result
);
2903 if (fd
->isNested ())
2904 fd
= fd
->toParent2 ()->isFuncDeclaration ();
2905 /* The frame/closure record always points to the outer function's
2906 frame, even if there are intervening nested classes or structs.
2907 So, we can just skip over these. */
2909 fd
= get_outer_function (fd
->isThis ());
2913 return error_no_frame_access (outer
);
2915 /* Go get our frame record. */
2916 tree frame_type
= FRAMEINFO_TYPE (get_frameinfo (outer
));
2918 if (frame_type
!= NULL_TREE
)
2920 result
= build_nop (build_pointer_type (frame_type
), result
);
2925 error_at (make_location_t (inner
->loc
),
2926 "forward reference to frame of %qs", outer
->toChars ());
2927 return null_pointer_node
;