* gimplify.c (find_single_pointer_decl_1): New static function.
[official-gcc.git] / gcc / ada / trans.c
blobfb741a3e03081409cfc78c80de97f7e8d79c0592
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * T R A N S *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 1992-2005, Free Software Foundation, Inc. *
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 51 Franklin Street, Fifth Floor, *
20 * Boston, MA 02110-1301, USA. *
21 * *
22 * GNAT was originally developed by the GNAT team at New York University. *
23 * Extensive contributions were provided by Ada Core Technologies Inc. *
24 * *
25 ****************************************************************************/
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "tree.h"
32 #include "real.h"
33 #include "flags.h"
34 #include "toplev.h"
35 #include "rtl.h"
36 #include "expr.h"
37 #include "ggc.h"
38 #include "cgraph.h"
39 #include "function.h"
40 #include "except.h"
41 #include "debug.h"
42 #include "output.h"
43 #include "tree-gimple.h"
44 #include "ada.h"
45 #include "types.h"
46 #include "atree.h"
47 #include "elists.h"
48 #include "namet.h"
49 #include "nlists.h"
50 #include "snames.h"
51 #include "stringt.h"
52 #include "uintp.h"
53 #include "urealp.h"
54 #include "fe.h"
55 #include "sinfo.h"
56 #include "einfo.h"
57 #include "ada-tree.h"
58 #include "gigi.h"
60 int max_gnat_nodes;
61 int number_names;
62 struct Node *Nodes_Ptr;
63 Node_Id *Next_Node_Ptr;
64 Node_Id *Prev_Node_Ptr;
65 struct Elist_Header *Elists_Ptr;
66 struct Elmt_Item *Elmts_Ptr;
67 struct String_Entry *Strings_Ptr;
68 Char_Code *String_Chars_Ptr;
69 struct List_Header *List_Headers_Ptr;
71 /* Current filename without path. */
72 const char *ref_filename;
74 /* If true, then gigi is being called on an analyzed but unexpanded
75 tree, and the only purpose of the call is to properly annotate
76 types with representation information. */
77 bool type_annotate_only;
79 /* A structure used to gather together information about a statement group.
80 We use this to gather related statements, for example the "then" part
81 of a IF. In the case where it represents a lexical scope, we may also
82 have a BLOCK node corresponding to it and/or cleanups. */
84 struct stmt_group GTY((chain_next ("%h.previous"))) {
85 struct stmt_group *previous; /* Previous code group. */
86 tree stmt_list; /* List of statements for this code group. */
87 tree block; /* BLOCK for this code group, if any. */
88 tree cleanups; /* Cleanups for this code group, if any. */
91 static GTY(()) struct stmt_group *current_stmt_group;
93 /* List of unused struct stmt_group nodes. */
94 static GTY((deletable)) struct stmt_group *stmt_group_free_list;
96 /* A structure used to record information on elaboration procedures
97 we've made and need to process.
99 ??? gnat_node should be Node_Id, but gengtype gets confused. */
101 struct elab_info GTY((chain_next ("%h.next"))) {
102 struct elab_info *next; /* Pointer to next in chain. */
103 tree elab_proc; /* Elaboration procedure. */
104 int gnat_node; /* The N_Compilation_Unit. */
107 static GTY(()) struct elab_info *elab_info_list;
109 /* Free list of TREE_LIST nodes used for stacks. */
110 static GTY((deletable)) tree gnu_stack_free_list;
112 /* List of TREE_LIST nodes representing a stack of exception pointer
113 variables. TREE_VALUE is the VAR_DECL that stores the address of
114 the raised exception. Nonzero means we are in an exception
115 handler. Not used in the zero-cost case. */
116 static GTY(()) tree gnu_except_ptr_stack;
118 /* List of TREE_LIST nodes used to store the current elaboration procedure
119 decl. TREE_VALUE is the decl. */
120 static GTY(()) tree gnu_elab_proc_stack;
122 /* Variable that stores a list of labels to be used as a goto target instead of
123 a return in some functions. See processing for N_Subprogram_Body. */
124 static GTY(()) tree gnu_return_label_stack;
126 /* List of TREE_LIST nodes representing a stack of LOOP_STMT nodes.
127 TREE_VALUE of each entry is the label of the corresponding LOOP_STMT. */
128 static GTY(()) tree gnu_loop_label_stack;
130 /* List of TREE_LIST nodes representing labels for switch statements.
131 TREE_VALUE of each entry is the label at the end of the switch. */
132 static GTY(()) tree gnu_switch_label_stack;
134 /* Map GNAT tree codes to GCC tree codes for simple expressions. */
135 static enum tree_code gnu_codes[Number_Node_Kinds];
137 /* Current node being treated, in case abort called. */
138 Node_Id error_gnat_node;
140 static void Compilation_Unit_to_gnu (Node_Id);
141 static void record_code_position (Node_Id);
142 static void insert_code_for (Node_Id);
143 static void start_stmt_group (void);
144 static void add_cleanup (tree);
145 static tree mark_visited (tree *, int *, void *);
146 static tree mark_unvisited (tree *, int *, void *);
147 static tree end_stmt_group (void);
148 static void add_stmt_list (List_Id);
149 static tree build_stmt_group (List_Id, bool);
150 static void push_stack (tree *, tree, tree);
151 static void pop_stack (tree *);
152 static enum gimplify_status gnat_gimplify_stmt (tree *);
153 static void elaborate_all_entities (Node_Id);
154 static void process_freeze_entity (Node_Id);
155 static void process_inlined_subprograms (Node_Id);
156 static void process_decls (List_Id, List_Id, Node_Id, bool, bool);
157 static tree emit_range_check (tree, Node_Id);
158 static tree emit_index_check (tree, tree, tree, tree);
159 static tree emit_check (tree, tree, int);
160 static tree convert_with_check (Entity_Id, tree, bool, bool, bool);
161 static bool addressable_p (tree);
162 static tree assoc_to_constructor (Node_Id, tree);
163 static tree extract_values (tree, tree);
164 static tree pos_to_constructor (Node_Id, tree, Entity_Id);
165 static tree maybe_implicit_deref (tree);
166 static tree gnat_stabilize_reference_1 (tree, bool);
167 static void annotate_with_node (tree, Node_Id);
168 static void build_global_cdtor (int, tree *);
171 /* This is the main program of the back-end. It sets up all the table
172 structures and then generates code. */
174 void
175 gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
176 struct Node *nodes_ptr, Node_Id *next_node_ptr, Node_Id *prev_node_ptr,
177 struct Elist_Header *elists_ptr, struct Elmt_Item *elmts_ptr,
178 struct String_Entry *strings_ptr, Char_Code *string_chars_ptr,
179 struct List_Header *list_headers_ptr, Int number_units ATTRIBUTE_UNUSED,
180 char *file_info_ptr ATTRIBUTE_UNUSED, Entity_Id standard_integer,
181 Entity_Id standard_long_long_float, Entity_Id standard_exception_type,
182 Int gigi_operating_mode)
184 tree gnu_standard_long_long_float;
185 tree gnu_standard_exception_type;
186 struct elab_info *info;
188 max_gnat_nodes = max_gnat_node;
189 number_names = number_name;
190 Nodes_Ptr = nodes_ptr;
191 Next_Node_Ptr = next_node_ptr;
192 Prev_Node_Ptr = prev_node_ptr;
193 Elists_Ptr = elists_ptr;
194 Elmts_Ptr = elmts_ptr;
195 Strings_Ptr = strings_ptr;
196 String_Chars_Ptr = string_chars_ptr;
197 List_Headers_Ptr = list_headers_ptr;
199 type_annotate_only = (gigi_operating_mode == 1);
201 init_gnat_to_gnu ();
202 gnat_compute_largest_alignment ();
203 init_dummy_type ();
205 /* If we are just annotating types, give VOID_TYPE zero sizes to avoid
206 errors. */
207 if (type_annotate_only)
209 TYPE_SIZE (void_type_node) = bitsize_zero_node;
210 TYPE_SIZE_UNIT (void_type_node) = size_zero_node;
213 /* Save the type we made for integer as the type for Standard.Integer.
214 Then make the rest of the standard types. Note that some of these
215 may be subtypes. */
216 save_gnu_tree (Base_Type (standard_integer), TYPE_NAME (integer_type_node),
217 false);
219 gnu_except_ptr_stack = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
221 gnu_standard_long_long_float
222 = gnat_to_gnu_entity (Base_Type (standard_long_long_float), NULL_TREE, 0);
223 gnu_standard_exception_type
224 = gnat_to_gnu_entity (Base_Type (standard_exception_type), NULL_TREE, 0);
226 init_gigi_decls (gnu_standard_long_long_float, gnu_standard_exception_type);
228 /* Process any Pragma Ident for the main unit. */
229 #ifdef ASM_OUTPUT_IDENT
230 if (Present (Ident_String (Main_Unit)))
231 ASM_OUTPUT_IDENT
232 (asm_out_file,
233 TREE_STRING_POINTER (gnat_to_gnu (Ident_String (Main_Unit))));
234 #endif
236 /* If we are using the GCC exception mechanism, let GCC know. */
237 if (Exception_Mechanism == Back_End_Exceptions)
238 gnat_init_gcc_eh ();
240 gcc_assert (Nkind (gnat_root) == N_Compilation_Unit);
241 Compilation_Unit_to_gnu (gnat_root);
243 /* Now see if we have any elaboration procedures to deal with. */
244 for (info = elab_info_list; info; info = info->next)
246 tree gnu_body = DECL_SAVED_TREE (info->elab_proc);
247 tree gnu_stmts;
249 /* Mark everything we have as not visited. */
250 walk_tree_without_duplicates (&gnu_body, mark_unvisited, NULL);
252 /* Set the current function to be the elaboration procedure and gimplify
253 what we have. */
254 current_function_decl = info->elab_proc;
255 gimplify_body (&gnu_body, info->elab_proc, true);
257 /* We should have a BIND_EXPR, but it may or may not have any statements
258 in it. If it doesn't have any, we have nothing to do. */
259 gnu_stmts = gnu_body;
260 if (TREE_CODE (gnu_stmts) == BIND_EXPR)
261 gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
263 /* If there are no statements, there is no elaboration code. */
264 if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts))
265 Set_Has_No_Elaboration_Code (info->gnat_node, 1);
266 else
268 /* Otherwise, compile the function. Note that we'll be gimplifying
269 it twice, but that's fine for the nodes we use. */
270 begin_subprog_body (info->elab_proc);
271 end_subprog_body (gnu_body);
276 /* Perform initializations for this module. */
278 void
279 gnat_init_stmt_group ()
281 /* Initialize ourselves. */
282 init_code_table ();
283 start_stmt_group ();
285 /* Enable GNAT stack checking method if needed */
286 if (!Stack_Check_Probes_On_Target)
287 set_stack_check_libfunc (gen_rtx_SYMBOL_REF (Pmode, "_gnat_stack_check"));
290 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Identifier,
291 to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer to
292 where we should place the result type. */
294 static tree
295 Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
297 tree gnu_result_type;
298 tree gnu_result;
299 Node_Id gnat_temp, gnat_temp_type;
301 /* If the Etype of this node does not equal the Etype of the Entity,
302 something is wrong with the entity map, probably in generic
303 instantiation. However, this does not apply to types. Since we sometime
304 have strange Ekind's, just do this test for objects. Also, if the Etype of
305 the Entity is private, the Etype of the N_Identifier is allowed to be the
306 full type and also we consider a packed array type to be the same as the
307 original type. Similarly, a class-wide type is equivalent to a subtype of
308 itself. Finally, if the types are Itypes, one may be a copy of the other,
309 which is also legal. */
310 gnat_temp = (Nkind (gnat_node) == N_Defining_Identifier
311 ? gnat_node : Entity (gnat_node));
312 gnat_temp_type = Etype (gnat_temp);
314 gcc_assert (Etype (gnat_node) == gnat_temp_type
315 || (Is_Packed (gnat_temp_type)
316 && Etype (gnat_node) == Packed_Array_Type (gnat_temp_type))
317 || (Is_Class_Wide_Type (Etype (gnat_node)))
318 || (IN (Ekind (gnat_temp_type), Private_Kind)
319 && Present (Full_View (gnat_temp_type))
320 && ((Etype (gnat_node) == Full_View (gnat_temp_type))
321 || (Is_Packed (Full_View (gnat_temp_type))
322 && (Etype (gnat_node)
323 == Packed_Array_Type (Full_View
324 (gnat_temp_type))))))
325 || (Is_Itype (Etype (gnat_node)) && Is_Itype (gnat_temp_type))
326 || !(Ekind (gnat_temp) == E_Variable
327 || Ekind (gnat_temp) == E_Component
328 || Ekind (gnat_temp) == E_Constant
329 || Ekind (gnat_temp) == E_Loop_Parameter
330 || IN (Ekind (gnat_temp), Formal_Kind)));
332 /* If this is a reference to a deferred constant whose partial view is an
333 unconstrained private type, the proper type is on the full view of the
334 constant, not on the full view of the type, which may be unconstrained.
336 This may be a reference to a type, for example in the prefix of the
337 attribute Position, generated for dispatching code (see Make_DT in
338 exp_disp,adb). In that case we need the type itself, not is parent,
339 in particular if it is a derived type */
340 if (Is_Private_Type (gnat_temp_type)
341 && Has_Unknown_Discriminants (gnat_temp_type)
342 && Present (Full_View (gnat_temp))
343 && !Is_Type (gnat_temp))
345 gnat_temp = Full_View (gnat_temp);
346 gnat_temp_type = Etype (gnat_temp);
347 gnu_result_type = get_unpadded_type (gnat_temp_type);
349 else
351 /* Expand the type of this identifier first, in case it is an enumeral
352 literal, which only get made when the type is expanded. There is no
353 order-of-elaboration issue here. We want to use the Actual_Subtype if
354 it has already been elaborated, otherwise the Etype. Avoid using
355 Actual_Subtype for packed arrays to simplify things. */
356 if ((Ekind (gnat_temp) == E_Constant
357 || Ekind (gnat_temp) == E_Variable || Is_Formal (gnat_temp))
358 && !(Is_Array_Type (Etype (gnat_temp))
359 && Present (Packed_Array_Type (Etype (gnat_temp))))
360 && Present (Actual_Subtype (gnat_temp))
361 && present_gnu_tree (Actual_Subtype (gnat_temp)))
362 gnat_temp_type = Actual_Subtype (gnat_temp);
363 else
364 gnat_temp_type = Etype (gnat_node);
366 gnu_result_type = get_unpadded_type (gnat_temp_type);
369 gnu_result = gnat_to_gnu_entity (gnat_temp, NULL_TREE, 0);
371 /* If we are in an exception handler, force this variable into memory to
372 ensure optimization does not remove stores that appear redundant but are
373 actually needed in case an exception occurs.
375 ??? Note that we need not do this if the variable is declared within the
376 handler, only if it is referenced in the handler and declared in an
377 enclosing block, but we have no way of testing that right now.
379 ??? Also, for now all we can do is make it volatile. But we only
380 do this for SJLJ. */
381 if (TREE_VALUE (gnu_except_ptr_stack)
382 && TREE_CODE (gnu_result) == VAR_DECL)
383 TREE_THIS_VOLATILE (gnu_result) = TREE_SIDE_EFFECTS (gnu_result) = 1;
385 /* Some objects (such as parameters passed by reference, globals of
386 variable size, and renamed objects) actually represent the address
387 of the object. In that case, we must do the dereference. Likewise,
388 deal with parameters to foreign convention subprograms. Call fold
389 here since GNU_RESULT may be a CONST_DECL. */
390 if (DECL_P (gnu_result)
391 && (DECL_BY_REF_P (gnu_result)
392 || (TREE_CODE (gnu_result) == PARM_DECL
393 && DECL_BY_COMPONENT_PTR_P (gnu_result))))
395 bool ro = DECL_POINTS_TO_READONLY_P (gnu_result);
396 tree renamed_obj;
398 if (TREE_CODE (gnu_result) == PARM_DECL
399 && DECL_BY_COMPONENT_PTR_P (gnu_result))
400 gnu_result
401 = build_unary_op (INDIRECT_REF, NULL_TREE,
402 convert (build_pointer_type (gnu_result_type),
403 gnu_result));
405 /* If it's a renaming pointer and we are at the right binding level,
406 we can reference the renamed object directly, since the renamed
407 expression has been protected against multiple evaluations. */
408 else if (TREE_CODE (gnu_result) == VAR_DECL
409 && (renamed_obj = DECL_RENAMED_OBJECT (gnu_result)) != 0
410 && (! DECL_RENAMING_GLOBAL_P (gnu_result)
411 || global_bindings_p ())
412 /* Make sure it's an lvalue like INDIRECT_REF. */
413 && (DECL_P (renamed_obj)
414 || REFERENCE_CLASS_P (renamed_obj)
415 || (TREE_CODE (renamed_obj) == VIEW_CONVERT_EXPR
416 && (DECL_P (TREE_OPERAND (renamed_obj, 0))
417 || REFERENCE_CLASS_P (TREE_OPERAND (renamed_obj,0))))))
418 gnu_result = renamed_obj;
419 else
420 gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE,
421 fold (gnu_result));
423 TREE_READONLY (gnu_result) = TREE_STATIC (gnu_result) = ro;
426 /* The GNAT tree has the type of a function as the type of its result. Also
427 use the type of the result if the Etype is a subtype which is nominally
428 unconstrained. But remove any padding from the resulting type. */
429 if (TREE_CODE (TREE_TYPE (gnu_result)) == FUNCTION_TYPE
430 || Is_Constr_Subt_For_UN_Aliased (gnat_temp_type))
432 gnu_result_type = TREE_TYPE (gnu_result);
433 if (TREE_CODE (gnu_result_type) == RECORD_TYPE
434 && TYPE_IS_PADDING_P (gnu_result_type))
435 gnu_result_type = TREE_TYPE (TYPE_FIELDS (gnu_result_type));
438 /* We always want to return the underlying INTEGER_CST for an enumeration
439 literal to avoid the need to call fold in lots of places. But don't do
440 this is the parent will be taking the address of this object. */
441 if (TREE_CODE (gnu_result) == CONST_DECL)
443 gnat_temp = Parent (gnat_node);
444 if (!DECL_CONST_CORRESPONDING_VAR (gnu_result)
445 || (Nkind (gnat_temp) != N_Reference
446 && !(Nkind (gnat_temp) == N_Attribute_Reference
447 && ((Get_Attribute_Id (Attribute_Name (gnat_temp))
448 == Attr_Address)
449 || (Get_Attribute_Id (Attribute_Name (gnat_temp))
450 == Attr_Access)
451 || (Get_Attribute_Id (Attribute_Name (gnat_temp))
452 == Attr_Unchecked_Access)
453 || (Get_Attribute_Id (Attribute_Name (gnat_temp))
454 == Attr_Unrestricted_Access)))))
455 gnu_result = DECL_INITIAL (gnu_result);
458 *gnu_result_type_p = gnu_result_type;
459 return gnu_result;
462 /* Subroutine of gnat_to_gnu to process gnat_node, an N_Pragma. Return
463 any statements we generate. */
465 static tree
466 Pragma_to_gnu (Node_Id gnat_node)
468 Node_Id gnat_temp;
469 tree gnu_result = alloc_stmt_list ();
471 /* Check for (and ignore) unrecognized pragma and do nothing if we are just
472 annotating types. */
473 if (type_annotate_only || !Is_Pragma_Name (Chars (gnat_node)))
474 return gnu_result;
476 switch (Get_Pragma_Id (Chars (gnat_node)))
478 case Pragma_Inspection_Point:
479 /* Do nothing at top level: all such variables are already viewable. */
480 if (global_bindings_p ())
481 break;
483 for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
484 Present (gnat_temp);
485 gnat_temp = Next (gnat_temp))
487 tree gnu_expr = gnat_to_gnu (Expression (gnat_temp));
489 if (TREE_CODE (gnu_expr) == UNCONSTRAINED_ARRAY_REF)
490 gnu_expr = TREE_OPERAND (gnu_expr, 0);
492 gnu_expr = build1 (USE_STMT, void_type_node, gnu_expr);
493 annotate_with_node (gnu_expr, gnat_node);
494 append_to_statement_list (gnu_expr, &gnu_result);
496 break;
498 case Pragma_Optimize:
499 switch (Chars (Expression
500 (First (Pragma_Argument_Associations (gnat_node)))))
502 case Name_Time: case Name_Space:
503 if (optimize == 0)
504 post_error ("insufficient -O value?", gnat_node);
505 break;
507 case Name_Off:
508 if (optimize != 0)
509 post_error ("must specify -O0?", gnat_node);
510 break;
512 default:
513 gcc_unreachable ();
515 break;
517 case Pragma_Reviewable:
518 if (write_symbols == NO_DEBUG)
519 post_error ("must specify -g?", gnat_node);
520 break;
523 return gnu_result;
525 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Attribute,
526 to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer to
527 where we should place the result type. ATTRIBUTE is the attribute ID. */
529 static tree
530 Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
532 tree gnu_result = error_mark_node;
533 tree gnu_result_type;
534 tree gnu_expr;
535 bool prefix_unused = false;
536 tree gnu_prefix = gnat_to_gnu (Prefix (gnat_node));
537 tree gnu_type = TREE_TYPE (gnu_prefix);
539 /* If the input is a NULL_EXPR, make a new one. */
540 if (TREE_CODE (gnu_prefix) == NULL_EXPR)
542 *gnu_result_type_p = get_unpadded_type (Etype (gnat_node));
543 return build1 (NULL_EXPR, *gnu_result_type_p,
544 TREE_OPERAND (gnu_prefix, 0));
547 switch (attribute)
549 case Attr_Pos:
550 case Attr_Val:
551 /* These are just conversions until since representation clauses for
552 enumerations are handled in the front end. */
554 bool checkp = Do_Range_Check (First (Expressions (gnat_node)));
556 gnu_result = gnat_to_gnu (First (Expressions (gnat_node)));
557 gnu_result_type = get_unpadded_type (Etype (gnat_node));
558 gnu_result = convert_with_check (Etype (gnat_node), gnu_result,
559 checkp, checkp, true);
561 break;
563 case Attr_Pred:
564 case Attr_Succ:
565 /* These just add or subject the constant 1. Representation clauses for
566 enumerations are handled in the front-end. */
567 gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
568 gnu_result_type = get_unpadded_type (Etype (gnat_node));
570 if (Do_Range_Check (First (Expressions (gnat_node))))
572 gnu_expr = protect_multiple_eval (gnu_expr);
573 gnu_expr
574 = emit_check
575 (build_binary_op (EQ_EXPR, integer_type_node,
576 gnu_expr,
577 attribute == Attr_Pred
578 ? TYPE_MIN_VALUE (gnu_result_type)
579 : TYPE_MAX_VALUE (gnu_result_type)),
580 gnu_expr, CE_Range_Check_Failed);
583 gnu_result
584 = build_binary_op (attribute == Attr_Pred
585 ? MINUS_EXPR : PLUS_EXPR,
586 gnu_result_type, gnu_expr,
587 convert (gnu_result_type, integer_one_node));
588 break;
590 case Attr_Address:
591 case Attr_Unrestricted_Access:
592 /* Conversions don't change something's address but can cause us to miss
593 the COMPONENT_REF case below, so strip them off. */
594 gnu_prefix = remove_conversions (gnu_prefix,
595 !Must_Be_Byte_Aligned (gnat_node));
597 /* If we are taking 'Address of an unconstrained object, this is the
598 pointer to the underlying array. */
599 if (attribute == Attr_Address)
600 gnu_prefix = maybe_unconstrained_array (gnu_prefix);
602 /* ... fall through ... */
604 case Attr_Access:
605 case Attr_Unchecked_Access:
606 case Attr_Code_Address:
607 gnu_result_type = get_unpadded_type (Etype (gnat_node));
608 gnu_result
609 = build_unary_op (((attribute == Attr_Address
610 || attribute == Attr_Unrestricted_Access)
611 && !Must_Be_Byte_Aligned (gnat_node))
612 ? ATTR_ADDR_EXPR : ADDR_EXPR,
613 gnu_result_type, gnu_prefix);
615 /* For 'Code_Address, find an inner ADDR_EXPR and mark it so that we
616 don't try to build a trampoline. */
617 if (attribute == Attr_Code_Address)
619 for (gnu_expr = gnu_result;
620 TREE_CODE (gnu_expr) == NOP_EXPR
621 || TREE_CODE (gnu_expr) == CONVERT_EXPR;
622 gnu_expr = TREE_OPERAND (gnu_expr, 0))
623 TREE_CONSTANT (gnu_expr) = 1;
625 if (TREE_CODE (gnu_expr) == ADDR_EXPR)
626 TREE_STATIC (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;
628 break;
630 case Attr_Pool_Address:
632 tree gnu_obj_type;
633 tree gnu_ptr = gnu_prefix;
635 gnu_result_type = get_unpadded_type (Etype (gnat_node));
637 /* If this is an unconstrained array, we know the object must have been
638 allocated with the template in front of the object. So compute the
639 template address.*/
640 if (TYPE_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
641 gnu_ptr
642 = convert (build_pointer_type
643 (TYPE_OBJECT_RECORD_TYPE
644 (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr)))),
645 gnu_ptr);
647 gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));
648 if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
649 && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
651 tree gnu_char_ptr_type = build_pointer_type (char_type_node);
652 tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
653 tree gnu_byte_offset
654 = convert (gnu_char_ptr_type,
655 size_diffop (size_zero_node, gnu_pos));
657 gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
658 gnu_ptr = build_binary_op (MINUS_EXPR, gnu_char_ptr_type,
659 gnu_ptr, gnu_byte_offset);
662 gnu_result = convert (gnu_result_type, gnu_ptr);
664 break;
666 case Attr_Size:
667 case Attr_Object_Size:
668 case Attr_Value_Size:
669 case Attr_Max_Size_In_Storage_Elements:
670 gnu_expr = gnu_prefix;
672 /* Remove NOPS from gnu_expr and conversions from gnu_prefix.
673 We only use GNU_EXPR to see if a COMPONENT_REF was involved. */
674 while (TREE_CODE (gnu_expr) == NOP_EXPR)
675 gnu_expr = TREE_OPERAND (gnu_expr, 0)
678 gnu_prefix = remove_conversions (gnu_prefix, true);
679 prefix_unused = true;
680 gnu_type = TREE_TYPE (gnu_prefix);
682 /* Replace an unconstrained array type with the type of the underlying
683 array. We can't do this with a call to maybe_unconstrained_array
684 since we may have a TYPE_DECL. For 'Max_Size_In_Storage_Elements,
685 use the record type that will be used to allocate the object and its
686 template. */
687 if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
689 gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
690 if (attribute != Attr_Max_Size_In_Storage_Elements)
691 gnu_type = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_type)));
694 /* If we're looking for the size of a field, return the field size.
695 Otherwise, if the prefix is an object, or if 'Object_Size or
696 'Max_Size_In_Storage_Elements has been specified, the result is the
697 GCC size of the type. Otherwise, the result is the RM_Size of the
698 type. */
699 if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
700 gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1));
701 else if (TREE_CODE (gnu_prefix) != TYPE_DECL
702 || attribute == Attr_Object_Size
703 || attribute == Attr_Max_Size_In_Storage_Elements)
705 /* If this is a padded type, the GCC size isn't relevant to the
706 programmer. Normally, what we want is the RM_Size, which was set
707 from the specified size, but if it was not set, we want the size
708 of the relevant field. Using the MAX of those two produces the
709 right result in all case. Don't use the size of the field if it's
710 a self-referential type, since that's never what's wanted. */
711 if (TREE_CODE (gnu_type) == RECORD_TYPE
712 && TYPE_IS_PADDING_P (gnu_type)
713 && TREE_CODE (gnu_expr) == COMPONENT_REF)
715 gnu_result = rm_size (gnu_type);
716 if (!(CONTAINS_PLACEHOLDER_P
717 (DECL_SIZE (TREE_OPERAND (gnu_expr, 1)))))
718 gnu_result
719 = size_binop (MAX_EXPR, gnu_result,
720 DECL_SIZE (TREE_OPERAND (gnu_expr, 1)));
722 else
723 gnu_result = TYPE_SIZE (gnu_type);
725 else
726 gnu_result = rm_size (gnu_type);
728 gcc_assert (gnu_result);
730 /* Deal with a self-referential size by returning the maximum size for a
731 type and by qualifying the size with the object for 'Size of an
732 object. */
733 if (CONTAINS_PLACEHOLDER_P (gnu_result))
735 if (TREE_CODE (gnu_prefix) != TYPE_DECL)
736 gnu_result = substitute_placeholder_in_expr (gnu_result, gnu_expr);
737 else
738 gnu_result = max_size (gnu_result, true);
741 /* If the type contains a template, subtract its size. */
742 if (TREE_CODE (gnu_type) == RECORD_TYPE
743 && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
744 gnu_result = size_binop (MINUS_EXPR, gnu_result,
745 DECL_SIZE (TYPE_FIELDS (gnu_type)));
747 gnu_result_type = get_unpadded_type (Etype (gnat_node));
749 /* Always perform division using unsigned arithmetic as the size cannot
750 be negative, but may be an overflowed positive value. This provides
751 correct results for sizes up to 512 MB.
753 ??? Size should be calculated in storage elements directly. */
755 if (attribute == Attr_Max_Size_In_Storage_Elements)
756 gnu_result = convert (sizetype,
757 fold (build2 (CEIL_DIV_EXPR, bitsizetype,
758 gnu_result, bitsize_unit_node)));
759 break;
761 case Attr_Alignment:
762 if (TREE_CODE (gnu_prefix) == COMPONENT_REF
763 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))
764 == RECORD_TYPE)
765 && (TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
766 gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
768 gnu_type = TREE_TYPE (gnu_prefix);
769 gnu_result_type = get_unpadded_type (Etype (gnat_node));
770 prefix_unused = true;
772 if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
773 gnu_result = size_int (DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)));
774 else
775 gnu_result = size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT);
776 break;
778 case Attr_First:
779 case Attr_Last:
780 case Attr_Range_Length:
781 prefix_unused = true;
783 if (INTEGRAL_TYPE_P (gnu_type) || TREE_CODE (gnu_type) == REAL_TYPE)
785 gnu_result_type = get_unpadded_type (Etype (gnat_node));
787 if (attribute == Attr_First)
788 gnu_result = TYPE_MIN_VALUE (gnu_type);
789 else if (attribute == Attr_Last)
790 gnu_result = TYPE_MAX_VALUE (gnu_type);
791 else
792 gnu_result
793 = build_binary_op
794 (MAX_EXPR, get_base_type (gnu_result_type),
795 build_binary_op
796 (PLUS_EXPR, get_base_type (gnu_result_type),
797 build_binary_op (MINUS_EXPR,
798 get_base_type (gnu_result_type),
799 convert (gnu_result_type,
800 TYPE_MAX_VALUE (gnu_type)),
801 convert (gnu_result_type,
802 TYPE_MIN_VALUE (gnu_type))),
803 convert (gnu_result_type, integer_one_node)),
804 convert (gnu_result_type, integer_zero_node));
806 break;
809 /* ... fall through ... */
811 case Attr_Length:
813 int Dimension = (Present (Expressions (gnat_node))
814 ? UI_To_Int (Intval (First (Expressions (gnat_node))))
815 : 1);
817 /* Make sure any implicit dereference gets done. */
818 gnu_prefix = maybe_implicit_deref (gnu_prefix);
819 gnu_prefix = maybe_unconstrained_array (gnu_prefix);
820 gnu_type = TREE_TYPE (gnu_prefix);
821 prefix_unused = true;
822 gnu_result_type = get_unpadded_type (Etype (gnat_node));
824 if (TYPE_CONVENTION_FORTRAN_P (gnu_type))
826 int ndim;
827 tree gnu_type_temp;
829 for (ndim = 1, gnu_type_temp = gnu_type;
830 TREE_CODE (TREE_TYPE (gnu_type_temp)) == ARRAY_TYPE
831 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type_temp));
832 ndim++, gnu_type_temp = TREE_TYPE (gnu_type_temp))
835 Dimension = ndim + 1 - Dimension;
838 for (; Dimension > 1; Dimension--)
839 gnu_type = TREE_TYPE (gnu_type);
841 gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
842 if (attribute == Attr_First)
843 gnu_result
844 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
845 else if (attribute == Attr_Last)
846 gnu_result
847 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
848 else
849 /* 'Length or 'Range_Length. */
851 tree gnu_compute_type
852 = gnat_signed_or_unsigned_type (0,
853 get_base_type (gnu_result_type));
855 gnu_result
856 = build_binary_op
857 (MAX_EXPR, gnu_compute_type,
858 build_binary_op
859 (PLUS_EXPR, gnu_compute_type,
860 build_binary_op
861 (MINUS_EXPR, gnu_compute_type,
862 convert (gnu_compute_type,
863 TYPE_MAX_VALUE
864 (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)))),
865 convert (gnu_compute_type,
866 TYPE_MIN_VALUE
867 (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))))),
868 convert (gnu_compute_type, integer_one_node)),
869 convert (gnu_compute_type, integer_zero_node));
872 /* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
873 handling. Note that these attributes could not have been used on
874 an unconstrained array type. */
875 gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result,
876 gnu_prefix);
877 break;
880 case Attr_Bit_Position:
881 case Attr_Position:
882 case Attr_First_Bit:
883 case Attr_Last_Bit:
884 case Attr_Bit:
886 HOST_WIDE_INT bitsize;
887 HOST_WIDE_INT bitpos;
888 tree gnu_offset;
889 tree gnu_field_bitpos;
890 tree gnu_field_offset;
891 tree gnu_inner;
892 enum machine_mode mode;
893 int unsignedp, volatilep;
895 gnu_result_type = get_unpadded_type (Etype (gnat_node));
896 gnu_prefix = remove_conversions (gnu_prefix, true);
897 prefix_unused = true;
899 /* We can have 'Bit on any object, but if it isn't a COMPONENT_REF,
900 the result is 0. Don't allow 'Bit on a bare component, though. */
901 if (attribute == Attr_Bit
902 && TREE_CODE (gnu_prefix) != COMPONENT_REF
903 && TREE_CODE (gnu_prefix) != FIELD_DECL)
905 gnu_result = integer_zero_node;
906 break;
909 else
910 gcc_assert (TREE_CODE (gnu_prefix) == COMPONENT_REF
911 || (attribute == Attr_Bit_Position
912 && TREE_CODE (gnu_prefix) == FIELD_DECL));
914 get_inner_reference (gnu_prefix, &bitsize, &bitpos, &gnu_offset,
915 &mode, &unsignedp, &volatilep, false);
917 if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
919 gnu_field_bitpos = bit_position (TREE_OPERAND (gnu_prefix, 1));
920 gnu_field_offset = byte_position (TREE_OPERAND (gnu_prefix, 1));
922 for (gnu_inner = TREE_OPERAND (gnu_prefix, 0);
923 TREE_CODE (gnu_inner) == COMPONENT_REF
924 && DECL_INTERNAL_P (TREE_OPERAND (gnu_inner, 1));
925 gnu_inner = TREE_OPERAND (gnu_inner, 0))
927 gnu_field_bitpos
928 = size_binop (PLUS_EXPR, gnu_field_bitpos,
929 bit_position (TREE_OPERAND (gnu_inner, 1)));
930 gnu_field_offset
931 = size_binop (PLUS_EXPR, gnu_field_offset,
932 byte_position (TREE_OPERAND (gnu_inner, 1)));
935 else if (TREE_CODE (gnu_prefix) == FIELD_DECL)
937 gnu_field_bitpos = bit_position (gnu_prefix);
938 gnu_field_offset = byte_position (gnu_prefix);
940 else
942 gnu_field_bitpos = bitsize_zero_node;
943 gnu_field_offset = size_zero_node;
946 switch (attribute)
948 case Attr_Position:
949 gnu_result = gnu_field_offset;
950 break;
952 case Attr_First_Bit:
953 case Attr_Bit:
954 gnu_result = size_int (bitpos % BITS_PER_UNIT);
955 break;
957 case Attr_Last_Bit:
958 gnu_result = bitsize_int (bitpos % BITS_PER_UNIT);
959 gnu_result = size_binop (PLUS_EXPR, gnu_result,
960 TYPE_SIZE (TREE_TYPE (gnu_prefix)));
961 gnu_result = size_binop (MINUS_EXPR, gnu_result,
962 bitsize_one_node);
963 break;
965 case Attr_Bit_Position:
966 gnu_result = gnu_field_bitpos;
967 break;
970 /* If this has a PLACEHOLDER_EXPR, qualify it by the object
971 we are handling. */
972 gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
973 break;
976 case Attr_Min:
977 case Attr_Max:
979 tree gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node)));
980 tree gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node))));
982 gnu_result_type = get_unpadded_type (Etype (gnat_node));
983 gnu_result = build_binary_op (attribute == Attr_Min
984 ? MIN_EXPR : MAX_EXPR,
985 gnu_result_type, gnu_lhs, gnu_rhs);
987 break;
989 case Attr_Passed_By_Reference:
990 gnu_result = size_int (default_pass_by_ref (gnu_type)
991 || must_pass_by_ref (gnu_type));
992 gnu_result_type = get_unpadded_type (Etype (gnat_node));
993 break;
995 case Attr_Component_Size:
996 if (TREE_CODE (gnu_prefix) == COMPONENT_REF
997 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))
998 == RECORD_TYPE)
999 && (TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
1000 gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
1002 gnu_prefix = maybe_implicit_deref (gnu_prefix);
1003 gnu_type = TREE_TYPE (gnu_prefix);
1005 if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
1006 gnu_type = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_type))));
1008 while (TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
1009 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type)))
1010 gnu_type = TREE_TYPE (gnu_type);
1012 gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
1014 /* Note this size cannot be self-referential. */
1015 gnu_result = TYPE_SIZE (TREE_TYPE (gnu_type));
1016 gnu_result_type = get_unpadded_type (Etype (gnat_node));
1017 prefix_unused = true;
1018 break;
1020 case Attr_Null_Parameter:
1021 /* This is just a zero cast to the pointer type for
1022 our prefix and dereferenced. */
1023 gnu_result_type = get_unpadded_type (Etype (gnat_node));
1024 gnu_result
1025 = build_unary_op (INDIRECT_REF, NULL_TREE,
1026 convert (build_pointer_type (gnu_result_type),
1027 integer_zero_node));
1028 TREE_PRIVATE (gnu_result) = 1;
1029 break;
1031 case Attr_Mechanism_Code:
1033 int code;
1034 Entity_Id gnat_obj = Entity (Prefix (gnat_node));
1036 prefix_unused = true;
1037 gnu_result_type = get_unpadded_type (Etype (gnat_node));
1038 if (Present (Expressions (gnat_node)))
1040 int i = UI_To_Int (Intval (First (Expressions (gnat_node))));
1042 for (gnat_obj = First_Formal (gnat_obj); i > 1;
1043 i--, gnat_obj = Next_Formal (gnat_obj))
1047 code = Mechanism (gnat_obj);
1048 if (code == Default)
1049 code = ((present_gnu_tree (gnat_obj)
1050 && (DECL_BY_REF_P (get_gnu_tree (gnat_obj))
1051 || ((TREE_CODE (get_gnu_tree (gnat_obj))
1052 == PARM_DECL)
1053 && (DECL_BY_COMPONENT_PTR_P
1054 (get_gnu_tree (gnat_obj))))))
1055 ? By_Reference : By_Copy);
1056 gnu_result = convert (gnu_result_type, size_int (- code));
1058 break;
1060 default:
1061 /* Say we have an unimplemented attribute. Then set the value to be
1062 returned to be a zero and hope that's something we can convert to the
1063 type of this attribute. */
1064 post_error ("unimplemented attribute", gnat_node);
1065 gnu_result_type = get_unpadded_type (Etype (gnat_node));
1066 gnu_result = integer_zero_node;
1067 break;
1070 /* If this is an attribute where the prefix was unused, force a use of it if
1071 it has a side-effect. But don't do it if the prefix is just an entity
1072 name. However, if an access check is needed, we must do it. See second
1073 example in AARM 11.6(5.e). */
1074 if (prefix_unused && TREE_SIDE_EFFECTS (gnu_prefix)
1075 && !Is_Entity_Name (Prefix (gnat_node)))
1076 gnu_result = fold (build2 (COMPOUND_EXPR, TREE_TYPE (gnu_result),
1077 gnu_prefix, gnu_result));
1079 *gnu_result_type_p = gnu_result_type;
1080 return gnu_result;
1083 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Case_Statement,
1084 to a GCC tree, which is returned. */
1086 static tree
1087 Case_Statement_to_gnu (Node_Id gnat_node)
1089 tree gnu_result;
1090 tree gnu_expr;
1091 Node_Id gnat_when;
1093 gnu_expr = gnat_to_gnu (Expression (gnat_node));
1094 gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr);
1096 /* The range of values in a case statement is determined by the rules in
1097 RM 5.4(7-9). In almost all cases, this range is represented by the Etype
1098 of the expression. One exception arises in the case of a simple name that
1099 is parenthesized. This still has the Etype of the name, but since it is
1100 not a name, para 7 does not apply, and we need to go to the base type.
1101 This is the only case where parenthesization affects the dynamic
1102 semantics (i.e. the range of possible values at runtime that is covered
1103 by the others alternative.
1105 Another exception is if the subtype of the expression is non-static. In
1106 that case, we also have to use the base type. */
1107 if (Paren_Count (Expression (gnat_node)) != 0
1108 || !Is_OK_Static_Subtype (Underlying_Type
1109 (Etype (Expression (gnat_node)))))
1110 gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr);
1112 /* We build a SWITCH_EXPR that contains the code with interspersed
1113 CASE_LABEL_EXPRs for each label. */
1115 push_stack (&gnu_switch_label_stack, NULL_TREE, create_artificial_label ());
1116 start_stmt_group ();
1117 for (gnat_when = First_Non_Pragma (Alternatives (gnat_node));
1118 Present (gnat_when);
1119 gnat_when = Next_Non_Pragma (gnat_when))
1121 Node_Id gnat_choice;
1123 /* First compile all the different case choices for the current WHEN
1124 alternative. */
1125 for (gnat_choice = First (Discrete_Choices (gnat_when));
1126 Present (gnat_choice); gnat_choice = Next (gnat_choice))
1128 tree gnu_low = NULL_TREE, gnu_high = NULL_TREE;
1130 switch (Nkind (gnat_choice))
1132 case N_Range:
1133 gnu_low = gnat_to_gnu (Low_Bound (gnat_choice));
1134 gnu_high = gnat_to_gnu (High_Bound (gnat_choice));
1135 break;
1137 case N_Subtype_Indication:
1138 gnu_low = gnat_to_gnu (Low_Bound (Range_Expression
1139 (Constraint (gnat_choice))));
1140 gnu_high = gnat_to_gnu (High_Bound (Range_Expression
1141 (Constraint (gnat_choice))));
1142 break;
1144 case N_Identifier:
1145 case N_Expanded_Name:
1146 /* This represents either a subtype range or a static value of
1147 some kind; Ekind says which. If a static value, fall through
1148 to the next case. */
1149 if (IN (Ekind (Entity (gnat_choice)), Type_Kind))
1151 tree gnu_type = get_unpadded_type (Entity (gnat_choice));
1153 gnu_low = fold (TYPE_MIN_VALUE (gnu_type));
1154 gnu_high = fold (TYPE_MAX_VALUE (gnu_type));
1155 break;
1158 /* ... fall through ... */
1160 case N_Character_Literal:
1161 case N_Integer_Literal:
1162 gnu_low = gnat_to_gnu (gnat_choice);
1163 break;
1165 case N_Others_Choice:
1166 break;
1168 default:
1169 gcc_unreachable ();
1172 add_stmt_with_node (build3 (CASE_LABEL_EXPR, void_type_node,
1173 gnu_low, gnu_high,
1174 create_artificial_label ()),
1175 gnat_choice);
1178 /* Push a binding level here in case variables are declared since we want
1179 them to be local to this set of statements instead of the block
1180 containing the Case statement. */
1181 add_stmt (build_stmt_group (Statements (gnat_when), true));
1182 add_stmt (build1 (GOTO_EXPR, void_type_node,
1183 TREE_VALUE (gnu_switch_label_stack)));
1186 /* Now emit a definition of the label all the cases branched to. */
1187 add_stmt (build1 (LABEL_EXPR, void_type_node,
1188 TREE_VALUE (gnu_switch_label_stack)));
1189 gnu_result = build3 (SWITCH_EXPR, TREE_TYPE (gnu_expr), gnu_expr,
1190 end_stmt_group (), NULL_TREE);
1191 pop_stack (&gnu_switch_label_stack);
1193 return gnu_result;
1196 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Loop_Statement,
1197 to a GCC tree, which is returned. */
1199 static tree
1200 Loop_Statement_to_gnu (Node_Id gnat_node)
1202 /* ??? It would be nice to use "build" here, but there's no build5. */
1203 tree gnu_loop_stmt = build_nt (LOOP_STMT, NULL_TREE, NULL_TREE,
1204 NULL_TREE, NULL_TREE, NULL_TREE);
1205 tree gnu_loop_var = NULL_TREE;
1206 Node_Id gnat_iter_scheme = Iteration_Scheme (gnat_node);
1207 tree gnu_cond_expr = NULL_TREE;
1208 tree gnu_result;
1210 TREE_TYPE (gnu_loop_stmt) = void_type_node;
1211 TREE_SIDE_EFFECTS (gnu_loop_stmt) = 1;
1212 LOOP_STMT_LABEL (gnu_loop_stmt) = create_artificial_label ();
1213 annotate_with_node (gnu_loop_stmt, gnat_node);
1215 /* Save the end label of this LOOP_STMT in a stack so that the corresponding
1216 N_Exit_Statement can find it. */
1217 push_stack (&gnu_loop_label_stack, NULL_TREE,
1218 LOOP_STMT_LABEL (gnu_loop_stmt));
1220 /* Set the condition that under which the loop should continue.
1221 For "LOOP .... END LOOP;" the condition is always true. */
1222 if (No (gnat_iter_scheme))
1224 /* The case "WHILE condition LOOP ..... END LOOP;" */
1225 else if (Present (Condition (gnat_iter_scheme)))
1226 LOOP_STMT_TOP_COND (gnu_loop_stmt)
1227 = gnat_to_gnu (Condition (gnat_iter_scheme));
1228 else
1230 /* We have an iteration scheme. */
1231 Node_Id gnat_loop_spec = Loop_Parameter_Specification (gnat_iter_scheme);
1232 Entity_Id gnat_loop_var = Defining_Entity (gnat_loop_spec);
1233 Entity_Id gnat_type = Etype (gnat_loop_var);
1234 tree gnu_type = get_unpadded_type (gnat_type);
1235 tree gnu_low = TYPE_MIN_VALUE (gnu_type);
1236 tree gnu_high = TYPE_MAX_VALUE (gnu_type);
1237 bool reversep = Reverse_Present (gnat_loop_spec);
1238 tree gnu_first = reversep ? gnu_high : gnu_low;
1239 tree gnu_last = reversep ? gnu_low : gnu_high;
1240 enum tree_code end_code = reversep ? GE_EXPR : LE_EXPR;
1241 tree gnu_base_type = get_base_type (gnu_type);
1242 tree gnu_limit = (reversep ? TYPE_MIN_VALUE (gnu_base_type)
1243 : TYPE_MAX_VALUE (gnu_base_type));
1245 /* We know the loop variable will not overflow if GNU_LAST is a constant
1246 and is not equal to GNU_LIMIT. If it might overflow, we have to move
1247 the limit test to the end of the loop. In that case, we have to test
1248 for an empty loop outside the loop. */
1249 if (TREE_CODE (gnu_last) != INTEGER_CST
1250 || TREE_CODE (gnu_limit) != INTEGER_CST
1251 || tree_int_cst_equal (gnu_last, gnu_limit))
1253 gnu_cond_expr
1254 = build3 (COND_EXPR, void_type_node,
1255 build_binary_op (LE_EXPR, integer_type_node,
1256 gnu_low, gnu_high),
1257 NULL_TREE, alloc_stmt_list ());
1258 annotate_with_node (gnu_cond_expr, gnat_loop_spec);
1261 /* Open a new nesting level that will surround the loop to declare the
1262 loop index variable. */
1263 start_stmt_group ();
1264 gnat_pushlevel ();
1266 /* Declare the loop index and set it to its initial value. */
1267 gnu_loop_var = gnat_to_gnu_entity (gnat_loop_var, gnu_first, 1);
1268 if (DECL_BY_REF_P (gnu_loop_var))
1269 gnu_loop_var = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_loop_var);
1271 /* The loop variable might be a padded type, so use `convert' to get a
1272 reference to the inner variable if so. */
1273 gnu_loop_var = convert (get_base_type (gnu_type), gnu_loop_var);
1275 /* Set either the top or bottom exit condition as appropriate depending
1276 on whether or not we know an overflow cannot occur. */
1277 if (gnu_cond_expr)
1278 LOOP_STMT_BOT_COND (gnu_loop_stmt)
1279 = build_binary_op (NE_EXPR, integer_type_node,
1280 gnu_loop_var, gnu_last);
1281 else
1282 LOOP_STMT_TOP_COND (gnu_loop_stmt)
1283 = build_binary_op (end_code, integer_type_node,
1284 gnu_loop_var, gnu_last);
1286 LOOP_STMT_UPDATE (gnu_loop_stmt)
1287 = build_binary_op (reversep ? PREDECREMENT_EXPR
1288 : PREINCREMENT_EXPR,
1289 TREE_TYPE (gnu_loop_var),
1290 gnu_loop_var,
1291 convert (TREE_TYPE (gnu_loop_var),
1292 integer_one_node));
1293 annotate_with_node (LOOP_STMT_UPDATE (gnu_loop_stmt),
1294 gnat_iter_scheme);
1297 /* If the loop was named, have the name point to this loop. In this case,
1298 the association is not a ..._DECL node, but the end label from this
1299 LOOP_STMT. */
1300 if (Present (Identifier (gnat_node)))
1301 save_gnu_tree (Entity (Identifier (gnat_node)),
1302 LOOP_STMT_LABEL (gnu_loop_stmt), true);
1304 /* Make the loop body into its own block, so any allocated storage will be
1305 released every iteration. This is needed for stack allocation. */
1306 LOOP_STMT_BODY (gnu_loop_stmt)
1307 = build_stmt_group (Statements (gnat_node), true);
1309 /* If we declared a variable, then we are in a statement group for that
1310 declaration. Add the LOOP_STMT to it and make that the "loop". */
1311 if (gnu_loop_var)
1313 add_stmt (gnu_loop_stmt);
1314 gnat_poplevel ();
1315 gnu_loop_stmt = end_stmt_group ();
1318 /* If we have an outer COND_EXPR, that's our result and this loop is its
1319 "true" statement. Otherwise, the result is the LOOP_STMT. */
1320 if (gnu_cond_expr)
1322 COND_EXPR_THEN (gnu_cond_expr) = gnu_loop_stmt;
1323 gnu_result = gnu_cond_expr;
1324 recalculate_side_effects (gnu_cond_expr);
1326 else
1327 gnu_result = gnu_loop_stmt;
1329 pop_stack (&gnu_loop_label_stack);
1331 return gnu_result;
1334 /* Subroutine of gnat_to_gnu to process gnat_node, an N_Subprogram_Body. We
1335 don't return anything. */
1337 static void
1338 Subprogram_Body_to_gnu (Node_Id gnat_node)
1340 /* Save debug output mode in case it is reset. */
1341 enum debug_info_type save_write_symbols = write_symbols;
1342 const struct gcc_debug_hooks *const save_debug_hooks = debug_hooks;
1343 /* Defining identifier of a parameter to the subprogram. */
1344 Entity_Id gnat_param;
1345 /* The defining identifier for the subprogram body. Note that if a
1346 specification has appeared before for this body, then the identifier
1347 occurring in that specification will also be a defining identifier and all
1348 the calls to this subprogram will point to that specification. */
1349 Entity_Id gnat_subprog_id
1350 = (Present (Corresponding_Spec (gnat_node))
1351 ? Corresponding_Spec (gnat_node) : Defining_Entity (gnat_node));
1352 /* The FUNCTION_DECL node corresponding to the subprogram spec. */
1353 tree gnu_subprog_decl;
1354 /* The FUNCTION_TYPE node corresponding to the subprogram spec. */
1355 tree gnu_subprog_type;
1356 tree gnu_cico_list;
1357 tree gnu_result;
1359 /* If this is a generic object or if it has been eliminated,
1360 ignore it. */
1361 if (Ekind (gnat_subprog_id) == E_Generic_Procedure
1362 || Ekind (gnat_subprog_id) == E_Generic_Function
1363 || Is_Eliminated (gnat_subprog_id))
1364 return;
1366 /* If debug information is suppressed for the subprogram, turn debug
1367 mode off for the duration of processing. */
1368 if (!Needs_Debug_Info (gnat_subprog_id))
1370 write_symbols = NO_DEBUG;
1371 debug_hooks = &do_nothing_debug_hooks;
1374 /* If this subprogram acts as its own spec, define it. Otherwise, just get
1375 the already-elaborated tree node. However, if this subprogram had its
1376 elaboration deferred, we will already have made a tree node for it. So
1377 treat it as not being defined in that case. Such a subprogram cannot
1378 have an address clause or a freeze node, so this test is safe, though it
1379 does disable some otherwise-useful error checking. */
1380 gnu_subprog_decl
1381 = gnat_to_gnu_entity (gnat_subprog_id, NULL_TREE,
1382 Acts_As_Spec (gnat_node)
1383 && !present_gnu_tree (gnat_subprog_id));
1385 gnu_subprog_type = TREE_TYPE (gnu_subprog_decl);
1387 /* Set the line number in the decl to correspond to that of the body so that
1388 the line number notes are written
1389 correctly. */
1390 Sloc_to_locus (Sloc (gnat_node), &DECL_SOURCE_LOCATION (gnu_subprog_decl));
1392 begin_subprog_body (gnu_subprog_decl);
1393 gnu_cico_list = TYPE_CI_CO_LIST (gnu_subprog_type);
1395 /* If there are OUT parameters, we need to ensure that the return statement
1396 properly copies them out. We do this by making a new block and converting
1397 any inner return into a goto to a label at the end of the block. */
1398 push_stack (&gnu_return_label_stack, NULL_TREE,
1399 gnu_cico_list ? create_artificial_label () : NULL_TREE);
1401 /* Get a tree corresponding to the code for the subprogram. */
1402 start_stmt_group ();
1403 gnat_pushlevel ();
1405 /* See if there are any parameters for which we don't yet have GCC entities.
1406 These must be for OUT parameters for which we will be making VAR_DECL
1407 nodes here. Fill them in to TYPE_CI_CO_LIST, which must contain the empty
1408 entry as well. We can match up the entries because TYPE_CI_CO_LIST is in
1409 the order of the parameters. */
1410 for (gnat_param = First_Formal (gnat_subprog_id);
1411 Present (gnat_param);
1412 gnat_param = Next_Formal_With_Extras (gnat_param))
1413 if (!present_gnu_tree (gnat_param))
1415 /* Skip any entries that have been already filled in; they must
1416 correspond to IN OUT parameters. */
1417 for (; gnu_cico_list && TREE_VALUE (gnu_cico_list);
1418 gnu_cico_list = TREE_CHAIN (gnu_cico_list))
1421 /* Do any needed references for padded types. */
1422 TREE_VALUE (gnu_cico_list)
1423 = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_list)),
1424 gnat_to_gnu_entity (gnat_param, NULL_TREE, 1));
1427 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
1429 /* Generate the code of the subprogram itself. A return statement will be
1430 present and any OUT parameters will be handled there. */
1431 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
1432 gnat_poplevel ();
1433 gnu_result = end_stmt_group ();
1435 /* If we made a special return label, we need to make a block that contains
1436 the definition of that label and the copying to the return value. That
1437 block first contains the function, then the label and copy statement. */
1438 if (TREE_VALUE (gnu_return_label_stack))
1440 tree gnu_retval;
1442 start_stmt_group ();
1443 gnat_pushlevel ();
1444 add_stmt (gnu_result);
1445 add_stmt (build1 (LABEL_EXPR, void_type_node,
1446 TREE_VALUE (gnu_return_label_stack)));
1448 gnu_cico_list = TYPE_CI_CO_LIST (gnu_subprog_type);
1449 if (list_length (gnu_cico_list) == 1)
1450 gnu_retval = TREE_VALUE (gnu_cico_list);
1451 else
1452 gnu_retval = gnat_build_constructor (TREE_TYPE (gnu_subprog_type),
1453 gnu_cico_list);
1455 if (DECL_P (gnu_retval) && DECL_BY_REF_P (gnu_retval))
1456 gnu_retval = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_retval);
1458 add_stmt_with_node
1459 (build1 (RETURN_EXPR, void_type_node,
1460 build2 (MODIFY_EXPR, TREE_TYPE (gnu_retval),
1461 DECL_RESULT (current_function_decl), gnu_retval)),
1462 gnat_node);
1463 gnat_poplevel ();
1464 gnu_result = end_stmt_group ();
1467 pop_stack (&gnu_return_label_stack);
1469 /* Initialize the information node for the function and set the
1470 end location. */
1471 allocate_struct_function (current_function_decl);
1472 Sloc_to_locus
1473 ((Present (End_Label (Handled_Statement_Sequence (gnat_node)))
1474 ? Sloc (End_Label (Handled_Statement_Sequence (gnat_node)))
1475 : Sloc (gnat_node)),
1476 &cfun->function_end_locus);
1478 end_subprog_body (gnu_result);
1480 /* Disconnect the trees for parameters that we made variables for from the
1481 GNAT entities since these are unusable after we end the function. */
1482 for (gnat_param = First_Formal (gnat_subprog_id);
1483 Present (gnat_param);
1484 gnat_param = Next_Formal_With_Extras (gnat_param))
1485 if (TREE_CODE (get_gnu_tree (gnat_param)) == VAR_DECL)
1486 save_gnu_tree (gnat_param, NULL_TREE, false);
1488 mark_out_of_scope (Defining_Unit_Name (Specification (gnat_node)));
1489 write_symbols = save_write_symbols;
1490 debug_hooks = save_debug_hooks;
1493 /* Subroutine of gnat_to_gnu to translate gnat_node, either an N_Function_Call
1494 or an N_Procedure_Call_Statement, to a GCC tree, which is returned.
1495 GNU_RESULT_TYPE_P is a pointer to where we should place the result type.
1496 If GNU_TARGET is non-null, this must be a function call and the result
1497 of the call is to be placed into that object. */
1499 static tree
1500 call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
1502 tree gnu_result;
1503 /* The GCC node corresponding to the GNAT subprogram name. This can either
1504 be a FUNCTION_DECL node if we are dealing with a standard subprogram call,
1505 or an indirect reference expression (an INDIRECT_REF node) pointing to a
1506 subprogram. */
1507 tree gnu_subprog_node = gnat_to_gnu (Name (gnat_node));
1508 /* The FUNCTION_TYPE node giving the GCC type of the subprogram. */
1509 tree gnu_subprog_type = TREE_TYPE (gnu_subprog_node);
1510 tree gnu_subprog_addr = build_unary_op (ADDR_EXPR, NULL_TREE,
1511 gnu_subprog_node);
1512 Entity_Id gnat_formal;
1513 Node_Id gnat_actual;
1514 tree gnu_actual_list = NULL_TREE;
1515 tree gnu_name_list = NULL_TREE;
1516 tree gnu_before_list = NULL_TREE;
1517 tree gnu_after_list = NULL_TREE;
1518 tree gnu_subprog_call;
1520 switch (Nkind (Name (gnat_node)))
1522 case N_Identifier:
1523 case N_Operator_Symbol:
1524 case N_Expanded_Name:
1525 case N_Attribute_Reference:
1526 if (Is_Eliminated (Entity (Name (gnat_node))))
1527 Eliminate_Error_Msg (gnat_node, Entity (Name (gnat_node)));
1530 gcc_assert (TREE_CODE (gnu_subprog_type) == FUNCTION_TYPE);
1532 /* If we are calling a stubbed function, make this into a raise of
1533 Program_Error. Elaborate all our args first. */
1534 if (TREE_CODE (gnu_subprog_node) == FUNCTION_DECL
1535 && DECL_STUBBED_P (gnu_subprog_node))
1537 for (gnat_actual = First_Actual (gnat_node);
1538 Present (gnat_actual);
1539 gnat_actual = Next_Actual (gnat_actual))
1540 add_stmt (gnat_to_gnu (gnat_actual));
1542 if (Nkind (gnat_node) == N_Function_Call && !gnu_target)
1544 *gnu_result_type_p = TREE_TYPE (gnu_subprog_type);
1545 return build1 (NULL_EXPR, *gnu_result_type_p,
1546 build_call_raise (PE_Stubbed_Subprogram_Called));
1548 else
1549 return build_call_raise (PE_Stubbed_Subprogram_Called);
1552 /* If we are calling by supplying a pointer to a target, set up that
1553 pointer as the first argument. Use GNU_TARGET if one was passed;
1554 otherwise, make a target by building a variable of the maximum size
1555 of the type. */
1556 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
1558 tree gnu_real_ret_type
1559 = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (gnu_subprog_type)));
1561 if (!gnu_target)
1563 tree gnu_obj_type
1564 = maybe_pad_type (gnu_real_ret_type,
1565 max_size (TYPE_SIZE (gnu_real_ret_type), true),
1566 0, Etype (Name (gnat_node)), "PAD", false,
1567 false, false);
1569 gnu_target = create_tmp_var_raw (gnu_obj_type, "LR");
1570 gnat_pushdecl (gnu_target, gnat_node);
1573 gnu_actual_list
1574 = tree_cons (NULL_TREE,
1575 build_unary_op (ADDR_EXPR, NULL_TREE,
1576 unchecked_convert (gnu_real_ret_type,
1577 gnu_target,
1578 false)),
1579 NULL_TREE);
1583 /* The only way we can be making a call via an access type is if Name is an
1584 explicit dereference. In that case, get the list of formal args from the
1585 type the access type is pointing to. Otherwise, get the formals from
1586 entity being called. */
1587 if (Nkind (Name (gnat_node)) == N_Explicit_Dereference)
1588 gnat_formal = First_Formal (Etype (Name (gnat_node)));
1589 else if (Nkind (Name (gnat_node)) == N_Attribute_Reference)
1590 /* Assume here that this must be 'Elab_Body or 'Elab_Spec. */
1591 gnat_formal = 0;
1592 else
1593 gnat_formal = First_Formal (Entity (Name (gnat_node)));
1595 /* Create the list of the actual parameters as GCC expects it, namely a chain
1596 of TREE_LIST nodes in which the TREE_VALUE field of each node is a
1597 parameter-expression and the TREE_PURPOSE field is null. Skip OUT
1598 parameters not passed by reference and don't need to be copied in. */
1599 for (gnat_actual = First_Actual (gnat_node);
1600 Present (gnat_actual);
1601 gnat_formal = Next_Formal_With_Extras (gnat_formal),
1602 gnat_actual = Next_Actual (gnat_actual))
1604 tree gnu_formal
1605 = (present_gnu_tree (gnat_formal)
1606 ? get_gnu_tree (gnat_formal) : NULL_TREE);
1607 /* We treat a conversion between aggregate types as if it is an
1608 unchecked conversion. */
1609 bool unchecked_convert_p
1610 = (Nkind (gnat_actual) == N_Unchecked_Type_Conversion
1611 || (Nkind (gnat_actual) == N_Type_Conversion
1612 && Is_Composite_Type (Underlying_Type (Etype (gnat_formal)))));
1613 Node_Id gnat_name = (unchecked_convert_p
1614 ? Expression (gnat_actual) : gnat_actual);
1615 tree gnu_name = gnat_to_gnu (gnat_name);
1616 tree gnu_name_type = gnat_to_gnu_type (Etype (gnat_name));
1617 tree gnu_actual;
1618 tree gnu_formal_type;
1620 /* If it's possible we may need to use this expression twice, make sure
1621 than any side-effects are handled via SAVE_EXPRs. Likewise if we need
1622 to force side-effects before the call.
1624 ??? This is more conservative than we need since we don't need to do
1625 this for pass-by-ref with no conversion. If we are passing a
1626 non-addressable Out or In Out parameter by reference, pass the address
1627 of a copy and set up to copy back out after the call. */
1628 if (Ekind (gnat_formal) != E_In_Parameter)
1630 gnu_name = gnat_stabilize_reference (gnu_name, true);
1631 if (!addressable_p (gnu_name)
1632 && gnu_formal
1633 && (DECL_BY_REF_P (gnu_formal)
1634 || (TREE_CODE (gnu_formal) == PARM_DECL
1635 && (DECL_BY_COMPONENT_PTR_P (gnu_formal)
1636 || (DECL_BY_DESCRIPTOR_P (gnu_formal))))))
1638 tree gnu_copy = gnu_name;
1639 tree gnu_temp;
1641 /* For users of Starlet we issue a warning because the
1642 interface apparently assumes that by-ref parameters
1643 outlive the procedure invocation. The code still
1644 will not work as intended, but we cannot do much
1645 better since other low-level parts of the back-end
1646 would allocate temporaries at will because of the
1647 misalignment if we did not do so here. */
1649 if (Is_Valued_Procedure (Entity (Name (gnat_node))))
1651 post_error
1652 ("?possible violation of implicit assumption",
1653 gnat_actual);
1654 post_error_ne
1655 ("?made by pragma Import_Valued_Procedure on &",
1656 gnat_actual, Entity (Name (gnat_node)));
1657 post_error_ne
1658 ("?because of misalignment of &",
1659 gnat_actual, gnat_formal);
1662 /* Remove any unpadding on the actual and make a copy. But if
1663 the actual is a justified modular type, first convert
1664 to it. */
1665 if (TREE_CODE (gnu_name) == COMPONENT_REF
1666 && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_name, 0)))
1667 == RECORD_TYPE)
1668 && (TYPE_IS_PADDING_P
1669 (TREE_TYPE (TREE_OPERAND (gnu_name, 0))))))
1670 gnu_name = gnu_copy = TREE_OPERAND (gnu_name, 0);
1671 else if (TREE_CODE (gnu_name_type) == RECORD_TYPE
1672 && (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type)))
1673 gnu_name = convert (gnu_name_type, gnu_name);
1675 gnu_actual = save_expr (gnu_name);
1677 /* Since we're going to take the address of the SAVE_EXPR, we
1678 don't want it to be marked as unchanging. So set
1679 TREE_ADDRESSABLE. */
1680 gnu_temp = skip_simple_arithmetic (gnu_actual);
1681 if (TREE_CODE (gnu_temp) == SAVE_EXPR)
1683 TREE_ADDRESSABLE (gnu_temp) = 1;
1684 TREE_READONLY (gnu_temp) = 0;
1687 /* Set up to move the copy back to the original. */
1688 gnu_temp = build2 (MODIFY_EXPR, TREE_TYPE (gnu_copy),
1689 gnu_copy, gnu_actual);
1690 annotate_with_node (gnu_temp, gnat_actual);
1691 append_to_statement_list (gnu_temp, &gnu_after_list);
1695 /* If this was a procedure call, we may not have removed any padding.
1696 So do it here for the part we will use as an input, if any. */
1697 gnu_actual = gnu_name;
1698 if (Ekind (gnat_formal) != E_Out_Parameter
1699 && TREE_CODE (TREE_TYPE (gnu_actual)) == RECORD_TYPE
1700 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual)))
1701 gnu_actual = convert (get_unpadded_type (Etype (gnat_actual)),
1702 gnu_actual);
1704 /* Unless this is an In parameter, we must remove any LJM building
1705 from GNU_NAME. */
1706 if (Ekind (gnat_formal) != E_In_Parameter
1707 && TREE_CODE (gnu_name) == CONSTRUCTOR
1708 && TREE_CODE (TREE_TYPE (gnu_name)) == RECORD_TYPE
1709 && TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (gnu_name)))
1710 gnu_name = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_name))),
1711 gnu_name);
1713 if (Ekind (gnat_formal) != E_Out_Parameter
1714 && !unchecked_convert_p
1715 && Do_Range_Check (gnat_actual))
1716 gnu_actual = emit_range_check (gnu_actual, Etype (gnat_formal));
1718 /* Do any needed conversions. We need only check for unchecked
1719 conversion since normal conversions will be handled by just
1720 converting to the formal type. */
1721 if (unchecked_convert_p)
1723 gnu_actual
1724 = unchecked_convert (gnat_to_gnu_type (Etype (gnat_actual)),
1725 gnu_actual,
1726 (Nkind (gnat_actual)
1727 == N_Unchecked_Type_Conversion)
1728 && No_Truncation (gnat_actual));
1730 /* One we've done the unchecked conversion, we still must ensure that
1731 the object is in range of the formal's type. */
1732 if (Ekind (gnat_formal) != E_Out_Parameter
1733 && Do_Range_Check (gnat_actual))
1734 gnu_actual = emit_range_check (gnu_actual,
1735 Etype (gnat_formal));
1737 else if (TREE_CODE (gnu_actual) != SAVE_EXPR)
1738 /* We may have suppressed a conversion to the Etype of the actual since
1739 the parent is a procedure call. So add the conversion here. */
1740 gnu_actual = convert (gnat_to_gnu_type (Etype (gnat_actual)),
1741 gnu_actual);
1743 /* If we have not saved a GCC object for the formal, it means it is an
1744 OUT parameter not passed by reference and that does not need to be
1745 copied in. Otherwise, look at the PARM_DECL to see if it is passed by
1746 reference. */
1747 if (gnu_formal
1748 && TREE_CODE (gnu_formal) == PARM_DECL && DECL_BY_REF_P (gnu_formal))
1750 if (Ekind (gnat_formal) != E_In_Parameter)
1752 gnu_actual = gnu_name;
1754 /* If we have a padded type, be sure we've removed padding. */
1755 if (TREE_CODE (TREE_TYPE (gnu_actual)) == RECORD_TYPE
1756 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual))
1757 && TREE_CODE (gnu_actual) != SAVE_EXPR)
1758 gnu_actual = convert (get_unpadded_type (Etype (gnat_actual)),
1759 gnu_actual);
1761 /* If we have the constructed subtype of an aliased object
1762 with an unconstrained nominal subtype, the type of the
1763 actual includes the template, although it is formally
1764 constrained. So we need to convert it back to the real
1765 constructed subtype to retrieve the constrained part
1766 and takes its address. */
1767 if (TREE_CODE (TREE_TYPE (gnu_actual)) == RECORD_TYPE
1768 && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (gnu_actual))
1769 && TREE_CODE (gnu_actual) != SAVE_EXPR
1770 && Is_Constr_Subt_For_UN_Aliased (Etype (gnat_actual))
1771 && Is_Array_Type (Etype (gnat_actual)))
1772 gnu_actual = convert (gnat_to_gnu_type (Etype (gnat_actual)),
1773 gnu_actual);
1776 /* Otherwise, if we have a non-addressable COMPONENT_REF of a
1777 variable-size type see if it's doing a unpadding operation. If
1778 so, remove that operation since we have no way of allocating the
1779 required temporary. */
1780 if (TREE_CODE (gnu_actual) == COMPONENT_REF
1781 && !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual)))
1782 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_actual, 0)))
1783 == RECORD_TYPE)
1784 && TYPE_IS_PADDING_P (TREE_TYPE
1785 (TREE_OPERAND (gnu_actual, 0)))
1786 && !addressable_p (gnu_actual))
1787 gnu_actual = TREE_OPERAND (gnu_actual, 0);
1789 /* The symmetry of the paths to the type of an entity is broken here
1790 since arguments don't know that they will be passed by ref. */
1791 gnu_formal_type = TREE_TYPE (get_gnu_tree (gnat_formal));
1792 gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
1794 else if (gnu_formal && TREE_CODE (gnu_formal) == PARM_DECL
1795 && DECL_BY_COMPONENT_PTR_P (gnu_formal))
1797 gnu_formal_type = TREE_TYPE (get_gnu_tree (gnat_formal));
1798 gnu_actual = maybe_implicit_deref (gnu_actual);
1799 gnu_actual = maybe_unconstrained_array (gnu_actual);
1801 if (TREE_CODE (gnu_formal_type) == RECORD_TYPE
1802 && TYPE_IS_PADDING_P (gnu_formal_type))
1804 gnu_formal_type = TREE_TYPE (TYPE_FIELDS (gnu_formal_type));
1805 gnu_actual = convert (gnu_formal_type, gnu_actual);
1808 /* Take the address of the object and convert to the proper pointer
1809 type. We'd like to actually compute the address of the beginning
1810 of the array using an ADDR_EXPR of an ARRAY_REF, but there's a
1811 possibility that the ARRAY_REF might return a constant and we'd be
1812 getting the wrong address. Neither approach is exactly correct,
1813 but this is the most likely to work in all cases. */
1814 gnu_actual = convert (gnu_formal_type,
1815 build_unary_op (ADDR_EXPR, NULL_TREE,
1816 gnu_actual));
1818 else if (gnu_formal && TREE_CODE (gnu_formal) == PARM_DECL
1819 && DECL_BY_DESCRIPTOR_P (gnu_formal))
1821 /* If arg is 'Null_Parameter, pass zero descriptor. */
1822 if ((TREE_CODE (gnu_actual) == INDIRECT_REF
1823 || TREE_CODE (gnu_actual) == UNCONSTRAINED_ARRAY_REF)
1824 && TREE_PRIVATE (gnu_actual))
1825 gnu_actual = convert (DECL_ARG_TYPE (get_gnu_tree (gnat_formal)),
1826 integer_zero_node);
1827 else
1828 gnu_actual = build_unary_op (ADDR_EXPR, NULL_TREE,
1829 fill_vms_descriptor (gnu_actual,
1830 gnat_formal));
1832 else
1834 tree gnu_actual_size = TYPE_SIZE (TREE_TYPE (gnu_actual));
1836 if (Ekind (gnat_formal) != E_In_Parameter)
1837 gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list);
1839 if (!gnu_formal || TREE_CODE (gnu_formal) != PARM_DECL)
1840 continue;
1842 /* If this is 'Null_Parameter, pass a zero even though we are
1843 dereferencing it. */
1844 else if (TREE_CODE (gnu_actual) == INDIRECT_REF
1845 && TREE_PRIVATE (gnu_actual)
1846 && host_integerp (gnu_actual_size, 1)
1847 && 0 >= compare_tree_int (gnu_actual_size,
1848 BITS_PER_WORD))
1849 gnu_actual
1850 = unchecked_convert (DECL_ARG_TYPE (gnu_formal),
1851 convert (gnat_type_for_size
1852 (tree_low_cst (gnu_actual_size, 1),
1854 integer_zero_node),
1855 false);
1856 else
1857 gnu_actual = convert (DECL_ARG_TYPE (gnu_formal), gnu_actual);
1860 gnu_actual_list = tree_cons (NULL_TREE, gnu_actual, gnu_actual_list);
1863 gnu_subprog_call = build3 (CALL_EXPR, TREE_TYPE (gnu_subprog_type),
1864 gnu_subprog_addr, nreverse (gnu_actual_list),
1865 NULL_TREE);
1867 /* If we return by passing a target, we emit the call and return the target
1868 as our result. */
1869 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
1871 add_stmt_with_node (gnu_subprog_call, gnat_node);
1872 *gnu_result_type_p
1873 = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (gnu_subprog_type)));
1874 return unchecked_convert (*gnu_result_type_p, gnu_target, false);
1877 /* If it is a function call, the result is the call expression unless
1878 a target is specified, in which case we copy the result into the target
1879 and return the assignment statement. */
1880 else if (Nkind (gnat_node) == N_Function_Call)
1882 gnu_result = gnu_subprog_call;
1884 /* If the function returns an unconstrained array or by reference,
1885 we have to de-dereference the pointer. */
1886 if (TYPE_RETURNS_UNCONSTRAINED_P (gnu_subprog_type)
1887 || TYPE_RETURNS_BY_REF_P (gnu_subprog_type))
1888 gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
1890 if (gnu_target)
1891 gnu_result = build_binary_op (MODIFY_EXPR, NULL_TREE,
1892 gnu_target, gnu_result);
1893 else
1894 *gnu_result_type_p = get_unpadded_type (Etype (gnat_node));
1896 return gnu_result;
1899 /* If this is the case where the GNAT tree contains a procedure call
1900 but the Ada procedure has copy in copy out parameters, the special
1901 parameter passing mechanism must be used. */
1902 else if (TYPE_CI_CO_LIST (gnu_subprog_type) != NULL_TREE)
1904 /* List of FIELD_DECLs associated with the PARM_DECLs of the copy
1905 in copy out parameters. */
1906 tree scalar_return_list = TYPE_CI_CO_LIST (gnu_subprog_type);
1907 int length = list_length (scalar_return_list);
1909 if (length > 1)
1911 tree gnu_name;
1913 gnu_subprog_call = save_expr (gnu_subprog_call);
1914 gnu_name_list = nreverse (gnu_name_list);
1916 /* If any of the names had side-effects, ensure they are all
1917 evaluated before the call. */
1918 for (gnu_name = gnu_name_list; gnu_name;
1919 gnu_name = TREE_CHAIN (gnu_name))
1920 if (TREE_SIDE_EFFECTS (TREE_VALUE (gnu_name)))
1921 append_to_statement_list (TREE_VALUE (gnu_name),
1922 &gnu_before_list);
1925 if (Nkind (Name (gnat_node)) == N_Explicit_Dereference)
1926 gnat_formal = First_Formal (Etype (Name (gnat_node)));
1927 else
1928 gnat_formal = First_Formal (Entity (Name (gnat_node)));
1930 for (gnat_actual = First_Actual (gnat_node);
1931 Present (gnat_actual);
1932 gnat_formal = Next_Formal_With_Extras (gnat_formal),
1933 gnat_actual = Next_Actual (gnat_actual))
1934 /* If we are dealing with a copy in copy out parameter, we must
1935 retrieve its value from the record returned in the call. */
1936 if (!(present_gnu_tree (gnat_formal)
1937 && TREE_CODE (get_gnu_tree (gnat_formal)) == PARM_DECL
1938 && (DECL_BY_REF_P (get_gnu_tree (gnat_formal))
1939 || (TREE_CODE (get_gnu_tree (gnat_formal)) == PARM_DECL
1940 && ((DECL_BY_COMPONENT_PTR_P (get_gnu_tree (gnat_formal))
1941 || (DECL_BY_DESCRIPTOR_P
1942 (get_gnu_tree (gnat_formal))))))))
1943 && Ekind (gnat_formal) != E_In_Parameter)
1945 /* Get the value to assign to this OUT or IN OUT parameter. It is
1946 either the result of the function if there is only a single such
1947 parameter or the appropriate field from the record returned. */
1948 tree gnu_result
1949 = length == 1 ? gnu_subprog_call
1950 : build_component_ref (gnu_subprog_call, NULL_TREE,
1951 TREE_PURPOSE (scalar_return_list),
1952 false);
1953 bool unchecked_conversion = (Nkind (gnat_actual)
1954 == N_Unchecked_Type_Conversion);
1955 /* If the actual is a conversion, get the inner expression, which
1956 will be the real destination, and convert the result to the
1957 type of the actual parameter. */
1958 tree gnu_actual
1959 = maybe_unconstrained_array (TREE_VALUE (gnu_name_list));
1961 /* If the result is a padded type, remove the padding. */
1962 if (TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE
1963 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result)))
1964 gnu_result = convert (TREE_TYPE (TYPE_FIELDS
1965 (TREE_TYPE (gnu_result))),
1966 gnu_result);
1968 /* If the result is a type conversion, do it. */
1969 if (Nkind (gnat_actual) == N_Type_Conversion)
1970 gnu_result
1971 = convert_with_check
1972 (Etype (Expression (gnat_actual)), gnu_result,
1973 Do_Overflow_Check (gnat_actual),
1974 Do_Range_Check (Expression (gnat_actual)),
1975 Float_Truncate (gnat_actual));
1977 else if (unchecked_conversion)
1978 gnu_result = unchecked_convert (TREE_TYPE (gnu_actual),
1979 gnu_result,
1980 No_Truncation (gnat_actual));
1981 else
1983 if (Do_Range_Check (gnat_actual))
1984 gnu_result = emit_range_check (gnu_result,
1985 Etype (gnat_actual));
1987 if (!(!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual)))
1988 && TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_result)))))
1989 gnu_result = convert (TREE_TYPE (gnu_actual), gnu_result);
1992 gnu_result = build_binary_op (MODIFY_EXPR, NULL_TREE,
1993 gnu_actual, gnu_result);
1994 annotate_with_node (gnu_result, gnat_actual);
1995 append_to_statement_list (gnu_result, &gnu_before_list);
1996 scalar_return_list = TREE_CHAIN (scalar_return_list);
1997 gnu_name_list = TREE_CHAIN (gnu_name_list);
2000 else
2002 annotate_with_node (gnu_subprog_call, gnat_node);
2003 append_to_statement_list (gnu_subprog_call, &gnu_before_list);
2006 append_to_statement_list (gnu_after_list, &gnu_before_list);
2007 return gnu_before_list;
2010 /* Subroutine of gnat_to_gnu to translate gnat_node, an
2011 N_Handled_Sequence_Of_Statements, to a GCC tree, which is returned. */
2013 static tree
2014 Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
2016 tree gnu_jmpsave_decl = NULL_TREE;
2017 tree gnu_jmpbuf_decl = NULL_TREE;
2018 /* If just annotating, ignore all EH and cleanups. */
2019 bool gcc_zcx = (!type_annotate_only
2020 && Present (Exception_Handlers (gnat_node))
2021 && Exception_Mechanism == Back_End_Exceptions);
2022 bool setjmp_longjmp
2023 = (!type_annotate_only && Present (Exception_Handlers (gnat_node))
2024 && Exception_Mechanism == Setjmp_Longjmp);
2025 bool at_end = !type_annotate_only && Present (At_End_Proc (gnat_node));
2026 bool binding_for_block = (at_end || gcc_zcx || setjmp_longjmp);
2027 tree gnu_inner_block; /* The statement(s) for the block itself. */
2028 tree gnu_result;
2029 tree gnu_expr;
2030 Node_Id gnat_temp;
2032 /* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes
2033 and we have our own SJLJ mechanism. To call the GCC mechanism, we call
2034 add_cleanup, and when we leave the binding, end_stmt_group will create
2035 the TRY_FINALLY_EXPR.
2037 ??? The region level calls down there have been specifically put in place
2038 for a ZCX context and currently the order in which things are emitted
2039 (region/handlers) is different from the SJLJ case. Instead of putting
2040 other calls with different conditions at other places for the SJLJ case,
2041 it seems cleaner to reorder things for the SJLJ case and generalize the
2042 condition to make it not ZCX specific.
2044 If there are any exceptions or cleanup processing involved, we need an
2045 outer statement group (for Setjmp_Longjmp) and binding level. */
2046 if (binding_for_block)
2048 start_stmt_group ();
2049 gnat_pushlevel ();
2052 /* If we are to call a function when exiting this block add a cleanup
2053 to the binding level we made above. */
2054 if (at_end)
2055 add_cleanup (build_call_0_expr (gnat_to_gnu (At_End_Proc (gnat_node))));
2057 /* If using setjmp_longjmp, make the variables for the setjmp buffer and save
2058 area for address of previous buffer. Do this first since we need to have
2059 the setjmp buf known for any decls in this block. */
2060 if (setjmp_longjmp)
2062 gnu_jmpsave_decl = create_var_decl (get_identifier ("JMPBUF_SAVE"),
2063 NULL_TREE, jmpbuf_ptr_type,
2064 build_call_0_expr (get_jmpbuf_decl),
2065 false, false, false, false, NULL,
2066 gnat_node);
2067 gnu_jmpbuf_decl = create_var_decl (get_identifier ("JMP_BUF"),
2068 NULL_TREE, jmpbuf_type,
2069 NULL_TREE, false, false, false, false,
2070 NULL, gnat_node);
2072 set_block_jmpbuf_decl (gnu_jmpbuf_decl);
2074 /* When we exit this block, restore the saved value. */
2075 add_cleanup (build_call_1_expr (set_jmpbuf_decl, gnu_jmpsave_decl));
2078 /* Now build the tree for the declarations and statements inside this block.
2079 If this is SJLJ, set our jmp_buf as the current buffer. */
2080 start_stmt_group ();
2082 if (setjmp_longjmp)
2083 add_stmt (build_call_1_expr (set_jmpbuf_decl,
2084 build_unary_op (ADDR_EXPR, NULL_TREE,
2085 gnu_jmpbuf_decl)));
2087 if (Present (First_Real_Statement (gnat_node)))
2088 process_decls (Statements (gnat_node), Empty,
2089 First_Real_Statement (gnat_node), true, true);
2091 /* Generate code for each statement in the block. */
2092 for (gnat_temp = (Present (First_Real_Statement (gnat_node))
2093 ? First_Real_Statement (gnat_node)
2094 : First (Statements (gnat_node)));
2095 Present (gnat_temp); gnat_temp = Next (gnat_temp))
2096 add_stmt (gnat_to_gnu (gnat_temp));
2097 gnu_inner_block = end_stmt_group ();
2099 /* Now generate code for the two exception models, if either is relevant for
2100 this block. */
2101 if (setjmp_longjmp)
2103 tree *gnu_else_ptr = 0;
2104 tree gnu_handler;
2106 /* Make a binding level for the exception handling declarations and code
2107 and set up gnu_except_ptr_stack for the handlers to use. */
2108 start_stmt_group ();
2109 gnat_pushlevel ();
2111 push_stack (&gnu_except_ptr_stack, NULL_TREE,
2112 create_var_decl (get_identifier ("EXCEPT_PTR"),
2113 NULL_TREE,
2114 build_pointer_type (except_type_node),
2115 build_call_0_expr (get_excptr_decl), false,
2116 false, false, false, NULL, gnat_node));
2118 /* Generate code for each handler. The N_Exception_Handler case does the
2119 real work and returns a COND_EXPR for each handler, which we chain
2120 together here. */
2121 for (gnat_temp = First_Non_Pragma (Exception_Handlers (gnat_node));
2122 Present (gnat_temp); gnat_temp = Next_Non_Pragma (gnat_temp))
2124 gnu_expr = gnat_to_gnu (gnat_temp);
2126 /* If this is the first one, set it as the outer one. Otherwise,
2127 point the "else" part of the previous handler to us. Then point
2128 to our "else" part. */
2129 if (!gnu_else_ptr)
2130 add_stmt (gnu_expr);
2131 else
2132 *gnu_else_ptr = gnu_expr;
2134 gnu_else_ptr = &COND_EXPR_ELSE (gnu_expr);
2137 /* If none of the exception handlers did anything, re-raise but do not
2138 defer abortion. */
2139 gnu_expr = build_call_1_expr (raise_nodefer_decl,
2140 TREE_VALUE (gnu_except_ptr_stack));
2141 annotate_with_node (gnu_expr, gnat_node);
2143 if (gnu_else_ptr)
2144 *gnu_else_ptr = gnu_expr;
2145 else
2146 add_stmt (gnu_expr);
2148 /* End the binding level dedicated to the exception handlers and get the
2149 whole statement group. */
2150 pop_stack (&gnu_except_ptr_stack);
2151 gnat_poplevel ();
2152 gnu_handler = end_stmt_group ();
2154 /* If the setjmp returns 1, we restore our incoming longjmp value and
2155 then check the handlers. */
2156 start_stmt_group ();
2157 add_stmt_with_node (build_call_1_expr (set_jmpbuf_decl,
2158 gnu_jmpsave_decl),
2159 gnat_node);
2160 add_stmt (gnu_handler);
2161 gnu_handler = end_stmt_group ();
2163 /* This block is now "if (setjmp) ... <handlers> else <block>". */
2164 gnu_result = build3 (COND_EXPR, void_type_node,
2165 (build_call_1_expr
2166 (setjmp_decl,
2167 build_unary_op (ADDR_EXPR, NULL_TREE,
2168 gnu_jmpbuf_decl))),
2169 gnu_handler, gnu_inner_block);
2171 else if (gcc_zcx)
2173 tree gnu_handlers;
2175 /* First make a block containing the handlers. */
2176 start_stmt_group ();
2177 for (gnat_temp = First_Non_Pragma (Exception_Handlers (gnat_node));
2178 Present (gnat_temp);
2179 gnat_temp = Next_Non_Pragma (gnat_temp))
2180 add_stmt (gnat_to_gnu (gnat_temp));
2181 gnu_handlers = end_stmt_group ();
2183 /* Now make the TRY_CATCH_EXPR for the block. */
2184 gnu_result = build2 (TRY_CATCH_EXPR, void_type_node,
2185 gnu_inner_block, gnu_handlers);
2187 else
2188 gnu_result = gnu_inner_block;
2190 /* Now close our outer block, if we had to make one. */
2191 if (binding_for_block)
2193 add_stmt (gnu_result);
2194 gnat_poplevel ();
2195 gnu_result = end_stmt_group ();
2198 return gnu_result;
2201 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
2202 to a GCC tree, which is returned. This is the variant for Setjmp_Longjmp
2203 exception handling. */
2205 static tree
2206 Exception_Handler_to_gnu_sjlj (Node_Id gnat_node)
2208 /* Unless this is "Others" or the special "Non-Ada" exception for Ada, make
2209 an "if" statement to select the proper exceptions. For "Others", exclude
2210 exceptions where Handled_By_Others is nonzero unless the All_Others flag
2211 is set. For "Non-ada", accept an exception if "Lang" is 'V'. */
2212 tree gnu_choice = integer_zero_node;
2213 tree gnu_body = build_stmt_group (Statements (gnat_node), false);
2214 Node_Id gnat_temp;
2216 for (gnat_temp = First (Exception_Choices (gnat_node));
2217 gnat_temp; gnat_temp = Next (gnat_temp))
2219 tree this_choice;
2221 if (Nkind (gnat_temp) == N_Others_Choice)
2223 if (All_Others (gnat_temp))
2224 this_choice = integer_one_node;
2225 else
2226 this_choice
2227 = build_binary_op
2228 (EQ_EXPR, integer_type_node,
2229 convert
2230 (integer_type_node,
2231 build_component_ref
2232 (build_unary_op
2233 (INDIRECT_REF, NULL_TREE,
2234 TREE_VALUE (gnu_except_ptr_stack)),
2235 get_identifier ("not_handled_by_others"), NULL_TREE,
2236 false)),
2237 integer_zero_node);
2240 else if (Nkind (gnat_temp) == N_Identifier
2241 || Nkind (gnat_temp) == N_Expanded_Name)
2243 Entity_Id gnat_ex_id = Entity (gnat_temp);
2244 tree gnu_expr;
2246 /* Exception may be a renaming. Recover original exception which is
2247 the one elaborated and registered. */
2248 if (Present (Renamed_Object (gnat_ex_id)))
2249 gnat_ex_id = Renamed_Object (gnat_ex_id);
2251 gnu_expr = gnat_to_gnu_entity (gnat_ex_id, NULL_TREE, 0);
2253 this_choice
2254 = build_binary_op
2255 (EQ_EXPR, integer_type_node, TREE_VALUE (gnu_except_ptr_stack),
2256 convert (TREE_TYPE (TREE_VALUE (gnu_except_ptr_stack)),
2257 build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr)));
2259 /* If this is the distinguished exception "Non_Ada_Error" (and we are
2260 in VMS mode), also allow a non-Ada exception (a VMS condition) t
2261 match. */
2262 if (Is_Non_Ada_Error (Entity (gnat_temp)))
2264 tree gnu_comp
2265 = build_component_ref
2266 (build_unary_op (INDIRECT_REF, NULL_TREE,
2267 TREE_VALUE (gnu_except_ptr_stack)),
2268 get_identifier ("lang"), NULL_TREE, false);
2270 this_choice
2271 = build_binary_op
2272 (TRUTH_ORIF_EXPR, integer_type_node,
2273 build_binary_op (EQ_EXPR, integer_type_node, gnu_comp,
2274 build_int_cst (TREE_TYPE (gnu_comp), 'V')),
2275 this_choice);
2278 else
2279 gcc_unreachable ();
2281 gnu_choice = build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
2282 gnu_choice, this_choice);
2285 return build3 (COND_EXPR, void_type_node, gnu_choice, gnu_body, NULL_TREE);
2288 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
2289 to a GCC tree, which is returned. This is the variant for ZCX. */
2291 static tree
2292 Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
2294 tree gnu_etypes_list = NULL_TREE;
2295 tree gnu_expr;
2296 tree gnu_etype;
2297 tree gnu_current_exc_ptr;
2298 tree gnu_incoming_exc_ptr;
2299 Node_Id gnat_temp;
2301 /* We build a TREE_LIST of nodes representing what exception types this
2302 handler can catch, with special cases for others and all others cases.
2304 Each exception type is actually identified by a pointer to the exception
2305 id, or to a dummy object for "others" and "all others".
2307 Care should be taken to ensure that the control flow impact of "others"
2308 and "all others" is known to GCC. lang_eh_type_covers is doing the trick
2309 currently. */
2310 for (gnat_temp = First (Exception_Choices (gnat_node));
2311 gnat_temp; gnat_temp = Next (gnat_temp))
2313 if (Nkind (gnat_temp) == N_Others_Choice)
2315 tree gnu_expr
2316 = All_Others (gnat_temp) ? all_others_decl : others_decl;
2318 gnu_etype
2319 = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
2321 else if (Nkind (gnat_temp) == N_Identifier
2322 || Nkind (gnat_temp) == N_Expanded_Name)
2324 Entity_Id gnat_ex_id = Entity (gnat_temp);
2326 /* Exception may be a renaming. Recover original exception which is
2327 the one elaborated and registered. */
2328 if (Present (Renamed_Object (gnat_ex_id)))
2329 gnat_ex_id = Renamed_Object (gnat_ex_id);
2331 gnu_expr = gnat_to_gnu_entity (gnat_ex_id, NULL_TREE, 0);
2332 gnu_etype = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
2334 /* The Non_Ada_Error case for VMS exceptions is handled
2335 by the personality routine. */
2337 else
2338 gcc_unreachable ();
2340 /* The GCC interface expects NULL to be passed for catch all handlers, so
2341 it would be quite tempting to set gnu_etypes_list to NULL if gnu_etype
2342 is integer_zero_node. It would not work, however, because GCC's
2343 notion of "catch all" is stronger than our notion of "others". Until
2344 we correctly use the cleanup interface as well, doing that would
2345 prevent the "all others" handlers from being seen, because nothing
2346 can be caught beyond a catch all from GCC's point of view. */
2347 gnu_etypes_list = tree_cons (NULL_TREE, gnu_etype, gnu_etypes_list);
2350 start_stmt_group ();
2351 gnat_pushlevel ();
2353 /* Expand a call to the begin_handler hook at the beginning of the handler,
2354 and arrange for a call to the end_handler hook to occur on every possible
2355 exit path.
2357 The hooks expect a pointer to the low level occurrence. This is required
2358 for our stack management scheme because a raise inside the handler pushes
2359 a new occurrence on top of the stack, which means that this top does not
2360 necessarily match the occurrence this handler was dealing with.
2362 The EXC_PTR_EXPR object references the exception occurrence being
2363 propagated. Upon handler entry, this is the exception for which the
2364 handler is triggered. This might not be the case upon handler exit,
2365 however, as we might have a new occurrence propagated by the handler's
2366 body, and the end_handler hook called as a cleanup in this context.
2368 We use a local variable to retrieve the incoming value at handler entry
2369 time, and reuse it to feed the end_handler hook's argument at exit. */
2370 gnu_current_exc_ptr = build0 (EXC_PTR_EXPR, ptr_type_node);
2371 gnu_incoming_exc_ptr = create_var_decl (get_identifier ("EXPTR"), NULL_TREE,
2372 ptr_type_node, gnu_current_exc_ptr,
2373 false, false, false, false, NULL,
2374 gnat_node);
2376 add_stmt_with_node (build_call_1_expr (begin_handler_decl,
2377 gnu_incoming_exc_ptr),
2378 gnat_node);
2379 add_cleanup (build_call_1_expr (end_handler_decl, gnu_incoming_exc_ptr));
2380 add_stmt_list (Statements (gnat_node));
2381 gnat_poplevel ();
2383 return build2 (CATCH_EXPR, void_type_node, gnu_etypes_list,
2384 end_stmt_group ());
2387 /* Subroutine of gnat_to_gnu to generate code for an N_Compilation unit. */
2389 static void
2390 Compilation_Unit_to_gnu (Node_Id gnat_node)
2392 /* Make the decl for the elaboration procedure. */
2393 bool body_p = (Defining_Entity (Unit (gnat_node)),
2394 Nkind (Unit (gnat_node)) == N_Package_Body
2395 || Nkind (Unit (gnat_node)) == N_Subprogram_Body);
2396 Entity_Id gnat_unit_entity = Defining_Entity (Unit (gnat_node));
2397 tree gnu_elab_proc_decl
2398 = create_subprog_decl
2399 (create_concat_name (gnat_unit_entity,
2400 body_p ? "elabb" : "elabs"),
2401 NULL_TREE, void_ftype, NULL_TREE, false, true, false, NULL,
2402 gnat_unit_entity);
2403 struct elab_info *info;
2405 push_stack (&gnu_elab_proc_stack, NULL_TREE, gnu_elab_proc_decl);
2407 DECL_ELABORATION_PROC_P (gnu_elab_proc_decl) = 1;
2408 allocate_struct_function (gnu_elab_proc_decl);
2409 Sloc_to_locus (Sloc (gnat_unit_entity), &cfun->function_end_locus);
2410 cfun = 0;
2412 /* For a body, first process the spec if there is one. */
2413 if (Nkind (Unit (gnat_node)) == N_Package_Body
2414 || (Nkind (Unit (gnat_node)) == N_Subprogram_Body
2415 && !Acts_As_Spec (gnat_node)))
2416 add_stmt (gnat_to_gnu (Library_Unit (gnat_node)));
2418 process_inlined_subprograms (gnat_node);
2420 if (type_annotate_only)
2422 elaborate_all_entities (gnat_node);
2424 if (Nkind (Unit (gnat_node)) == N_Subprogram_Declaration
2425 || Nkind (Unit (gnat_node)) == N_Generic_Package_Declaration
2426 || Nkind (Unit (gnat_node)) == N_Generic_Subprogram_Declaration)
2427 return;
2430 process_decls (Declarations (Aux_Decls_Node (gnat_node)), Empty, Empty,
2431 true, true);
2432 add_stmt (gnat_to_gnu (Unit (gnat_node)));
2434 /* Process any pragmas and actions following the unit. */
2435 add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node)));
2436 add_stmt_list (Actions (Aux_Decls_Node (gnat_node)));
2438 /* Save away what we've made so far and record this potential elaboration
2439 procedure. */
2440 info = (struct elab_info *) ggc_alloc (sizeof (struct elab_info));
2441 set_current_block_context (gnu_elab_proc_decl);
2442 gnat_poplevel ();
2443 DECL_SAVED_TREE (gnu_elab_proc_decl) = end_stmt_group ();
2444 info->next = elab_info_list;
2445 info->elab_proc = gnu_elab_proc_decl;
2446 info->gnat_node = gnat_node;
2447 elab_info_list = info;
2449 /* Generate elaboration code for this unit, if necessary, and say whether
2450 we did or not. */
2451 pop_stack (&gnu_elab_proc_stack);
2453 /* Generate functions to call static constructors and destructors
2454 for targets that do not support .ctors/.dtors sections. These
2455 functions have magic names which are detected by collect2. */
2456 if (static_ctors)
2457 build_global_cdtor ('I', &static_ctors);
2459 if (static_dtors)
2460 build_global_cdtor ('D', &static_dtors);
2463 /* This function is the driver of the GNAT to GCC tree transformation
2464 process. It is the entry point of the tree transformer. GNAT_NODE is the
2465 root of some GNAT tree. Return the root of the corresponding GCC tree.
2466 If this is an expression, return the GCC equivalent of the expression. If
2467 it is a statement, return the statement. In the case when called for a
2468 statement, it may also add statements to the current statement group, in
2469 which case anything it returns is to be interpreted as occurring after
2470 anything `it already added. */
2472 tree
2473 gnat_to_gnu (Node_Id gnat_node)
2475 bool went_into_elab_proc = false;
2476 tree gnu_result = error_mark_node; /* Default to no value. */
2477 tree gnu_result_type = void_type_node;
2478 tree gnu_expr;
2479 tree gnu_lhs, gnu_rhs;
2480 Node_Id gnat_temp;
2482 /* Save node number for error message and set location information. */
2483 error_gnat_node = gnat_node;
2484 Sloc_to_locus (Sloc (gnat_node), &input_location);
2486 if (type_annotate_only
2487 && IN (Nkind (gnat_node), N_Statement_Other_Than_Procedure_Call))
2488 return alloc_stmt_list ();
2490 /* If this node is a non-static subexpression and we are only
2491 annotating types, make this into a NULL_EXPR. */
2492 if (type_annotate_only
2493 && IN (Nkind (gnat_node), N_Subexpr)
2494 && Nkind (gnat_node) != N_Identifier
2495 && !Compile_Time_Known_Value (gnat_node))
2496 return build1 (NULL_EXPR, get_unpadded_type (Etype (gnat_node)),
2497 build_call_raise (CE_Range_Check_Failed));
2499 /* If this is a Statement and we are at top level, it must be part of
2500 the elaboration procedure, so mark us as being in that procedure
2501 and push our context. */
2502 if (!current_function_decl
2503 && ((IN (Nkind (gnat_node), N_Statement_Other_Than_Procedure_Call)
2504 && Nkind (gnat_node) != N_Null_Statement)
2505 || Nkind (gnat_node) == N_Procedure_Call_Statement
2506 || Nkind (gnat_node) == N_Label
2507 || Nkind (gnat_node) == N_Implicit_Label_Declaration
2508 || Nkind (gnat_node) == N_Handled_Sequence_Of_Statements
2509 || ((Nkind (gnat_node) == N_Raise_Constraint_Error
2510 || Nkind (gnat_node) == N_Raise_Storage_Error
2511 || Nkind (gnat_node) == N_Raise_Program_Error)
2512 && (Ekind (Etype (gnat_node)) == E_Void))))
2514 current_function_decl = TREE_VALUE (gnu_elab_proc_stack);
2515 start_stmt_group ();
2516 gnat_pushlevel ();
2517 went_into_elab_proc = true;
2520 switch (Nkind (gnat_node))
2522 /********************************/
2523 /* Chapter 2: Lexical Elements: */
2524 /********************************/
2526 case N_Identifier:
2527 case N_Expanded_Name:
2528 case N_Operator_Symbol:
2529 case N_Defining_Identifier:
2530 gnu_result = Identifier_to_gnu (gnat_node, &gnu_result_type);
2531 break;
2533 case N_Integer_Literal:
2535 tree gnu_type;
2537 /* Get the type of the result, looking inside any padding and
2538 justified modular types. Then get the value in that type. */
2539 gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));
2541 if (TREE_CODE (gnu_type) == RECORD_TYPE
2542 && TYPE_JUSTIFIED_MODULAR_P (gnu_type))
2543 gnu_type = TREE_TYPE (TYPE_FIELDS (gnu_type));
2545 gnu_result = UI_To_gnu (Intval (gnat_node), gnu_type);
2547 /* If the result overflows (meaning it doesn't fit in its base type),
2548 abort. We would like to check that the value is within the range
2549 of the subtype, but that causes problems with subtypes whose usage
2550 will raise Constraint_Error and with biased representation, so
2551 we don't. */
2552 gcc_assert (!TREE_CONSTANT_OVERFLOW (gnu_result));
2554 break;
2556 case N_Character_Literal:
2557 /* If a Entity is present, it means that this was one of the
2558 literals in a user-defined character type. In that case,
2559 just return the value in the CONST_DECL. Otherwise, use the
2560 character code. In that case, the base type should be an
2561 INTEGER_TYPE, but we won't bother checking for that. */
2562 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2563 if (Present (Entity (gnat_node)))
2564 gnu_result = DECL_INITIAL (get_gnu_tree (Entity (gnat_node)));
2565 else
2566 gnu_result
2567 = force_fit_type
2568 (build_int_cst
2569 (gnu_result_type, UI_To_CC (Char_Literal_Value (gnat_node))),
2570 false, false, false);
2571 break;
2573 case N_Real_Literal:
2574 /* If this is of a fixed-point type, the value we want is the
2575 value of the corresponding integer. */
2576 if (IN (Ekind (Underlying_Type (Etype (gnat_node))), Fixed_Point_Kind))
2578 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2579 gnu_result = UI_To_gnu (Corresponding_Integer_Value (gnat_node),
2580 gnu_result_type);
2581 gcc_assert (!TREE_CONSTANT_OVERFLOW (gnu_result));
2584 /* We should never see a Vax_Float type literal, since the front end
2585 is supposed to transform these using appropriate conversions */
2586 else if (Vax_Float (Underlying_Type (Etype (gnat_node))))
2587 gcc_unreachable ();
2589 else
2591 Ureal ur_realval = Realval (gnat_node);
2593 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2595 /* If the real value is zero, so is the result. Otherwise,
2596 convert it to a machine number if it isn't already. That
2597 forces BASE to 0 or 2 and simplifies the rest of our logic. */
2598 if (UR_Is_Zero (ur_realval))
2599 gnu_result = convert (gnu_result_type, integer_zero_node);
2600 else
2602 if (!Is_Machine_Number (gnat_node))
2603 ur_realval
2604 = Machine (Base_Type (Underlying_Type (Etype (gnat_node))),
2605 ur_realval, Round_Even, gnat_node);
2607 gnu_result
2608 = UI_To_gnu (Numerator (ur_realval), gnu_result_type);
2610 /* If we have a base of zero, divide by the denominator.
2611 Otherwise, the base must be 2 and we scale the value, which
2612 we know can fit in the mantissa of the type (hence the use
2613 of that type above). */
2614 if (No (Rbase (ur_realval)))
2615 gnu_result
2616 = build_binary_op (RDIV_EXPR,
2617 get_base_type (gnu_result_type),
2618 gnu_result,
2619 UI_To_gnu (Denominator (ur_realval),
2620 gnu_result_type));
2621 else
2623 REAL_VALUE_TYPE tmp;
2625 gcc_assert (Rbase (ur_realval) == 2);
2626 real_ldexp (&tmp, &TREE_REAL_CST (gnu_result),
2627 - UI_To_Int (Denominator (ur_realval)));
2628 gnu_result = build_real (gnu_result_type, tmp);
2632 /* Now see if we need to negate the result. Do it this way to
2633 properly handle -0. */
2634 if (UR_Is_Negative (Realval (gnat_node)))
2635 gnu_result
2636 = build_unary_op (NEGATE_EXPR, get_base_type (gnu_result_type),
2637 gnu_result);
2640 break;
2642 case N_String_Literal:
2643 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2644 if (TYPE_PRECISION (TREE_TYPE (gnu_result_type)) == HOST_BITS_PER_CHAR)
2646 String_Id gnat_string = Strval (gnat_node);
2647 int length = String_Length (gnat_string);
2648 char *string = (char *) alloca (length + 1);
2649 int i;
2651 /* Build the string with the characters in the literal. Note
2652 that Ada strings are 1-origin. */
2653 for (i = 0; i < length; i++)
2654 string[i] = Get_String_Char (gnat_string, i + 1);
2656 /* Put a null at the end of the string in case it's in a context
2657 where GCC will want to treat it as a C string. */
2658 string[i] = 0;
2660 gnu_result = build_string (length, string);
2662 /* Strings in GCC don't normally have types, but we want
2663 this to not be converted to the array type. */
2664 TREE_TYPE (gnu_result) = gnu_result_type;
2666 else
2668 /* Build a list consisting of each character, then make
2669 the aggregate. */
2670 String_Id gnat_string = Strval (gnat_node);
2671 int length = String_Length (gnat_string);
2672 int i;
2673 tree gnu_list = NULL_TREE;
2674 tree gnu_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type));
2676 for (i = 0; i < length; i++)
2678 gnu_list
2679 = tree_cons (gnu_idx,
2680 build_int_cst (TREE_TYPE (gnu_result_type),
2681 Get_String_Char (gnat_string,
2682 i + 1)),
2683 gnu_list);
2685 gnu_idx = int_const_binop (PLUS_EXPR, gnu_idx, integer_one_node,
2689 gnu_result
2690 = gnat_build_constructor (gnu_result_type, nreverse (gnu_list));
2692 break;
2694 case N_Pragma:
2695 gnu_result = Pragma_to_gnu (gnat_node);
2696 break;
2698 /**************************************/
2699 /* Chapter 3: Declarations and Types: */
2700 /**************************************/
2702 case N_Subtype_Declaration:
2703 case N_Full_Type_Declaration:
2704 case N_Incomplete_Type_Declaration:
2705 case N_Private_Type_Declaration:
2706 case N_Private_Extension_Declaration:
2707 case N_Task_Type_Declaration:
2708 process_type (Defining_Entity (gnat_node));
2709 gnu_result = alloc_stmt_list ();
2710 break;
2712 case N_Object_Declaration:
2713 case N_Exception_Declaration:
2714 gnat_temp = Defining_Entity (gnat_node);
2715 gnu_result = alloc_stmt_list ();
2717 /* If we are just annotating types and this object has an unconstrained
2718 or task type, don't elaborate it. */
2719 if (type_annotate_only
2720 && (((Is_Array_Type (Etype (gnat_temp))
2721 || Is_Record_Type (Etype (gnat_temp)))
2722 && !Is_Constrained (Etype (gnat_temp)))
2723 || Is_Concurrent_Type (Etype (gnat_temp))))
2724 break;
2726 if (Present (Expression (gnat_node))
2727 && !(Nkind (gnat_node) == N_Object_Declaration
2728 && No_Initialization (gnat_node))
2729 && (!type_annotate_only
2730 || Compile_Time_Known_Value (Expression (gnat_node))))
2732 gnu_expr = gnat_to_gnu (Expression (gnat_node));
2733 if (Do_Range_Check (Expression (gnat_node)))
2734 gnu_expr = emit_range_check (gnu_expr, Etype (gnat_temp));
2736 /* If this object has its elaboration delayed, we must force
2737 evaluation of GNU_EXPR right now and save it for when the object
2738 is frozen. */
2739 if (Present (Freeze_Node (gnat_temp)))
2741 if ((Is_Public (gnat_temp) || global_bindings_p ())
2742 && !TREE_CONSTANT (gnu_expr))
2743 gnu_expr
2744 = create_var_decl (create_concat_name (gnat_temp, "init"),
2745 NULL_TREE, TREE_TYPE (gnu_expr),
2746 gnu_expr, false, Is_Public (gnat_temp),
2747 false, false, NULL, gnat_temp);
2748 else
2749 gnu_expr = maybe_variable (gnu_expr);
2751 save_gnu_tree (gnat_node, gnu_expr, true);
2754 else
2755 gnu_expr = NULL_TREE;
2757 if (type_annotate_only && gnu_expr && TREE_CODE (gnu_expr) == ERROR_MARK)
2758 gnu_expr = NULL_TREE;
2760 if (No (Freeze_Node (gnat_temp)))
2761 gnat_to_gnu_entity (gnat_temp, gnu_expr, 1);
2762 break;
2764 case N_Object_Renaming_Declaration:
2765 gnat_temp = Defining_Entity (gnat_node);
2767 /* Don't do anything if this renaming is handled by the front end or if
2768 we are just annotating types and this object has a composite or task
2769 type, don't elaborate it. We return the result in case it has any
2770 SAVE_EXPRs in it that need to be evaluated here. */
2771 if (!Is_Renaming_Of_Object (gnat_temp)
2772 && ! (type_annotate_only
2773 && (Is_Array_Type (Etype (gnat_temp))
2774 || Is_Record_Type (Etype (gnat_temp))
2775 || Is_Concurrent_Type (Etype (gnat_temp)))))
2776 gnu_result
2777 = gnat_to_gnu_entity (gnat_temp,
2778 gnat_to_gnu (Renamed_Object (gnat_temp)), 1);
2779 else
2780 gnu_result = alloc_stmt_list ();
2781 break;
2783 case N_Implicit_Label_Declaration:
2784 gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, 1);
2785 gnu_result = alloc_stmt_list ();
2786 break;
2788 case N_Exception_Renaming_Declaration:
2789 case N_Number_Declaration:
2790 case N_Package_Renaming_Declaration:
2791 case N_Subprogram_Renaming_Declaration:
2792 /* These are fully handled in the front end. */
2793 gnu_result = alloc_stmt_list ();
2794 break;
2796 /*************************************/
2797 /* Chapter 4: Names and Expressions: */
2798 /*************************************/
2800 case N_Explicit_Dereference:
2801 gnu_result = gnat_to_gnu (Prefix (gnat_node));
2802 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2803 gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
2804 break;
2806 case N_Indexed_Component:
2808 tree gnu_array_object = gnat_to_gnu (Prefix (gnat_node));
2809 tree gnu_type;
2810 int ndim;
2811 int i;
2812 Node_Id *gnat_expr_array;
2814 gnu_array_object = maybe_implicit_deref (gnu_array_object);
2815 gnu_array_object = maybe_unconstrained_array (gnu_array_object);
2817 /* If we got a padded type, remove it too. */
2818 if (TREE_CODE (TREE_TYPE (gnu_array_object)) == RECORD_TYPE
2819 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_array_object)))
2820 gnu_array_object
2821 = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_array_object))),
2822 gnu_array_object);
2824 gnu_result = gnu_array_object;
2826 /* First compute the number of dimensions of the array, then
2827 fill the expression array, the order depending on whether
2828 this is a Convention_Fortran array or not. */
2829 for (ndim = 1, gnu_type = TREE_TYPE (gnu_array_object);
2830 TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
2831 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type));
2832 ndim++, gnu_type = TREE_TYPE (gnu_type))
2835 gnat_expr_array = (Node_Id *) alloca (ndim * sizeof (Node_Id));
2837 if (TYPE_CONVENTION_FORTRAN_P (TREE_TYPE (gnu_array_object)))
2838 for (i = ndim - 1, gnat_temp = First (Expressions (gnat_node));
2839 i >= 0;
2840 i--, gnat_temp = Next (gnat_temp))
2841 gnat_expr_array[i] = gnat_temp;
2842 else
2843 for (i = 0, gnat_temp = First (Expressions (gnat_node));
2844 i < ndim;
2845 i++, gnat_temp = Next (gnat_temp))
2846 gnat_expr_array[i] = gnat_temp;
2848 for (i = 0, gnu_type = TREE_TYPE (gnu_array_object);
2849 i < ndim; i++, gnu_type = TREE_TYPE (gnu_type))
2851 gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
2852 gnat_temp = gnat_expr_array[i];
2853 gnu_expr = gnat_to_gnu (gnat_temp);
2855 if (Do_Range_Check (gnat_temp))
2856 gnu_expr
2857 = emit_index_check
2858 (gnu_array_object, gnu_expr,
2859 TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))),
2860 TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))));
2862 gnu_result = build_binary_op (ARRAY_REF, NULL_TREE,
2863 gnu_result, gnu_expr);
2867 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2868 break;
2870 case N_Slice:
2872 tree gnu_type;
2873 Node_Id gnat_range_node = Discrete_Range (gnat_node);
2875 gnu_result = gnat_to_gnu (Prefix (gnat_node));
2876 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2878 /* Do any implicit dereferences of the prefix and do any needed
2879 range check. */
2880 gnu_result = maybe_implicit_deref (gnu_result);
2881 gnu_result = maybe_unconstrained_array (gnu_result);
2882 gnu_type = TREE_TYPE (gnu_result);
2883 if (Do_Range_Check (gnat_range_node))
2885 /* Get the bounds of the slice. */
2886 tree gnu_index_type
2887 = TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_result_type));
2888 tree gnu_min_expr = TYPE_MIN_VALUE (gnu_index_type);
2889 tree gnu_max_expr = TYPE_MAX_VALUE (gnu_index_type);
2890 tree gnu_expr_l, gnu_expr_h, gnu_expr_type;
2892 /* Check to see that the minimum slice value is in range */
2893 gnu_expr_l
2894 = emit_index_check
2895 (gnu_result, gnu_min_expr,
2896 TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))),
2897 TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))));
2899 /* Check to see that the maximum slice value is in range */
2900 gnu_expr_h
2901 = emit_index_check
2902 (gnu_result, gnu_max_expr,
2903 TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))),
2904 TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))));
2906 /* Derive a good type to convert everything too */
2907 gnu_expr_type = get_base_type (TREE_TYPE (gnu_expr_l));
2909 /* Build a compound expression that does the range checks */
2910 gnu_expr
2911 = build_binary_op (COMPOUND_EXPR, gnu_expr_type,
2912 convert (gnu_expr_type, gnu_expr_h),
2913 convert (gnu_expr_type, gnu_expr_l));
2915 /* Build a conditional expression that returns the range checks
2916 expression if the slice range is not null (max >= min) or
2917 returns the min if the slice range is null */
2918 gnu_expr
2919 = fold (build3 (COND_EXPR, gnu_expr_type,
2920 build_binary_op (GE_EXPR, gnu_expr_type,
2921 convert (gnu_expr_type,
2922 gnu_max_expr),
2923 convert (gnu_expr_type,
2924 gnu_min_expr)),
2925 gnu_expr, gnu_min_expr));
2927 else
2928 gnu_expr = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type));
2930 gnu_result = build_binary_op (ARRAY_RANGE_REF, gnu_result_type,
2931 gnu_result, gnu_expr);
2933 break;
2935 case N_Selected_Component:
2937 tree gnu_prefix = gnat_to_gnu (Prefix (gnat_node));
2938 Entity_Id gnat_field = Entity (Selector_Name (gnat_node));
2939 Entity_Id gnat_pref_type = Etype (Prefix (gnat_node));
2940 tree gnu_field;
2942 while (IN (Ekind (gnat_pref_type), Incomplete_Or_Private_Kind)
2943 || IN (Ekind (gnat_pref_type), Access_Kind))
2945 if (IN (Ekind (gnat_pref_type), Incomplete_Or_Private_Kind))
2946 gnat_pref_type = Underlying_Type (gnat_pref_type);
2947 else if (IN (Ekind (gnat_pref_type), Access_Kind))
2948 gnat_pref_type = Designated_Type (gnat_pref_type);
2951 gnu_prefix = maybe_implicit_deref (gnu_prefix);
2953 /* For discriminant references in tagged types always substitute the
2954 corresponding discriminant as the actual selected component. */
2956 if (Is_Tagged_Type (gnat_pref_type))
2957 while (Present (Corresponding_Discriminant (gnat_field)))
2958 gnat_field = Corresponding_Discriminant (gnat_field);
2960 /* For discriminant references of untagged types always substitute the
2961 corresponding stored discriminant. */
2963 else if (Present (Corresponding_Discriminant (gnat_field)))
2964 gnat_field = Original_Record_Component (gnat_field);
2966 /* Handle extracting the real or imaginary part of a complex.
2967 The real part is the first field and the imaginary the last. */
2969 if (TREE_CODE (TREE_TYPE (gnu_prefix)) == COMPLEX_TYPE)
2970 gnu_result = build_unary_op (Present (Next_Entity (gnat_field))
2971 ? REALPART_EXPR : IMAGPART_EXPR,
2972 NULL_TREE, gnu_prefix);
2973 else
2975 gnu_field = gnat_to_gnu_field_decl (gnat_field);
2977 /* If there are discriminants, the prefix might be
2978 evaluated more than once, which is a problem if it has
2979 side-effects. */
2980 if (Has_Discriminants (Is_Access_Type (Etype (Prefix (gnat_node)))
2981 ? Designated_Type (Etype
2982 (Prefix (gnat_node)))
2983 : Etype (Prefix (gnat_node))))
2984 gnu_prefix = gnat_stabilize_reference (gnu_prefix, 0);
2986 gnu_result
2987 = build_component_ref (gnu_prefix, NULL_TREE, gnu_field,
2988 (Nkind (Parent (gnat_node))
2989 == N_Attribute_Reference));
2992 gcc_assert (gnu_result);
2993 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2995 break;
2997 case N_Attribute_Reference:
2999 /* The attribute designator (like an enumeration value). */
3000 int attribute = Get_Attribute_Id (Attribute_Name (gnat_node));
3002 /* The Elab_Spec and Elab_Body attributes are special in that
3003 Prefix is a unit, not an object with a GCC equivalent. Similarly
3004 for Elaborated, since that variable isn't otherwise known. */
3005 if (attribute == Attr_Elab_Body || attribute == Attr_Elab_Spec)
3006 return (create_subprog_decl
3007 (create_concat_name (Entity (Prefix (gnat_node)),
3008 attribute == Attr_Elab_Body
3009 ? "elabb" : "elabs"),
3010 NULL_TREE, void_ftype, NULL_TREE, false, true, true, NULL,
3011 gnat_node));
3013 gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attribute);
3015 break;
3017 case N_Reference:
3018 /* Like 'Access as far as we are concerned. */
3019 gnu_result = gnat_to_gnu (Prefix (gnat_node));
3020 gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_result);
3021 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3022 break;
3024 case N_Aggregate:
3025 case N_Extension_Aggregate:
3027 tree gnu_aggr_type;
3029 /* ??? It is wrong to evaluate the type now, but there doesn't
3030 seem to be any other practical way of doing it. */
3032 gcc_assert (!Expansion_Delayed (gnat_node));
3034 gnu_aggr_type = gnu_result_type
3035 = get_unpadded_type (Etype (gnat_node));
3037 if (TREE_CODE (gnu_result_type) == RECORD_TYPE
3038 && TYPE_CONTAINS_TEMPLATE_P (gnu_result_type))
3039 gnu_aggr_type
3040 = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_result_type)));
3042 if (Null_Record_Present (gnat_node))
3043 gnu_result = gnat_build_constructor (gnu_aggr_type, NULL_TREE);
3045 else if (TREE_CODE (gnu_aggr_type) == UNION_TYPE
3046 && TYPE_UNCHECKED_UNION_P (gnu_aggr_type))
3048 /* The first element is the discrimant, which we ignore. The
3049 next is the field we're building. Convert the expression
3050 to the type of the field and then to the union type. */
3051 Node_Id gnat_assoc
3052 = Next (First (Component_Associations (gnat_node)));
3053 Entity_Id gnat_field = Entity (First (Choices (gnat_assoc)));
3054 tree gnu_field_type
3055 = TREE_TYPE (gnat_to_gnu_entity (gnat_field, NULL_TREE, 0));
3057 gnu_result = convert (gnu_field_type,
3058 gnat_to_gnu (Expression (gnat_assoc)));
3060 else if (TREE_CODE (gnu_aggr_type) == RECORD_TYPE
3061 || TREE_CODE (gnu_aggr_type) == UNION_TYPE)
3062 gnu_result
3063 = assoc_to_constructor (First (Component_Associations (gnat_node)),
3064 gnu_aggr_type);
3065 else if (TREE_CODE (gnu_aggr_type) == ARRAY_TYPE)
3066 gnu_result = pos_to_constructor (First (Expressions (gnat_node)),
3067 gnu_aggr_type,
3068 Component_Type (Etype (gnat_node)));
3069 else if (TREE_CODE (gnu_aggr_type) == COMPLEX_TYPE)
3070 gnu_result
3071 = build_binary_op
3072 (COMPLEX_EXPR, gnu_aggr_type,
3073 gnat_to_gnu (Expression (First
3074 (Component_Associations (gnat_node)))),
3075 gnat_to_gnu (Expression
3076 (Next
3077 (First (Component_Associations (gnat_node))))));
3078 else
3079 gcc_unreachable ();
3081 gnu_result = convert (gnu_result_type, gnu_result);
3083 break;
3085 case N_Null:
3086 gnu_result = null_pointer_node;
3087 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3088 break;
3090 case N_Type_Conversion:
3091 case N_Qualified_Expression:
3092 /* Get the operand expression. */
3093 gnu_result = gnat_to_gnu (Expression (gnat_node));
3094 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3096 gnu_result
3097 = convert_with_check (Etype (gnat_node), gnu_result,
3098 Do_Overflow_Check (gnat_node),
3099 Do_Range_Check (Expression (gnat_node)),
3100 Nkind (gnat_node) == N_Type_Conversion
3101 && Float_Truncate (gnat_node));
3102 break;
3104 case N_Unchecked_Type_Conversion:
3105 gnu_result = gnat_to_gnu (Expression (gnat_node));
3106 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3108 /* If the result is a pointer type, see if we are improperly
3109 converting to a stricter alignment. */
3111 if (STRICT_ALIGNMENT && POINTER_TYPE_P (gnu_result_type)
3112 && IN (Ekind (Etype (gnat_node)), Access_Kind))
3114 unsigned int align = known_alignment (gnu_result);
3115 tree gnu_obj_type = TREE_TYPE (gnu_result_type);
3116 unsigned int oalign = TYPE_ALIGN (gnu_obj_type);
3118 if (align != 0 && align < oalign && !TYPE_ALIGN_OK (gnu_obj_type))
3119 post_error_ne_tree_2
3120 ("?source alignment (^) '< alignment of & (^)",
3121 gnat_node, Designated_Type (Etype (gnat_node)),
3122 size_int (align / BITS_PER_UNIT), oalign / BITS_PER_UNIT);
3125 gnu_result = unchecked_convert (gnu_result_type, gnu_result,
3126 No_Truncation (gnat_node));
3127 break;
3129 case N_In:
3130 case N_Not_In:
3132 tree gnu_object = gnat_to_gnu (Left_Opnd (gnat_node));
3133 Node_Id gnat_range = Right_Opnd (gnat_node);
3134 tree gnu_low;
3135 tree gnu_high;
3137 /* GNAT_RANGE is either an N_Range node or an identifier
3138 denoting a subtype. */
3139 if (Nkind (gnat_range) == N_Range)
3141 gnu_low = gnat_to_gnu (Low_Bound (gnat_range));
3142 gnu_high = gnat_to_gnu (High_Bound (gnat_range));
3144 else if (Nkind (gnat_range) == N_Identifier
3145 || Nkind (gnat_range) == N_Expanded_Name)
3147 tree gnu_range_type = get_unpadded_type (Entity (gnat_range));
3149 gnu_low = TYPE_MIN_VALUE (gnu_range_type);
3150 gnu_high = TYPE_MAX_VALUE (gnu_range_type);
3152 else
3153 gcc_unreachable ();
3155 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3157 /* If LOW and HIGH are identical, perform an equality test.
3158 Otherwise, ensure that GNU_OBJECT is only evaluated once
3159 and perform a full range test. */
3160 if (operand_equal_p (gnu_low, gnu_high, 0))
3161 gnu_result = build_binary_op (EQ_EXPR, gnu_result_type,
3162 gnu_object, gnu_low);
3163 else
3165 gnu_object = protect_multiple_eval (gnu_object);
3166 gnu_result
3167 = build_binary_op (TRUTH_ANDIF_EXPR, gnu_result_type,
3168 build_binary_op (GE_EXPR, gnu_result_type,
3169 gnu_object, gnu_low),
3170 build_binary_op (LE_EXPR, gnu_result_type,
3171 gnu_object, gnu_high));
3174 if (Nkind (gnat_node) == N_Not_In)
3175 gnu_result = invert_truthvalue (gnu_result);
3177 break;
3179 case N_Op_Divide:
3180 gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
3181 gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
3182 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3183 gnu_result = build_binary_op (FLOAT_TYPE_P (gnu_result_type)
3184 ? RDIV_EXPR
3185 : (Rounded_Result (gnat_node)
3186 ? ROUND_DIV_EXPR : TRUNC_DIV_EXPR),
3187 gnu_result_type, gnu_lhs, gnu_rhs);
3188 break;
3190 case N_Op_Or: case N_Op_And: case N_Op_Xor:
3191 /* These can either be operations on booleans or on modular types.
3192 Fall through for boolean types since that's the way GNU_CODES is
3193 set up. */
3194 if (IN (Ekind (Underlying_Type (Etype (gnat_node))),
3195 Modular_Integer_Kind))
3197 enum tree_code code
3198 = (Nkind (gnat_node) == N_Op_Or ? BIT_IOR_EXPR
3199 : Nkind (gnat_node) == N_Op_And ? BIT_AND_EXPR
3200 : BIT_XOR_EXPR);
3202 gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
3203 gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
3204 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3205 gnu_result = build_binary_op (code, gnu_result_type,
3206 gnu_lhs, gnu_rhs);
3207 break;
3210 /* ... fall through ... */
3212 case N_Op_Eq: case N_Op_Ne: case N_Op_Lt:
3213 case N_Op_Le: case N_Op_Gt: case N_Op_Ge:
3214 case N_Op_Add: case N_Op_Subtract: case N_Op_Multiply:
3215 case N_Op_Mod: case N_Op_Rem:
3216 case N_Op_Rotate_Left:
3217 case N_Op_Rotate_Right:
3218 case N_Op_Shift_Left:
3219 case N_Op_Shift_Right:
3220 case N_Op_Shift_Right_Arithmetic:
3221 case N_And_Then: case N_Or_Else:
3223 enum tree_code code = gnu_codes[Nkind (gnat_node)];
3224 tree gnu_type;
3226 gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
3227 gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
3228 gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));
3230 /* If this is a comparison operator, convert any references to
3231 an unconstrained array value into a reference to the
3232 actual array. */
3233 if (TREE_CODE_CLASS (code) == tcc_comparison)
3235 gnu_lhs = maybe_unconstrained_array (gnu_lhs);
3236 gnu_rhs = maybe_unconstrained_array (gnu_rhs);
3239 /* If the result type is a private type, its full view may be a
3240 numeric subtype. The representation we need is that of its base
3241 type, given that it is the result of an arithmetic operation. */
3242 else if (Is_Private_Type (Etype (gnat_node)))
3243 gnu_type = gnu_result_type
3244 = get_unpadded_type (Base_Type (Full_View (Etype (gnat_node))));
3246 /* If this is a shift whose count is not guaranteed to be correct,
3247 we need to adjust the shift count. */
3248 if (IN (Nkind (gnat_node), N_Op_Shift)
3249 && !Shift_Count_OK (gnat_node))
3251 tree gnu_count_type = get_base_type (TREE_TYPE (gnu_rhs));
3252 tree gnu_max_shift
3253 = convert (gnu_count_type, TYPE_SIZE (gnu_type));
3255 if (Nkind (gnat_node) == N_Op_Rotate_Left
3256 || Nkind (gnat_node) == N_Op_Rotate_Right)
3257 gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, gnu_count_type,
3258 gnu_rhs, gnu_max_shift);
3259 else if (Nkind (gnat_node) == N_Op_Shift_Right_Arithmetic)
3260 gnu_rhs
3261 = build_binary_op
3262 (MIN_EXPR, gnu_count_type,
3263 build_binary_op (MINUS_EXPR,
3264 gnu_count_type,
3265 gnu_max_shift,
3266 convert (gnu_count_type,
3267 integer_one_node)),
3268 gnu_rhs);
3271 /* For right shifts, the type says what kind of shift to do,
3272 so we may need to choose a different type. */
3273 if (Nkind (gnat_node) == N_Op_Shift_Right
3274 && !TYPE_UNSIGNED (gnu_type))
3275 gnu_type = gnat_unsigned_type (gnu_type);
3276 else if (Nkind (gnat_node) == N_Op_Shift_Right_Arithmetic
3277 && TYPE_UNSIGNED (gnu_type))
3278 gnu_type = gnat_signed_type (gnu_type);
3280 if (gnu_type != gnu_result_type)
3282 gnu_lhs = convert (gnu_type, gnu_lhs);
3283 gnu_rhs = convert (gnu_type, gnu_rhs);
3286 gnu_result = build_binary_op (code, gnu_type, gnu_lhs, gnu_rhs);
3288 /* If this is a logical shift with the shift count not verified,
3289 we must return zero if it is too large. We cannot compensate
3290 above in this case. */
3291 if ((Nkind (gnat_node) == N_Op_Shift_Left
3292 || Nkind (gnat_node) == N_Op_Shift_Right)
3293 && !Shift_Count_OK (gnat_node))
3294 gnu_result
3295 = build_cond_expr
3296 (gnu_type,
3297 build_binary_op (GE_EXPR, integer_type_node,
3298 gnu_rhs,
3299 convert (TREE_TYPE (gnu_rhs),
3300 TYPE_SIZE (gnu_type))),
3301 convert (gnu_type, integer_zero_node),
3302 gnu_result);
3304 break;
3306 case N_Conditional_Expression:
3308 tree gnu_cond = gnat_to_gnu (First (Expressions (gnat_node)));
3309 tree gnu_true = gnat_to_gnu (Next (First (Expressions (gnat_node))));
3310 tree gnu_false
3311 = gnat_to_gnu (Next (Next (First (Expressions (gnat_node)))));
3313 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3314 gnu_result = build_cond_expr (gnu_result_type,
3315 gnat_truthvalue_conversion (gnu_cond),
3316 gnu_true, gnu_false);
3318 break;
3320 case N_Op_Plus:
3321 gnu_result = gnat_to_gnu (Right_Opnd (gnat_node));
3322 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3323 break;
3325 case N_Op_Not:
3326 /* This case can apply to a boolean or a modular type.
3327 Fall through for a boolean operand since GNU_CODES is set
3328 up to handle this. */
3329 if (IN (Ekind (Etype (gnat_node)), Modular_Integer_Kind))
3331 gnu_expr = gnat_to_gnu (Right_Opnd (gnat_node));
3332 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3333 gnu_result = build_unary_op (BIT_NOT_EXPR, gnu_result_type,
3334 gnu_expr);
3335 break;
3338 /* ... fall through ... */
3340 case N_Op_Minus: case N_Op_Abs:
3341 gnu_expr = gnat_to_gnu (Right_Opnd (gnat_node));
3343 if (Ekind (Etype (gnat_node)) != E_Private_Type)
3344 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3345 else
3346 gnu_result_type = get_unpadded_type (Base_Type
3347 (Full_View (Etype (gnat_node))));
3349 gnu_result = build_unary_op (gnu_codes[Nkind (gnat_node)],
3350 gnu_result_type, gnu_expr);
3351 break;
3353 case N_Allocator:
3355 tree gnu_init = 0;
3356 tree gnu_type;
3357 bool ignore_init_type = false;
3359 gnat_temp = Expression (gnat_node);
3361 /* The Expression operand can either be an N_Identifier or
3362 Expanded_Name, which must represent a type, or a
3363 N_Qualified_Expression, which contains both the object type and an
3364 initial value for the object. */
3365 if (Nkind (gnat_temp) == N_Identifier
3366 || Nkind (gnat_temp) == N_Expanded_Name)
3367 gnu_type = gnat_to_gnu_type (Entity (gnat_temp));
3368 else if (Nkind (gnat_temp) == N_Qualified_Expression)
3370 Entity_Id gnat_desig_type
3371 = Designated_Type (Underlying_Type (Etype (gnat_node)));
3373 ignore_init_type = Has_Constrained_Partial_View (gnat_desig_type);
3374 gnu_init = gnat_to_gnu (Expression (gnat_temp));
3376 gnu_init = maybe_unconstrained_array (gnu_init);
3377 if (Do_Range_Check (Expression (gnat_temp)))
3378 gnu_init = emit_range_check (gnu_init, gnat_desig_type);
3380 if (Is_Elementary_Type (gnat_desig_type)
3381 || Is_Constrained (gnat_desig_type))
3383 gnu_type = gnat_to_gnu_type (gnat_desig_type);
3384 gnu_init = convert (gnu_type, gnu_init);
3386 else
3388 gnu_type = gnat_to_gnu_type (Etype (Expression (gnat_temp)));
3389 if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
3390 gnu_type = TREE_TYPE (gnu_init);
3392 gnu_init = convert (gnu_type, gnu_init);
3395 else
3396 gcc_unreachable ();
3398 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3399 return build_allocator (gnu_type, gnu_init, gnu_result_type,
3400 Procedure_To_Call (gnat_node),
3401 Storage_Pool (gnat_node), gnat_node,
3402 ignore_init_type);
3404 break;
3406 /***************************/
3407 /* Chapter 5: Statements: */
3408 /***************************/
3410 case N_Label:
3411 gnu_result = build1 (LABEL_EXPR, void_type_node,
3412 gnat_to_gnu (Identifier (gnat_node)));
3413 break;
3415 case N_Null_Statement:
3416 gnu_result = alloc_stmt_list ();
3417 break;
3419 case N_Assignment_Statement:
3420 /* Get the LHS and RHS of the statement and convert any reference to an
3421 unconstrained array into a reference to the underlying array.
3422 If we are not to do range checking and the RHS is an N_Function_Call,
3423 pass the LHS to the call function. */
3424 gnu_lhs = maybe_unconstrained_array (gnat_to_gnu (Name (gnat_node)));
3426 /* If the type has a size that overflows, convert this into raise of
3427 Storage_Error: execution shouldn't have gotten here anyway. */
3428 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_lhs))) == INTEGER_CST
3429 && TREE_OVERFLOW (TYPE_SIZE (TREE_TYPE (gnu_lhs))))
3430 gnu_result = build_call_raise (SE_Object_Too_Large);
3431 else if (Nkind (Expression (gnat_node)) == N_Function_Call
3432 && !Do_Range_Check (Expression (gnat_node)))
3433 gnu_result = call_to_gnu (Expression (gnat_node),
3434 &gnu_result_type, gnu_lhs);
3435 else
3437 gnu_rhs
3438 = maybe_unconstrained_array (gnat_to_gnu (Expression (gnat_node)));
3440 /* If range check is needed, emit code to generate it */
3441 if (Do_Range_Check (Expression (gnat_node)))
3442 gnu_rhs = emit_range_check (gnu_rhs, Etype (Name (gnat_node)));
3444 gnu_result
3445 = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_lhs, gnu_rhs);
3447 break;
3449 case N_If_Statement:
3451 tree *gnu_else_ptr; /* Point to put next "else if" or "else". */
3453 /* Make the outer COND_EXPR. Avoid non-determinism. */
3454 gnu_result = build3 (COND_EXPR, void_type_node,
3455 gnat_to_gnu (Condition (gnat_node)),
3456 NULL_TREE, NULL_TREE);
3457 COND_EXPR_THEN (gnu_result)
3458 = build_stmt_group (Then_Statements (gnat_node), false);
3459 TREE_SIDE_EFFECTS (gnu_result) = 1;
3460 gnu_else_ptr = &COND_EXPR_ELSE (gnu_result);
3462 /* Now make a COND_EXPR for each of the "else if" parts. Put each
3463 into the previous "else" part and point to where to put any
3464 outer "else". Also avoid non-determinism. */
3465 if (Present (Elsif_Parts (gnat_node)))
3466 for (gnat_temp = First (Elsif_Parts (gnat_node));
3467 Present (gnat_temp); gnat_temp = Next (gnat_temp))
3469 gnu_expr = build3 (COND_EXPR, void_type_node,
3470 gnat_to_gnu (Condition (gnat_temp)),
3471 NULL_TREE, NULL_TREE);
3472 COND_EXPR_THEN (gnu_expr)
3473 = build_stmt_group (Then_Statements (gnat_temp), false);
3474 TREE_SIDE_EFFECTS (gnu_expr) = 1;
3475 annotate_with_node (gnu_expr, gnat_temp);
3476 *gnu_else_ptr = gnu_expr;
3477 gnu_else_ptr = &COND_EXPR_ELSE (gnu_expr);
3480 *gnu_else_ptr = build_stmt_group (Else_Statements (gnat_node), false);
3482 break;
3484 case N_Case_Statement:
3485 gnu_result = Case_Statement_to_gnu (gnat_node);
3486 break;
3488 case N_Loop_Statement:
3489 gnu_result = Loop_Statement_to_gnu (gnat_node);
3490 break;
3492 case N_Block_Statement:
3493 start_stmt_group ();
3494 gnat_pushlevel ();
3495 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
3496 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
3497 gnat_poplevel ();
3498 gnu_result = end_stmt_group ();
3500 if (Present (Identifier (gnat_node)))
3501 mark_out_of_scope (Entity (Identifier (gnat_node)));
3502 break;
3504 case N_Exit_Statement:
3505 gnu_result
3506 = build2 (EXIT_STMT, void_type_node,
3507 (Present (Condition (gnat_node))
3508 ? gnat_to_gnu (Condition (gnat_node)) : NULL_TREE),
3509 (Present (Name (gnat_node))
3510 ? get_gnu_tree (Entity (Name (gnat_node)))
3511 : TREE_VALUE (gnu_loop_label_stack)));
3512 break;
3514 case N_Return_Statement:
3516 /* The gnu function type of the subprogram currently processed. */
3517 tree gnu_subprog_type = TREE_TYPE (current_function_decl);
3518 /* The return value from the subprogram. */
3519 tree gnu_ret_val = NULL_TREE;
3520 /* The place to put the return value. */
3521 tree gnu_lhs;
3522 /* Avoid passing error_mark_node to RETURN_EXPR. */
3523 gnu_result = NULL_TREE;
3525 /* If we are dealing with a "return;" from an Ada procedure with
3526 parameters passed by copy in copy out, we need to return a record
3527 containing the final values of these parameters. If the list
3528 contains only one entry, return just that entry.
3530 For a full description of the copy in copy out parameter mechanism,
3531 see the part of the gnat_to_gnu_entity routine dealing with the
3532 translation of subprograms.
3534 But if we have a return label defined, convert this into
3535 a branch to that label. */
3537 if (TREE_VALUE (gnu_return_label_stack))
3539 gnu_result = build1 (GOTO_EXPR, void_type_node,
3540 TREE_VALUE (gnu_return_label_stack));
3541 break;
3544 else if (TYPE_CI_CO_LIST (gnu_subprog_type))
3546 gnu_lhs = DECL_RESULT (current_function_decl);
3547 if (list_length (TYPE_CI_CO_LIST (gnu_subprog_type)) == 1)
3548 gnu_ret_val = TREE_VALUE (TYPE_CI_CO_LIST (gnu_subprog_type));
3549 else
3550 gnu_ret_val
3551 = gnat_build_constructor (TREE_TYPE (gnu_subprog_type),
3552 TYPE_CI_CO_LIST (gnu_subprog_type));
3555 /* If the Ada subprogram is a function, we just need to return the
3556 expression. If the subprogram returns an unconstrained
3557 array, we have to allocate a new version of the result and
3558 return it. If we return by reference, return a pointer. */
3560 else if (Present (Expression (gnat_node)))
3562 /* If the current function returns by target pointer and we
3563 are doing a call, pass that target to the call. */
3564 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type)
3565 && Nkind (Expression (gnat_node)) == N_Function_Call)
3567 gnu_lhs
3568 = build_unary_op (INDIRECT_REF, NULL_TREE,
3569 DECL_ARGUMENTS (current_function_decl));
3570 gnu_result = call_to_gnu (Expression (gnat_node),
3571 &gnu_result_type, gnu_lhs);
3573 else
3575 gnu_ret_val = gnat_to_gnu (Expression (gnat_node));
3577 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
3578 /* The original return type was unconstrained so dereference
3579 the TARGET pointer in the actual return value's type. */
3580 gnu_lhs
3581 = build_unary_op (INDIRECT_REF, TREE_TYPE (gnu_ret_val),
3582 DECL_ARGUMENTS (current_function_decl));
3583 else
3584 gnu_lhs = DECL_RESULT (current_function_decl);
3586 /* Do not remove the padding from GNU_RET_VAL if the inner
3587 type is self-referential since we want to allocate the fixed
3588 size in that case. */
3589 if (TREE_CODE (gnu_ret_val) == COMPONENT_REF
3590 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_ret_val, 0)))
3591 == RECORD_TYPE)
3592 && (TYPE_IS_PADDING_P
3593 (TREE_TYPE (TREE_OPERAND (gnu_ret_val, 0))))
3594 && (CONTAINS_PLACEHOLDER_P
3595 (TYPE_SIZE (TREE_TYPE (gnu_ret_val)))))
3596 gnu_ret_val = TREE_OPERAND (gnu_ret_val, 0);
3598 if (TYPE_RETURNS_BY_REF_P (gnu_subprog_type)
3599 || By_Ref (gnat_node))
3600 gnu_ret_val
3601 = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_ret_val);
3603 else if (TYPE_RETURNS_UNCONSTRAINED_P (gnu_subprog_type))
3605 gnu_ret_val = maybe_unconstrained_array (gnu_ret_val);
3607 /* We have two cases: either the function returns with
3608 depressed stack or not. If not, we allocate on the
3609 secondary stack. If so, we allocate in the stack frame.
3610 if no copy is needed, the front end will set By_Ref,
3611 which we handle in the case above. */
3612 if (TYPE_RETURNS_STACK_DEPRESSED (gnu_subprog_type))
3613 gnu_ret_val
3614 = build_allocator (TREE_TYPE (gnu_ret_val),
3615 gnu_ret_val,
3616 TREE_TYPE (gnu_subprog_type),
3617 0, -1, gnat_node, false);
3618 else
3619 gnu_ret_val
3620 = build_allocator (TREE_TYPE (gnu_ret_val),
3621 gnu_ret_val,
3622 TREE_TYPE (gnu_subprog_type),
3623 Procedure_To_Call (gnat_node),
3624 Storage_Pool (gnat_node),
3625 gnat_node, false);
3630 if (gnu_ret_val)
3631 gnu_result = build2 (MODIFY_EXPR, TREE_TYPE (gnu_ret_val),
3632 gnu_lhs, gnu_ret_val);
3634 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
3636 add_stmt_with_node (gnu_result, gnat_node);
3637 gnu_result = NULL_TREE;
3640 gnu_result = build1 (RETURN_EXPR, void_type_node, gnu_result);
3642 break;
3644 case N_Goto_Statement:
3645 gnu_result = build1 (GOTO_EXPR, void_type_node,
3646 gnat_to_gnu (Name (gnat_node)));
3647 break;
3649 /****************************/
3650 /* Chapter 6: Subprograms: */
3651 /****************************/
3653 case N_Subprogram_Declaration:
3654 /* Unless there is a freeze node, declare the subprogram. We consider
3655 this a "definition" even though we're not generating code for
3656 the subprogram because we will be making the corresponding GCC
3657 node here. */
3659 if (No (Freeze_Node (Defining_Entity (Specification (gnat_node)))))
3660 gnat_to_gnu_entity (Defining_Entity (Specification (gnat_node)),
3661 NULL_TREE, 1);
3662 gnu_result = alloc_stmt_list ();
3663 break;
3665 case N_Abstract_Subprogram_Declaration:
3666 /* This subprogram doesn't exist for code generation purposes, but we
3667 have to elaborate the types of any parameters, unless they are
3668 imported types (nothing to generate in this case). */
3669 for (gnat_temp
3670 = First_Formal (Defining_Entity (Specification (gnat_node)));
3671 Present (gnat_temp);
3672 gnat_temp = Next_Formal_With_Extras (gnat_temp))
3673 if (Is_Itype (Etype (gnat_temp))
3674 && !From_With_Type (Etype (gnat_temp)))
3675 gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, 0);
3677 gnu_result = alloc_stmt_list ();
3678 break;
3680 case N_Defining_Program_Unit_Name:
3681 /* For a child unit identifier go up a level to get the
3682 specification. We get this when we try to find the spec of
3683 a child unit package that is the compilation unit being compiled. */
3684 gnu_result = gnat_to_gnu (Parent (gnat_node));
3685 break;
3687 case N_Subprogram_Body:
3688 Subprogram_Body_to_gnu (gnat_node);
3689 gnu_result = alloc_stmt_list ();
3690 break;
3692 case N_Function_Call:
3693 case N_Procedure_Call_Statement:
3694 gnu_result = call_to_gnu (gnat_node, &gnu_result_type, NULL_TREE);
3695 break;
3697 /*************************/
3698 /* Chapter 7: Packages: */
3699 /*************************/
3701 case N_Package_Declaration:
3702 gnu_result = gnat_to_gnu (Specification (gnat_node));
3703 break;
3705 case N_Package_Specification:
3707 start_stmt_group ();
3708 process_decls (Visible_Declarations (gnat_node),
3709 Private_Declarations (gnat_node), Empty, true, true);
3710 gnu_result = end_stmt_group ();
3711 break;
3713 case N_Package_Body:
3715 /* If this is the body of a generic package - do nothing */
3716 if (Ekind (Corresponding_Spec (gnat_node)) == E_Generic_Package)
3718 gnu_result = alloc_stmt_list ();
3719 break;
3722 start_stmt_group ();
3723 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
3725 if (Present (Handled_Statement_Sequence (gnat_node)))
3726 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
3728 gnu_result = end_stmt_group ();
3729 break;
3731 /*********************************/
3732 /* Chapter 8: Visibility Rules: */
3733 /*********************************/
3735 case N_Use_Package_Clause:
3736 case N_Use_Type_Clause:
3737 /* Nothing to do here - but these may appear in list of declarations */
3738 gnu_result = alloc_stmt_list ();
3739 break;
3741 /***********************/
3742 /* Chapter 9: Tasks: */
3743 /***********************/
3745 case N_Protected_Type_Declaration:
3746 gnu_result = alloc_stmt_list ();
3747 break;
3749 case N_Single_Task_Declaration:
3750 gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, 1);
3751 gnu_result = alloc_stmt_list ();
3752 break;
3754 /***********************************************************/
3755 /* Chapter 10: Program Structure and Compilation Issues: */
3756 /***********************************************************/
3758 case N_Compilation_Unit:
3760 /* This is not called for the main unit, which is handled in function
3761 gigi above. */
3762 start_stmt_group ();
3763 gnat_pushlevel ();
3765 Compilation_Unit_to_gnu (gnat_node);
3766 gnu_result = alloc_stmt_list ();
3767 break;
3769 case N_Subprogram_Body_Stub:
3770 case N_Package_Body_Stub:
3771 case N_Protected_Body_Stub:
3772 case N_Task_Body_Stub:
3773 /* Simply process whatever unit is being inserted. */
3774 gnu_result = gnat_to_gnu (Unit (Library_Unit (gnat_node)));
3775 break;
3777 case N_Subunit:
3778 gnu_result = gnat_to_gnu (Proper_Body (gnat_node));
3779 break;
3781 /***************************/
3782 /* Chapter 11: Exceptions: */
3783 /***************************/
3785 case N_Handled_Sequence_Of_Statements:
3786 /* If there is an At_End procedure attached to this node, and the EH
3787 mechanism is SJLJ, we must have at least a corresponding At_End
3788 handler, unless the No_Exception_Handlers restriction is set. */
3789 gcc_assert (type_annotate_only
3790 || Exception_Mechanism != Setjmp_Longjmp
3791 || No (At_End_Proc (gnat_node))
3792 || Present (Exception_Handlers (gnat_node))
3793 || No_Exception_Handlers_Set ());
3795 gnu_result = Handled_Sequence_Of_Statements_to_gnu (gnat_node);
3796 break;
3798 case N_Exception_Handler:
3799 if (Exception_Mechanism == Setjmp_Longjmp)
3800 gnu_result = Exception_Handler_to_gnu_sjlj (gnat_node);
3801 else if (Exception_Mechanism == Back_End_Exceptions)
3802 gnu_result = Exception_Handler_to_gnu_zcx (gnat_node);
3803 else
3804 gcc_unreachable ();
3806 break;
3808 /*******************************/
3809 /* Chapter 12: Generic Units: */
3810 /*******************************/
3812 case N_Generic_Function_Renaming_Declaration:
3813 case N_Generic_Package_Renaming_Declaration:
3814 case N_Generic_Procedure_Renaming_Declaration:
3815 case N_Generic_Package_Declaration:
3816 case N_Generic_Subprogram_Declaration:
3817 case N_Package_Instantiation:
3818 case N_Procedure_Instantiation:
3819 case N_Function_Instantiation:
3820 /* These nodes can appear on a declaration list but there is nothing to
3821 to be done with them. */
3822 gnu_result = alloc_stmt_list ();
3823 break;
3825 /***************************************************/
3826 /* Chapter 13: Representation Clauses and */
3827 /* Implementation-Dependent Features: */
3828 /***************************************************/
3830 case N_Attribute_Definition_Clause:
3832 gnu_result = alloc_stmt_list ();
3834 /* The only one we need deal with is for 'Address. For the others, SEM
3835 puts the information elsewhere. We need only deal with 'Address
3836 if the object has a Freeze_Node (which it never will currently). */
3837 if (Get_Attribute_Id (Chars (gnat_node)) != Attr_Address
3838 || No (Freeze_Node (Entity (Name (gnat_node)))))
3839 break;
3841 /* Get the value to use as the address and save it as the
3842 equivalent for GNAT_TEMP. When the object is frozen,
3843 gnat_to_gnu_entity will do the right thing. */
3844 save_gnu_tree (Entity (Name (gnat_node)),
3845 gnat_to_gnu (Expression (gnat_node)), true);
3846 break;
3848 case N_Enumeration_Representation_Clause:
3849 case N_Record_Representation_Clause:
3850 case N_At_Clause:
3851 /* We do nothing with these. SEM puts the information elsewhere. */
3852 gnu_result = alloc_stmt_list ();
3853 break;
3855 case N_Code_Statement:
3856 if (!type_annotate_only)
3858 tree gnu_template = gnat_to_gnu (Asm_Template (gnat_node));
3859 tree gnu_input_list = NULL_TREE, gnu_output_list = NULL_TREE;
3860 tree gnu_clobber_list = NULL_TREE;
3861 char *clobber;
3863 /* First process inputs, then outputs, then clobbers. */
3864 Setup_Asm_Inputs (gnat_node);
3865 while (Present (gnat_temp = Asm_Input_Value ()))
3867 tree gnu_value = gnat_to_gnu (gnat_temp);
3868 tree gnu_constr = build_tree_list (NULL_TREE, gnat_to_gnu
3869 (Asm_Input_Constraint ()));
3871 gnu_input_list
3872 = tree_cons (gnu_constr, gnu_value, gnu_input_list);
3873 Next_Asm_Input ();
3876 Setup_Asm_Outputs (gnat_node);
3877 while (Present (gnat_temp = Asm_Output_Variable ()))
3879 tree gnu_value = gnat_to_gnu (gnat_temp);
3880 tree gnu_constr = build_tree_list (NULL_TREE, gnat_to_gnu
3881 (Asm_Output_Constraint ()));
3883 gnu_output_list
3884 = tree_cons (gnu_constr, gnu_value, gnu_output_list);
3885 Next_Asm_Output ();
3888 Clobber_Setup (gnat_node);
3889 while ((clobber = Clobber_Get_Next ()))
3890 gnu_clobber_list
3891 = tree_cons (NULL_TREE,
3892 build_string (strlen (clobber) + 1, clobber),
3893 gnu_clobber_list);
3895 gnu_input_list = nreverse (gnu_input_list);
3896 gnu_output_list = nreverse (gnu_output_list);
3897 gnu_result = build4 (ASM_EXPR, void_type_node,
3898 gnu_template, gnu_output_list,
3899 gnu_input_list, gnu_clobber_list);
3900 ASM_VOLATILE_P (gnu_result) = Is_Asm_Volatile (gnat_node);
3902 else
3903 gnu_result = alloc_stmt_list ();
3905 break;
3907 /***************************************************/
3908 /* Added Nodes */
3909 /***************************************************/
3911 case N_Freeze_Entity:
3912 start_stmt_group ();
3913 process_freeze_entity (gnat_node);
3914 process_decls (Actions (gnat_node), Empty, Empty, true, true);
3915 gnu_result = end_stmt_group ();
3916 break;
3918 case N_Itype_Reference:
3919 if (!present_gnu_tree (Itype (gnat_node)))
3920 process_type (Itype (gnat_node));
3922 gnu_result = alloc_stmt_list ();
3923 break;
3925 case N_Free_Statement:
3926 if (!type_annotate_only)
3928 tree gnu_ptr = gnat_to_gnu (Expression (gnat_node));
3929 tree gnu_obj_type;
3930 tree gnu_obj_size;
3931 int align;
3933 /* If this is a thin pointer, we must dereference it to create
3934 a fat pointer, then go back below to a thin pointer. The
3935 reason for this is that we need a fat pointer someplace in
3936 order to properly compute the size. */
3937 if (TYPE_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
3938 gnu_ptr = build_unary_op (ADDR_EXPR, NULL_TREE,
3939 build_unary_op (INDIRECT_REF, NULL_TREE,
3940 gnu_ptr));
3942 /* If this is an unconstrained array, we know the object must
3943 have been allocated with the template in front of the object.
3944 So pass the template address, but get the total size. Do this
3945 by converting to a thin pointer. */
3946 if (TYPE_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
3947 gnu_ptr
3948 = convert (build_pointer_type
3949 (TYPE_OBJECT_RECORD_TYPE
3950 (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr)))),
3951 gnu_ptr);
3953 gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));
3954 gnu_obj_size = TYPE_SIZE_UNIT (gnu_obj_type);
3955 align = TYPE_ALIGN (gnu_obj_type);
3957 if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
3958 && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
3960 tree gnu_char_ptr_type = build_pointer_type (char_type_node);
3961 tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
3962 tree gnu_byte_offset
3963 = convert (gnu_char_ptr_type,
3964 size_diffop (size_zero_node, gnu_pos));
3966 gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
3967 gnu_ptr = build_binary_op (MINUS_EXPR, gnu_char_ptr_type,
3968 gnu_ptr, gnu_byte_offset);
3971 gnu_result = build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, align,
3972 Procedure_To_Call (gnat_node),
3973 Storage_Pool (gnat_node),
3974 gnat_node);
3976 break;
3978 case N_Raise_Constraint_Error:
3979 case N_Raise_Program_Error:
3980 case N_Raise_Storage_Error:
3981 if (type_annotate_only)
3983 gnu_result = alloc_stmt_list ();
3984 break;
3987 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3988 gnu_result = build_call_raise (UI_To_Int (Reason (gnat_node)));
3990 /* If the type is VOID, this is a statement, so we need to
3991 generate the code for the call. Handle a Condition, if there
3992 is one. */
3993 if (TREE_CODE (gnu_result_type) == VOID_TYPE)
3995 annotate_with_node (gnu_result, gnat_node);
3997 if (Present (Condition (gnat_node)))
3998 gnu_result = build3 (COND_EXPR, void_type_node,
3999 gnat_to_gnu (Condition (gnat_node)),
4000 gnu_result, alloc_stmt_list ());
4002 else
4003 gnu_result = build1 (NULL_EXPR, gnu_result_type, gnu_result);
4004 break;
4006 case N_Validate_Unchecked_Conversion:
4007 /* If the result is a pointer type, see if we are either converting
4008 from a non-pointer or from a pointer to a type with a different
4009 alias set and warn if so. If the result defined in the same unit as
4010 this unchecked conversion, we can allow this because we can know to
4011 make that type have alias set 0. */
4013 tree gnu_source_type = gnat_to_gnu_type (Source_Type (gnat_node));
4014 tree gnu_target_type = gnat_to_gnu_type (Target_Type (gnat_node));
4016 if (POINTER_TYPE_P (gnu_target_type)
4017 && !In_Same_Source_Unit (Target_Type (gnat_node), gnat_node)
4018 && get_alias_set (TREE_TYPE (gnu_target_type)) != 0
4019 && !No_Strict_Aliasing (Underlying_Type (Target_Type (gnat_node)))
4020 && (!POINTER_TYPE_P (gnu_source_type)
4021 || (get_alias_set (TREE_TYPE (gnu_source_type))
4022 != get_alias_set (TREE_TYPE (gnu_target_type)))))
4024 post_error_ne
4025 ("?possible aliasing problem for type&",
4026 gnat_node, Target_Type (gnat_node));
4027 post_error
4028 ("\\?use -fno-strict-aliasing switch for references",
4029 gnat_node);
4030 post_error_ne
4031 ("\\?or use `pragma No_Strict_Aliasing (&);`",
4032 gnat_node, Target_Type (gnat_node));
4035 /* The No_Strict_Aliasing flag is not propagated to the back-end for
4036 fat pointers so unconditionally warn in problematic cases. */
4037 else if (TYPE_FAT_POINTER_P (gnu_target_type))
4039 tree array_type
4040 = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
4042 if (get_alias_set (array_type) != 0
4043 && (!TYPE_FAT_POINTER_P (gnu_source_type)
4044 || (get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_source_type))))
4045 != get_alias_set (array_type))))
4047 post_error_ne
4048 ("?possible aliasing problem for type&",
4049 gnat_node, Target_Type (gnat_node));
4050 post_error
4051 ("\\?use -fno-strict-aliasing switch for references",
4052 gnat_node);
4056 gnu_result = alloc_stmt_list ();
4057 break;
4059 case N_Raise_Statement:
4060 case N_Function_Specification:
4061 case N_Procedure_Specification:
4062 case N_Op_Concat:
4063 case N_Component_Association:
4064 case N_Task_Body:
4065 default:
4066 gcc_assert (type_annotate_only);
4067 gnu_result = alloc_stmt_list ();
4070 /* If we pushed our level as part of processing the elaboration routine,
4071 pop it back now. */
4072 if (went_into_elab_proc)
4074 add_stmt (gnu_result);
4075 gnat_poplevel ();
4076 gnu_result = end_stmt_group ();
4077 current_function_decl = NULL_TREE;
4080 /* Set the location information into the result. Note that we may have
4081 no result if we tried to build a CALL_EXPR node to a procedure with
4082 no side-effects and optimization is enabled. */
4083 if (gnu_result && EXPR_P (gnu_result))
4084 annotate_with_node (gnu_result, gnat_node);
4086 /* If we're supposed to return something of void_type, it means we have
4087 something we're elaborating for effect, so just return. */
4088 if (TREE_CODE (gnu_result_type) == VOID_TYPE)
4089 return gnu_result;
4091 /* If the result is a constant that overflows, raise constraint error. */
4092 else if (TREE_CODE (gnu_result) == INTEGER_CST
4093 && TREE_CONSTANT_OVERFLOW (gnu_result))
4095 post_error ("Constraint_Error will be raised at run-time?", gnat_node);
4097 gnu_result
4098 = build1 (NULL_EXPR, gnu_result_type,
4099 build_call_raise (CE_Overflow_Check_Failed));
4102 /* If our result has side-effects and is of an unconstrained type,
4103 make a SAVE_EXPR so that we can be sure it will only be referenced
4104 once. Note we must do this before any conversions. */
4105 if (TREE_SIDE_EFFECTS (gnu_result)
4106 && (TREE_CODE (gnu_result_type) == UNCONSTRAINED_ARRAY_TYPE
4107 || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))))
4108 gnu_result = gnat_stabilize_reference (gnu_result, 0);
4110 /* Now convert the result to the proper type. If the type is void or if
4111 we have no result, return error_mark_node to show we have no result.
4112 If the type of the result is correct or if we have a label (which doesn't
4113 have any well-defined type), return our result. Also don't do the
4114 conversion if the "desired" type involves a PLACEHOLDER_EXPR in its size
4115 since those are the cases where the front end may have the type wrong due
4116 to "instantiating" the unconstrained record with discriminant values
4117 or if this is a FIELD_DECL. If this is the Name of an assignment
4118 statement or a parameter of a procedure call, return what we have since
4119 the RHS has to be converted to our type there in that case, unless
4120 GNU_RESULT_TYPE has a simpler size. Similarly, if the two types are
4121 record types with the same name, the expression type has integral mode,
4122 and GNU_RESULT_TYPE BLKmode, don't convert. This will be the case when
4123 we are converting from a packable type to its actual type and we need
4124 those conversions to be NOPs in order for assignments into these types to
4125 work properly if the inner object is a bitfield and hence can't have
4126 its address taken. Finally, don't convert integral types that are the
4127 operand of an unchecked conversion since we need to ignore those
4128 conversions (for 'Valid). Otherwise, convert the result to the proper
4129 type. */
4131 if (Present (Parent (gnat_node))
4132 && ((Nkind (Parent (gnat_node)) == N_Assignment_Statement
4133 && Name (Parent (gnat_node)) == gnat_node)
4134 || (Nkind (Parent (gnat_node)) == N_Procedure_Call_Statement
4135 && Name (Parent (gnat_node)) != gnat_node)
4136 || (Nkind (Parent (gnat_node)) == N_Unchecked_Type_Conversion
4137 && !AGGREGATE_TYPE_P (gnu_result_type)
4138 && !AGGREGATE_TYPE_P (TREE_TYPE (gnu_result)))
4139 || Nkind (Parent (gnat_node)) == N_Parameter_Association)
4140 && !(TYPE_SIZE (gnu_result_type)
4141 && TYPE_SIZE (TREE_TYPE (gnu_result))
4142 && (AGGREGATE_TYPE_P (gnu_result_type)
4143 == AGGREGATE_TYPE_P (TREE_TYPE (gnu_result)))
4144 && ((TREE_CODE (TYPE_SIZE (gnu_result_type)) == INTEGER_CST
4145 && (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_result)))
4146 != INTEGER_CST))
4147 || (TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST
4148 && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))
4149 && (CONTAINS_PLACEHOLDER_P
4150 (TYPE_SIZE (TREE_TYPE (gnu_result))))))
4151 && !(TREE_CODE (gnu_result_type) == RECORD_TYPE
4152 && TYPE_JUSTIFIED_MODULAR_P (gnu_result_type))))
4154 /* In this case remove padding only if the inner object is of
4155 self-referential size: in that case it must be an object of
4156 unconstrained type with a default discriminant. In other cases,
4157 we want to avoid copying too much data. */
4158 if (TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE
4159 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result))
4160 && CONTAINS_PLACEHOLDER_P (TYPE_SIZE
4161 (TREE_TYPE (TYPE_FIELDS
4162 (TREE_TYPE (gnu_result))))))
4163 gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))),
4164 gnu_result);
4167 else if (TREE_CODE (gnu_result) == LABEL_DECL
4168 || TREE_CODE (gnu_result) == FIELD_DECL
4169 || TREE_CODE (gnu_result) == ERROR_MARK
4170 || (TYPE_SIZE (gnu_result_type)
4171 && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST
4172 && TREE_CODE (gnu_result) != INDIRECT_REF
4173 && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type)))
4174 || ((TYPE_NAME (gnu_result_type)
4175 == TYPE_NAME (TREE_TYPE (gnu_result)))
4176 && TREE_CODE (gnu_result_type) == RECORD_TYPE
4177 && TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE
4178 && TYPE_MODE (gnu_result_type) == BLKmode
4179 && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (gnu_result)))
4180 == MODE_INT)))
4182 /* Remove any padding record, but do nothing more in this case. */
4183 if (TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE
4184 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result)))
4185 gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))),
4186 gnu_result);
4189 else if (gnu_result == error_mark_node
4190 || gnu_result_type == void_type_node)
4191 gnu_result = error_mark_node;
4192 else if (gnu_result_type != TREE_TYPE (gnu_result))
4193 gnu_result = convert (gnu_result_type, gnu_result);
4195 /* We don't need any NOP_EXPR or NON_LVALUE_EXPR on GNU_RESULT. */
4196 while ((TREE_CODE (gnu_result) == NOP_EXPR
4197 || TREE_CODE (gnu_result) == NON_LVALUE_EXPR)
4198 && TREE_TYPE (TREE_OPERAND (gnu_result, 0)) == TREE_TYPE (gnu_result))
4199 gnu_result = TREE_OPERAND (gnu_result, 0);
4201 return gnu_result;
4204 /* Record the current code position in GNAT_NODE. */
4206 static void
4207 record_code_position (Node_Id gnat_node)
4209 tree stmt_stmt = build1 (STMT_STMT, void_type_node, NULL_TREE);
4211 add_stmt_with_node (stmt_stmt, gnat_node);
4212 save_gnu_tree (gnat_node, stmt_stmt, true);
4215 /* Insert the code for GNAT_NODE at the position saved for that node. */
4217 static void
4218 insert_code_for (Node_Id gnat_node)
4220 STMT_STMT_STMT (get_gnu_tree (gnat_node)) = gnat_to_gnu (gnat_node);
4221 save_gnu_tree (gnat_node, NULL_TREE, true);
4224 /* Start a new statement group chained to the previous group. */
4226 static void
4227 start_stmt_group ()
4229 struct stmt_group *group = stmt_group_free_list;
4231 /* First see if we can get one from the free list. */
4232 if (group)
4233 stmt_group_free_list = group->previous;
4234 else
4235 group = (struct stmt_group *) ggc_alloc (sizeof (struct stmt_group));
4237 group->previous = current_stmt_group;
4238 group->stmt_list = group->block = group->cleanups = NULL_TREE;
4239 current_stmt_group = group;
4242 /* Add GNU_STMT to the current statement group. */
4244 void
4245 add_stmt (tree gnu_stmt)
4247 append_to_statement_list (gnu_stmt, &current_stmt_group->stmt_list);
4249 /* If we're at top level, show everything in here is in use in case
4250 any of it is shared by a subprogram. */
4251 if (global_bindings_p ())
4252 walk_tree (&gnu_stmt, mark_visited, NULL, NULL);
4256 /* Similar, but set the location of GNU_STMT to that of GNAT_NODE. */
4258 void
4259 add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node)
4261 if (Present (gnat_node))
4262 annotate_with_node (gnu_stmt, gnat_node);
4263 add_stmt (gnu_stmt);
4266 /* Add a declaration statement for GNU_DECL to the current statement group.
4267 Get SLOC from Entity_Id. */
4269 void
4270 add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
4272 tree gnu_stmt;
4274 /* If this is a variable that Gigi is to ignore, we may have been given
4275 an ERROR_MARK. So test for it. We also might have been given a
4276 reference for a renaming. So only do something for a decl. Also
4277 ignore a TYPE_DECL for an UNCONSTRAINED_ARRAY_TYPE. */
4278 if (!DECL_P (gnu_decl)
4279 || (TREE_CODE (gnu_decl) == TYPE_DECL
4280 && TREE_CODE (TREE_TYPE (gnu_decl)) == UNCONSTRAINED_ARRAY_TYPE))
4281 return;
4283 /* If we are global, we don't want to actually output the DECL_EXPR for
4284 this decl since we already have evaluated the expressions in the
4285 sizes and positions as globals and doing it again would be wrong.
4286 But we do have to mark everything as used. */
4287 gnu_stmt = build1 (DECL_EXPR, void_type_node, gnu_decl);
4288 if (!global_bindings_p ())
4289 add_stmt_with_node (gnu_stmt, gnat_entity);
4290 else
4292 walk_tree (&gnu_stmt, mark_visited, NULL, NULL);
4293 if (TREE_CODE (gnu_decl) == VAR_DECL
4294 || TREE_CODE (gnu_decl) == CONST_DECL)
4296 walk_tree (&DECL_SIZE (gnu_decl), mark_visited, NULL, NULL);
4297 walk_tree (&DECL_SIZE_UNIT (gnu_decl), mark_visited, NULL, NULL);
4298 walk_tree (&DECL_INITIAL (gnu_decl), mark_visited, NULL, NULL);
4302 /* If this is a DECL_EXPR for a variable with DECL_INITIAL set,
4303 there are two cases we need to handle here. */
4304 if (TREE_CODE (gnu_decl) == VAR_DECL && DECL_INITIAL (gnu_decl))
4306 tree gnu_init = DECL_INITIAL (gnu_decl);
4307 tree gnu_lhs = NULL_TREE;
4309 /* If this is a DECL_EXPR for a variable with DECL_INITIAL set
4310 and decl has a padded type, convert it to the unpadded type so the
4311 assignment is done properly. */
4312 if (TREE_CODE (TREE_TYPE (gnu_decl)) == RECORD_TYPE
4313 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_decl)))
4314 gnu_lhs
4315 = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_decl))), gnu_decl);
4317 /* Otherwise, if this is going into memory and the initializer isn't
4318 valid for the assembler and loader. Gimplification could do this,
4319 but would be run too late if -fno-unit-at-a-time. */
4320 else if (TREE_STATIC (gnu_decl)
4321 && !initializer_constant_valid_p (gnu_init,
4322 TREE_TYPE (gnu_decl)))
4323 gnu_lhs = gnu_decl;
4325 if (gnu_lhs)
4327 tree gnu_assign_stmt
4328 = build_binary_op (MODIFY_EXPR, NULL_TREE,
4329 gnu_lhs, DECL_INITIAL (gnu_decl));
4331 DECL_INITIAL (gnu_decl) = 0;
4332 TREE_READONLY (gnu_decl) = 0;
4333 annotate_with_locus (gnu_assign_stmt,
4334 DECL_SOURCE_LOCATION (gnu_decl));
4335 add_stmt (gnu_assign_stmt);
4340 /* Utility function to mark nodes with TREE_VISITED and types as having their
4341 sized gimplified. Called from walk_tree. We use this to indicate all
4342 variable sizes and positions in global types may not be shared by any
4343 subprogram. */
4345 static tree
4346 mark_visited (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
4348 if (TREE_VISITED (*tp))
4349 *walk_subtrees = 0;
4351 /* Don't mark a dummy type as visited because we want to mark its sizes
4352 and fields once it's filled in. */
4353 else if (!TYPE_IS_DUMMY_P (*tp))
4354 TREE_VISITED (*tp) = 1;
4356 if (TYPE_P (*tp))
4357 TYPE_SIZES_GIMPLIFIED (*tp) = 1;
4359 return NULL_TREE;
4362 /* Likewise, but to mark as unvisited. */
4364 static tree
4365 mark_unvisited (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
4366 void *data ATTRIBUTE_UNUSED)
4368 TREE_VISITED (*tp) = 0;
4370 return NULL_TREE;
4373 /* Add GNU_CLEANUP, a cleanup action, to the current code group. */
4375 static void
4376 add_cleanup (tree gnu_cleanup)
4378 append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
4381 /* Set the BLOCK node corresponding to the current code group to GNU_BLOCK. */
4383 void
4384 set_block_for_group (tree gnu_block)
4386 gcc_assert (!current_stmt_group->block);
4387 current_stmt_group->block = gnu_block;
4390 /* Return code corresponding to the current code group. It is normally
4391 a STATEMENT_LIST, but may also be a BIND_EXPR or TRY_FINALLY_EXPR if
4392 BLOCK or cleanups were set. */
4394 static tree
4395 end_stmt_group ()
4397 struct stmt_group *group = current_stmt_group;
4398 tree gnu_retval = group->stmt_list;
4400 /* If this is a null list, allocate a new STATEMENT_LIST. Then, if there
4401 are cleanups, make a TRY_FINALLY_EXPR. Last, if there is a BLOCK,
4402 make a BIND_EXPR. Note that we nest in that because the cleanup may
4403 reference variables in the block. */
4404 if (gnu_retval == NULL_TREE)
4405 gnu_retval = alloc_stmt_list ();
4407 if (group->cleanups)
4408 gnu_retval = build2 (TRY_FINALLY_EXPR, void_type_node, gnu_retval,
4409 group->cleanups);
4411 if (current_stmt_group->block)
4412 gnu_retval = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (group->block),
4413 gnu_retval, group->block);
4415 /* Remove this group from the stack and add it to the free list. */
4416 current_stmt_group = group->previous;
4417 group->previous = stmt_group_free_list;
4418 stmt_group_free_list = group;
4420 return gnu_retval;
4423 /* Add a list of statements from GNAT_LIST, a possibly-empty list of
4424 statements.*/
4426 static void
4427 add_stmt_list (List_Id gnat_list)
4429 Node_Id gnat_node;
4431 if (Present (gnat_list))
4432 for (gnat_node = First (gnat_list); Present (gnat_node);
4433 gnat_node = Next (gnat_node))
4434 add_stmt (gnat_to_gnu (gnat_node));
4437 /* Build a tree from GNAT_LIST, a possibly-empty list of statements.
4438 If BINDING_P is true, push and pop a binding level around the list. */
4440 static tree
4441 build_stmt_group (List_Id gnat_list, bool binding_p)
4443 start_stmt_group ();
4444 if (binding_p)
4445 gnat_pushlevel ();
4447 add_stmt_list (gnat_list);
4448 if (binding_p)
4449 gnat_poplevel ();
4451 return end_stmt_group ();
4454 /* Push and pop routines for stacks. We keep a free list around so we
4455 don't waste tree nodes. */
4457 static void
4458 push_stack (tree *gnu_stack_ptr, tree gnu_purpose, tree gnu_value)
4460 tree gnu_node = gnu_stack_free_list;
4462 if (gnu_node)
4464 gnu_stack_free_list = TREE_CHAIN (gnu_node);
4465 TREE_CHAIN (gnu_node) = *gnu_stack_ptr;
4466 TREE_PURPOSE (gnu_node) = gnu_purpose;
4467 TREE_VALUE (gnu_node) = gnu_value;
4469 else
4470 gnu_node = tree_cons (gnu_purpose, gnu_value, *gnu_stack_ptr);
4472 *gnu_stack_ptr = gnu_node;
4475 static void
4476 pop_stack (tree *gnu_stack_ptr)
4478 tree gnu_node = *gnu_stack_ptr;
4480 *gnu_stack_ptr = TREE_CHAIN (gnu_node);
4481 TREE_CHAIN (gnu_node) = gnu_stack_free_list;
4482 gnu_stack_free_list = gnu_node;
4485 /* GNU_STMT is a statement. We generate code for that statement. */
4487 void
4488 gnat_expand_stmt (tree gnu_stmt)
4490 #if 0
4491 tree gnu_elmt, gnu_elmt_2;
4492 #endif
4494 switch (TREE_CODE (gnu_stmt))
4496 #if 0
4497 case USE_STMT:
4498 /* First write a volatile ASM_INPUT to prevent anything from being
4499 moved. */
4500 gnu_elmt = gen_rtx_ASM_INPUT (VOIDmode, "");
4501 MEM_VOLATILE_P (gnu_elmt) = 1;
4502 emit_insn (gnu_elmt);
4504 gnu_elmt = expand_expr (TREE_OPERAND (gnu_stmt, 0), NULL_RTX, VOIDmode,
4505 modifier);
4506 emit_insn (gen_rtx_USE (VOIDmode, ));
4507 return target;
4508 #endif
4510 default:
4511 gcc_unreachable ();
4515 /* Generate GIMPLE in place for the expression at *EXPR_P. */
4518 gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
4520 tree expr = *expr_p;
4522 if (IS_ADA_STMT (expr))
4523 return gnat_gimplify_stmt (expr_p);
4525 switch (TREE_CODE (expr))
4527 case NULL_EXPR:
4528 /* If this is for a scalar, just make a VAR_DECL for it. If for
4529 an aggregate, get a null pointer of the appropriate type and
4530 dereference it. */
4531 if (AGGREGATE_TYPE_P (TREE_TYPE (expr)))
4532 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (expr),
4533 convert (build_pointer_type (TREE_TYPE (expr)),
4534 integer_zero_node));
4535 else
4537 *expr_p = create_tmp_var (TREE_TYPE (expr), NULL);
4538 TREE_NO_WARNING (*expr_p) = 1;
4541 append_to_statement_list (TREE_OPERAND (expr, 0), pre_p);
4542 return GS_OK;
4544 case UNCONSTRAINED_ARRAY_REF:
4545 /* We should only do this if we are just elaborating for side-effects,
4546 but we can't know that yet. */
4547 *expr_p = TREE_OPERAND (*expr_p, 0);
4548 return GS_OK;
4550 case ADDR_EXPR:
4551 /* If we're taking the address of a constant CONSTRUCTOR, force it to
4552 be put into static memory. We know it's going to be readonly given
4553 the semantics we have and it's required to be static memory in
4554 the case when the reference is in an elaboration procedure. */
4555 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CONSTRUCTOR
4556 && TREE_CONSTANT (TREE_OPERAND (expr, 0)))
4558 tree new_var
4559 = create_tmp_var (TREE_TYPE (TREE_OPERAND (expr, 0)), "C");
4561 TREE_READONLY (new_var) = 1;
4562 TREE_STATIC (new_var) = 1;
4563 TREE_ADDRESSABLE (new_var) = 1;
4564 DECL_INITIAL (new_var) = TREE_OPERAND (expr, 0);
4566 TREE_OPERAND (expr, 0) = new_var;
4567 recompute_tree_invarant_for_addr_expr (expr);
4568 return GS_ALL_DONE;
4570 return GS_UNHANDLED;
4572 case COMPONENT_REF:
4573 /* We have a kludge here. If the FIELD_DECL is from a fat pointer and is
4574 from an early dummy type, replace it with the proper FIELD_DECL. */
4575 if (TYPE_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
4576 && DECL_ORIGINAL_FIELD (TREE_OPERAND (*expr_p, 1)))
4578 TREE_OPERAND (*expr_p, 1)
4579 = DECL_ORIGINAL_FIELD (TREE_OPERAND (*expr_p, 1));
4580 return GS_OK;
4583 /* ... fall through ... */
4585 default:
4586 return GS_UNHANDLED;
4590 /* Generate GIMPLE in place for the statement at *STMT_P. */
4592 static enum gimplify_status
4593 gnat_gimplify_stmt (tree *stmt_p)
4595 tree stmt = *stmt_p;
4597 switch (TREE_CODE (stmt))
4599 case STMT_STMT:
4600 *stmt_p = STMT_STMT_STMT (stmt);
4601 return GS_OK;
4603 case USE_STMT:
4604 *stmt_p = NULL_TREE;
4605 return GS_ALL_DONE;
4607 case LOOP_STMT:
4609 tree gnu_start_label = create_artificial_label ();
4610 tree gnu_end_label = LOOP_STMT_LABEL (stmt);
4612 /* Set to emit the statements of the loop. */
4613 *stmt_p = NULL_TREE;
4615 /* We first emit the start label and then a conditional jump to
4616 the end label if there's a top condition, then the body of the
4617 loop, then a conditional branch to the end label, then the update,
4618 if any, and finally a jump to the start label and the definition
4619 of the end label. */
4620 append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
4621 gnu_start_label),
4622 stmt_p);
4624 if (LOOP_STMT_TOP_COND (stmt))
4625 append_to_statement_list (build3 (COND_EXPR, void_type_node,
4626 LOOP_STMT_TOP_COND (stmt),
4627 alloc_stmt_list (),
4628 build1 (GOTO_EXPR,
4629 void_type_node,
4630 gnu_end_label)),
4631 stmt_p);
4633 append_to_statement_list (LOOP_STMT_BODY (stmt), stmt_p);
4635 if (LOOP_STMT_BOT_COND (stmt))
4636 append_to_statement_list (build3 (COND_EXPR, void_type_node,
4637 LOOP_STMT_BOT_COND (stmt),
4638 alloc_stmt_list (),
4639 build1 (GOTO_EXPR,
4640 void_type_node,
4641 gnu_end_label)),
4642 stmt_p);
4644 if (LOOP_STMT_UPDATE (stmt))
4645 append_to_statement_list (LOOP_STMT_UPDATE (stmt), stmt_p);
4647 append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
4648 gnu_start_label),
4649 stmt_p);
4650 append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
4651 gnu_end_label),
4652 stmt_p);
4653 return GS_OK;
4656 case EXIT_STMT:
4657 /* Build a statement to jump to the corresponding end label, then
4658 see if it needs to be conditional. */
4659 *stmt_p = build1 (GOTO_EXPR, void_type_node, EXIT_STMT_LABEL (stmt));
4660 if (EXIT_STMT_COND (stmt))
4661 *stmt_p = build3 (COND_EXPR, void_type_node,
4662 EXIT_STMT_COND (stmt), *stmt_p, alloc_stmt_list ());
4663 return GS_OK;
4665 default:
4666 gcc_unreachable ();
4670 /* Force references to each of the entities in packages GNAT_NODE with's
4671 so that the debugging information for all of them are identical
4672 in all clients. Operate recursively on anything it with's, but check
4673 that we aren't elaborating something more than once. */
4675 /* The reason for this routine's existence is two-fold.
4676 First, with some debugging formats, notably MDEBUG on SGI
4677 IRIX, the linker will remove duplicate debugging information if two
4678 clients have identical debugguing information. With the normal scheme
4679 of elaboration, this does not usually occur, since entities in with'ed
4680 packages are elaborated on demand, and if clients have different usage
4681 patterns, the normal case, then the order and selection of entities
4682 will differ. In most cases however, it seems that linkers do not know
4683 how to eliminate duplicate debugging information, even if it is
4684 identical, so the use of this routine would increase the total amount
4685 of debugging information in the final executable.
4687 Second, this routine is called in type_annotate mode, to compute DDA
4688 information for types in withed units, for ASIS use */
4690 static void
4691 elaborate_all_entities (Node_Id gnat_node)
4693 Entity_Id gnat_with_clause, gnat_entity;
4695 /* Process each unit only once. As we trace the context of all relevant
4696 units transitively, including generic bodies, we may encounter the
4697 same generic unit repeatedly */
4699 if (!present_gnu_tree (gnat_node))
4700 save_gnu_tree (gnat_node, integer_zero_node, true);
4702 /* Save entities in all context units. A body may have an implicit_with
4703 on its own spec, if the context includes a child unit, so don't save
4704 the spec twice. */
4706 for (gnat_with_clause = First (Context_Items (gnat_node));
4707 Present (gnat_with_clause);
4708 gnat_with_clause = Next (gnat_with_clause))
4709 if (Nkind (gnat_with_clause) == N_With_Clause
4710 && !present_gnu_tree (Library_Unit (gnat_with_clause))
4711 && Library_Unit (gnat_with_clause) != Library_Unit (Cunit (Main_Unit)))
4713 elaborate_all_entities (Library_Unit (gnat_with_clause));
4715 if (Ekind (Entity (Name (gnat_with_clause))) == E_Package)
4717 for (gnat_entity = First_Entity (Entity (Name (gnat_with_clause)));
4718 Present (gnat_entity);
4719 gnat_entity = Next_Entity (gnat_entity))
4720 if (Is_Public (gnat_entity)
4721 && Convention (gnat_entity) != Convention_Intrinsic
4722 && Ekind (gnat_entity) != E_Package
4723 && Ekind (gnat_entity) != E_Package_Body
4724 && Ekind (gnat_entity) != E_Operator
4725 && !(IN (Ekind (gnat_entity), Type_Kind)
4726 && !Is_Frozen (gnat_entity))
4727 && !((Ekind (gnat_entity) == E_Procedure
4728 || Ekind (gnat_entity) == E_Function)
4729 && Is_Intrinsic_Subprogram (gnat_entity))
4730 && !IN (Ekind (gnat_entity), Named_Kind)
4731 && !IN (Ekind (gnat_entity), Generic_Unit_Kind))
4732 gnat_to_gnu_entity (gnat_entity, NULL_TREE, 0);
4734 else if (Ekind (Entity (Name (gnat_with_clause))) == E_Generic_Package)
4736 Node_Id gnat_body
4737 = Corresponding_Body (Unit (Library_Unit (gnat_with_clause)));
4739 /* Retrieve compilation unit node of generic body. */
4740 while (Present (gnat_body)
4741 && Nkind (gnat_body) != N_Compilation_Unit)
4742 gnat_body = Parent (gnat_body);
4744 /* If body is available, elaborate its context. */
4745 if (Present (gnat_body))
4746 elaborate_all_entities (gnat_body);
4750 if (Nkind (Unit (gnat_node)) == N_Package_Body && type_annotate_only)
4751 elaborate_all_entities (Library_Unit (gnat_node));
4754 /* Do the processing of N_Freeze_Entity, GNAT_NODE. */
4756 static void
4757 process_freeze_entity (Node_Id gnat_node)
4759 Entity_Id gnat_entity = Entity (gnat_node);
4760 tree gnu_old;
4761 tree gnu_new;
4762 tree gnu_init
4763 = (Nkind (Declaration_Node (gnat_entity)) == N_Object_Declaration
4764 && present_gnu_tree (Declaration_Node (gnat_entity)))
4765 ? get_gnu_tree (Declaration_Node (gnat_entity)) : NULL_TREE;
4767 /* If this is a package, need to generate code for the package. */
4768 if (Ekind (gnat_entity) == E_Package)
4770 insert_code_for
4771 (Parent (Corresponding_Body
4772 (Parent (Declaration_Node (gnat_entity)))));
4773 return;
4776 /* Check for old definition after the above call. This Freeze_Node
4777 might be for one its Itypes. */
4778 gnu_old
4779 = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : 0;
4781 /* If this entity has an Address representation clause, GNU_OLD is the
4782 address, so discard it here. */
4783 if (Present (Address_Clause (gnat_entity)))
4784 gnu_old = 0;
4786 /* Don't do anything for class-wide types they are always
4787 transformed into their root type. */
4788 if (Ekind (gnat_entity) == E_Class_Wide_Type
4789 || (Ekind (gnat_entity) == E_Class_Wide_Subtype
4790 && Present (Equivalent_Type (gnat_entity))))
4791 return;
4793 /* Don't do anything for subprograms that may have been elaborated before
4794 their freeze nodes. This can happen, for example because of an inner call
4795 in an instance body, or a previous compilation of a spec for inlining
4796 purposes. */
4797 if ((gnu_old
4798 && TREE_CODE (gnu_old) == FUNCTION_DECL
4799 && (Ekind (gnat_entity) == E_Function
4800 || Ekind (gnat_entity) == E_Procedure))
4801 || (gnu_old
4802 && (TREE_CODE (TREE_TYPE (gnu_old)) == FUNCTION_TYPE
4803 && Ekind (gnat_entity) == E_Subprogram_Type)))
4804 return;
4806 /* If we have a non-dummy type old tree, we have nothing to do. Unless
4807 this is the public view of a private type whose full view was not
4808 delayed, this node was never delayed as it should have been.
4809 Also allow this to happen for concurrent types since we may have
4810 frozen both the Corresponding_Record_Type and this type. */
4811 if (gnu_old
4812 && !(TREE_CODE (gnu_old) == TYPE_DECL
4813 && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old))))
4815 gcc_assert ((IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
4816 && Present (Full_View (gnat_entity))
4817 && No (Freeze_Node (Full_View (gnat_entity))))
4818 || Is_Concurrent_Type (gnat_entity));
4819 return;
4822 /* Reset the saved tree, if any, and elaborate the object or type for real.
4823 If there is a full declaration, elaborate it and copy the type to
4824 GNAT_ENTITY. Likewise if this is the record subtype corresponding to
4825 a class wide type or subtype. */
4826 if (gnu_old)
4828 save_gnu_tree (gnat_entity, NULL_TREE, false);
4829 if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
4830 && Present (Full_View (gnat_entity))
4831 && present_gnu_tree (Full_View (gnat_entity)))
4832 save_gnu_tree (Full_View (gnat_entity), NULL_TREE, false);
4833 if (Present (Class_Wide_Type (gnat_entity))
4834 && Class_Wide_Type (gnat_entity) != gnat_entity)
4835 save_gnu_tree (Class_Wide_Type (gnat_entity), NULL_TREE, false);
4838 if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
4839 && Present (Full_View (gnat_entity)))
4841 gnu_new = gnat_to_gnu_entity (Full_View (gnat_entity), NULL_TREE, 1);
4843 /* Propagate back-annotations from full view to partial view. */
4844 if (Unknown_Alignment (gnat_entity))
4845 Set_Alignment (gnat_entity, Alignment (Full_View (gnat_entity)));
4847 if (Unknown_Esize (gnat_entity))
4848 Set_Esize (gnat_entity, Esize (Full_View (gnat_entity)));
4850 if (Unknown_RM_Size (gnat_entity))
4851 Set_RM_Size (gnat_entity, RM_Size (Full_View (gnat_entity)));
4853 /* The above call may have defined this entity (the simplest example
4854 of this is when we have a private enumeral type since the bounds
4855 will have the public view. */
4856 if (!present_gnu_tree (gnat_entity))
4857 save_gnu_tree (gnat_entity, gnu_new, false);
4858 if (Present (Class_Wide_Type (gnat_entity))
4859 && Class_Wide_Type (gnat_entity) != gnat_entity)
4860 save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);
4862 else
4863 gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, 1);
4865 /* If we've made any pointers to the old version of this type, we
4866 have to update them. */
4867 if (gnu_old)
4868 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
4869 TREE_TYPE (gnu_new));
4872 /* Process the list of inlined subprograms of GNAT_NODE, which is an
4873 N_Compilation_Unit. */
4875 static void
4876 process_inlined_subprograms (Node_Id gnat_node)
4878 Entity_Id gnat_entity;
4879 Node_Id gnat_body;
4881 /* If we can inline, generate RTL for all the inlined subprograms.
4882 Define the entity first so we set DECL_EXTERNAL. */
4883 if (optimize > 0 && !flag_really_no_inline)
4884 for (gnat_entity = First_Inlined_Subprogram (gnat_node);
4885 Present (gnat_entity);
4886 gnat_entity = Next_Inlined_Subprogram (gnat_entity))
4888 gnat_body = Parent (Declaration_Node (gnat_entity));
4890 if (Nkind (gnat_body) != N_Subprogram_Body)
4892 /* ??? This really should always be Present. */
4893 if (No (Corresponding_Body (gnat_body)))
4894 continue;
4896 gnat_body
4897 = Parent (Declaration_Node (Corresponding_Body (gnat_body)));
4900 if (Present (gnat_body))
4902 gnat_to_gnu_entity (gnat_entity, NULL_TREE, 0);
4903 add_stmt (gnat_to_gnu (gnat_body));
4908 /* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
4909 We make two passes, one to elaborate anything other than bodies (but
4910 we declare a function if there was no spec). The second pass
4911 elaborates the bodies.
4913 GNAT_END_LIST gives the element in the list past the end. Normally,
4914 this is Empty, but can be First_Real_Statement for a
4915 Handled_Sequence_Of_Statements.
4917 We make a complete pass through both lists if PASS1P is true, then make
4918 the second pass over both lists if PASS2P is true. The lists usually
4919 correspond to the public and private parts of a package. */
4921 static void
4922 process_decls (List_Id gnat_decls, List_Id gnat_decls2,
4923 Node_Id gnat_end_list, bool pass1p, bool pass2p)
4925 List_Id gnat_decl_array[2];
4926 Node_Id gnat_decl;
4927 int i;
4929 gnat_decl_array[0] = gnat_decls, gnat_decl_array[1] = gnat_decls2;
4931 if (pass1p)
4932 for (i = 0; i <= 1; i++)
4933 if (Present (gnat_decl_array[i]))
4934 for (gnat_decl = First (gnat_decl_array[i]);
4935 gnat_decl != gnat_end_list; gnat_decl = Next (gnat_decl))
4937 /* For package specs, we recurse inside the declarations,
4938 thus taking the two pass approach inside the boundary. */
4939 if (Nkind (gnat_decl) == N_Package_Declaration
4940 && (Nkind (Specification (gnat_decl)
4941 == N_Package_Specification)))
4942 process_decls (Visible_Declarations (Specification (gnat_decl)),
4943 Private_Declarations (Specification (gnat_decl)),
4944 Empty, true, false);
4946 /* Similarly for any declarations in the actions of a
4947 freeze node. */
4948 else if (Nkind (gnat_decl) == N_Freeze_Entity)
4950 process_freeze_entity (gnat_decl);
4951 process_decls (Actions (gnat_decl), Empty, Empty, true, false);
4954 /* Package bodies with freeze nodes get their elaboration deferred
4955 until the freeze node, but the code must be placed in the right
4956 place, so record the code position now. */
4957 else if (Nkind (gnat_decl) == N_Package_Body
4958 && Present (Freeze_Node (Corresponding_Spec (gnat_decl))))
4959 record_code_position (gnat_decl);
4961 else if (Nkind (gnat_decl) == N_Package_Body_Stub
4962 && Present (Library_Unit (gnat_decl))
4963 && Present (Freeze_Node
4964 (Corresponding_Spec
4965 (Proper_Body (Unit
4966 (Library_Unit (gnat_decl)))))))
4967 record_code_position
4968 (Proper_Body (Unit (Library_Unit (gnat_decl))));
4970 /* We defer most subprogram bodies to the second pass. */
4971 else if (Nkind (gnat_decl) == N_Subprogram_Body)
4973 if (Acts_As_Spec (gnat_decl))
4975 Node_Id gnat_subprog_id = Defining_Entity (gnat_decl);
4977 if (Ekind (gnat_subprog_id) != E_Generic_Procedure
4978 && Ekind (gnat_subprog_id) != E_Generic_Function)
4979 gnat_to_gnu_entity (gnat_subprog_id, NULL_TREE, 1);
4982 /* For bodies and stubs that act as their own specs, the entity
4983 itself must be elaborated in the first pass, because it may
4984 be used in other declarations. */
4985 else if (Nkind (gnat_decl) == N_Subprogram_Body_Stub)
4987 Node_Id gnat_subprog_id =
4988 Defining_Entity (Specification (gnat_decl));
4990 if (Ekind (gnat_subprog_id) != E_Subprogram_Body
4991 && Ekind (gnat_subprog_id) != E_Generic_Procedure
4992 && Ekind (gnat_subprog_id) != E_Generic_Function)
4993 gnat_to_gnu_entity (gnat_subprog_id, NULL_TREE, 1);
4996 /* Concurrent stubs stand for the corresponding subprogram bodies,
4997 which are deferred like other bodies. */
4998 else if (Nkind (gnat_decl) == N_Task_Body_Stub
4999 || Nkind (gnat_decl) == N_Protected_Body_Stub)
5001 else
5002 add_stmt (gnat_to_gnu (gnat_decl));
5005 /* Here we elaborate everything we deferred above except for package bodies,
5006 which are elaborated at their freeze nodes. Note that we must also
5007 go inside things (package specs and freeze nodes) the first pass did. */
5008 if (pass2p)
5009 for (i = 0; i <= 1; i++)
5010 if (Present (gnat_decl_array[i]))
5011 for (gnat_decl = First (gnat_decl_array[i]);
5012 gnat_decl != gnat_end_list; gnat_decl = Next (gnat_decl))
5014 if (Nkind (gnat_decl) == N_Subprogram_Body
5015 || Nkind (gnat_decl) == N_Subprogram_Body_Stub
5016 || Nkind (gnat_decl) == N_Task_Body_Stub
5017 || Nkind (gnat_decl) == N_Protected_Body_Stub)
5018 add_stmt (gnat_to_gnu (gnat_decl));
5020 else if (Nkind (gnat_decl) == N_Package_Declaration
5021 && (Nkind (Specification (gnat_decl)
5022 == N_Package_Specification)))
5023 process_decls (Visible_Declarations (Specification (gnat_decl)),
5024 Private_Declarations (Specification (gnat_decl)),
5025 Empty, false, true);
5027 else if (Nkind (gnat_decl) == N_Freeze_Entity)
5028 process_decls (Actions (gnat_decl), Empty, Empty, false, true);
5032 /* Emit code for a range check. GNU_EXPR is the expression to be checked,
5033 GNAT_RANGE_TYPE the gnat type or subtype containing the bounds against
5034 which we have to check. */
5036 static tree
5037 emit_range_check (tree gnu_expr, Entity_Id gnat_range_type)
5039 tree gnu_range_type = get_unpadded_type (gnat_range_type);
5040 tree gnu_low = TYPE_MIN_VALUE (gnu_range_type);
5041 tree gnu_high = TYPE_MAX_VALUE (gnu_range_type);
5042 tree gnu_compare_type = get_base_type (TREE_TYPE (gnu_expr));
5044 /* If GNU_EXPR has an integral type that is narrower than GNU_RANGE_TYPE,
5045 we can't do anything since we might be truncating the bounds. No
5046 check is needed in this case. */
5047 if (INTEGRAL_TYPE_P (TREE_TYPE (gnu_expr))
5048 && (TYPE_PRECISION (gnu_compare_type)
5049 < TYPE_PRECISION (get_base_type (gnu_range_type))))
5050 return gnu_expr;
5052 /* Checked expressions must be evaluated only once. */
5053 gnu_expr = protect_multiple_eval (gnu_expr);
5055 /* There's no good type to use here, so we might as well use
5056 integer_type_node. Note that the form of the check is
5057 (not (expr >= lo)) or (not (expr >= hi))
5058 the reason for this slightly convoluted form is that NaN's
5059 are not considered to be in range in the float case. */
5060 return emit_check
5061 (build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
5062 invert_truthvalue
5063 (build_binary_op (GE_EXPR, integer_type_node,
5064 convert (gnu_compare_type, gnu_expr),
5065 convert (gnu_compare_type, gnu_low))),
5066 invert_truthvalue
5067 (build_binary_op (LE_EXPR, integer_type_node,
5068 convert (gnu_compare_type, gnu_expr),
5069 convert (gnu_compare_type,
5070 gnu_high)))),
5071 gnu_expr, CE_Range_Check_Failed);
5074 /* Emit code for an index check. GNU_ARRAY_OBJECT is the array object
5075 which we are about to index, GNU_EXPR is the index expression to be
5076 checked, GNU_LOW and GNU_HIGH are the lower and upper bounds
5077 against which GNU_EXPR has to be checked. Note that for index
5078 checking we cannot use the emit_range_check function (although very
5079 similar code needs to be generated in both cases) since for index
5080 checking the array type against which we are checking the indeces
5081 may be unconstrained and consequently we need to retrieve the
5082 actual index bounds from the array object itself
5083 (GNU_ARRAY_OBJECT). The place where we need to do that is in
5084 subprograms having unconstrained array formal parameters */
5086 static tree
5087 emit_index_check (tree gnu_array_object,
5088 tree gnu_expr,
5089 tree gnu_low,
5090 tree gnu_high)
5092 tree gnu_expr_check;
5094 /* Checked expressions must be evaluated only once. */
5095 gnu_expr = protect_multiple_eval (gnu_expr);
5097 /* Must do this computation in the base type in case the expression's
5098 type is an unsigned subtypes. */
5099 gnu_expr_check = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr);
5101 /* If GNU_LOW or GNU_HIGH are a PLACEHOLDER_EXPR, qualify them by
5102 the object we are handling. */
5103 gnu_low = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_low, gnu_array_object);
5104 gnu_high = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_high, gnu_array_object);
5106 /* There's no good type to use here, so we might as well use
5107 integer_type_node. */
5108 return emit_check
5109 (build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
5110 build_binary_op (LT_EXPR, integer_type_node,
5111 gnu_expr_check,
5112 convert (TREE_TYPE (gnu_expr_check),
5113 gnu_low)),
5114 build_binary_op (GT_EXPR, integer_type_node,
5115 gnu_expr_check,
5116 convert (TREE_TYPE (gnu_expr_check),
5117 gnu_high))),
5118 gnu_expr, CE_Index_Check_Failed);
5121 /* GNU_COND contains the condition corresponding to an access, discriminant or
5122 range check of value GNU_EXPR. Build a COND_EXPR that returns GNU_EXPR if
5123 GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true.
5124 REASON is the code that says why the exception was raised. */
5126 static tree
5127 emit_check (tree gnu_cond, tree gnu_expr, int reason)
5129 tree gnu_call;
5130 tree gnu_result;
5132 gnu_call = build_call_raise (reason);
5134 /* Use an outer COMPOUND_EXPR to make sure that GNU_EXPR will get evaluated
5135 in front of the comparison in case it ends up being a SAVE_EXPR. Put the
5136 whole thing inside its own SAVE_EXPR so the inner SAVE_EXPR doesn't leak
5137 out. */
5138 gnu_result = fold (build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
5139 build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr),
5140 gnu_call, gnu_expr),
5141 gnu_expr));
5143 /* If GNU_EXPR has side effects, make the outer COMPOUND_EXPR and
5144 protect it. Otherwise, show GNU_RESULT has no side effects: we
5145 don't need to evaluate it just for the check. */
5146 if (TREE_SIDE_EFFECTS (gnu_expr))
5147 gnu_result
5148 = build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_expr, gnu_result);
5149 else
5150 TREE_SIDE_EFFECTS (gnu_result) = 0;
5152 /* ??? Unfortunately, if we don't put a SAVE_EXPR around this whole thing,
5153 we will repeatedly do the test. It would be nice if GCC was able
5154 to optimize this and only do it once. */
5155 return save_expr (gnu_result);
5158 /* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing
5159 overflow checks if OVERFLOW_P is nonzero and range checks if
5160 RANGE_P is nonzero. GNAT_TYPE is known to be an integral type.
5161 If TRUNCATE_P is nonzero, do a float to integer conversion with
5162 truncation; otherwise round. */
5164 static tree
5165 convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp,
5166 bool rangep, bool truncatep)
5168 tree gnu_type = get_unpadded_type (gnat_type);
5169 tree gnu_in_type = TREE_TYPE (gnu_expr);
5170 tree gnu_in_basetype = get_base_type (gnu_in_type);
5171 tree gnu_base_type = get_base_type (gnu_type);
5172 tree gnu_ada_base_type = get_ada_base_type (gnu_type);
5173 tree gnu_result = gnu_expr;
5175 /* If we are not doing any checks, the output is an integral type, and
5176 the input is not a floating type, just do the conversion. This
5177 shortcut is required to avoid problems with packed array types
5178 and simplifies code in all cases anyway. */
5179 if (!rangep && !overflowp && INTEGRAL_TYPE_P (gnu_base_type)
5180 && !FLOAT_TYPE_P (gnu_in_type))
5181 return convert (gnu_type, gnu_expr);
5183 /* First convert the expression to its base type. This
5184 will never generate code, but makes the tests below much simpler.
5185 But don't do this if converting from an integer type to an unconstrained
5186 array type since then we need to get the bounds from the original
5187 (unpacked) type. */
5188 if (TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE)
5189 gnu_result = convert (gnu_in_basetype, gnu_result);
5191 /* If overflow checks are requested, we need to be sure the result will
5192 fit in the output base type. But don't do this if the input
5193 is integer and the output floating-point. */
5194 if (overflowp
5195 && !(FLOAT_TYPE_P (gnu_base_type) && INTEGRAL_TYPE_P (gnu_in_basetype)))
5197 /* Ensure GNU_EXPR only gets evaluated once. */
5198 tree gnu_input = protect_multiple_eval (gnu_result);
5199 tree gnu_cond = integer_zero_node;
5200 tree gnu_in_lb = TYPE_MIN_VALUE (gnu_in_basetype);
5201 tree gnu_in_ub = TYPE_MAX_VALUE (gnu_in_basetype);
5202 tree gnu_out_lb = TYPE_MIN_VALUE (gnu_base_type);
5203 tree gnu_out_ub = TYPE_MAX_VALUE (gnu_base_type);
5205 /* Convert the lower bounds to signed types, so we're sure we're
5206 comparing them properly. Likewise, convert the upper bounds
5207 to unsigned types. */
5208 if (INTEGRAL_TYPE_P (gnu_in_basetype) && TYPE_UNSIGNED (gnu_in_basetype))
5209 gnu_in_lb = convert (gnat_signed_type (gnu_in_basetype), gnu_in_lb);
5211 if (INTEGRAL_TYPE_P (gnu_in_basetype)
5212 && !TYPE_UNSIGNED (gnu_in_basetype))
5213 gnu_in_ub = convert (gnat_unsigned_type (gnu_in_basetype), gnu_in_ub);
5215 if (INTEGRAL_TYPE_P (gnu_base_type) && TYPE_UNSIGNED (gnu_base_type))
5216 gnu_out_lb = convert (gnat_signed_type (gnu_base_type), gnu_out_lb);
5218 if (INTEGRAL_TYPE_P (gnu_base_type) && !TYPE_UNSIGNED (gnu_base_type))
5219 gnu_out_ub = convert (gnat_unsigned_type (gnu_base_type), gnu_out_ub);
5221 /* Check each bound separately and only if the result bound
5222 is tighter than the bound on the input type. Note that all the
5223 types are base types, so the bounds must be constant. Also,
5224 the comparison is done in the base type of the input, which
5225 always has the proper signedness. First check for input
5226 integer (which means output integer), output float (which means
5227 both float), or mixed, in which case we always compare.
5228 Note that we have to do the comparison which would *fail* in the
5229 case of an error since if it's an FP comparison and one of the
5230 values is a NaN or Inf, the comparison will fail. */
5231 if (INTEGRAL_TYPE_P (gnu_in_basetype)
5232 ? tree_int_cst_lt (gnu_in_lb, gnu_out_lb)
5233 : (FLOAT_TYPE_P (gnu_base_type)
5234 ? REAL_VALUES_LESS (TREE_REAL_CST (gnu_in_lb),
5235 TREE_REAL_CST (gnu_out_lb))
5236 : 1))
5237 gnu_cond
5238 = invert_truthvalue
5239 (build_binary_op (GE_EXPR, integer_type_node,
5240 gnu_input, convert (gnu_in_basetype,
5241 gnu_out_lb)));
5243 if (INTEGRAL_TYPE_P (gnu_in_basetype)
5244 ? tree_int_cst_lt (gnu_out_ub, gnu_in_ub)
5245 : (FLOAT_TYPE_P (gnu_base_type)
5246 ? REAL_VALUES_LESS (TREE_REAL_CST (gnu_out_ub),
5247 TREE_REAL_CST (gnu_in_lb))
5248 : 1))
5249 gnu_cond
5250 = build_binary_op (TRUTH_ORIF_EXPR, integer_type_node, gnu_cond,
5251 invert_truthvalue
5252 (build_binary_op (LE_EXPR, integer_type_node,
5253 gnu_input,
5254 convert (gnu_in_basetype,
5255 gnu_out_ub))));
5257 if (!integer_zerop (gnu_cond))
5258 gnu_result = emit_check (gnu_cond, gnu_input,
5259 CE_Overflow_Check_Failed);
5262 /* Now convert to the result base type. If this is a non-truncating
5263 float-to-integer conversion, round. */
5264 if (INTEGRAL_TYPE_P (gnu_ada_base_type) && FLOAT_TYPE_P (gnu_in_basetype)
5265 && !truncatep)
5267 REAL_VALUE_TYPE half_minus_pred_half, pred_half;
5268 tree gnu_conv, gnu_zero, gnu_comp, gnu_saved_result, calc_type;
5269 tree gnu_pred_half, gnu_add_pred_half, gnu_subtract_pred_half;
5270 const struct real_format *fmt;
5272 /* The following calculations depend on proper rounding to even
5273 of each arithmetic operation. In order to prevent excess
5274 precision from spoiling this property, use the widest hardware
5275 floating-point type.
5277 FIXME: For maximum efficiency, this should only be done for machines
5278 and types where intermediates may have extra precision. */
5280 calc_type = longest_float_type_node;
5281 /* FIXME: Should not have padding in the first place */
5282 if (TREE_CODE (calc_type) == RECORD_TYPE
5283 && TYPE_IS_PADDING_P (calc_type))
5284 calc_type = TREE_TYPE (TYPE_FIELDS (calc_type));
5286 /* Compute the exact value calc_type'Pred (0.5) at compile time. */
5287 fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type));
5288 real_2expN (&half_minus_pred_half, -(fmt->p) - 1);
5289 REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf,
5290 half_minus_pred_half);
5291 gnu_pred_half = build_real (calc_type, pred_half);
5293 /* If the input is strictly negative, subtract this value
5294 and otherwise add it from the input. For 0.5, the result
5295 is exactly between 1.0 and the machine number preceding 1.0
5296 (for calc_type). Since the last bit of 1.0 is even, this 0.5
5297 will round to 1.0, while all other number with an absolute
5298 value less than 0.5 round to 0.0. For larger numbers exactly
5299 halfway between integers, rounding will always be correct as
5300 the true mathematical result will be closer to the higher
5301 integer compared to the lower one. So, this constant works
5302 for all floating-point numbers.
5304 The reason to use the same constant with subtract/add instead
5305 of a positive and negative constant is to allow the comparison
5306 to be scheduled in parallel with retrieval of the constant and
5307 conversion of the input to the calc_type (if necessary).
5310 gnu_zero = convert (gnu_in_basetype, integer_zero_node);
5311 gnu_saved_result = save_expr (gnu_result);
5312 gnu_conv = convert (calc_type, gnu_saved_result);
5313 gnu_comp = build2 (GE_EXPR, integer_type_node,
5314 gnu_saved_result, gnu_zero);
5315 gnu_add_pred_half
5316 = build2 (PLUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
5317 gnu_subtract_pred_half
5318 = build2 (MINUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
5319 gnu_result = build3 (COND_EXPR, calc_type, gnu_comp,
5320 gnu_add_pred_half, gnu_subtract_pred_half);
5323 if (TREE_CODE (gnu_ada_base_type) == INTEGER_TYPE
5324 && TYPE_HAS_ACTUAL_BOUNDS_P (gnu_ada_base_type)
5325 && TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
5326 gnu_result = unchecked_convert (gnu_ada_base_type, gnu_result, false);
5327 else
5328 gnu_result = convert (gnu_ada_base_type, gnu_result);
5330 /* Finally, do the range check if requested. Note that if the
5331 result type is a modular type, the range check is actually
5332 an overflow check. */
5334 if (rangep
5335 || (TREE_CODE (gnu_base_type) == INTEGER_TYPE
5336 && TYPE_MODULAR_P (gnu_base_type) && overflowp))
5337 gnu_result = emit_range_check (gnu_result, gnat_type);
5339 return convert (gnu_type, gnu_result);
5342 /* Return 1 if GNU_EXPR can be directly addressed. This is the case unless
5343 it is an expression involving computation or if it involves a reference
5344 to a bitfield or to a field not sufficiently aligned for its type. */
5346 static bool
5347 addressable_p (tree gnu_expr)
5349 switch (TREE_CODE (gnu_expr))
5351 case VAR_DECL:
5352 case PARM_DECL:
5353 case FUNCTION_DECL:
5354 case RESULT_DECL:
5355 /* All DECLs are addressable: if they are in a register, we can force
5356 them to memory. */
5357 return true;
5359 case UNCONSTRAINED_ARRAY_REF:
5360 case INDIRECT_REF:
5361 case CONSTRUCTOR:
5362 case NULL_EXPR:
5363 case SAVE_EXPR:
5364 return true;
5366 case COMPONENT_REF:
5367 return (!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr, 1))
5368 && (!STRICT_ALIGNMENT
5369 /* If the field was marked as "semantically" addressable
5370 in create_field_decl, we are guaranteed that it can
5371 be directly addressed. */
5372 || !DECL_NONADDRESSABLE_P (TREE_OPERAND (gnu_expr, 1))
5373 /* Otherwise it can nevertheless be directly addressed
5374 if it has been sufficiently aligned in the record. */
5375 || DECL_ALIGN (TREE_OPERAND (gnu_expr, 1))
5376 >= TYPE_ALIGN (TREE_TYPE (gnu_expr)))
5377 && addressable_p (TREE_OPERAND (gnu_expr, 0)));
5379 case ARRAY_REF: case ARRAY_RANGE_REF:
5380 case REALPART_EXPR: case IMAGPART_EXPR:
5381 case NOP_EXPR:
5382 return addressable_p (TREE_OPERAND (gnu_expr, 0));
5384 case CONVERT_EXPR:
5385 return (AGGREGATE_TYPE_P (TREE_TYPE (gnu_expr))
5386 && addressable_p (TREE_OPERAND (gnu_expr, 0)));
5388 case VIEW_CONVERT_EXPR:
5390 /* This is addressable if we can avoid a copy. */
5391 tree type = TREE_TYPE (gnu_expr);
5392 tree inner_type = TREE_TYPE (TREE_OPERAND (gnu_expr, 0));
5394 return (((TYPE_MODE (type) == TYPE_MODE (inner_type)
5395 && (TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
5396 || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT))
5397 || ((TYPE_MODE (type) == BLKmode
5398 || TYPE_MODE (inner_type) == BLKmode)
5399 && (TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
5400 || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT
5401 || TYPE_ALIGN_OK (type)
5402 || TYPE_ALIGN_OK (inner_type))))
5403 && addressable_p (TREE_OPERAND (gnu_expr, 0)));
5406 default:
5407 return false;
5411 /* Do the processing for the declaration of a GNAT_ENTITY, a type. If
5412 a separate Freeze node exists, delay the bulk of the processing. Otherwise
5413 make a GCC type for GNAT_ENTITY and set up the correspondence. */
5415 void
5416 process_type (Entity_Id gnat_entity)
5418 tree gnu_old
5419 = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : 0;
5420 tree gnu_new;
5422 /* If we are to delay elaboration of this type, just do any
5423 elaborations needed for expressions within the declaration and
5424 make a dummy type entry for this node and its Full_View (if
5425 any) in case something points to it. Don't do this if it
5426 has already been done (the only way that can happen is if
5427 the private completion is also delayed). */
5428 if (Present (Freeze_Node (gnat_entity))
5429 || (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
5430 && Present (Full_View (gnat_entity))
5431 && Freeze_Node (Full_View (gnat_entity))
5432 && !present_gnu_tree (Full_View (gnat_entity))))
5434 elaborate_entity (gnat_entity);
5436 if (!gnu_old)
5438 tree gnu_decl = create_type_decl (get_entity_name (gnat_entity),
5439 make_dummy_type (gnat_entity),
5440 NULL, false, false, gnat_entity);
5442 save_gnu_tree (gnat_entity, gnu_decl, false);
5443 if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
5444 && Present (Full_View (gnat_entity)))
5445 save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
5448 return;
5451 /* If we saved away a dummy type for this node it means that this
5452 made the type that corresponds to the full type of an incomplete
5453 type. Clear that type for now and then update the type in the
5454 pointers. */
5455 if (gnu_old)
5457 if (TREE_CODE (gnu_old) != TYPE_DECL
5458 || !TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old)))
5460 /* If this was a withed access type, this is not an error
5461 and merely indicates we've already elaborated the type
5462 already. */
5463 gcc_assert (Is_Type (gnat_entity) && From_With_Type (gnat_entity));
5464 return;
5467 save_gnu_tree (gnat_entity, NULL_TREE, false);
5470 /* Now fully elaborate the type. */
5471 gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 1);
5472 gcc_assert (TREE_CODE (gnu_new) == TYPE_DECL);
5474 /* If we have an old type and we've made pointers to this type,
5475 update those pointers. */
5476 if (gnu_old)
5477 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
5478 TREE_TYPE (gnu_new));
5480 /* If this is a record type corresponding to a task or protected type
5481 that is a completion of an incomplete type, perform a similar update
5482 on the type. */
5483 /* ??? Including protected types here is a guess. */
5485 if (IN (Ekind (gnat_entity), Record_Kind)
5486 && Is_Concurrent_Record_Type (gnat_entity)
5487 && present_gnu_tree (Corresponding_Concurrent_Type (gnat_entity)))
5489 tree gnu_task_old
5490 = get_gnu_tree (Corresponding_Concurrent_Type (gnat_entity));
5492 save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity),
5493 NULL_TREE, false);
5494 save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity),
5495 gnu_new, false);
5497 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_task_old)),
5498 TREE_TYPE (gnu_new));
5502 /* GNAT_ASSOC is the front of the Component_Associations of an N_Aggregate.
5503 GNU_TYPE is the GCC type of the corresponding record.
5505 Return a CONSTRUCTOR to build the record. */
5507 static tree
5508 assoc_to_constructor (Node_Id gnat_assoc, tree gnu_type)
5510 tree gnu_list, gnu_result;
5512 /* We test for GNU_FIELD being empty in the case where a variant
5513 was the last thing since we don't take things off GNAT_ASSOC in
5514 that case. We check GNAT_ASSOC in case we have a variant, but it
5515 has no fields. */
5517 for (gnu_list = NULL_TREE; Present (gnat_assoc);
5518 gnat_assoc = Next (gnat_assoc))
5520 Node_Id gnat_field = First (Choices (gnat_assoc));
5521 tree gnu_field = gnat_to_gnu_field_decl (Entity (gnat_field));
5522 tree gnu_expr = gnat_to_gnu (Expression (gnat_assoc));
5524 /* The expander is supposed to put a single component selector name
5525 in every record component association */
5526 gcc_assert (No (Next (gnat_field)));
5528 /* Ignore fields that have Corresponding_Discriminants since we'll
5529 be setting that field in the parent. */
5530 if (Present (Corresponding_Discriminant (Entity (gnat_field)))
5531 && Is_Tagged_Type (Scope (Entity (gnat_field))))
5532 continue;
5534 /* Before assigning a value in an aggregate make sure range checks
5535 are done if required. Then convert to the type of the field. */
5536 if (Do_Range_Check (Expression (gnat_assoc)))
5537 gnu_expr = emit_range_check (gnu_expr, Etype (gnat_field));
5539 gnu_expr = convert (TREE_TYPE (gnu_field), gnu_expr);
5541 /* Add the field and expression to the list. */
5542 gnu_list = tree_cons (gnu_field, gnu_expr, gnu_list);
5545 gnu_result = extract_values (gnu_list, gnu_type);
5547 #ifdef ENABLE_CHECKING
5549 tree gnu_field;
5551 /* Verify every enty in GNU_LIST was used. */
5552 for (gnu_field = gnu_list; gnu_field; gnu_field = TREE_CHAIN (gnu_field))
5553 gcc_assert (TREE_ADDRESSABLE (gnu_field));
5555 #endif
5557 return gnu_result;
5560 /* Builds a possibly nested constructor for array aggregates. GNAT_EXPR
5561 is the first element of an array aggregate. It may itself be an
5562 aggregate (an array or record aggregate). GNU_ARRAY_TYPE is the gnu type
5563 corresponding to the array aggregate. GNAT_COMPONENT_TYPE is the type
5564 of the array component. It is needed for range checking. */
5566 static tree
5567 pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type,
5568 Entity_Id gnat_component_type)
5570 tree gnu_expr_list = NULL_TREE;
5571 tree gnu_index = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_array_type));
5572 tree gnu_expr;
5574 for ( ; Present (gnat_expr); gnat_expr = Next (gnat_expr))
5576 /* If the expression is itself an array aggregate then first build the
5577 innermost constructor if it is part of our array (multi-dimensional
5578 case). */
5580 if (Nkind (gnat_expr) == N_Aggregate
5581 && TREE_CODE (TREE_TYPE (gnu_array_type)) == ARRAY_TYPE
5582 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_array_type)))
5583 gnu_expr = pos_to_constructor (First (Expressions (gnat_expr)),
5584 TREE_TYPE (gnu_array_type),
5585 gnat_component_type);
5586 else
5588 gnu_expr = gnat_to_gnu (gnat_expr);
5590 /* before assigning the element to the array make sure it is
5591 in range */
5592 if (Do_Range_Check (gnat_expr))
5593 gnu_expr = emit_range_check (gnu_expr, gnat_component_type);
5596 gnu_expr_list
5597 = tree_cons (gnu_index, convert (TREE_TYPE (gnu_array_type), gnu_expr),
5598 gnu_expr_list);
5600 gnu_index = int_const_binop (PLUS_EXPR, gnu_index, integer_one_node, 0);
5603 return gnat_build_constructor (gnu_array_type, nreverse (gnu_expr_list));
5606 /* Subroutine of assoc_to_constructor: VALUES is a list of field associations,
5607 some of which are from RECORD_TYPE. Return a CONSTRUCTOR consisting
5608 of the associations that are from RECORD_TYPE. If we see an internal
5609 record, make a recursive call to fill it in as well. */
5611 static tree
5612 extract_values (tree values, tree record_type)
5614 tree result = NULL_TREE;
5615 tree field, tem;
5617 for (field = TYPE_FIELDS (record_type); field; field = TREE_CHAIN (field))
5619 tree value = 0;
5621 /* _Parent is an internal field, but may have values in the aggregate,
5622 so check for values first. */
5623 if ((tem = purpose_member (field, values)))
5625 value = TREE_VALUE (tem);
5626 TREE_ADDRESSABLE (tem) = 1;
5629 else if (DECL_INTERNAL_P (field))
5631 value = extract_values (values, TREE_TYPE (field));
5632 if (TREE_CODE (value) == CONSTRUCTOR
5633 && VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (value)))
5634 value = 0;
5636 else
5637 /* If we have a record subtype, the names will match, but not the
5638 actual FIELD_DECLs. */
5639 for (tem = values; tem; tem = TREE_CHAIN (tem))
5640 if (DECL_NAME (TREE_PURPOSE (tem)) == DECL_NAME (field))
5642 value = convert (TREE_TYPE (field), TREE_VALUE (tem));
5643 TREE_ADDRESSABLE (tem) = 1;
5646 if (!value)
5647 continue;
5649 result = tree_cons (field, value, result);
5652 return gnat_build_constructor (record_type, nreverse (result));
5655 /* EXP is to be treated as an array or record. Handle the cases when it is
5656 an access object and perform the required dereferences. */
5658 static tree
5659 maybe_implicit_deref (tree exp)
5661 /* If the type is a pointer, dereference it. */
5663 if (POINTER_TYPE_P (TREE_TYPE (exp)) || TYPE_FAT_POINTER_P (TREE_TYPE (exp)))
5664 exp = build_unary_op (INDIRECT_REF, NULL_TREE, exp);
5666 /* If we got a padded type, remove it too. */
5667 if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
5668 && TYPE_IS_PADDING_P (TREE_TYPE (exp)))
5669 exp = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp))), exp);
5671 return exp;
5674 /* Protect EXP from multiple evaluation. This may make a SAVE_EXPR. */
5676 tree
5677 protect_multiple_eval (tree exp)
5679 tree type = TREE_TYPE (exp);
5681 /* If this has no side effects, we don't need to do anything. */
5682 if (!TREE_SIDE_EFFECTS (exp))
5683 return exp;
5685 /* If it is a conversion, protect what's inside the conversion.
5686 Similarly, if we're indirectly referencing something, we only
5687 actually need to protect the address since the data itself can't
5688 change in these situations. */
5689 else if (TREE_CODE (exp) == NON_LVALUE_EXPR
5690 || TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
5691 || TREE_CODE (exp) == VIEW_CONVERT_EXPR
5692 || TREE_CODE (exp) == INDIRECT_REF
5693 || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF)
5694 return build1 (TREE_CODE (exp), type,
5695 protect_multiple_eval (TREE_OPERAND (exp, 0)));
5697 /* If EXP is a fat pointer or something that can be placed into a register,
5698 just make a SAVE_EXPR. */
5699 if (TYPE_FAT_POINTER_P (type) || TYPE_MODE (type) != BLKmode)
5700 return save_expr (exp);
5702 /* Otherwise, dereference, protect the address, and re-reference. */
5703 else
5704 return
5705 build_unary_op (INDIRECT_REF, type,
5706 save_expr (build_unary_op (ADDR_EXPR,
5707 build_reference_type (type),
5708 exp)));
5711 /* This is equivalent to stabilize_reference in GCC's tree.c, but we know
5712 how to handle our new nodes and we take an extra argument that says
5713 whether to force evaluation of everything. */
5715 tree
5716 gnat_stabilize_reference (tree ref, bool force)
5718 tree type = TREE_TYPE (ref);
5719 enum tree_code code = TREE_CODE (ref);
5720 tree result;
5722 switch (code)
5724 case VAR_DECL:
5725 case PARM_DECL:
5726 case RESULT_DECL:
5727 /* No action is needed in this case. */
5728 return ref;
5730 case NOP_EXPR:
5731 case CONVERT_EXPR:
5732 case FLOAT_EXPR:
5733 case FIX_TRUNC_EXPR:
5734 case FIX_FLOOR_EXPR:
5735 case FIX_ROUND_EXPR:
5736 case FIX_CEIL_EXPR:
5737 case VIEW_CONVERT_EXPR:
5738 case ADDR_EXPR:
5739 result
5740 = build1 (code, type,
5741 gnat_stabilize_reference (TREE_OPERAND (ref, 0), force));
5742 break;
5744 case INDIRECT_REF:
5745 case UNCONSTRAINED_ARRAY_REF:
5746 result = build1 (code, type,
5747 gnat_stabilize_reference_1 (TREE_OPERAND (ref, 0),
5748 force));
5749 break;
5751 case COMPONENT_REF:
5752 result = build3 (COMPONENT_REF, type,
5753 gnat_stabilize_reference (TREE_OPERAND (ref, 0),
5754 force),
5755 TREE_OPERAND (ref, 1), NULL_TREE);
5756 break;
5758 case BIT_FIELD_REF:
5759 result = build3 (BIT_FIELD_REF, type,
5760 gnat_stabilize_reference (TREE_OPERAND (ref, 0), force),
5761 gnat_stabilize_reference_1 (TREE_OPERAND (ref, 1),
5762 force),
5763 gnat_stabilize_reference_1 (TREE_OPERAND (ref, 2),
5764 force));
5765 break;
5767 case ARRAY_REF:
5768 case ARRAY_RANGE_REF:
5769 result = build4 (code, type,
5770 gnat_stabilize_reference (TREE_OPERAND (ref, 0), force),
5771 gnat_stabilize_reference_1 (TREE_OPERAND (ref, 1),
5772 force),
5773 NULL_TREE, NULL_TREE);
5774 break;
5776 case COMPOUND_EXPR:
5777 result = build2 (COMPOUND_EXPR, type,
5778 gnat_stabilize_reference_1 (TREE_OPERAND (ref, 0),
5779 force),
5780 gnat_stabilize_reference (TREE_OPERAND (ref, 1),
5781 force));
5782 break;
5784 /* If arg isn't a kind of lvalue we recognize, make no change.
5785 Caller should recognize the error for an invalid lvalue. */
5786 default:
5787 return ref;
5789 case ERROR_MARK:
5790 return error_mark_node;
5793 TREE_READONLY (result) = TREE_READONLY (ref);
5795 /* TREE_THIS_VOLATILE and TREE_SIDE_EFFECTS attached to the initial
5796 expression may not be sustained across some paths, such as the way via
5797 build1 for INDIRECT_REF. We re-populate those flags here for the general
5798 case, which is consistent with the GCC version of this routine.
5800 Special care should be taken regarding TREE_SIDE_EFFECTS, because some
5801 paths introduce side effects where there was none initially (e.g. calls
5802 to save_expr), and we also want to keep track of that. */
5804 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
5805 TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (ref);
5807 return result;
5810 /* Similar to stabilize_reference_1 in tree.c, but supports an extra
5811 arg to force a SAVE_EXPR for everything. */
5813 static tree
5814 gnat_stabilize_reference_1 (tree e, bool force)
5816 enum tree_code code = TREE_CODE (e);
5817 tree type = TREE_TYPE (e);
5818 tree result;
5820 /* We cannot ignore const expressions because it might be a reference
5821 to a const array but whose index contains side-effects. But we can
5822 ignore things that are actual constant or that already have been
5823 handled by this function. */
5825 if (TREE_CONSTANT (e) || code == SAVE_EXPR)
5826 return e;
5828 switch (TREE_CODE_CLASS (code))
5830 case tcc_exceptional:
5831 case tcc_type:
5832 case tcc_declaration:
5833 case tcc_comparison:
5834 case tcc_statement:
5835 case tcc_expression:
5836 case tcc_reference:
5837 /* If this is a COMPONENT_REF of a fat pointer, save the entire
5838 fat pointer. This may be more efficient, but will also allow
5839 us to more easily find the match for the PLACEHOLDER_EXPR. */
5840 if (code == COMPONENT_REF
5841 && TYPE_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (e, 0))))
5842 result = build3 (COMPONENT_REF, type,
5843 gnat_stabilize_reference_1 (TREE_OPERAND (e, 0),
5844 force),
5845 TREE_OPERAND (e, 1), TREE_OPERAND (e, 2));
5846 else if (TREE_SIDE_EFFECTS (e) || force)
5847 return save_expr (e);
5848 else
5849 return e;
5850 break;
5852 case tcc_constant:
5853 /* Constants need no processing. In fact, we should never reach
5854 here. */
5855 return e;
5857 case tcc_binary:
5858 /* Recursively stabilize each operand. */
5859 result = build2 (code, type,
5860 gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), force),
5861 gnat_stabilize_reference_1 (TREE_OPERAND (e, 1),
5862 force));
5863 break;
5865 case tcc_unary:
5866 /* Recursively stabilize each operand. */
5867 result = build1 (code, type,
5868 gnat_stabilize_reference_1 (TREE_OPERAND (e, 0),
5869 force));
5870 break;
5872 default:
5873 gcc_unreachable ();
5876 TREE_READONLY (result) = TREE_READONLY (e);
5878 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
5879 TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (e);
5880 return result;
5883 /* Build a global constructor or destructor function. METHOD_TYPE gives
5884 the type of the function and CDTORS points to the list of constructor
5885 or destructor functions to be invoked. FIXME: Migrate into cgraph. */
5887 static void
5888 build_global_cdtor (int method_type, tree *cdtors)
5890 tree body = 0;
5892 for (; *cdtors; *cdtors = TREE_CHAIN (*cdtors))
5894 tree fn = TREE_VALUE (*cdtors);
5895 tree fntype = TREE_TYPE (fn);
5896 tree fnaddr = build1 (ADDR_EXPR, build_pointer_type (fntype), fn);
5897 tree fncall = build3 (CALL_EXPR, TREE_TYPE (fntype), fnaddr, NULL_TREE,
5898 NULL_TREE);
5899 append_to_statement_list (fncall, &body);
5902 cgraph_build_static_cdtor (method_type, body, DEFAULT_INIT_PRIORITY);
5905 extern char *__gnat_to_canonical_file_spec (char *);
5907 /* Convert Sloc into *LOCUS (a location_t). Return true if this Sloc
5908 corresponds to a source code location and false if it doesn't. In the
5909 latter case, we don't update *LOCUS. We also set the Gigi global variable
5910 REF_FILENAME to the reference file name as given by sinput (i.e no
5911 directory). */
5913 bool
5914 Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
5916 /* If node not from source code, ignore. */
5917 if (Sloc < 0)
5918 return false;
5920 /* Use the identifier table to make a hashed, permanent copy of the filename,
5921 since the name table gets reallocated after Gigi returns but before all
5922 the debugging information is output. The __gnat_to_canonical_file_spec
5923 call translates filenames from pragmas Source_Reference that contain host
5924 style syntax not understood by gdb. */
5925 locus->file
5926 = IDENTIFIER_POINTER
5927 (get_identifier
5928 (__gnat_to_canonical_file_spec
5929 (Get_Name_String (Full_Debug_Name (Get_Source_File_Index (Sloc))))));
5931 locus->line = Get_Logical_Line_Number (Sloc);
5933 ref_filename
5934 = IDENTIFIER_POINTER
5935 (get_identifier
5936 (Get_Name_String (Debug_Source_Name (Get_Source_File_Index (Sloc)))));;
5938 return true;
5941 /* Similar to annotate_with_locus, but start with the Sloc of GNAT_NODE and
5942 don't do anything if it doesn't correspond to a source location. */
5944 static void
5945 annotate_with_node (tree node, Node_Id gnat_node)
5947 location_t locus;
5949 if (!Sloc_to_locus (Sloc (gnat_node), &locus))
5950 return;
5952 annotate_with_locus (node, locus);
5955 /* Post an error message. MSG is the error message, properly annotated.
5956 NODE is the node at which to post the error and the node to use for the
5957 "&" substitution. */
5959 void
5960 post_error (const char *msg, Node_Id node)
5962 String_Template temp;
5963 Fat_Pointer fp;
5965 temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
5966 fp.Array = msg, fp.Bounds = &temp;
5967 if (Present (node))
5968 Error_Msg_N (fp, node);
5971 /* Similar, but NODE is the node at which to post the error and ENT
5972 is the node to use for the "&" substitution. */
5974 void
5975 post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
5977 String_Template temp;
5978 Fat_Pointer fp;
5980 temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
5981 fp.Array = msg, fp.Bounds = &temp;
5982 if (Present (node))
5983 Error_Msg_NE (fp, node, ent);
5986 /* Similar, but NODE is the node at which to post the error, ENT is the node
5987 to use for the "&" substitution, and N is the number to use for the ^. */
5989 void
5990 post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int n)
5992 String_Template temp;
5993 Fat_Pointer fp;
5995 temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
5996 fp.Array = msg, fp.Bounds = &temp;
5997 Error_Msg_Uint_1 = UI_From_Int (n);
5999 if (Present (node))
6000 Error_Msg_NE (fp, node, ent);
6003 /* Similar to post_error_ne_num, but T is a GCC tree representing the
6004 number to write. If the tree represents a constant that fits within
6005 a host integer, the text inside curly brackets in MSG will be output
6006 (presumably including a '^'). Otherwise that text will not be output
6007 and the text inside square brackets will be output instead. */
6009 void
6010 post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
6012 char *newmsg = alloca (strlen (msg) + 1);
6013 String_Template temp = {1, 0};
6014 Fat_Pointer fp;
6015 char start_yes, end_yes, start_no, end_no;
6016 const char *p;
6017 char *q;
6019 fp.Array = newmsg, fp.Bounds = &temp;
6021 if (host_integerp (t, 1)
6022 #if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_INT
6024 compare_tree_int
6025 (t, (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_INT - 1)) - 1)) < 0
6026 #endif
6029 Error_Msg_Uint_1 = UI_From_Int (tree_low_cst (t, 1));
6030 start_yes = '{', end_yes = '}', start_no = '[', end_no = ']';
6032 else
6033 start_yes = '[', end_yes = ']', start_no = '{', end_no = '}';
6035 for (p = msg, q = newmsg; *p; p++)
6037 if (*p == start_yes)
6038 for (p++; *p != end_yes; p++)
6039 *q++ = *p;
6040 else if (*p == start_no)
6041 for (p++; *p != end_no; p++)
6043 else
6044 *q++ = *p;
6047 *q = 0;
6049 temp.High_Bound = strlen (newmsg);
6050 if (Present (node))
6051 Error_Msg_NE (fp, node, ent);
6054 /* Similar to post_error_ne_tree, except that NUM is a second
6055 integer to write in the message. */
6057 void
6058 post_error_ne_tree_2 (const char *msg,
6059 Node_Id node,
6060 Entity_Id ent,
6061 tree t,
6062 int num)
6064 Error_Msg_Uint_2 = UI_From_Int (num);
6065 post_error_ne_tree (msg, node, ent, t);
6068 /* Initialize the table that maps GNAT codes to GCC codes for simple
6069 binary and unary operations. */
6071 void
6072 init_code_table (void)
6074 gnu_codes[N_And_Then] = TRUTH_ANDIF_EXPR;
6075 gnu_codes[N_Or_Else] = TRUTH_ORIF_EXPR;
6077 gnu_codes[N_Op_And] = TRUTH_AND_EXPR;
6078 gnu_codes[N_Op_Or] = TRUTH_OR_EXPR;
6079 gnu_codes[N_Op_Xor] = TRUTH_XOR_EXPR;
6080 gnu_codes[N_Op_Eq] = EQ_EXPR;
6081 gnu_codes[N_Op_Ne] = NE_EXPR;
6082 gnu_codes[N_Op_Lt] = LT_EXPR;
6083 gnu_codes[N_Op_Le] = LE_EXPR;
6084 gnu_codes[N_Op_Gt] = GT_EXPR;
6085 gnu_codes[N_Op_Ge] = GE_EXPR;
6086 gnu_codes[N_Op_Add] = PLUS_EXPR;
6087 gnu_codes[N_Op_Subtract] = MINUS_EXPR;
6088 gnu_codes[N_Op_Multiply] = MULT_EXPR;
6089 gnu_codes[N_Op_Mod] = FLOOR_MOD_EXPR;
6090 gnu_codes[N_Op_Rem] = TRUNC_MOD_EXPR;
6091 gnu_codes[N_Op_Minus] = NEGATE_EXPR;
6092 gnu_codes[N_Op_Abs] = ABS_EXPR;
6093 gnu_codes[N_Op_Not] = TRUTH_NOT_EXPR;
6094 gnu_codes[N_Op_Rotate_Left] = LROTATE_EXPR;
6095 gnu_codes[N_Op_Rotate_Right] = RROTATE_EXPR;
6096 gnu_codes[N_Op_Shift_Left] = LSHIFT_EXPR;
6097 gnu_codes[N_Op_Shift_Right] = RSHIFT_EXPR;
6098 gnu_codes[N_Op_Shift_Right_Arithmetic] = RSHIFT_EXPR;
6101 #include "gt-ada-trans.h"