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