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