1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 1992-2007, Free Software Foundation, Inc. *
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. *
22 * GNAT was originally developed by the GNAT team at New York University. *
23 * Extensive contributions were provided by Ada Core Technologies Inc. *
25 ****************************************************************************/
29 #include "coretypes.h"
43 #include "tree-gimple.h"
60 /* We should avoid allocating more than ALLOCA_THRESHOLD bytes via alloca,
61 for fear of running out of stack space. If we need more, we use xmalloc
63 #define ALLOCA_THRESHOLD 1000
65 /* Let code below know whether we are targetting VMS without need of
66 intrusive preprocessor directives. */
67 #ifndef TARGET_ABI_OPEN_VMS
68 #define TARGET_ABI_OPEN_VMS 0
71 extern char *__gnat_to_canonical_file_spec (char *);
76 struct Node
*Nodes_Ptr
;
77 Node_Id
*Next_Node_Ptr
;
78 Node_Id
*Prev_Node_Ptr
;
79 struct Elist_Header
*Elists_Ptr
;
80 struct Elmt_Item
*Elmts_Ptr
;
81 struct String_Entry
*Strings_Ptr
;
82 Char_Code
*String_Chars_Ptr
;
83 struct List_Header
*List_Headers_Ptr
;
85 /* Current filename without path. */
86 const char *ref_filename
;
88 /* If true, then gigi is being called on an analyzed but unexpanded
89 tree, and the only purpose of the call is to properly annotate
90 types with representation information. */
91 bool type_annotate_only
;
93 /* When not optimizing, we cache the 'First, 'Last and 'Length attributes
94 of unconstrained array IN parameters to avoid emitting a great deal of
95 redundant instructions to recompute them each time. */
96 struct parm_attr
GTY (())
98 int id
; /* GTY doesn't like Entity_Id. */
105 typedef struct parm_attr
*parm_attr
;
107 DEF_VEC_P(parm_attr
);
108 DEF_VEC_ALLOC_P(parm_attr
,gc
);
110 struct language_function
GTY(())
112 VEC(parm_attr
,gc
) *parm_attr_cache
;
115 #define f_parm_attr_cache \
116 DECL_STRUCT_FUNCTION (current_function_decl)->language->parm_attr_cache
118 /* A structure used to gather together information about a statement group.
119 We use this to gather related statements, for example the "then" part
120 of a IF. In the case where it represents a lexical scope, we may also
121 have a BLOCK node corresponding to it and/or cleanups. */
123 struct stmt_group
GTY((chain_next ("%h.previous"))) {
124 struct stmt_group
*previous
; /* Previous code group. */
125 tree stmt_list
; /* List of statements for this code group. */
126 tree block
; /* BLOCK for this code group, if any. */
127 tree cleanups
; /* Cleanups for this code group, if any. */
130 static GTY(()) struct stmt_group
*current_stmt_group
;
132 /* List of unused struct stmt_group nodes. */
133 static GTY((deletable
)) struct stmt_group
*stmt_group_free_list
;
135 /* A structure used to record information on elaboration procedures
136 we've made and need to process.
138 ??? gnat_node should be Node_Id, but gengtype gets confused. */
140 struct elab_info
GTY((chain_next ("%h.next"))) {
141 struct elab_info
*next
; /* Pointer to next in chain. */
142 tree elab_proc
; /* Elaboration procedure. */
143 int gnat_node
; /* The N_Compilation_Unit. */
146 static GTY(()) struct elab_info
*elab_info_list
;
148 /* Free list of TREE_LIST nodes used for stacks. */
149 static GTY((deletable
)) tree gnu_stack_free_list
;
151 /* List of TREE_LIST nodes representing a stack of exception pointer
152 variables. TREE_VALUE is the VAR_DECL that stores the address of
153 the raised exception. Nonzero means we are in an exception
154 handler. Not used in the zero-cost case. */
155 static GTY(()) tree gnu_except_ptr_stack
;
157 /* List of TREE_LIST nodes used to store the current elaboration procedure
158 decl. TREE_VALUE is the decl. */
159 static GTY(()) tree gnu_elab_proc_stack
;
161 /* Variable that stores a list of labels to be used as a goto target instead of
162 a return in some functions. See processing for N_Subprogram_Body. */
163 static GTY(()) tree gnu_return_label_stack
;
165 /* List of TREE_LIST nodes representing a stack of LOOP_STMT nodes.
166 TREE_VALUE of each entry is the label of the corresponding LOOP_STMT. */
167 static GTY(()) tree gnu_loop_label_stack
;
169 /* List of TREE_LIST nodes representing labels for switch statements.
170 TREE_VALUE of each entry is the label at the end of the switch. */
171 static GTY(()) tree gnu_switch_label_stack
;
173 /* List of TREE_LIST nodes containing the stacks for N_{Push,Pop}_*_Label. */
174 static GTY(()) tree gnu_constraint_error_label_stack
;
175 static GTY(()) tree gnu_storage_error_label_stack
;
176 static GTY(()) tree gnu_program_error_label_stack
;
178 /* Map GNAT tree codes to GCC tree codes for simple expressions. */
179 static enum tree_code gnu_codes
[Number_Node_Kinds
];
181 /* Current node being treated, in case abort called. */
182 Node_Id error_gnat_node
;
184 static void Compilation_Unit_to_gnu (Node_Id
);
185 static void record_code_position (Node_Id
);
186 static void insert_code_for (Node_Id
);
187 static void add_cleanup (tree
, Node_Id
);
188 static tree
mark_visited (tree
*, int *, void *);
189 static tree
unshare_save_expr (tree
*, int *, void *);
190 static void add_stmt_list (List_Id
);
191 static void push_exception_label_stack (tree
*, Entity_Id
);
192 static tree
build_stmt_group (List_Id
, bool);
193 static void push_stack (tree
*, tree
, tree
);
194 static void pop_stack (tree
*);
195 static enum gimplify_status
gnat_gimplify_stmt (tree
*);
196 static void elaborate_all_entities (Node_Id
);
197 static void process_freeze_entity (Node_Id
);
198 static void process_inlined_subprograms (Node_Id
);
199 static void process_decls (List_Id
, List_Id
, Node_Id
, bool, bool);
200 static tree
emit_range_check (tree
, Node_Id
);
201 static tree
emit_index_check (tree
, tree
, tree
, tree
);
202 static tree
emit_check (tree
, tree
, int);
203 static tree
convert_with_check (Entity_Id
, tree
, bool, bool, bool);
204 static bool addressable_p (tree
);
205 static tree
assoc_to_constructor (Entity_Id
, Node_Id
, tree
);
206 static tree
extract_values (tree
, tree
);
207 static tree
pos_to_constructor (Node_Id
, tree
, Entity_Id
);
208 static tree
maybe_implicit_deref (tree
);
209 static tree
gnat_stabilize_reference (tree
, bool);
210 static tree
gnat_stabilize_reference_1 (tree
, bool);
211 static void set_expr_location_from_node (tree
, Node_Id
);
212 static int lvalue_required_p (Node_Id
, tree
, int);
214 /* This is the main program of the back-end. It sets up all the table
215 structures and then generates code. */
218 gigi (Node_Id gnat_root
, int max_gnat_node
, int number_name
,
219 struct Node
*nodes_ptr
, Node_Id
*next_node_ptr
, Node_Id
*prev_node_ptr
,
220 struct Elist_Header
*elists_ptr
, struct Elmt_Item
*elmts_ptr
,
221 struct String_Entry
*strings_ptr
, Char_Code
*string_chars_ptr
,
222 struct List_Header
*list_headers_ptr
, Nat number_file
,
223 struct File_Info_Type
*file_info_ptr ATTRIBUTE_UNUSED
,
224 Entity_Id standard_integer
, Entity_Id standard_long_long_float
,
225 Entity_Id standard_exception_type
, Int gigi_operating_mode
)
227 tree gnu_standard_long_long_float
;
228 tree gnu_standard_exception_type
;
229 struct elab_info
*info
;
230 int i ATTRIBUTE_UNUSED
;
232 max_gnat_nodes
= max_gnat_node
;
233 number_names
= number_name
;
234 number_files
= number_file
;
235 Nodes_Ptr
= nodes_ptr
;
236 Next_Node_Ptr
= next_node_ptr
;
237 Prev_Node_Ptr
= prev_node_ptr
;
238 Elists_Ptr
= elists_ptr
;
239 Elmts_Ptr
= elmts_ptr
;
240 Strings_Ptr
= strings_ptr
;
241 String_Chars_Ptr
= string_chars_ptr
;
242 List_Headers_Ptr
= list_headers_ptr
;
244 type_annotate_only
= (gigi_operating_mode
== 1);
246 #ifdef USE_MAPPED_LOCATION
247 for (i
= 0; i
< number_files
; i
++)
249 /* Use the identifier table to make a permanent copy of the filename as
250 the name table gets reallocated after Gigi returns but before all the
251 debugging information is output. The __gnat_to_canonical_file_spec
252 call translates filenames from pragmas Source_Reference that contain
253 host style syntax not understood by gdb. */
257 (__gnat_to_canonical_file_spec
258 (Get_Name_String (file_info_ptr
[i
].File_Name
))));
260 /* We rely on the order isomorphism between files and line maps. */
261 gcc_assert ((int) line_table
->used
== i
);
263 /* We create the line map for a source file at once, with a fixed number
264 of columns chosen to avoid jumping over the next power of 2. */
265 linemap_add (line_table
, LC_ENTER
, 0, filename
, 1);
266 linemap_line_start (line_table
, file_info_ptr
[i
].Num_Source_Lines
, 252);
267 linemap_position_for_column (line_table
, 252 - 1);
268 linemap_add (line_table
, LC_LEAVE
, 0, NULL
, 0);
273 gnat_compute_largest_alignment ();
276 /* If we are just annotating types, give VOID_TYPE zero sizes to avoid
278 if (type_annotate_only
)
280 TYPE_SIZE (void_type_node
) = bitsize_zero_node
;
281 TYPE_SIZE_UNIT (void_type_node
) = size_zero_node
;
284 /* Save the type we made for integer as the type for Standard.Integer.
285 Then make the rest of the standard types. Note that some of these
287 save_gnu_tree (Base_Type (standard_integer
), TYPE_NAME (integer_type_node
),
290 gnu_except_ptr_stack
= tree_cons (NULL_TREE
, NULL_TREE
, NULL_TREE
);
291 gnu_constraint_error_label_stack
292 = tree_cons (NULL_TREE
, NULL_TREE
, NULL_TREE
);
293 gnu_storage_error_label_stack
= tree_cons (NULL_TREE
, NULL_TREE
, NULL_TREE
);
294 gnu_program_error_label_stack
= tree_cons (NULL_TREE
, NULL_TREE
, NULL_TREE
);
296 gnu_standard_long_long_float
297 = gnat_to_gnu_entity (Base_Type (standard_long_long_float
), NULL_TREE
, 0);
298 gnu_standard_exception_type
299 = gnat_to_gnu_entity (Base_Type (standard_exception_type
), NULL_TREE
, 0);
301 init_gigi_decls (gnu_standard_long_long_float
, gnu_standard_exception_type
);
303 /* Process any Pragma Ident for the main unit. */
304 #ifdef ASM_OUTPUT_IDENT
305 if (Present (Ident_String (Main_Unit
)))
308 TREE_STRING_POINTER (gnat_to_gnu (Ident_String (Main_Unit
))));
311 /* If we are using the GCC exception mechanism, let GCC know. */
312 if (Exception_Mechanism
== Back_End_Exceptions
)
315 gcc_assert (Nkind (gnat_root
) == N_Compilation_Unit
);
316 Compilation_Unit_to_gnu (gnat_root
);
318 /* Now see if we have any elaboration procedures to deal with. */
319 for (info
= elab_info_list
; info
; info
= info
->next
)
321 tree gnu_body
= DECL_SAVED_TREE (info
->elab_proc
);
324 /* Unshare SAVE_EXPRs between subprograms. These are not unshared by
325 the gimplifier for obvious reasons, but it turns out that we need to
326 unshare them for the global level because of SAVE_EXPRs made around
327 checks for global objects and around allocators for global objects
328 of variable size, in order to prevent node sharing in the underlying
329 expression. Note that this implicitly assumes that the SAVE_EXPR
330 nodes themselves are not shared between subprograms, which would be
331 an upstream bug for which we would not change the outcome. */
332 walk_tree_without_duplicates (&gnu_body
, unshare_save_expr
, NULL
);
334 /* Set the current function to be the elaboration procedure and gimplify
336 current_function_decl
= info
->elab_proc
;
337 gimplify_body (&gnu_body
, info
->elab_proc
, true);
339 /* We should have a BIND_EXPR, but it may or may not have any statements
340 in it. If it doesn't have any, we have nothing to do. */
341 gnu_stmts
= gnu_body
;
342 if (TREE_CODE (gnu_stmts
) == BIND_EXPR
)
343 gnu_stmts
= BIND_EXPR_BODY (gnu_stmts
);
345 /* If there are no statements, there is no elaboration code. */
346 if (!gnu_stmts
|| !STATEMENT_LIST_HEAD (gnu_stmts
))
348 Set_Has_No_Elaboration_Code (info
->gnat_node
, 1);
349 cgraph_remove_node (cgraph_node (info
->elab_proc
));
353 /* Otherwise, compile the function. Note that we'll be gimplifying
354 it twice, but that's fine for the nodes we use. */
355 begin_subprog_body (info
->elab_proc
);
356 end_subprog_body (gnu_body
);
360 /* We cannot track the location of errors past this point. */
361 error_gnat_node
= Empty
;
364 /* Perform initializations for this module. */
367 gnat_init_stmt_group (void)
369 /* Initialize ourselves. */
373 /* Enable GNAT stack checking method if needed */
374 if (!Stack_Check_Probes_On_Target
)
375 set_stack_check_libfunc (gen_rtx_SYMBOL_REF (Pmode
, "_gnat_stack_check"));
378 /* Returns a positive value if GNAT_NODE requires an lvalue for an
379 operand of OPERAND_TYPE, whose aliasing is specified by ALIASED,
380 zero otherwise. This is int instead of bool to facilitate usage
381 in non purely binary logic contexts. */
384 lvalue_required_p (Node_Id gnat_node
, tree operand_type
, int aliased
)
386 switch (Nkind (gnat_node
))
391 case N_Attribute_Reference
:
393 unsigned char id
= Get_Attribute_Id (Attribute_Name (gnat_node
));
394 return id
== Attr_Address
396 || id
== Attr_Unchecked_Access
397 || id
== Attr_Unrestricted_Access
;
400 case N_Parameter_Association
:
401 case N_Function_Call
:
402 case N_Procedure_Call_Statement
:
403 return must_pass_by_ref (operand_type
)
404 || default_pass_by_ref (operand_type
);
406 case N_Indexed_Component
:
409 /* ??? Consider that referencing an indexed component with a
410 non-constant index forces the whole aggregate to memory.
411 Note that N_Integer_Literal is conservative, any static
412 expression in the RM sense could probably be accepted. */
413 for (gnat_temp
= First (Expressions (gnat_node
));
415 gnat_temp
= Next (gnat_temp
))
416 if (Nkind (gnat_temp
) != N_Integer_Literal
)
420 /* ... fall through ... */
423 aliased
|= Has_Aliased_Components (Etype (Prefix (gnat_node
)));
424 return lvalue_required_p (Parent (gnat_node
), operand_type
, aliased
);
426 case N_Selected_Component
:
427 aliased
|= Is_Aliased (Entity (Selector_Name (gnat_node
)));
428 return lvalue_required_p (Parent (gnat_node
), operand_type
, aliased
);
430 case N_Object_Renaming_Declaration
:
431 /* We need to make a real renaming only if the constant object is
432 aliased or if we may use a renaming pointer; otherwise we can
433 optimize and return the rvalue. We make an exception if the object
434 is an identifier since in this case the rvalue can be propagated
435 attached to the CONST_DECL. */
437 /* This should match the constant case of the renaming code. */
438 || Is_Composite_Type (Etype (Name (gnat_node
)))
439 || Nkind (Name (gnat_node
)) == N_Identifier
);
448 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Identifier,
449 to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer to
450 where we should place the result type. */
453 Identifier_to_gnu (Node_Id gnat_node
, tree
*gnu_result_type_p
)
455 tree gnu_result_type
;
457 Node_Id gnat_temp
, gnat_temp_type
;
459 /* Whether the parent of gnat_node requires an lvalue. Needed in
460 specific circumstances only, so evaluated lazily. < 0 means unknown,
461 > 0 means known true, 0 means known false. */
462 int parent_requires_lvalue
= -1;
464 /* If GNAT_NODE is a constant, whether we should use the initialization
465 value instead of the constant entity, typically for scalars with an
466 address clause when the parent doesn't require an lvalue. */
467 bool use_constant_initializer
= false;
469 /* If the Etype of this node does not equal the Etype of the Entity,
470 something is wrong with the entity map, probably in generic
471 instantiation. However, this does not apply to types. Since we sometime
472 have strange Ekind's, just do this test for objects. Also, if the Etype of
473 the Entity is private, the Etype of the N_Identifier is allowed to be the
474 full type and also we consider a packed array type to be the same as the
475 original type. Similarly, a class-wide type is equivalent to a subtype of
476 itself. Finally, if the types are Itypes, one may be a copy of the other,
477 which is also legal. */
478 gnat_temp
= (Nkind (gnat_node
) == N_Defining_Identifier
479 ? gnat_node
: Entity (gnat_node
));
480 gnat_temp_type
= Etype (gnat_temp
);
482 gcc_assert (Etype (gnat_node
) == gnat_temp_type
483 || (Is_Packed (gnat_temp_type
)
484 && Etype (gnat_node
) == Packed_Array_Type (gnat_temp_type
))
485 || (Is_Class_Wide_Type (Etype (gnat_node
)))
486 || (IN (Ekind (gnat_temp_type
), Private_Kind
)
487 && Present (Full_View (gnat_temp_type
))
488 && ((Etype (gnat_node
) == Full_View (gnat_temp_type
))
489 || (Is_Packed (Full_View (gnat_temp_type
))
490 && (Etype (gnat_node
)
491 == Packed_Array_Type (Full_View
492 (gnat_temp_type
))))))
493 || (Is_Itype (Etype (gnat_node
)) && Is_Itype (gnat_temp_type
))
494 || !(Ekind (gnat_temp
) == E_Variable
495 || Ekind (gnat_temp
) == E_Component
496 || Ekind (gnat_temp
) == E_Constant
497 || Ekind (gnat_temp
) == E_Loop_Parameter
498 || IN (Ekind (gnat_temp
), Formal_Kind
)));
500 /* If this is a reference to a deferred constant whose partial view is an
501 unconstrained private type, the proper type is on the full view of the
502 constant, not on the full view of the type, which may be unconstrained.
504 This may be a reference to a type, for example in the prefix of the
505 attribute Position, generated for dispatching code (see Make_DT in
506 exp_disp,adb). In that case we need the type itself, not is parent,
507 in particular if it is a derived type */
508 if (Is_Private_Type (gnat_temp_type
)
509 && Has_Unknown_Discriminants (gnat_temp_type
)
510 && Ekind (gnat_temp
) == E_Constant
511 && Present (Full_View (gnat_temp
)))
513 gnat_temp
= Full_View (gnat_temp
);
514 gnat_temp_type
= Etype (gnat_temp
);
518 /* We want to use the Actual_Subtype if it has already been elaborated,
519 otherwise the Etype. Avoid using Actual_Subtype for packed arrays to
521 if ((Ekind (gnat_temp
) == E_Constant
522 || Ekind (gnat_temp
) == E_Variable
|| Is_Formal (gnat_temp
))
523 && !(Is_Array_Type (Etype (gnat_temp
))
524 && Present (Packed_Array_Type (Etype (gnat_temp
))))
525 && Present (Actual_Subtype (gnat_temp
))
526 && present_gnu_tree (Actual_Subtype (gnat_temp
)))
527 gnat_temp_type
= Actual_Subtype (gnat_temp
);
529 gnat_temp_type
= Etype (gnat_node
);
532 /* Expand the type of this identifier first, in case it is an enumeral
533 literal, which only get made when the type is expanded. There is no
534 order-of-elaboration issue here. */
535 gnu_result_type
= get_unpadded_type (gnat_temp_type
);
537 /* If this is a non-imported scalar constant with an address clause,
538 retrieve the value instead of a pointer to be dereferenced unless the
539 parent requires an lvalue. This is generally more efficient and
540 actually required if this is a static expression because it might be used
541 in a context where a dereference is inappropriate, such as a case
542 statement alternative or a record discriminant. There is no possible
543 volatile-ness shortciruit here since Volatile constants must be imported
545 if (Ekind (gnat_temp
) == E_Constant
&& Is_Scalar_Type (gnat_temp_type
)
546 && !Is_Imported (gnat_temp
)
547 && Present (Address_Clause (gnat_temp
)))
549 parent_requires_lvalue
550 = lvalue_required_p (Parent (gnat_node
), gnu_result_type
,
551 Is_Aliased (gnat_temp
));
552 use_constant_initializer
= !parent_requires_lvalue
;
555 if (use_constant_initializer
)
557 /* If this is a deferred constant, the initializer is attached to the
559 if (Present (Full_View (gnat_temp
)))
560 gnat_temp
= Full_View (gnat_temp
);
562 gnu_result
= gnat_to_gnu (Expression (Declaration_Node (gnat_temp
)));
565 gnu_result
= gnat_to_gnu_entity (gnat_temp
, NULL_TREE
, 0);
567 /* If we are in an exception handler, force this variable into memory to
568 ensure optimization does not remove stores that appear redundant but are
569 actually needed in case an exception occurs.
571 ??? Note that we need not do this if the variable is declared within the
572 handler, only if it is referenced in the handler and declared in an
573 enclosing block, but we have no way of testing that right now.
575 ??? We used to essentially set the TREE_ADDRESSABLE flag on the variable
576 here, but it can now be removed by the Tree aliasing machinery if the
577 address of the variable is never taken. All we can do is to make the
578 variable volatile, which might incur the generation of temporaries just
579 to access the memory in some circumstances. This can be avoided for
580 variables of non-constant size because they are automatically allocated
581 to memory. There might be no way of allocating a proper temporary for
582 them in any case. We only do this for SJLJ though. */
583 if (TREE_VALUE (gnu_except_ptr_stack
)
584 && TREE_CODE (gnu_result
) == VAR_DECL
585 && TREE_CODE (DECL_SIZE_UNIT (gnu_result
)) == INTEGER_CST
)
586 TREE_THIS_VOLATILE (gnu_result
) = TREE_SIDE_EFFECTS (gnu_result
) = 1;
588 /* Some objects (such as parameters passed by reference, globals of
589 variable size, and renamed objects) actually represent the address
590 of the object. In that case, we must do the dereference. Likewise,
591 deal with parameters to foreign convention subprograms. */
592 if (DECL_P (gnu_result
)
593 && (DECL_BY_REF_P (gnu_result
)
594 || (TREE_CODE (gnu_result
) == PARM_DECL
595 && DECL_BY_COMPONENT_PTR_P (gnu_result
))))
597 bool ro
= DECL_POINTS_TO_READONLY_P (gnu_result
);
600 if (TREE_CODE (gnu_result
) == PARM_DECL
601 && DECL_BY_COMPONENT_PTR_P (gnu_result
))
603 = build_unary_op (INDIRECT_REF
, NULL_TREE
,
604 convert (build_pointer_type (gnu_result_type
),
607 /* If it's a renaming pointer and we are at the right binding level,
608 we can reference the renamed object directly, since the renamed
609 expression has been protected against multiple evaluations. */
610 else if (TREE_CODE (gnu_result
) == VAR_DECL
611 && (renamed_obj
= DECL_RENAMED_OBJECT (gnu_result
)) != 0
612 && (! DECL_RENAMING_GLOBAL_P (gnu_result
)
613 || global_bindings_p ()))
614 gnu_result
= renamed_obj
;
616 /* Return the underlying CST for a CONST_DECL like a few lines below,
617 after dereferencing in this case. */
618 else if (TREE_CODE (gnu_result
) == CONST_DECL
)
619 gnu_result
= build_unary_op (INDIRECT_REF
, NULL_TREE
,
620 DECL_INITIAL (gnu_result
));
623 gnu_result
= build_unary_op (INDIRECT_REF
, NULL_TREE
, gnu_result
);
625 TREE_READONLY (gnu_result
) = TREE_STATIC (gnu_result
) = ro
;
628 /* The GNAT tree has the type of a function as the type of its result. Also
629 use the type of the result if the Etype is a subtype which is nominally
630 unconstrained. But remove any padding from the resulting type. */
631 if (TREE_CODE (TREE_TYPE (gnu_result
)) == FUNCTION_TYPE
632 || Is_Constr_Subt_For_UN_Aliased (gnat_temp_type
))
634 gnu_result_type
= TREE_TYPE (gnu_result
);
635 if (TREE_CODE (gnu_result_type
) == RECORD_TYPE
636 && TYPE_IS_PADDING_P (gnu_result_type
))
637 gnu_result_type
= TREE_TYPE (TYPE_FIELDS (gnu_result_type
));
640 /* If we have a constant declaration and its initializer at hand,
641 try to return the latter to avoid the need to call fold in lots
642 of places and the need of elaboration code if this Id is used as
643 an initializer itself. */
644 if (TREE_CONSTANT (gnu_result
)
645 && DECL_P (gnu_result
) && DECL_INITIAL (gnu_result
))
648 = (TREE_CODE (gnu_result
) == CONST_DECL
649 ? DECL_CONST_CORRESPONDING_VAR (gnu_result
) : gnu_result
);
651 /* If there is a corresponding variable, we only want to return the CST
652 value if the parent doesn't require an lvalue. Evaluate this now if
653 we have not already done so. */
654 if (object
&& parent_requires_lvalue
< 0)
655 parent_requires_lvalue
656 = lvalue_required_p (Parent (gnat_node
), gnu_result_type
,
657 Is_Aliased (gnat_temp
));
659 if (!object
|| !parent_requires_lvalue
)
660 gnu_result
= unshare_expr (DECL_INITIAL (gnu_result
));
663 *gnu_result_type_p
= gnu_result_type
;
667 /* Subroutine of gnat_to_gnu to process gnat_node, an N_Pragma. Return
668 any statements we generate. */
671 Pragma_to_gnu (Node_Id gnat_node
)
674 tree gnu_result
= alloc_stmt_list ();
676 /* Check for (and ignore) unrecognized pragma and do nothing if we are just
678 if (type_annotate_only
|| !Is_Pragma_Name (Chars (gnat_node
)))
681 switch (Get_Pragma_Id (Chars (gnat_node
)))
683 case Pragma_Inspection_Point
:
684 /* Do nothing at top level: all such variables are already viewable. */
685 if (global_bindings_p ())
688 for (gnat_temp
= First (Pragma_Argument_Associations (gnat_node
));
690 gnat_temp
= Next (gnat_temp
))
692 Node_Id gnat_expr
= Expression (gnat_temp
);
693 tree gnu_expr
= gnat_to_gnu (gnat_expr
);
695 enum machine_mode mode
;
696 tree asm_constraint
= NULL_TREE
;
697 #ifdef ASM_COMMENT_START
701 if (TREE_CODE (gnu_expr
) == UNCONSTRAINED_ARRAY_REF
)
702 gnu_expr
= TREE_OPERAND (gnu_expr
, 0);
704 /* Use the value only if it fits into a normal register,
705 otherwise use the address. */
706 mode
= TYPE_MODE (TREE_TYPE (gnu_expr
));
707 use_address
= ((GET_MODE_CLASS (mode
) != MODE_INT
708 && GET_MODE_CLASS (mode
) != MODE_PARTIAL_INT
)
709 || GET_MODE_SIZE (mode
) > UNITS_PER_WORD
);
712 gnu_expr
= build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_expr
);
714 #ifdef ASM_COMMENT_START
715 comment
= concat (ASM_COMMENT_START
,
716 " inspection point: ",
717 Get_Name_String (Chars (gnat_expr
)),
718 use_address
? " address" : "",
721 asm_constraint
= build_string (strlen (comment
), comment
);
724 gnu_expr
= build4 (ASM_EXPR
, void_type_node
,
728 (build_tree_list (NULL_TREE
,
729 build_string (1, "g")),
730 gnu_expr
, NULL_TREE
),
732 ASM_VOLATILE_P (gnu_expr
) = 1;
733 set_expr_location_from_node (gnu_expr
, gnat_node
);
734 append_to_statement_list (gnu_expr
, &gnu_result
);
738 case Pragma_Optimize
:
739 switch (Chars (Expression
740 (First (Pragma_Argument_Associations (gnat_node
)))))
742 case Name_Time
: case Name_Space
:
744 post_error ("insufficient -O value?", gnat_node
);
749 post_error ("must specify -O0?", gnat_node
);
757 case Pragma_Reviewable
:
758 if (write_symbols
== NO_DEBUG
)
759 post_error ("must specify -g?", gnat_node
);
765 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Attribute,
766 to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer to
767 where we should place the result type. ATTRIBUTE is the attribute ID. */
770 Attribute_to_gnu (Node_Id gnat_node
, tree
*gnu_result_type_p
, int attribute
)
772 tree gnu_result
= error_mark_node
;
773 tree gnu_result_type
;
775 bool prefix_unused
= false;
776 tree gnu_prefix
= gnat_to_gnu (Prefix (gnat_node
));
777 tree gnu_type
= TREE_TYPE (gnu_prefix
);
779 /* If the input is a NULL_EXPR, make a new one. */
780 if (TREE_CODE (gnu_prefix
) == NULL_EXPR
)
782 *gnu_result_type_p
= get_unpadded_type (Etype (gnat_node
));
783 return build1 (NULL_EXPR
, *gnu_result_type_p
,
784 TREE_OPERAND (gnu_prefix
, 0));
791 /* These are just conversions until since representation clauses for
792 enumerations are handled in the front end. */
794 bool checkp
= Do_Range_Check (First (Expressions (gnat_node
)));
796 gnu_result
= gnat_to_gnu (First (Expressions (gnat_node
)));
797 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
798 gnu_result
= convert_with_check (Etype (gnat_node
), gnu_result
,
799 checkp
, checkp
, true);
805 /* These just add or subject the constant 1. Representation clauses for
806 enumerations are handled in the front-end. */
807 gnu_expr
= gnat_to_gnu (First (Expressions (gnat_node
)));
808 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
810 if (Do_Range_Check (First (Expressions (gnat_node
))))
812 gnu_expr
= protect_multiple_eval (gnu_expr
);
815 (build_binary_op (EQ_EXPR
, integer_type_node
,
817 attribute
== Attr_Pred
818 ? TYPE_MIN_VALUE (gnu_result_type
)
819 : TYPE_MAX_VALUE (gnu_result_type
)),
820 gnu_expr
, CE_Range_Check_Failed
);
824 = build_binary_op (attribute
== Attr_Pred
825 ? MINUS_EXPR
: PLUS_EXPR
,
826 gnu_result_type
, gnu_expr
,
827 convert (gnu_result_type
, integer_one_node
));
831 case Attr_Unrestricted_Access
:
832 /* Conversions don't change something's address but can cause us to miss
833 the COMPONENT_REF case below, so strip them off. */
834 gnu_prefix
= remove_conversions (gnu_prefix
,
835 !Must_Be_Byte_Aligned (gnat_node
));
837 /* If we are taking 'Address of an unconstrained object, this is the
838 pointer to the underlying array. */
839 if (attribute
== Attr_Address
)
840 gnu_prefix
= maybe_unconstrained_array (gnu_prefix
);
842 /* ... fall through ... */
845 case Attr_Unchecked_Access
:
846 case Attr_Code_Address
:
847 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
849 = build_unary_op (((attribute
== Attr_Address
850 || attribute
== Attr_Unrestricted_Access
)
851 && !Must_Be_Byte_Aligned (gnat_node
))
852 ? ATTR_ADDR_EXPR
: ADDR_EXPR
,
853 gnu_result_type
, gnu_prefix
);
855 /* For 'Code_Address, find an inner ADDR_EXPR and mark it so that we
856 don't try to build a trampoline. */
857 if (attribute
== Attr_Code_Address
)
859 for (gnu_expr
= gnu_result
;
860 TREE_CODE (gnu_expr
) == NOP_EXPR
861 || TREE_CODE (gnu_expr
) == CONVERT_EXPR
;
862 gnu_expr
= TREE_OPERAND (gnu_expr
, 0))
863 TREE_CONSTANT (gnu_expr
) = 1;
865 if (TREE_CODE (gnu_expr
) == ADDR_EXPR
)
866 TREE_STATIC (gnu_expr
) = TREE_CONSTANT (gnu_expr
) = 1;
870 case Attr_Pool_Address
:
873 tree gnu_ptr
= gnu_prefix
;
875 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
877 /* If this is an unconstrained array, we know the object must have been
878 allocated with the template in front of the object. So compute the
880 if (TYPE_FAT_POINTER_P (TREE_TYPE (gnu_ptr
)))
882 = convert (build_pointer_type
883 (TYPE_OBJECT_RECORD_TYPE
884 (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr
)))),
887 gnu_obj_type
= TREE_TYPE (TREE_TYPE (gnu_ptr
));
888 if (TREE_CODE (gnu_obj_type
) == RECORD_TYPE
889 && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type
))
891 tree gnu_char_ptr_type
= build_pointer_type (char_type_node
);
892 tree gnu_pos
= byte_position (TYPE_FIELDS (gnu_obj_type
));
895 size_diffop (size_zero_node
, gnu_pos
));
896 gnu_byte_offset
= fold_build1 (NEGATE_EXPR
, sizetype
, gnu_byte_offset
);
898 gnu_ptr
= convert (gnu_char_ptr_type
, gnu_ptr
);
899 gnu_ptr
= build_binary_op (POINTER_PLUS_EXPR
, gnu_char_ptr_type
,
900 gnu_ptr
, gnu_byte_offset
);
903 gnu_result
= convert (gnu_result_type
, gnu_ptr
);
908 case Attr_Object_Size
:
909 case Attr_Value_Size
:
910 case Attr_Max_Size_In_Storage_Elements
:
911 gnu_expr
= gnu_prefix
;
913 /* Remove NOPS from gnu_expr and conversions from gnu_prefix.
914 We only use GNU_EXPR to see if a COMPONENT_REF was involved. */
915 while (TREE_CODE (gnu_expr
) == NOP_EXPR
)
916 gnu_expr
= TREE_OPERAND (gnu_expr
, 0)
919 gnu_prefix
= remove_conversions (gnu_prefix
, true);
920 prefix_unused
= true;
921 gnu_type
= TREE_TYPE (gnu_prefix
);
923 /* Replace an unconstrained array type with the type of the underlying
924 array. We can't do this with a call to maybe_unconstrained_array
925 since we may have a TYPE_DECL. For 'Max_Size_In_Storage_Elements,
926 use the record type that will be used to allocate the object and its
928 if (TREE_CODE (gnu_type
) == UNCONSTRAINED_ARRAY_TYPE
)
930 gnu_type
= TYPE_OBJECT_RECORD_TYPE (gnu_type
);
931 if (attribute
!= Attr_Max_Size_In_Storage_Elements
)
932 gnu_type
= TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_type
)));
935 /* If we're looking for the size of a field, return the field size.
936 Otherwise, if the prefix is an object, or if 'Object_Size or
937 'Max_Size_In_Storage_Elements has been specified, the result is the
938 GCC size of the type. Otherwise, the result is the RM_Size of the
940 if (TREE_CODE (gnu_prefix
) == COMPONENT_REF
)
941 gnu_result
= DECL_SIZE (TREE_OPERAND (gnu_prefix
, 1));
942 else if (TREE_CODE (gnu_prefix
) != TYPE_DECL
943 || attribute
== Attr_Object_Size
944 || attribute
== Attr_Max_Size_In_Storage_Elements
)
946 /* If this is a padded type, the GCC size isn't relevant to the
947 programmer. Normally, what we want is the RM_Size, which was set
948 from the specified size, but if it was not set, we want the size
949 of the relevant field. Using the MAX of those two produces the
950 right result in all case. Don't use the size of the field if it's
951 a self-referential type, since that's never what's wanted. */
952 if (TREE_CODE (gnu_type
) == RECORD_TYPE
953 && TYPE_IS_PADDING_P (gnu_type
)
954 && TREE_CODE (gnu_expr
) == COMPONENT_REF
)
956 gnu_result
= rm_size (gnu_type
);
957 if (!(CONTAINS_PLACEHOLDER_P
958 (DECL_SIZE (TREE_OPERAND (gnu_expr
, 1)))))
960 = size_binop (MAX_EXPR
, gnu_result
,
961 DECL_SIZE (TREE_OPERAND (gnu_expr
, 1)));
963 else if (Nkind (Prefix (gnat_node
)) == N_Explicit_Dereference
)
965 Node_Id gnat_deref
= Prefix (gnat_node
);
966 Node_Id gnat_actual_subtype
= Actual_Designated_Subtype (gnat_deref
);
967 tree gnu_ptr_type
= TREE_TYPE (gnat_to_gnu (Prefix (gnat_deref
)));
968 if (TYPE_FAT_OR_THIN_POINTER_P (gnu_ptr_type
)
969 && Present (gnat_actual_subtype
))
971 tree gnu_actual_obj_type
= gnat_to_gnu_type (gnat_actual_subtype
);
972 gnu_type
= build_unc_object_type_from_ptr (gnu_ptr_type
,
973 gnu_actual_obj_type
, get_identifier ("SIZE"));
976 gnu_result
= TYPE_SIZE (gnu_type
);
979 gnu_result
= TYPE_SIZE (gnu_type
);
982 gnu_result
= rm_size (gnu_type
);
984 gcc_assert (gnu_result
);
986 /* Deal with a self-referential size by returning the maximum size for a
987 type and by qualifying the size with the object for 'Size of an
989 if (CONTAINS_PLACEHOLDER_P (gnu_result
))
991 if (TREE_CODE (gnu_prefix
) != TYPE_DECL
)
992 gnu_result
= substitute_placeholder_in_expr (gnu_result
, gnu_expr
);
994 gnu_result
= max_size (gnu_result
, true);
997 /* If the type contains a template, subtract its size. */
998 if (TREE_CODE (gnu_type
) == RECORD_TYPE
999 && TYPE_CONTAINS_TEMPLATE_P (gnu_type
))
1000 gnu_result
= size_binop (MINUS_EXPR
, gnu_result
,
1001 DECL_SIZE (TYPE_FIELDS (gnu_type
)));
1003 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1005 /* Always perform division using unsigned arithmetic as the size cannot
1006 be negative, but may be an overflowed positive value. This provides
1007 correct results for sizes up to 512 MB.
1009 ??? Size should be calculated in storage elements directly. */
1011 if (attribute
== Attr_Max_Size_In_Storage_Elements
)
1012 gnu_result
= convert (sizetype
,
1013 fold_build2 (CEIL_DIV_EXPR
, bitsizetype
,
1014 gnu_result
, bitsize_unit_node
));
1017 case Attr_Alignment
:
1018 if (TREE_CODE (gnu_prefix
) == COMPONENT_REF
1019 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix
, 0)))
1021 && (TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix
, 0)))))
1022 gnu_prefix
= TREE_OPERAND (gnu_prefix
, 0);
1024 gnu_type
= TREE_TYPE (gnu_prefix
);
1025 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1026 prefix_unused
= true;
1028 gnu_result
= size_int ((TREE_CODE (gnu_prefix
) == COMPONENT_REF
1029 ? DECL_ALIGN (TREE_OPERAND (gnu_prefix
, 1))
1030 : TYPE_ALIGN (gnu_type
)) / BITS_PER_UNIT
);
1035 case Attr_Range_Length
:
1036 prefix_unused
= true;
1038 if (INTEGRAL_TYPE_P (gnu_type
) || TREE_CODE (gnu_type
) == REAL_TYPE
)
1040 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1042 if (attribute
== Attr_First
)
1043 gnu_result
= TYPE_MIN_VALUE (gnu_type
);
1044 else if (attribute
== Attr_Last
)
1045 gnu_result
= TYPE_MAX_VALUE (gnu_type
);
1049 (MAX_EXPR
, get_base_type (gnu_result_type
),
1051 (PLUS_EXPR
, get_base_type (gnu_result_type
),
1052 build_binary_op (MINUS_EXPR
,
1053 get_base_type (gnu_result_type
),
1054 convert (gnu_result_type
,
1055 TYPE_MAX_VALUE (gnu_type
)),
1056 convert (gnu_result_type
,
1057 TYPE_MIN_VALUE (gnu_type
))),
1058 convert (gnu_result_type
, integer_one_node
)),
1059 convert (gnu_result_type
, integer_zero_node
));
1064 /* ... fall through ... */
1068 int Dimension
= (Present (Expressions (gnat_node
))
1069 ? UI_To_Int (Intval (First (Expressions (gnat_node
))))
1071 struct parm_attr
*pa
= NULL
;
1072 Entity_Id gnat_param
= Empty
;
1074 /* Make sure any implicit dereference gets done. */
1075 gnu_prefix
= maybe_implicit_deref (gnu_prefix
);
1076 gnu_prefix
= maybe_unconstrained_array (gnu_prefix
);
1077 /* We treat unconstrained array IN parameters specially. */
1078 if (Nkind (Prefix (gnat_node
)) == N_Identifier
1079 && !Is_Constrained (Etype (Prefix (gnat_node
)))
1080 && Ekind (Entity (Prefix (gnat_node
))) == E_In_Parameter
)
1081 gnat_param
= Entity (Prefix (gnat_node
));
1082 gnu_type
= TREE_TYPE (gnu_prefix
);
1083 prefix_unused
= true;
1084 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1086 if (TYPE_CONVENTION_FORTRAN_P (gnu_type
))
1091 for (ndim
= 1, gnu_type_temp
= gnu_type
;
1092 TREE_CODE (TREE_TYPE (gnu_type_temp
)) == ARRAY_TYPE
1093 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type_temp
));
1094 ndim
++, gnu_type_temp
= TREE_TYPE (gnu_type_temp
))
1097 Dimension
= ndim
+ 1 - Dimension
;
1100 for (i
= 1; i
< Dimension
; i
++)
1101 gnu_type
= TREE_TYPE (gnu_type
);
1103 gcc_assert (TREE_CODE (gnu_type
) == ARRAY_TYPE
);
1105 /* When not optimizing, look up the slot associated with the parameter
1106 and the dimension in the cache and create a new one on failure. */
1107 if (!optimize
&& Present (gnat_param
))
1109 for (i
= 0; VEC_iterate (parm_attr
, f_parm_attr_cache
, i
, pa
); i
++)
1110 if (pa
->id
== gnat_param
&& pa
->dim
== Dimension
)
1115 pa
= GGC_CNEW (struct parm_attr
);
1116 pa
->id
= gnat_param
;
1117 pa
->dim
= Dimension
;
1118 VEC_safe_push (parm_attr
, gc
, f_parm_attr_cache
, pa
);
1122 /* Return the cached expression or build a new one. */
1123 if (attribute
== Attr_First
)
1125 if (pa
&& pa
->first
)
1127 gnu_result
= pa
->first
;
1132 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
)));
1135 else if (attribute
== Attr_Last
)
1139 gnu_result
= pa
->last
;
1144 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
)));
1147 else /* attribute == Attr_Range_Length || attribute == Attr_Length */
1149 tree gnu_compute_type
;
1151 if (pa
&& pa
->length
)
1153 gnu_result
= pa
->length
;
1158 = signed_or_unsigned_type_for (0,
1159 get_base_type (gnu_result_type
));
1163 (MAX_EXPR
, gnu_compute_type
,
1165 (PLUS_EXPR
, gnu_compute_type
,
1167 (MINUS_EXPR
, gnu_compute_type
,
1168 convert (gnu_compute_type
,
1170 (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
)))),
1171 convert (gnu_compute_type
,
1173 (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
))))),
1174 convert (gnu_compute_type
, integer_one_node
)),
1175 convert (gnu_compute_type
, integer_zero_node
));
1178 /* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
1179 handling. Note that these attributes could not have been used on
1180 an unconstrained array type. */
1181 gnu_result
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result
,
1184 /* Cache the expression we have just computed. Since we want to do it
1185 at runtime, we force the use of a SAVE_EXPR and let the gimplifier
1186 create the temporary. */
1190 = build1 (SAVE_EXPR
, TREE_TYPE (gnu_result
), gnu_result
);
1191 TREE_SIDE_EFFECTS (gnu_result
) = 1;
1192 TREE_INVARIANT (gnu_result
) = 1;
1193 if (attribute
== Attr_First
)
1194 pa
->first
= gnu_result
;
1195 else if (attribute
== Attr_Last
)
1196 pa
->last
= gnu_result
;
1198 pa
->length
= gnu_result
;
1203 case Attr_Bit_Position
:
1205 case Attr_First_Bit
:
1209 HOST_WIDE_INT bitsize
;
1210 HOST_WIDE_INT bitpos
;
1212 tree gnu_field_bitpos
;
1213 tree gnu_field_offset
;
1215 enum machine_mode mode
;
1216 int unsignedp
, volatilep
;
1218 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1219 gnu_prefix
= remove_conversions (gnu_prefix
, true);
1220 prefix_unused
= true;
1222 /* We can have 'Bit on any object, but if it isn't a COMPONENT_REF,
1223 the result is 0. Don't allow 'Bit on a bare component, though. */
1224 if (attribute
== Attr_Bit
1225 && TREE_CODE (gnu_prefix
) != COMPONENT_REF
1226 && TREE_CODE (gnu_prefix
) != FIELD_DECL
)
1228 gnu_result
= integer_zero_node
;
1233 gcc_assert (TREE_CODE (gnu_prefix
) == COMPONENT_REF
1234 || (attribute
== Attr_Bit_Position
1235 && TREE_CODE (gnu_prefix
) == FIELD_DECL
));
1237 get_inner_reference (gnu_prefix
, &bitsize
, &bitpos
, &gnu_offset
,
1238 &mode
, &unsignedp
, &volatilep
, false);
1240 if (TREE_CODE (gnu_prefix
) == COMPONENT_REF
)
1242 gnu_field_bitpos
= bit_position (TREE_OPERAND (gnu_prefix
, 1));
1243 gnu_field_offset
= byte_position (TREE_OPERAND (gnu_prefix
, 1));
1245 for (gnu_inner
= TREE_OPERAND (gnu_prefix
, 0);
1246 TREE_CODE (gnu_inner
) == COMPONENT_REF
1247 && DECL_INTERNAL_P (TREE_OPERAND (gnu_inner
, 1));
1248 gnu_inner
= TREE_OPERAND (gnu_inner
, 0))
1251 = size_binop (PLUS_EXPR
, gnu_field_bitpos
,
1252 bit_position (TREE_OPERAND (gnu_inner
, 1)));
1254 = size_binop (PLUS_EXPR
, gnu_field_offset
,
1255 byte_position (TREE_OPERAND (gnu_inner
, 1)));
1258 else if (TREE_CODE (gnu_prefix
) == FIELD_DECL
)
1260 gnu_field_bitpos
= bit_position (gnu_prefix
);
1261 gnu_field_offset
= byte_position (gnu_prefix
);
1265 gnu_field_bitpos
= bitsize_zero_node
;
1266 gnu_field_offset
= size_zero_node
;
1272 gnu_result
= gnu_field_offset
;
1275 case Attr_First_Bit
:
1277 gnu_result
= size_int (bitpos
% BITS_PER_UNIT
);
1281 gnu_result
= bitsize_int (bitpos
% BITS_PER_UNIT
);
1282 gnu_result
= size_binop (PLUS_EXPR
, gnu_result
,
1283 TYPE_SIZE (TREE_TYPE (gnu_prefix
)));
1284 gnu_result
= size_binop (MINUS_EXPR
, gnu_result
,
1288 case Attr_Bit_Position
:
1289 gnu_result
= gnu_field_bitpos
;
1293 /* If this has a PLACEHOLDER_EXPR, qualify it by the object
1295 gnu_result
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result
, gnu_prefix
);
1302 tree gnu_lhs
= gnat_to_gnu (First (Expressions (gnat_node
)));
1303 tree gnu_rhs
= gnat_to_gnu (Next (First (Expressions (gnat_node
))));
1305 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1306 gnu_result
= build_binary_op (attribute
== Attr_Min
1307 ? MIN_EXPR
: MAX_EXPR
,
1308 gnu_result_type
, gnu_lhs
, gnu_rhs
);
1312 case Attr_Passed_By_Reference
:
1313 gnu_result
= size_int (default_pass_by_ref (gnu_type
)
1314 || must_pass_by_ref (gnu_type
));
1315 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1318 case Attr_Component_Size
:
1319 if (TREE_CODE (gnu_prefix
) == COMPONENT_REF
1320 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix
, 0)))
1322 && (TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix
, 0)))))
1323 gnu_prefix
= TREE_OPERAND (gnu_prefix
, 0);
1325 gnu_prefix
= maybe_implicit_deref (gnu_prefix
);
1326 gnu_type
= TREE_TYPE (gnu_prefix
);
1328 if (TREE_CODE (gnu_type
) == UNCONSTRAINED_ARRAY_TYPE
)
1329 gnu_type
= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_type
))));
1331 while (TREE_CODE (TREE_TYPE (gnu_type
)) == ARRAY_TYPE
1332 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type
)))
1333 gnu_type
= TREE_TYPE (gnu_type
);
1335 gcc_assert (TREE_CODE (gnu_type
) == ARRAY_TYPE
);
1337 /* Note this size cannot be self-referential. */
1338 gnu_result
= TYPE_SIZE (TREE_TYPE (gnu_type
));
1339 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1340 prefix_unused
= true;
1343 case Attr_Null_Parameter
:
1344 /* This is just a zero cast to the pointer type for
1345 our prefix and dereferenced. */
1346 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1348 = build_unary_op (INDIRECT_REF
, NULL_TREE
,
1349 convert (build_pointer_type (gnu_result_type
),
1350 integer_zero_node
));
1351 TREE_PRIVATE (gnu_result
) = 1;
1354 case Attr_Mechanism_Code
:
1357 Entity_Id gnat_obj
= Entity (Prefix (gnat_node
));
1359 prefix_unused
= true;
1360 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1361 if (Present (Expressions (gnat_node
)))
1363 int i
= UI_To_Int (Intval (First (Expressions (gnat_node
))));
1365 for (gnat_obj
= First_Formal (gnat_obj
); i
> 1;
1366 i
--, gnat_obj
= Next_Formal (gnat_obj
))
1370 code
= Mechanism (gnat_obj
);
1371 if (code
== Default
)
1372 code
= ((present_gnu_tree (gnat_obj
)
1373 && (DECL_BY_REF_P (get_gnu_tree (gnat_obj
))
1374 || ((TREE_CODE (get_gnu_tree (gnat_obj
))
1376 && (DECL_BY_COMPONENT_PTR_P
1377 (get_gnu_tree (gnat_obj
))))))
1378 ? By_Reference
: By_Copy
);
1379 gnu_result
= convert (gnu_result_type
, size_int (- code
));
1384 /* Say we have an unimplemented attribute. Then set the value to be
1385 returned to be a zero and hope that's something we can convert to the
1386 type of this attribute. */
1387 post_error ("unimplemented attribute", gnat_node
);
1388 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
1389 gnu_result
= integer_zero_node
;
1393 /* If this is an attribute where the prefix was unused, force a use of it if
1394 it has a side-effect. But don't do it if the prefix is just an entity
1395 name. However, if an access check is needed, we must do it. See second
1396 example in AARM 11.6(5.e). */
1397 if (prefix_unused
&& TREE_SIDE_EFFECTS (gnu_prefix
)
1398 && !Is_Entity_Name (Prefix (gnat_node
)))
1399 gnu_result
= fold_build2 (COMPOUND_EXPR
, TREE_TYPE (gnu_result
),
1400 gnu_prefix
, gnu_result
);
1402 *gnu_result_type_p
= gnu_result_type
;
1406 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Case_Statement,
1407 to a GCC tree, which is returned. */
1410 Case_Statement_to_gnu (Node_Id gnat_node
)
1416 gnu_expr
= gnat_to_gnu (Expression (gnat_node
));
1417 gnu_expr
= convert (get_base_type (TREE_TYPE (gnu_expr
)), gnu_expr
);
1419 /* The range of values in a case statement is determined by the rules in
1420 RM 5.4(7-9). In almost all cases, this range is represented by the Etype
1421 of the expression. One exception arises in the case of a simple name that
1422 is parenthesized. This still has the Etype of the name, but since it is
1423 not a name, para 7 does not apply, and we need to go to the base type.
1424 This is the only case where parenthesization affects the dynamic
1425 semantics (i.e. the range of possible values at runtime that is covered
1426 by the others alternative.
1428 Another exception is if the subtype of the expression is non-static. In
1429 that case, we also have to use the base type. */
1430 if (Paren_Count (Expression (gnat_node
)) != 0
1431 || !Is_OK_Static_Subtype (Underlying_Type
1432 (Etype (Expression (gnat_node
)))))
1433 gnu_expr
= convert (get_base_type (TREE_TYPE (gnu_expr
)), gnu_expr
);
1435 /* We build a SWITCH_EXPR that contains the code with interspersed
1436 CASE_LABEL_EXPRs for each label. */
1438 push_stack (&gnu_switch_label_stack
, NULL_TREE
, create_artificial_label ());
1439 start_stmt_group ();
1440 for (gnat_when
= First_Non_Pragma (Alternatives (gnat_node
));
1441 Present (gnat_when
);
1442 gnat_when
= Next_Non_Pragma (gnat_when
))
1444 Node_Id gnat_choice
;
1445 int choices_added
= 0;
1447 /* First compile all the different case choices for the current WHEN
1449 for (gnat_choice
= First (Discrete_Choices (gnat_when
));
1450 Present (gnat_choice
); gnat_choice
= Next (gnat_choice
))
1452 tree gnu_low
= NULL_TREE
, gnu_high
= NULL_TREE
;
1454 switch (Nkind (gnat_choice
))
1457 gnu_low
= gnat_to_gnu (Low_Bound (gnat_choice
));
1458 gnu_high
= gnat_to_gnu (High_Bound (gnat_choice
));
1461 case N_Subtype_Indication
:
1462 gnu_low
= gnat_to_gnu (Low_Bound (Range_Expression
1463 (Constraint (gnat_choice
))));
1464 gnu_high
= gnat_to_gnu (High_Bound (Range_Expression
1465 (Constraint (gnat_choice
))));
1469 case N_Expanded_Name
:
1470 /* This represents either a subtype range or a static value of
1471 some kind; Ekind says which. */
1472 if (IN (Ekind (Entity (gnat_choice
)), Type_Kind
))
1474 tree gnu_type
= get_unpadded_type (Entity (gnat_choice
));
1476 gnu_low
= fold (TYPE_MIN_VALUE (gnu_type
));
1477 gnu_high
= fold (TYPE_MAX_VALUE (gnu_type
));
1481 /* ... fall through ... */
1483 case N_Character_Literal
:
1484 case N_Integer_Literal
:
1485 gnu_low
= gnat_to_gnu (gnat_choice
);
1488 case N_Others_Choice
:
1495 /* If the case value is a subtype that raises Constraint_Error at
1496 run-time because of a wrong bound, then gnu_low or gnu_high
1497 is not translated into an INTEGER_CST. In such a case, we need
1498 to ensure that the when statement is not added in the tree,
1499 otherwise it will crash the gimplifier. */
1500 if ((!gnu_low
|| TREE_CODE (gnu_low
) == INTEGER_CST
)
1501 && (!gnu_high
|| TREE_CODE (gnu_high
) == INTEGER_CST
))
1504 add_stmt_with_node (build3 (CASE_LABEL_EXPR
, void_type_node
,
1506 create_artificial_label ()),
1512 /* Push a binding level here in case variables are declared since we want
1513 them to be local to this set of statements instead of the block
1514 containing the Case statement. */
1516 if (choices_added
> 0)
1518 add_stmt (build_stmt_group (Statements (gnat_when
), true));
1519 add_stmt (build1 (GOTO_EXPR
, void_type_node
,
1520 TREE_VALUE (gnu_switch_label_stack
)));
1524 /* Now emit a definition of the label all the cases branched to. */
1525 add_stmt (build1 (LABEL_EXPR
, void_type_node
,
1526 TREE_VALUE (gnu_switch_label_stack
)));
1527 gnu_result
= build3 (SWITCH_EXPR
, TREE_TYPE (gnu_expr
), gnu_expr
,
1528 end_stmt_group (), NULL_TREE
);
1529 pop_stack (&gnu_switch_label_stack
);
1534 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Loop_Statement,
1535 to a GCC tree, which is returned. */
1538 Loop_Statement_to_gnu (Node_Id gnat_node
)
1540 /* ??? It would be nice to use "build" here, but there's no build5. */
1541 tree gnu_loop_stmt
= build_nt (LOOP_STMT
, NULL_TREE
, NULL_TREE
,
1542 NULL_TREE
, NULL_TREE
, NULL_TREE
);
1543 tree gnu_loop_var
= NULL_TREE
;
1544 Node_Id gnat_iter_scheme
= Iteration_Scheme (gnat_node
);
1545 tree gnu_cond_expr
= NULL_TREE
;
1548 TREE_TYPE (gnu_loop_stmt
) = void_type_node
;
1549 TREE_SIDE_EFFECTS (gnu_loop_stmt
) = 1;
1550 LOOP_STMT_LABEL (gnu_loop_stmt
) = create_artificial_label ();
1551 set_expr_location_from_node (gnu_loop_stmt
, gnat_node
);
1553 /* Save the end label of this LOOP_STMT in a stack so that the corresponding
1554 N_Exit_Statement can find it. */
1555 push_stack (&gnu_loop_label_stack
, NULL_TREE
,
1556 LOOP_STMT_LABEL (gnu_loop_stmt
));
1558 /* Set the condition that under which the loop should continue.
1559 For "LOOP .... END LOOP;" the condition is always true. */
1560 if (No (gnat_iter_scheme
))
1562 /* The case "WHILE condition LOOP ..... END LOOP;" */
1563 else if (Present (Condition (gnat_iter_scheme
)))
1564 LOOP_STMT_TOP_COND (gnu_loop_stmt
)
1565 = gnat_to_gnu (Condition (gnat_iter_scheme
));
1568 /* We have an iteration scheme. */
1569 Node_Id gnat_loop_spec
= Loop_Parameter_Specification (gnat_iter_scheme
);
1570 Entity_Id gnat_loop_var
= Defining_Entity (gnat_loop_spec
);
1571 Entity_Id gnat_type
= Etype (gnat_loop_var
);
1572 tree gnu_type
= get_unpadded_type (gnat_type
);
1573 tree gnu_low
= TYPE_MIN_VALUE (gnu_type
);
1574 tree gnu_high
= TYPE_MAX_VALUE (gnu_type
);
1575 bool reversep
= Reverse_Present (gnat_loop_spec
);
1576 tree gnu_first
= reversep
? gnu_high
: gnu_low
;
1577 tree gnu_last
= reversep
? gnu_low
: gnu_high
;
1578 enum tree_code end_code
= reversep
? GE_EXPR
: LE_EXPR
;
1579 tree gnu_base_type
= get_base_type (gnu_type
);
1580 tree gnu_limit
= (reversep
? TYPE_MIN_VALUE (gnu_base_type
)
1581 : TYPE_MAX_VALUE (gnu_base_type
));
1583 /* We know the loop variable will not overflow if GNU_LAST is a constant
1584 and is not equal to GNU_LIMIT. If it might overflow, we have to move
1585 the limit test to the end of the loop. In that case, we have to test
1586 for an empty loop outside the loop. */
1587 if (TREE_CODE (gnu_last
) != INTEGER_CST
1588 || TREE_CODE (gnu_limit
) != INTEGER_CST
1589 || tree_int_cst_equal (gnu_last
, gnu_limit
))
1592 = build3 (COND_EXPR
, void_type_node
,
1593 build_binary_op (LE_EXPR
, integer_type_node
,
1595 NULL_TREE
, alloc_stmt_list ());
1596 set_expr_location_from_node (gnu_cond_expr
, gnat_loop_spec
);
1599 /* Open a new nesting level that will surround the loop to declare the
1600 loop index variable. */
1601 start_stmt_group ();
1604 /* Declare the loop index and set it to its initial value. */
1605 gnu_loop_var
= gnat_to_gnu_entity (gnat_loop_var
, gnu_first
, 1);
1606 if (DECL_BY_REF_P (gnu_loop_var
))
1607 gnu_loop_var
= build_unary_op (INDIRECT_REF
, NULL_TREE
, gnu_loop_var
);
1609 /* The loop variable might be a padded type, so use `convert' to get a
1610 reference to the inner variable if so. */
1611 gnu_loop_var
= convert (get_base_type (gnu_type
), gnu_loop_var
);
1613 /* Set either the top or bottom exit condition as appropriate depending
1614 on whether or not we know an overflow cannot occur. */
1616 LOOP_STMT_BOT_COND (gnu_loop_stmt
)
1617 = build_binary_op (NE_EXPR
, integer_type_node
,
1618 gnu_loop_var
, gnu_last
);
1620 LOOP_STMT_TOP_COND (gnu_loop_stmt
)
1621 = build_binary_op (end_code
, integer_type_node
,
1622 gnu_loop_var
, gnu_last
);
1624 LOOP_STMT_UPDATE (gnu_loop_stmt
)
1625 = build_binary_op (reversep
? PREDECREMENT_EXPR
1626 : PREINCREMENT_EXPR
,
1627 TREE_TYPE (gnu_loop_var
),
1629 convert (TREE_TYPE (gnu_loop_var
),
1631 set_expr_location_from_node (LOOP_STMT_UPDATE (gnu_loop_stmt
),
1635 /* If the loop was named, have the name point to this loop. In this case,
1636 the association is not a ..._DECL node, but the end label from this
1638 if (Present (Identifier (gnat_node
)))
1639 save_gnu_tree (Entity (Identifier (gnat_node
)),
1640 LOOP_STMT_LABEL (gnu_loop_stmt
), true);
1642 /* Make the loop body into its own block, so any allocated storage will be
1643 released every iteration. This is needed for stack allocation. */
1644 LOOP_STMT_BODY (gnu_loop_stmt
)
1645 = build_stmt_group (Statements (gnat_node
), true);
1647 /* If we declared a variable, then we are in a statement group for that
1648 declaration. Add the LOOP_STMT to it and make that the "loop". */
1651 add_stmt (gnu_loop_stmt
);
1653 gnu_loop_stmt
= end_stmt_group ();
1656 /* If we have an outer COND_EXPR, that's our result and this loop is its
1657 "true" statement. Otherwise, the result is the LOOP_STMT. */
1660 COND_EXPR_THEN (gnu_cond_expr
) = gnu_loop_stmt
;
1661 gnu_result
= gnu_cond_expr
;
1662 recalculate_side_effects (gnu_cond_expr
);
1665 gnu_result
= gnu_loop_stmt
;
1667 pop_stack (&gnu_loop_label_stack
);
1672 /* Emit statements to establish __gnat_handle_vms_condition as a VMS condition
1673 handler for the current function. */
1675 /* This is implemented by issuing a call to the appropriate VMS specific
1676 builtin. To avoid having VMS specific sections in the global gigi decls
1677 array, we maintain the decls of interest here. We can't declare them
1678 inside the function because we must mark them never to be GC'd, which we
1679 can only do at the global level. */
1681 static GTY(()) tree vms_builtin_establish_handler_decl
= NULL_TREE
;
1682 static GTY(()) tree gnat_vms_condition_handler_decl
= NULL_TREE
;
1685 establish_gnat_vms_condition_handler (void)
1687 tree establish_stmt
;
1689 /* Elaborate the required decls on the first call. Check on the decl for
1690 the gnat condition handler to decide, as this is one we create so we are
1691 sure that it will be non null on subsequent calls. The builtin decl is
1692 looked up so remains null on targets where it is not implemented yet. */
1693 if (gnat_vms_condition_handler_decl
== NULL_TREE
)
1695 vms_builtin_establish_handler_decl
1697 (get_identifier ("__builtin_establish_vms_condition_handler"));
1699 gnat_vms_condition_handler_decl
1700 = create_subprog_decl (get_identifier ("__gnat_handle_vms_condition"),
1702 build_function_type_list (integer_type_node
,
1706 NULL_TREE
, 0, 1, 1, 0, Empty
);
1709 /* Do nothing if the establish builtin is not available, which might happen
1710 on targets where the facility is not implemented. */
1711 if (vms_builtin_establish_handler_decl
== NULL_TREE
)
1715 = build_call_1_expr (vms_builtin_establish_handler_decl
,
1717 (ADDR_EXPR
, NULL_TREE
,
1718 gnat_vms_condition_handler_decl
));
1720 add_stmt (establish_stmt
);
1723 /* Subroutine of gnat_to_gnu to process gnat_node, an N_Subprogram_Body. We
1724 don't return anything. */
1727 Subprogram_Body_to_gnu (Node_Id gnat_node
)
1729 /* Defining identifier of a parameter to the subprogram. */
1730 Entity_Id gnat_param
;
1731 /* The defining identifier for the subprogram body. Note that if a
1732 specification has appeared before for this body, then the identifier
1733 occurring in that specification will also be a defining identifier and all
1734 the calls to this subprogram will point to that specification. */
1735 Entity_Id gnat_subprog_id
1736 = (Present (Corresponding_Spec (gnat_node
))
1737 ? Corresponding_Spec (gnat_node
) : Defining_Entity (gnat_node
));
1738 /* The FUNCTION_DECL node corresponding to the subprogram spec. */
1739 tree gnu_subprog_decl
;
1740 /* The FUNCTION_TYPE node corresponding to the subprogram spec. */
1741 tree gnu_subprog_type
;
1744 VEC(parm_attr
,gc
) *cache
;
1746 /* If this is a generic object or if it has been eliminated,
1748 if (Ekind (gnat_subprog_id
) == E_Generic_Procedure
1749 || Ekind (gnat_subprog_id
) == E_Generic_Function
1750 || Is_Eliminated (gnat_subprog_id
))
1753 /* If this subprogram acts as its own spec, define it. Otherwise, just get
1754 the already-elaborated tree node. However, if this subprogram had its
1755 elaboration deferred, we will already have made a tree node for it. So
1756 treat it as not being defined in that case. Such a subprogram cannot
1757 have an address clause or a freeze node, so this test is safe, though it
1758 does disable some otherwise-useful error checking. */
1760 = gnat_to_gnu_entity (gnat_subprog_id
, NULL_TREE
,
1761 Acts_As_Spec (gnat_node
)
1762 && !present_gnu_tree (gnat_subprog_id
));
1764 gnu_subprog_type
= TREE_TYPE (gnu_subprog_decl
);
1766 /* Propagate the debug mode. */
1767 if (!Needs_Debug_Info (gnat_subprog_id
))
1768 DECL_IGNORED_P (gnu_subprog_decl
) = 1;
1770 /* Set the line number in the decl to correspond to that of the body so that
1771 the line number notes are written correctly. */
1772 Sloc_to_locus (Sloc (gnat_node
), &DECL_SOURCE_LOCATION (gnu_subprog_decl
));
1774 /* Initialize the information structure for the function. */
1775 allocate_struct_function (gnu_subprog_decl
);
1776 DECL_STRUCT_FUNCTION (gnu_subprog_decl
)->language
1777 = GGC_CNEW (struct language_function
);
1779 begin_subprog_body (gnu_subprog_decl
);
1780 gnu_cico_list
= TYPE_CI_CO_LIST (gnu_subprog_type
);
1782 /* If there are OUT parameters, we need to ensure that the return statement
1783 properly copies them out. We do this by making a new block and converting
1784 any inner return into a goto to a label at the end of the block. */
1785 push_stack (&gnu_return_label_stack
, NULL_TREE
,
1786 gnu_cico_list
? create_artificial_label () : NULL_TREE
);
1788 /* Get a tree corresponding to the code for the subprogram. */
1789 start_stmt_group ();
1792 /* See if there are any parameters for which we don't yet have GCC entities.
1793 These must be for OUT parameters for which we will be making VAR_DECL
1794 nodes here. Fill them in to TYPE_CI_CO_LIST, which must contain the empty
1795 entry as well. We can match up the entries because TYPE_CI_CO_LIST is in
1796 the order of the parameters. */
1797 for (gnat_param
= First_Formal_With_Extras (gnat_subprog_id
);
1798 Present (gnat_param
);
1799 gnat_param
= Next_Formal_With_Extras (gnat_param
))
1800 if (!present_gnu_tree (gnat_param
))
1802 /* Skip any entries that have been already filled in; they must
1803 correspond to IN OUT parameters. */
1804 for (; gnu_cico_list
&& TREE_VALUE (gnu_cico_list
);
1805 gnu_cico_list
= TREE_CHAIN (gnu_cico_list
))
1808 /* Do any needed references for padded types. */
1809 TREE_VALUE (gnu_cico_list
)
1810 = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_list
)),
1811 gnat_to_gnu_entity (gnat_param
, NULL_TREE
, 1));
1814 /* On VMS, establish our condition handler to possibly turn a condition into
1815 the corresponding exception if the subprogram has a foreign convention or
1818 To ensure proper execution of local finalizations on condition instances,
1819 we must turn a condition into the corresponding exception even if there
1820 is no applicable Ada handler, and need at least one condition handler per
1821 possible call chain involving GNAT code. OTOH, establishing the handler
1822 has a cost so we want to minimize the number of subprograms into which
1823 this happens. The foreign or exported condition is expected to satisfy
1824 all the constraints. */
1825 if (TARGET_ABI_OPEN_VMS
1826 && (Has_Foreign_Convention (gnat_node
) || Is_Exported (gnat_node
)))
1827 establish_gnat_vms_condition_handler ();
1829 process_decls (Declarations (gnat_node
), Empty
, Empty
, true, true);
1831 /* Generate the code of the subprogram itself. A return statement will be
1832 present and any OUT parameters will be handled there. */
1833 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node
)));
1835 gnu_result
= end_stmt_group ();
1837 /* If we populated the parameter attributes cache, we need to make sure
1838 that the cached expressions are evaluated on all possible paths. */
1839 cache
= DECL_STRUCT_FUNCTION (gnu_subprog_decl
)->language
->parm_attr_cache
;
1842 struct parm_attr
*pa
;
1845 start_stmt_group ();
1847 for (i
= 0; VEC_iterate (parm_attr
, cache
, i
, pa
); i
++)
1850 add_stmt (pa
->first
);
1852 add_stmt (pa
->last
);
1854 add_stmt (pa
->length
);
1857 add_stmt (gnu_result
);
1858 gnu_result
= end_stmt_group ();
1861 /* If we made a special return label, we need to make a block that contains
1862 the definition of that label and the copying to the return value. That
1863 block first contains the function, then the label and copy statement. */
1864 if (TREE_VALUE (gnu_return_label_stack
))
1868 start_stmt_group ();
1870 add_stmt (gnu_result
);
1871 add_stmt (build1 (LABEL_EXPR
, void_type_node
,
1872 TREE_VALUE (gnu_return_label_stack
)));
1874 gnu_cico_list
= TYPE_CI_CO_LIST (gnu_subprog_type
);
1875 if (list_length (gnu_cico_list
) == 1)
1876 gnu_retval
= TREE_VALUE (gnu_cico_list
);
1878 gnu_retval
= gnat_build_constructor (TREE_TYPE (gnu_subprog_type
),
1881 if (DECL_P (gnu_retval
) && DECL_BY_REF_P (gnu_retval
))
1882 gnu_retval
= build_unary_op (INDIRECT_REF
, NULL_TREE
, gnu_retval
);
1885 (build_return_expr (DECL_RESULT (gnu_subprog_decl
), gnu_retval
),
1888 gnu_result
= end_stmt_group ();
1891 pop_stack (&gnu_return_label_stack
);
1893 /* Set the end location. */
1895 ((Present (End_Label (Handled_Statement_Sequence (gnat_node
)))
1896 ? Sloc (End_Label (Handled_Statement_Sequence (gnat_node
)))
1897 : Sloc (gnat_node
)),
1898 &DECL_STRUCT_FUNCTION (gnu_subprog_decl
)->function_end_locus
);
1900 end_subprog_body (gnu_result
);
1902 /* Disconnect the trees for parameters that we made variables for from the
1903 GNAT entities since these are unusable after we end the function. */
1904 for (gnat_param
= First_Formal_With_Extras (gnat_subprog_id
);
1905 Present (gnat_param
);
1906 gnat_param
= Next_Formal_With_Extras (gnat_param
))
1907 if (TREE_CODE (get_gnu_tree (gnat_param
)) == VAR_DECL
)
1908 save_gnu_tree (gnat_param
, NULL_TREE
, false);
1910 if (DECL_FUNCTION_STUB (gnu_subprog_decl
))
1911 build_function_stub (gnu_subprog_decl
, gnat_subprog_id
);
1913 mark_out_of_scope (Defining_Unit_Name (Specification (gnat_node
)));
1916 /* Subroutine of gnat_to_gnu to translate gnat_node, either an N_Function_Call
1917 or an N_Procedure_Call_Statement, to a GCC tree, which is returned.
1918 GNU_RESULT_TYPE_P is a pointer to where we should place the result type.
1919 If GNU_TARGET is non-null, this must be a function call and the result
1920 of the call is to be placed into that object. */
1923 call_to_gnu (Node_Id gnat_node
, tree
*gnu_result_type_p
, tree gnu_target
)
1926 /* The GCC node corresponding to the GNAT subprogram name. This can either
1927 be a FUNCTION_DECL node if we are dealing with a standard subprogram call,
1928 or an indirect reference expression (an INDIRECT_REF node) pointing to a
1930 tree gnu_subprog_node
= gnat_to_gnu (Name (gnat_node
));
1931 /* The FUNCTION_TYPE node giving the GCC type of the subprogram. */
1932 tree gnu_subprog_type
= TREE_TYPE (gnu_subprog_node
);
1933 tree gnu_subprog_addr
= build_unary_op (ADDR_EXPR
, NULL_TREE
,
1935 Entity_Id gnat_formal
;
1936 Node_Id gnat_actual
;
1937 tree gnu_actual_list
= NULL_TREE
;
1938 tree gnu_name_list
= NULL_TREE
;
1939 tree gnu_before_list
= NULL_TREE
;
1940 tree gnu_after_list
= NULL_TREE
;
1941 tree gnu_subprog_call
;
1943 switch (Nkind (Name (gnat_node
)))
1946 case N_Operator_Symbol
:
1947 case N_Expanded_Name
:
1948 case N_Attribute_Reference
:
1949 if (Is_Eliminated (Entity (Name (gnat_node
))))
1950 Eliminate_Error_Msg (gnat_node
, Entity (Name (gnat_node
)));
1953 gcc_assert (TREE_CODE (gnu_subprog_type
) == FUNCTION_TYPE
);
1955 /* If we are calling a stubbed function, make this into a raise of
1956 Program_Error. Elaborate all our args first. */
1957 if (TREE_CODE (gnu_subprog_node
) == FUNCTION_DECL
1958 && DECL_STUBBED_P (gnu_subprog_node
))
1960 for (gnat_actual
= First_Actual (gnat_node
);
1961 Present (gnat_actual
);
1962 gnat_actual
= Next_Actual (gnat_actual
))
1963 add_stmt (gnat_to_gnu (gnat_actual
));
1967 = build_call_raise (PE_Stubbed_Subprogram_Called
, gnat_node
,
1968 N_Raise_Program_Error
);
1970 if (Nkind (gnat_node
) == N_Function_Call
&& !gnu_target
)
1972 *gnu_result_type_p
= TREE_TYPE (gnu_subprog_type
);
1973 return build1 (NULL_EXPR
, *gnu_result_type_p
, call_expr
);
1980 /* If we are calling by supplying a pointer to a target, set up that
1981 pointer as the first argument. Use GNU_TARGET if one was passed;
1982 otherwise, make a target by building a variable of the maximum size
1984 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type
))
1986 tree gnu_real_ret_type
1987 = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (gnu_subprog_type
)));
1992 = maybe_pad_type (gnu_real_ret_type
,
1993 max_size (TYPE_SIZE (gnu_real_ret_type
), true),
1994 0, Etype (Name (gnat_node
)), "PAD", false,
1997 /* ??? We may be about to create a static temporary if we happen to
1998 be at the global binding level. That's a regression from what
1999 the 3.x back-end would generate in the same situation, but we
2000 don't have a mechanism in Gigi for creating automatic variables
2001 in the elaboration routines. */
2003 = create_var_decl (create_tmp_var_name ("LR"), NULL
, gnu_obj_type
,
2004 NULL
, false, false, false, false, NULL
,
2009 = tree_cons (NULL_TREE
,
2010 build_unary_op (ADDR_EXPR
, NULL_TREE
,
2011 unchecked_convert (gnu_real_ret_type
,
2018 /* The only way we can be making a call via an access type is if Name is an
2019 explicit dereference. In that case, get the list of formal args from the
2020 type the access type is pointing to. Otherwise, get the formals from
2021 entity being called. */
2022 if (Nkind (Name (gnat_node
)) == N_Explicit_Dereference
)
2023 gnat_formal
= First_Formal_With_Extras (Etype (Name (gnat_node
)));
2024 else if (Nkind (Name (gnat_node
)) == N_Attribute_Reference
)
2025 /* Assume here that this must be 'Elab_Body or 'Elab_Spec. */
2028 gnat_formal
= First_Formal_With_Extras (Entity (Name (gnat_node
)));
2030 /* Create the list of the actual parameters as GCC expects it, namely a chain
2031 of TREE_LIST nodes in which the TREE_VALUE field of each node is a
2032 parameter-expression and the TREE_PURPOSE field is null. Skip OUT
2033 parameters not passed by reference and don't need to be copied in. */
2034 for (gnat_actual
= First_Actual (gnat_node
);
2035 Present (gnat_actual
);
2036 gnat_formal
= Next_Formal_With_Extras (gnat_formal
),
2037 gnat_actual
= Next_Actual (gnat_actual
))
2040 = (present_gnu_tree (gnat_formal
)
2041 ? get_gnu_tree (gnat_formal
) : NULL_TREE
);
2042 tree gnu_formal_type
= gnat_to_gnu_type (Etype (gnat_formal
));
2043 /* We treat a conversion between aggregate types as if it is an
2044 unchecked conversion. */
2045 bool unchecked_convert_p
2046 = (Nkind (gnat_actual
) == N_Unchecked_Type_Conversion
2047 || (Nkind (gnat_actual
) == N_Type_Conversion
2048 && Is_Composite_Type (Underlying_Type (Etype (gnat_formal
)))));
2049 Node_Id gnat_name
= (unchecked_convert_p
2050 ? Expression (gnat_actual
) : gnat_actual
);
2051 tree gnu_name
= gnat_to_gnu (gnat_name
);
2052 tree gnu_name_type
= gnat_to_gnu_type (Etype (gnat_name
));
2055 /* If it's possible we may need to use this expression twice, make sure
2056 than any side-effects are handled via SAVE_EXPRs. Likewise if we need
2057 to force side-effects before the call.
2059 ??? This is more conservative than we need since we don't need to do
2060 this for pass-by-ref with no conversion. If we are passing a
2061 non-addressable Out or In Out parameter by reference, pass the address
2062 of a copy and set up to copy back out after the call. */
2063 if (Ekind (gnat_formal
) != E_In_Parameter
)
2065 gnu_name
= gnat_stabilize_reference (gnu_name
, true);
2067 if (!addressable_p (gnu_name
)
2069 && (DECL_BY_REF_P (gnu_formal
)
2070 || (TREE_CODE (gnu_formal
) == PARM_DECL
2071 && (DECL_BY_COMPONENT_PTR_P (gnu_formal
)
2072 || (DECL_BY_DESCRIPTOR_P (gnu_formal
))))))
2074 tree gnu_copy
= gnu_name
;
2077 /* If the type is by_reference, a copy is not allowed. */
2078 if (Is_By_Reference_Type (Etype (gnat_formal
)))
2080 ("misaligned & cannot be passed by reference", gnat_actual
);
2082 /* For users of Starlet we issue a warning because the
2083 interface apparently assumes that by-ref parameters
2084 outlive the procedure invocation. The code still
2085 will not work as intended, but we cannot do much
2086 better since other low-level parts of the back-end
2087 would allocate temporaries at will because of the
2088 misalignment if we did not do so here. */
2090 else if (Is_Valued_Procedure (Entity (Name (gnat_node
))))
2093 ("?possible violation of implicit assumption",
2096 ("?made by pragma Import_Valued_Procedure on &",
2097 gnat_actual
, Entity (Name (gnat_node
)));
2099 ("?because of misalignment of &",
2100 gnat_actual
, gnat_formal
);
2103 /* Remove any unpadding on the actual and make a copy. But if
2104 the actual is a justified modular type, first convert
2106 if (TREE_CODE (gnu_name
) == COMPONENT_REF
2107 && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_name
, 0)))
2109 && (TYPE_IS_PADDING_P
2110 (TREE_TYPE (TREE_OPERAND (gnu_name
, 0))))))
2111 gnu_name
= gnu_copy
= TREE_OPERAND (gnu_name
, 0);
2112 else if (TREE_CODE (gnu_name_type
) == RECORD_TYPE
2113 && (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type
)))
2114 gnu_name
= convert (gnu_name_type
, gnu_name
);
2116 /* Make a SAVE_EXPR to both properly account for potential side
2117 effects and handle the creation of a temporary copy. Special
2118 code in gnat_gimplify_expr ensures that the same temporary is
2119 used as the actual and copied back after the call. */
2120 gnu_actual
= save_expr (gnu_name
);
2122 /* Set up to move the copy back to the original. */
2123 gnu_temp
= build_binary_op (MODIFY_EXPR
, NULL_TREE
,
2124 gnu_copy
, gnu_actual
);
2125 set_expr_location_from_node (gnu_temp
, gnat_actual
);
2126 append_to_statement_list (gnu_temp
, &gnu_after_list
);
2128 /* Account for next statement just below. */
2129 gnu_name
= gnu_actual
;
2133 /* If this was a procedure call, we may not have removed any padding.
2134 So do it here for the part we will use as an input, if any. */
2135 gnu_actual
= gnu_name
;
2136 if (Ekind (gnat_formal
) != E_Out_Parameter
2137 && TREE_CODE (TREE_TYPE (gnu_actual
)) == RECORD_TYPE
2138 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual
)))
2139 gnu_actual
= convert (get_unpadded_type (Etype (gnat_actual
)),
2142 /* Unless this is an In parameter, we must remove any LJM building
2144 if (Ekind (gnat_formal
) != E_In_Parameter
2145 && TREE_CODE (gnu_name
) == CONSTRUCTOR
2146 && TREE_CODE (TREE_TYPE (gnu_name
)) == RECORD_TYPE
2147 && TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (gnu_name
)))
2148 gnu_name
= convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_name
))),
2151 if (Ekind (gnat_formal
) != E_Out_Parameter
2152 && !unchecked_convert_p
2153 && Do_Range_Check (gnat_actual
))
2154 gnu_actual
= emit_range_check (gnu_actual
, Etype (gnat_formal
));
2156 /* Do any needed conversions. We need only check for unchecked
2157 conversion since normal conversions will be handled by just
2158 converting to the formal type. */
2159 if (unchecked_convert_p
)
2162 = unchecked_convert (gnat_to_gnu_type (Etype (gnat_actual
)),
2164 (Nkind (gnat_actual
)
2165 == N_Unchecked_Type_Conversion
)
2166 && No_Truncation (gnat_actual
));
2168 /* One we've done the unchecked conversion, we still must ensure that
2169 the object is in range of the formal's type. */
2170 if (Ekind (gnat_formal
) != E_Out_Parameter
2171 && Do_Range_Check (gnat_actual
))
2172 gnu_actual
= emit_range_check (gnu_actual
,
2173 Etype (gnat_formal
));
2175 else if (TREE_CODE (gnu_actual
) != SAVE_EXPR
)
2176 /* We may have suppressed a conversion to the Etype of the actual since
2177 the parent is a procedure call. So add the conversion here. */
2178 gnu_actual
= convert (gnat_to_gnu_type (Etype (gnat_actual
)),
2181 if (TREE_CODE (gnu_actual
) != SAVE_EXPR
)
2182 gnu_actual
= convert (gnu_formal_type
, gnu_actual
);
2184 /* If we have not saved a GCC object for the formal, it means it is an
2185 OUT parameter not passed by reference and that does not need to be
2186 copied in. Otherwise, look at the PARM_DECL to see if it is passed by
2189 && TREE_CODE (gnu_formal
) == PARM_DECL
&& DECL_BY_REF_P (gnu_formal
))
2191 if (Ekind (gnat_formal
) != E_In_Parameter
)
2193 gnu_actual
= gnu_name
;
2195 /* If we have a padded type, be sure we've removed padding. */
2196 if (TREE_CODE (TREE_TYPE (gnu_actual
)) == RECORD_TYPE
2197 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual
))
2198 && TREE_CODE (gnu_actual
) != SAVE_EXPR
)
2199 gnu_actual
= convert (get_unpadded_type (Etype (gnat_actual
)),
2202 /* If we have the constructed subtype of an aliased object
2203 with an unconstrained nominal subtype, the type of the
2204 actual includes the template, although it is formally
2205 constrained. So we need to convert it back to the real
2206 constructed subtype to retrieve the constrained part
2207 and takes its address. */
2208 if (TREE_CODE (TREE_TYPE (gnu_actual
)) == RECORD_TYPE
2209 && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (gnu_actual
))
2210 && TREE_CODE (gnu_actual
) != SAVE_EXPR
2211 && Is_Constr_Subt_For_UN_Aliased (Etype (gnat_actual
))
2212 && Is_Array_Type (Etype (gnat_actual
)))
2213 gnu_actual
= convert (gnat_to_gnu_type (Etype (gnat_actual
)),
2217 /* Otherwise, if we have a non-addressable COMPONENT_REF of a
2218 variable-size type see if it's doing a unpadding operation. If
2219 so, remove that operation since we have no way of allocating the
2220 required temporary. */
2221 if (TREE_CODE (gnu_actual
) == COMPONENT_REF
2222 && !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual
)))
2223 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_actual
, 0)))
2225 && TYPE_IS_PADDING_P (TREE_TYPE
2226 (TREE_OPERAND (gnu_actual
, 0)))
2227 && !addressable_p (gnu_actual
))
2228 gnu_actual
= TREE_OPERAND (gnu_actual
, 0);
2230 /* For In parameters, gnu_actual might still not be addressable at
2231 this point and we need the creation of a temporary copy since
2232 this is to be passed by ref. Resorting to save_expr to force a
2233 SAVE_EXPR temporary creation here is not guaranteed to work
2234 because the actual might be invariant or readonly without side
2235 effects, so we let the gimplifier process this case. */
2237 /* The symmetry of the paths to the type of an entity is broken here
2238 since arguments don't know that they will be passed by ref. */
2239 gnu_formal_type
= TREE_TYPE (get_gnu_tree (gnat_formal
));
2240 gnu_actual
= build_unary_op (ADDR_EXPR
, gnu_formal_type
, gnu_actual
);
2242 else if (gnu_formal
&& TREE_CODE (gnu_formal
) == PARM_DECL
2243 && DECL_BY_COMPONENT_PTR_P (gnu_formal
))
2245 gnu_formal_type
= TREE_TYPE (get_gnu_tree (gnat_formal
));
2246 gnu_actual
= maybe_implicit_deref (gnu_actual
);
2247 gnu_actual
= maybe_unconstrained_array (gnu_actual
);
2249 if (TREE_CODE (gnu_formal_type
) == RECORD_TYPE
2250 && TYPE_IS_PADDING_P (gnu_formal_type
))
2252 gnu_formal_type
= TREE_TYPE (TYPE_FIELDS (gnu_formal_type
));
2253 gnu_actual
= convert (gnu_formal_type
, gnu_actual
);
2256 /* Take the address of the object and convert to the proper pointer
2257 type. We'd like to actually compute the address of the beginning
2258 of the array using an ADDR_EXPR of an ARRAY_REF, but there's a
2259 possibility that the ARRAY_REF might return a constant and we'd be
2260 getting the wrong address. Neither approach is exactly correct,
2261 but this is the most likely to work in all cases. */
2262 gnu_actual
= convert (gnu_formal_type
,
2263 build_unary_op (ADDR_EXPR
, NULL_TREE
,
2266 else if (gnu_formal
&& TREE_CODE (gnu_formal
) == PARM_DECL
2267 && DECL_BY_DESCRIPTOR_P (gnu_formal
))
2269 /* If arg is 'Null_Parameter, pass zero descriptor. */
2270 if ((TREE_CODE (gnu_actual
) == INDIRECT_REF
2271 || TREE_CODE (gnu_actual
) == UNCONSTRAINED_ARRAY_REF
)
2272 && TREE_PRIVATE (gnu_actual
))
2273 gnu_actual
= convert (DECL_ARG_TYPE (get_gnu_tree (gnat_formal
)),
2276 gnu_actual
= build_unary_op (ADDR_EXPR
, NULL_TREE
,
2277 fill_vms_descriptor (gnu_actual
,
2282 tree gnu_actual_size
= TYPE_SIZE (TREE_TYPE (gnu_actual
));
2284 if (Ekind (gnat_formal
) != E_In_Parameter
)
2285 gnu_name_list
= tree_cons (NULL_TREE
, gnu_name
, gnu_name_list
);
2287 if (!gnu_formal
|| TREE_CODE (gnu_formal
) != PARM_DECL
)
2290 /* If this is 'Null_Parameter, pass a zero even though we are
2291 dereferencing it. */
2292 else if (TREE_CODE (gnu_actual
) == INDIRECT_REF
2293 && TREE_PRIVATE (gnu_actual
)
2294 && host_integerp (gnu_actual_size
, 1)
2295 && 0 >= compare_tree_int (gnu_actual_size
,
2298 = unchecked_convert (DECL_ARG_TYPE (gnu_formal
),
2299 convert (gnat_type_for_size
2300 (tree_low_cst (gnu_actual_size
, 1),
2305 gnu_actual
= convert (DECL_ARG_TYPE (gnu_formal
), gnu_actual
);
2308 gnu_actual_list
= tree_cons (NULL_TREE
, gnu_actual
, gnu_actual_list
);
2311 gnu_subprog_call
= build_call_list (TREE_TYPE (gnu_subprog_type
),
2313 nreverse (gnu_actual_list
));
2314 set_expr_location_from_node (gnu_subprog_call
, gnat_node
);
2316 /* If we return by passing a target, the result is the target after the
2317 call. We must not emit the call directly here because this might be
2318 evaluated as part of an expression with conditions to control whether
2319 the call should be emitted or not. */
2320 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type
))
2322 /* Conceptually, what we need is a COMPOUND_EXPR with the call followed
2323 by the target object converted to the proper type. Doing so would
2324 potentially be very inefficient, however, as this expresssion might
2325 end up wrapped into an outer SAVE_EXPR later on, which would incur a
2326 pointless temporary copy of the whole object.
2328 What we do instead is build a COMPOUND_EXPR returning the address of
2329 the target, and then dereference. Wrapping the COMPOUND_EXPR into a
2330 SAVE_EXPR later on then only incurs a pointer copy. */
2332 tree gnu_result_type
2333 = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (gnu_subprog_type
)));
2336 (result_type) *[gnu_subprog_call (&gnu_target, ...), &gnu_target] */
2338 tree gnu_target_address
2339 = build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_target
);
2340 set_expr_location_from_node (gnu_target_address
, gnat_node
);
2343 = build2 (COMPOUND_EXPR
, TREE_TYPE (gnu_target_address
),
2344 gnu_subprog_call
, gnu_target_address
);
2347 = unchecked_convert (gnu_result_type
,
2348 build_unary_op (INDIRECT_REF
, NULL_TREE
,
2352 *gnu_result_type_p
= gnu_result_type
;
2356 /* If it is a function call, the result is the call expression unless
2357 a target is specified, in which case we copy the result into the target
2358 and return the assignment statement. */
2359 else if (Nkind (gnat_node
) == N_Function_Call
)
2361 gnu_result
= gnu_subprog_call
;
2363 /* If the function returns an unconstrained array or by reference,
2364 we have to de-dereference the pointer. */
2365 if (TYPE_RETURNS_UNCONSTRAINED_P (gnu_subprog_type
)
2366 || TYPE_RETURNS_BY_REF_P (gnu_subprog_type
))
2367 gnu_result
= build_unary_op (INDIRECT_REF
, NULL_TREE
, gnu_result
);
2370 gnu_result
= build_binary_op (MODIFY_EXPR
, NULL_TREE
,
2371 gnu_target
, gnu_result
);
2373 *gnu_result_type_p
= get_unpadded_type (Etype (gnat_node
));
2378 /* If this is the case where the GNAT tree contains a procedure call
2379 but the Ada procedure has copy in copy out parameters, the special
2380 parameter passing mechanism must be used. */
2381 else if (TYPE_CI_CO_LIST (gnu_subprog_type
) != NULL_TREE
)
2383 /* List of FIELD_DECLs associated with the PARM_DECLs of the copy
2384 in copy out parameters. */
2385 tree scalar_return_list
= TYPE_CI_CO_LIST (gnu_subprog_type
);
2386 int length
= list_length (scalar_return_list
);
2392 gnu_subprog_call
= save_expr (gnu_subprog_call
);
2393 gnu_name_list
= nreverse (gnu_name_list
);
2395 /* If any of the names had side-effects, ensure they are all
2396 evaluated before the call. */
2397 for (gnu_name
= gnu_name_list
; gnu_name
;
2398 gnu_name
= TREE_CHAIN (gnu_name
))
2399 if (TREE_SIDE_EFFECTS (TREE_VALUE (gnu_name
)))
2400 append_to_statement_list (TREE_VALUE (gnu_name
),
2404 if (Nkind (Name (gnat_node
)) == N_Explicit_Dereference
)
2405 gnat_formal
= First_Formal_With_Extras (Etype (Name (gnat_node
)));
2407 gnat_formal
= First_Formal_With_Extras (Entity (Name (gnat_node
)));
2409 for (gnat_actual
= First_Actual (gnat_node
);
2410 Present (gnat_actual
);
2411 gnat_formal
= Next_Formal_With_Extras (gnat_formal
),
2412 gnat_actual
= Next_Actual (gnat_actual
))
2413 /* If we are dealing with a copy in copy out parameter, we must
2414 retrieve its value from the record returned in the call. */
2415 if (!(present_gnu_tree (gnat_formal
)
2416 && TREE_CODE (get_gnu_tree (gnat_formal
)) == PARM_DECL
2417 && (DECL_BY_REF_P (get_gnu_tree (gnat_formal
))
2418 || (TREE_CODE (get_gnu_tree (gnat_formal
)) == PARM_DECL
2419 && ((DECL_BY_COMPONENT_PTR_P (get_gnu_tree (gnat_formal
))
2420 || (DECL_BY_DESCRIPTOR_P
2421 (get_gnu_tree (gnat_formal
))))))))
2422 && Ekind (gnat_formal
) != E_In_Parameter
)
2424 /* Get the value to assign to this OUT or IN OUT parameter. It is
2425 either the result of the function if there is only a single such
2426 parameter or the appropriate field from the record returned. */
2428 = length
== 1 ? gnu_subprog_call
2429 : build_component_ref (gnu_subprog_call
, NULL_TREE
,
2430 TREE_PURPOSE (scalar_return_list
),
2433 /* If the actual is a conversion, get the inner expression, which
2434 will be the real destination, and convert the result to the
2435 type of the actual parameter. */
2437 = maybe_unconstrained_array (TREE_VALUE (gnu_name_list
));
2439 /* If the result is a padded type, remove the padding. */
2440 if (TREE_CODE (TREE_TYPE (gnu_result
)) == RECORD_TYPE
2441 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result
)))
2442 gnu_result
= convert (TREE_TYPE (TYPE_FIELDS
2443 (TREE_TYPE (gnu_result
))),
2446 /* If the actual is a type conversion, the real target object is
2447 denoted by the inner Expression and we need to convert the
2448 result to the associated type.
2450 We also need to convert our gnu assignment target to this type
2451 if the corresponding gnu_name was constructed from the GNAT
2452 conversion node and not from the inner Expression. */
2453 if (Nkind (gnat_actual
) == N_Type_Conversion
)
2456 = convert_with_check
2457 (Etype (Expression (gnat_actual
)), gnu_result
,
2458 Do_Overflow_Check (gnat_actual
),
2459 Do_Range_Check (Expression (gnat_actual
)),
2460 Float_Truncate (gnat_actual
));
2462 if (!Is_Composite_Type
2463 (Underlying_Type (Etype (gnat_formal
))))
2465 = convert (TREE_TYPE (gnu_result
), gnu_actual
);
2468 /* Unchecked conversions as actuals for out parameters are not
2469 allowed in user code because they are not variables, but do
2470 occur in front-end expansions. The associated gnu_name is
2471 always obtained from the inner expression in such cases. */
2472 else if (Nkind (gnat_actual
) == N_Unchecked_Type_Conversion
)
2473 gnu_result
= unchecked_convert (TREE_TYPE (gnu_actual
),
2475 No_Truncation (gnat_actual
));
2478 if (Do_Range_Check (gnat_actual
))
2479 gnu_result
= emit_range_check (gnu_result
,
2480 Etype (gnat_actual
));
2482 if (!(!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual
)))
2483 && TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_result
)))))
2484 gnu_result
= convert (TREE_TYPE (gnu_actual
), gnu_result
);
2487 gnu_result
= build_binary_op (MODIFY_EXPR
, NULL_TREE
,
2488 gnu_actual
, gnu_result
);
2489 set_expr_location_from_node (gnu_result
, gnat_actual
);
2490 append_to_statement_list (gnu_result
, &gnu_before_list
);
2491 scalar_return_list
= TREE_CHAIN (scalar_return_list
);
2492 gnu_name_list
= TREE_CHAIN (gnu_name_list
);
2496 append_to_statement_list (gnu_subprog_call
, &gnu_before_list
);
2498 append_to_statement_list (gnu_after_list
, &gnu_before_list
);
2499 return gnu_before_list
;
2502 /* Subroutine of gnat_to_gnu to translate gnat_node, an
2503 N_Handled_Sequence_Of_Statements, to a GCC tree, which is returned. */
2506 Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node
)
2508 tree gnu_jmpsave_decl
= NULL_TREE
;
2509 tree gnu_jmpbuf_decl
= NULL_TREE
;
2510 /* If just annotating, ignore all EH and cleanups. */
2511 bool gcc_zcx
= (!type_annotate_only
2512 && Present (Exception_Handlers (gnat_node
))
2513 && Exception_Mechanism
== Back_End_Exceptions
);
2515 = (!type_annotate_only
&& Present (Exception_Handlers (gnat_node
))
2516 && Exception_Mechanism
== Setjmp_Longjmp
);
2517 bool at_end
= !type_annotate_only
&& Present (At_End_Proc (gnat_node
));
2518 bool binding_for_block
= (at_end
|| gcc_zcx
|| setjmp_longjmp
);
2519 tree gnu_inner_block
; /* The statement(s) for the block itself. */
2524 /* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes
2525 and we have our own SJLJ mechanism. To call the GCC mechanism, we call
2526 add_cleanup, and when we leave the binding, end_stmt_group will create
2527 the TRY_FINALLY_EXPR.
2529 ??? The region level calls down there have been specifically put in place
2530 for a ZCX context and currently the order in which things are emitted
2531 (region/handlers) is different from the SJLJ case. Instead of putting
2532 other calls with different conditions at other places for the SJLJ case,
2533 it seems cleaner to reorder things for the SJLJ case and generalize the
2534 condition to make it not ZCX specific.
2536 If there are any exceptions or cleanup processing involved, we need an
2537 outer statement group (for Setjmp_Longjmp) and binding level. */
2538 if (binding_for_block
)
2540 start_stmt_group ();
2544 /* If using setjmp_longjmp, make the variables for the setjmp buffer and save
2545 area for address of previous buffer. Do this first since we need to have
2546 the setjmp buf known for any decls in this block. */
2549 gnu_jmpsave_decl
= create_var_decl (get_identifier ("JMPBUF_SAVE"),
2550 NULL_TREE
, jmpbuf_ptr_type
,
2551 build_call_0_expr (get_jmpbuf_decl
),
2552 false, false, false, false, NULL
,
2554 DECL_ARTIFICIAL (gnu_jmpsave_decl
) = 1;
2556 /* The __builtin_setjmp receivers will immediately reinstall it. Now
2557 because of the unstructured form of EH used by setjmp_longjmp, there
2558 might be forward edges going to __builtin_setjmp receivers on which
2559 it is uninitialized, although they will never be actually taken. */
2560 TREE_NO_WARNING (gnu_jmpsave_decl
) = 1;
2561 gnu_jmpbuf_decl
= create_var_decl (get_identifier ("JMP_BUF"),
2562 NULL_TREE
, jmpbuf_type
,
2563 NULL_TREE
, false, false, false, false,
2565 DECL_ARTIFICIAL (gnu_jmpbuf_decl
) = 1;
2567 set_block_jmpbuf_decl (gnu_jmpbuf_decl
);
2569 /* When we exit this block, restore the saved value. */
2570 add_cleanup (build_call_1_expr (set_jmpbuf_decl
, gnu_jmpsave_decl
),
2571 End_Label (gnat_node
));
2574 /* If we are to call a function when exiting this block, add a cleanup
2575 to the binding level we made above. Note that add_cleanup is FIFO
2576 so we must register this cleanup after the EH cleanup just above. */
2578 add_cleanup (build_call_0_expr (gnat_to_gnu (At_End_Proc (gnat_node
))),
2579 End_Label (gnat_node
));
2581 /* Now build the tree for the declarations and statements inside this block.
2582 If this is SJLJ, set our jmp_buf as the current buffer. */
2583 start_stmt_group ();
2586 add_stmt (build_call_1_expr (set_jmpbuf_decl
,
2587 build_unary_op (ADDR_EXPR
, NULL_TREE
,
2590 if (Present (First_Real_Statement (gnat_node
)))
2591 process_decls (Statements (gnat_node
), Empty
,
2592 First_Real_Statement (gnat_node
), true, true);
2594 /* Generate code for each statement in the block. */
2595 for (gnat_temp
= (Present (First_Real_Statement (gnat_node
))
2596 ? First_Real_Statement (gnat_node
)
2597 : First (Statements (gnat_node
)));
2598 Present (gnat_temp
); gnat_temp
= Next (gnat_temp
))
2599 add_stmt (gnat_to_gnu (gnat_temp
));
2600 gnu_inner_block
= end_stmt_group ();
2602 /* Now generate code for the two exception models, if either is relevant for
2606 tree
*gnu_else_ptr
= 0;
2609 /* Make a binding level for the exception handling declarations and code
2610 and set up gnu_except_ptr_stack for the handlers to use. */
2611 start_stmt_group ();
2614 push_stack (&gnu_except_ptr_stack
, NULL_TREE
,
2615 create_var_decl (get_identifier ("EXCEPT_PTR"),
2617 build_pointer_type (except_type_node
),
2618 build_call_0_expr (get_excptr_decl
), false,
2619 false, false, false, NULL
, gnat_node
));
2621 /* Generate code for each handler. The N_Exception_Handler case does the
2622 real work and returns a COND_EXPR for each handler, which we chain
2624 for (gnat_temp
= First_Non_Pragma (Exception_Handlers (gnat_node
));
2625 Present (gnat_temp
); gnat_temp
= Next_Non_Pragma (gnat_temp
))
2627 gnu_expr
= gnat_to_gnu (gnat_temp
);
2629 /* If this is the first one, set it as the outer one. Otherwise,
2630 point the "else" part of the previous handler to us. Then point
2631 to our "else" part. */
2633 add_stmt (gnu_expr
);
2635 *gnu_else_ptr
= gnu_expr
;
2637 gnu_else_ptr
= &COND_EXPR_ELSE (gnu_expr
);
2640 /* If none of the exception handlers did anything, re-raise but do not
2642 gnu_expr
= build_call_1_expr (raise_nodefer_decl
,
2643 TREE_VALUE (gnu_except_ptr_stack
));
2644 set_expr_location_from_node (gnu_expr
, gnat_node
);
2647 *gnu_else_ptr
= gnu_expr
;
2649 add_stmt (gnu_expr
);
2651 /* End the binding level dedicated to the exception handlers and get the
2652 whole statement group. */
2653 pop_stack (&gnu_except_ptr_stack
);
2655 gnu_handler
= end_stmt_group ();
2657 /* If the setjmp returns 1, we restore our incoming longjmp value and
2658 then check the handlers. */
2659 start_stmt_group ();
2660 add_stmt_with_node (build_call_1_expr (set_jmpbuf_decl
,
2663 add_stmt (gnu_handler
);
2664 gnu_handler
= end_stmt_group ();
2666 /* This block is now "if (setjmp) ... <handlers> else <block>". */
2667 gnu_result
= build3 (COND_EXPR
, void_type_node
,
2670 build_unary_op (ADDR_EXPR
, NULL_TREE
,
2672 gnu_handler
, gnu_inner_block
);
2678 /* First make a block containing the handlers. */
2679 start_stmt_group ();
2680 for (gnat_temp
= First_Non_Pragma (Exception_Handlers (gnat_node
));
2681 Present (gnat_temp
);
2682 gnat_temp
= Next_Non_Pragma (gnat_temp
))
2683 add_stmt (gnat_to_gnu (gnat_temp
));
2684 gnu_handlers
= end_stmt_group ();
2686 /* Now make the TRY_CATCH_EXPR for the block. */
2687 gnu_result
= build2 (TRY_CATCH_EXPR
, void_type_node
,
2688 gnu_inner_block
, gnu_handlers
);
2691 gnu_result
= gnu_inner_block
;
2693 /* Now close our outer block, if we had to make one. */
2694 if (binding_for_block
)
2696 add_stmt (gnu_result
);
2698 gnu_result
= end_stmt_group ();
2704 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
2705 to a GCC tree, which is returned. This is the variant for Setjmp_Longjmp
2706 exception handling. */
2709 Exception_Handler_to_gnu_sjlj (Node_Id gnat_node
)
2711 /* Unless this is "Others" or the special "Non-Ada" exception for Ada, make
2712 an "if" statement to select the proper exceptions. For "Others", exclude
2713 exceptions where Handled_By_Others is nonzero unless the All_Others flag
2714 is set. For "Non-ada", accept an exception if "Lang" is 'V'. */
2715 tree gnu_choice
= integer_zero_node
;
2716 tree gnu_body
= build_stmt_group (Statements (gnat_node
), false);
2719 for (gnat_temp
= First (Exception_Choices (gnat_node
));
2720 gnat_temp
; gnat_temp
= Next (gnat_temp
))
2724 if (Nkind (gnat_temp
) == N_Others_Choice
)
2726 if (All_Others (gnat_temp
))
2727 this_choice
= integer_one_node
;
2731 (EQ_EXPR
, integer_type_node
,
2736 (INDIRECT_REF
, NULL_TREE
,
2737 TREE_VALUE (gnu_except_ptr_stack
)),
2738 get_identifier ("not_handled_by_others"), NULL_TREE
,
2743 else if (Nkind (gnat_temp
) == N_Identifier
2744 || Nkind (gnat_temp
) == N_Expanded_Name
)
2746 Entity_Id gnat_ex_id
= Entity (gnat_temp
);
2749 /* Exception may be a renaming. Recover original exception which is
2750 the one elaborated and registered. */
2751 if (Present (Renamed_Object (gnat_ex_id
)))
2752 gnat_ex_id
= Renamed_Object (gnat_ex_id
);
2754 gnu_expr
= gnat_to_gnu_entity (gnat_ex_id
, NULL_TREE
, 0);
2758 (EQ_EXPR
, integer_type_node
, TREE_VALUE (gnu_except_ptr_stack
),
2759 convert (TREE_TYPE (TREE_VALUE (gnu_except_ptr_stack
)),
2760 build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_expr
)));
2762 /* If this is the distinguished exception "Non_Ada_Error" (and we are
2763 in VMS mode), also allow a non-Ada exception (a VMS condition) t
2765 if (Is_Non_Ada_Error (Entity (gnat_temp
)))
2768 = build_component_ref
2769 (build_unary_op (INDIRECT_REF
, NULL_TREE
,
2770 TREE_VALUE (gnu_except_ptr_stack
)),
2771 get_identifier ("lang"), NULL_TREE
, false);
2775 (TRUTH_ORIF_EXPR
, integer_type_node
,
2776 build_binary_op (EQ_EXPR
, integer_type_node
, gnu_comp
,
2777 build_int_cst (TREE_TYPE (gnu_comp
), 'V')),
2784 gnu_choice
= build_binary_op (TRUTH_ORIF_EXPR
, integer_type_node
,
2785 gnu_choice
, this_choice
);
2788 return build3 (COND_EXPR
, void_type_node
, gnu_choice
, gnu_body
, NULL_TREE
);
2791 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
2792 to a GCC tree, which is returned. This is the variant for ZCX. */
2795 Exception_Handler_to_gnu_zcx (Node_Id gnat_node
)
2797 tree gnu_etypes_list
= NULL_TREE
;
2800 tree gnu_current_exc_ptr
;
2801 tree gnu_incoming_exc_ptr
;
2804 /* We build a TREE_LIST of nodes representing what exception types this
2805 handler can catch, with special cases for others and all others cases.
2807 Each exception type is actually identified by a pointer to the exception
2808 id, or to a dummy object for "others" and "all others".
2810 Care should be taken to ensure that the control flow impact of "others"
2811 and "all others" is known to GCC. lang_eh_type_covers is doing the trick
2813 for (gnat_temp
= First (Exception_Choices (gnat_node
));
2814 gnat_temp
; gnat_temp
= Next (gnat_temp
))
2816 if (Nkind (gnat_temp
) == N_Others_Choice
)
2819 = All_Others (gnat_temp
) ? all_others_decl
: others_decl
;
2822 = build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_expr
);
2824 else if (Nkind (gnat_temp
) == N_Identifier
2825 || Nkind (gnat_temp
) == N_Expanded_Name
)
2827 Entity_Id gnat_ex_id
= Entity (gnat_temp
);
2829 /* Exception may be a renaming. Recover original exception which is
2830 the one elaborated and registered. */
2831 if (Present (Renamed_Object (gnat_ex_id
)))
2832 gnat_ex_id
= Renamed_Object (gnat_ex_id
);
2834 gnu_expr
= gnat_to_gnu_entity (gnat_ex_id
, NULL_TREE
, 0);
2835 gnu_etype
= build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_expr
);
2837 /* The Non_Ada_Error case for VMS exceptions is handled
2838 by the personality routine. */
2843 /* The GCC interface expects NULL to be passed for catch all handlers, so
2844 it would be quite tempting to set gnu_etypes_list to NULL if gnu_etype
2845 is integer_zero_node. It would not work, however, because GCC's
2846 notion of "catch all" is stronger than our notion of "others". Until
2847 we correctly use the cleanup interface as well, doing that would
2848 prevent the "all others" handlers from being seen, because nothing
2849 can be caught beyond a catch all from GCC's point of view. */
2850 gnu_etypes_list
= tree_cons (NULL_TREE
, gnu_etype
, gnu_etypes_list
);
2853 start_stmt_group ();
2856 /* Expand a call to the begin_handler hook at the beginning of the handler,
2857 and arrange for a call to the end_handler hook to occur on every possible
2860 The hooks expect a pointer to the low level occurrence. This is required
2861 for our stack management scheme because a raise inside the handler pushes
2862 a new occurrence on top of the stack, which means that this top does not
2863 necessarily match the occurrence this handler was dealing with.
2865 The EXC_PTR_EXPR object references the exception occurrence being
2866 propagated. Upon handler entry, this is the exception for which the
2867 handler is triggered. This might not be the case upon handler exit,
2868 however, as we might have a new occurrence propagated by the handler's
2869 body, and the end_handler hook called as a cleanup in this context.
2871 We use a local variable to retrieve the incoming value at handler entry
2872 time, and reuse it to feed the end_handler hook's argument at exit. */
2873 gnu_current_exc_ptr
= build0 (EXC_PTR_EXPR
, ptr_type_node
);
2874 gnu_incoming_exc_ptr
= create_var_decl (get_identifier ("EXPTR"), NULL_TREE
,
2875 ptr_type_node
, gnu_current_exc_ptr
,
2876 false, false, false, false, NULL
,
2879 add_stmt_with_node (build_call_1_expr (begin_handler_decl
,
2880 gnu_incoming_exc_ptr
),
2882 /* ??? We don't seem to have an End_Label at hand to set the location. */
2883 add_cleanup (build_call_1_expr (end_handler_decl
, gnu_incoming_exc_ptr
),
2885 add_stmt_list (Statements (gnat_node
));
2888 return build2 (CATCH_EXPR
, void_type_node
, gnu_etypes_list
,
2892 /* Subroutine of gnat_to_gnu to generate code for an N_Compilation unit. */
2895 Compilation_Unit_to_gnu (Node_Id gnat_node
)
2897 /* Make the decl for the elaboration procedure. */
2898 bool body_p
= (Defining_Entity (Unit (gnat_node
)),
2899 Nkind (Unit (gnat_node
)) == N_Package_Body
2900 || Nkind (Unit (gnat_node
)) == N_Subprogram_Body
);
2901 Entity_Id gnat_unit_entity
= Defining_Entity (Unit (gnat_node
));
2902 tree gnu_elab_proc_decl
2903 = create_subprog_decl
2904 (create_concat_name (gnat_unit_entity
,
2905 body_p
? "elabb" : "elabs"),
2906 NULL_TREE
, void_ftype
, NULL_TREE
, false, true, false, NULL
,
2908 struct elab_info
*info
;
2910 push_stack (&gnu_elab_proc_stack
, NULL_TREE
, gnu_elab_proc_decl
);
2912 DECL_ELABORATION_PROC_P (gnu_elab_proc_decl
) = 1;
2913 allocate_struct_function (gnu_elab_proc_decl
);
2914 Sloc_to_locus (Sloc (gnat_unit_entity
), &cfun
->function_end_locus
);
2917 /* For a body, first process the spec if there is one. */
2918 if (Nkind (Unit (gnat_node
)) == N_Package_Body
2919 || (Nkind (Unit (gnat_node
)) == N_Subprogram_Body
2920 && !Acts_As_Spec (gnat_node
)))
2922 add_stmt (gnat_to_gnu (Library_Unit (gnat_node
)));
2923 finalize_from_with_types ();
2926 process_inlined_subprograms (gnat_node
);
2928 if (type_annotate_only
&& gnat_node
== Cunit (Main_Unit
))
2930 elaborate_all_entities (gnat_node
);
2932 if (Nkind (Unit (gnat_node
)) == N_Subprogram_Declaration
2933 || Nkind (Unit (gnat_node
)) == N_Generic_Package_Declaration
2934 || Nkind (Unit (gnat_node
)) == N_Generic_Subprogram_Declaration
)
2938 process_decls (Declarations (Aux_Decls_Node (gnat_node
)), Empty
, Empty
,
2940 add_stmt (gnat_to_gnu (Unit (gnat_node
)));
2942 /* Process any pragmas and actions following the unit. */
2943 add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node
)));
2944 add_stmt_list (Actions (Aux_Decls_Node (gnat_node
)));
2945 finalize_from_with_types ();
2947 /* Save away what we've made so far and record this potential elaboration
2949 info
= (struct elab_info
*) ggc_alloc (sizeof (struct elab_info
));
2950 set_current_block_context (gnu_elab_proc_decl
);
2952 DECL_SAVED_TREE (gnu_elab_proc_decl
) = end_stmt_group ();
2953 info
->next
= elab_info_list
;
2954 info
->elab_proc
= gnu_elab_proc_decl
;
2955 info
->gnat_node
= gnat_node
;
2956 elab_info_list
= info
;
2958 /* Generate elaboration code for this unit, if necessary, and say whether
2960 pop_stack (&gnu_elab_proc_stack
);
2962 /* Invalidate the global renaming pointers. This is necessary because
2963 stabilization of the renamed entities may create SAVE_EXPRs which
2964 have been tied to a specific elaboration routine just above. */
2965 invalidate_global_renaming_pointers ();
2968 /* This function is the driver of the GNAT to GCC tree transformation
2969 process. It is the entry point of the tree transformer. GNAT_NODE is the
2970 root of some GNAT tree. Return the root of the corresponding GCC tree.
2971 If this is an expression, return the GCC equivalent of the expression. If
2972 it is a statement, return the statement. In the case when called for a
2973 statement, it may also add statements to the current statement group, in
2974 which case anything it returns is to be interpreted as occurring after
2975 anything `it already added. */
2978 gnat_to_gnu (Node_Id gnat_node
)
2980 bool went_into_elab_proc
= false;
2981 tree gnu_result
= error_mark_node
; /* Default to no value. */
2982 tree gnu_result_type
= void_type_node
;
2984 tree gnu_lhs
, gnu_rhs
;
2987 /* Save node number for error message and set location information. */
2988 error_gnat_node
= gnat_node
;
2989 Sloc_to_locus (Sloc (gnat_node
), &input_location
);
2991 if (type_annotate_only
2992 && IN (Nkind (gnat_node
), N_Statement_Other_Than_Procedure_Call
))
2993 return alloc_stmt_list ();
2995 /* If this node is a non-static subexpression and we are only
2996 annotating types, make this into a NULL_EXPR. */
2997 if (type_annotate_only
2998 && IN (Nkind (gnat_node
), N_Subexpr
)
2999 && Nkind (gnat_node
) != N_Identifier
3000 && !Compile_Time_Known_Value (gnat_node
))
3001 return build1 (NULL_EXPR
, get_unpadded_type (Etype (gnat_node
)),
3002 build_call_raise (CE_Range_Check_Failed
, gnat_node
,
3003 N_Raise_Constraint_Error
));
3005 /* If this is a Statement and we are at top level, it must be part of the
3006 elaboration procedure, so mark us as being in that procedure and push our
3009 If we are in the elaboration procedure, check if we are violating a a
3010 No_Elaboration_Code restriction by having a statement there. */
3011 if ((IN (Nkind (gnat_node
), N_Statement_Other_Than_Procedure_Call
)
3012 && Nkind (gnat_node
) != N_Null_Statement
)
3013 || Nkind (gnat_node
) == N_Procedure_Call_Statement
3014 || Nkind (gnat_node
) == N_Label
3015 || Nkind (gnat_node
) == N_Implicit_Label_Declaration
3016 || Nkind (gnat_node
) == N_Handled_Sequence_Of_Statements
3017 || ((Nkind (gnat_node
) == N_Raise_Constraint_Error
3018 || Nkind (gnat_node
) == N_Raise_Storage_Error
3019 || Nkind (gnat_node
) == N_Raise_Program_Error
)
3020 && (Ekind (Etype (gnat_node
)) == E_Void
)))
3022 if (!current_function_decl
)
3024 current_function_decl
= TREE_VALUE (gnu_elab_proc_stack
);
3025 start_stmt_group ();
3027 went_into_elab_proc
= true;
3030 /* Don't check for a possible No_Elaboration_Code restriction violation
3031 on N_Handled_Sequence_Of_Statements, as we want to signal an error on
3032 every nested real statement instead. This also avoids triggering
3033 spurious errors on dummy (empty) sequences created by the front-end
3034 for package bodies in some cases. */
3036 if (current_function_decl
== TREE_VALUE (gnu_elab_proc_stack
)
3037 && Nkind (gnat_node
) != N_Handled_Sequence_Of_Statements
)
3038 Check_Elaboration_Code_Allowed (gnat_node
);
3041 switch (Nkind (gnat_node
))
3043 /********************************/
3044 /* Chapter 2: Lexical Elements: */
3045 /********************************/
3048 case N_Expanded_Name
:
3049 case N_Operator_Symbol
:
3050 case N_Defining_Identifier
:
3051 gnu_result
= Identifier_to_gnu (gnat_node
, &gnu_result_type
);
3054 case N_Integer_Literal
:
3058 /* Get the type of the result, looking inside any padding and
3059 justified modular types. Then get the value in that type. */
3060 gnu_type
= gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3062 if (TREE_CODE (gnu_type
) == RECORD_TYPE
3063 && TYPE_JUSTIFIED_MODULAR_P (gnu_type
))
3064 gnu_type
= TREE_TYPE (TYPE_FIELDS (gnu_type
));
3066 gnu_result
= UI_To_gnu (Intval (gnat_node
), gnu_type
);
3068 /* If the result overflows (meaning it doesn't fit in its base type),
3069 abort. We would like to check that the value is within the range
3070 of the subtype, but that causes problems with subtypes whose usage
3071 will raise Constraint_Error and with biased representation, so
3073 gcc_assert (!TREE_OVERFLOW (gnu_result
));
3077 case N_Character_Literal
:
3078 /* If a Entity is present, it means that this was one of the
3079 literals in a user-defined character type. In that case,
3080 just return the value in the CONST_DECL. Otherwise, use the
3081 character code. In that case, the base type should be an
3082 INTEGER_TYPE, but we won't bother checking for that. */
3083 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3084 if (Present (Entity (gnat_node
)))
3085 gnu_result
= DECL_INITIAL (get_gnu_tree (Entity (gnat_node
)));
3088 = build_int_cst_type
3089 (gnu_result_type
, UI_To_CC (Char_Literal_Value (gnat_node
)));
3092 case N_Real_Literal
:
3093 /* If this is of a fixed-point type, the value we want is the
3094 value of the corresponding integer. */
3095 if (IN (Ekind (Underlying_Type (Etype (gnat_node
))), Fixed_Point_Kind
))
3097 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3098 gnu_result
= UI_To_gnu (Corresponding_Integer_Value (gnat_node
),
3100 gcc_assert (!TREE_OVERFLOW (gnu_result
));
3103 /* We should never see a Vax_Float type literal, since the front end
3104 is supposed to transform these using appropriate conversions */
3105 else if (Vax_Float (Underlying_Type (Etype (gnat_node
))))
3110 Ureal ur_realval
= Realval (gnat_node
);
3112 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3114 /* If the real value is zero, so is the result. Otherwise,
3115 convert it to a machine number if it isn't already. That
3116 forces BASE to 0 or 2 and simplifies the rest of our logic. */
3117 if (UR_Is_Zero (ur_realval
))
3118 gnu_result
= convert (gnu_result_type
, integer_zero_node
);
3121 if (!Is_Machine_Number (gnat_node
))
3123 = Machine (Base_Type (Underlying_Type (Etype (gnat_node
))),
3124 ur_realval
, Round_Even
, gnat_node
);
3127 = UI_To_gnu (Numerator (ur_realval
), gnu_result_type
);
3129 /* If we have a base of zero, divide by the denominator.
3130 Otherwise, the base must be 2 and we scale the value, which
3131 we know can fit in the mantissa of the type (hence the use
3132 of that type above). */
3133 if (No (Rbase (ur_realval
)))
3135 = build_binary_op (RDIV_EXPR
,
3136 get_base_type (gnu_result_type
),
3138 UI_To_gnu (Denominator (ur_realval
),
3142 REAL_VALUE_TYPE tmp
;
3144 gcc_assert (Rbase (ur_realval
) == 2);
3145 real_ldexp (&tmp
, &TREE_REAL_CST (gnu_result
),
3146 - UI_To_Int (Denominator (ur_realval
)));
3147 gnu_result
= build_real (gnu_result_type
, tmp
);
3151 /* Now see if we need to negate the result. Do it this way to
3152 properly handle -0. */
3153 if (UR_Is_Negative (Realval (gnat_node
)))
3155 = build_unary_op (NEGATE_EXPR
, get_base_type (gnu_result_type
),
3161 case N_String_Literal
:
3162 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3163 if (TYPE_PRECISION (TREE_TYPE (gnu_result_type
)) == HOST_BITS_PER_CHAR
)
3165 String_Id gnat_string
= Strval (gnat_node
);
3166 int length
= String_Length (gnat_string
);
3169 if (length
>= ALLOCA_THRESHOLD
)
3170 string
= xmalloc (length
+ 1); /* in case of large strings */
3172 string
= (char *) alloca (length
+ 1);
3174 /* Build the string with the characters in the literal. Note
3175 that Ada strings are 1-origin. */
3176 for (i
= 0; i
< length
; i
++)
3177 string
[i
] = Get_String_Char (gnat_string
, i
+ 1);
3179 /* Put a null at the end of the string in case it's in a context
3180 where GCC will want to treat it as a C string. */
3183 gnu_result
= build_string (length
, string
);
3185 /* Strings in GCC don't normally have types, but we want
3186 this to not be converted to the array type. */
3187 TREE_TYPE (gnu_result
) = gnu_result_type
;
3189 if (length
>= ALLOCA_THRESHOLD
) /* free if heap-allocated */
3194 /* Build a list consisting of each character, then make
3196 String_Id gnat_string
= Strval (gnat_node
);
3197 int length
= String_Length (gnat_string
);
3199 tree gnu_list
= NULL_TREE
;
3200 tree gnu_idx
= TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type
));
3202 for (i
= 0; i
< length
; i
++)
3205 = tree_cons (gnu_idx
,
3206 build_int_cst (TREE_TYPE (gnu_result_type
),
3207 Get_String_Char (gnat_string
,
3211 gnu_idx
= int_const_binop (PLUS_EXPR
, gnu_idx
, integer_one_node
,
3216 = gnat_build_constructor (gnu_result_type
, nreverse (gnu_list
));
3221 gnu_result
= Pragma_to_gnu (gnat_node
);
3224 /**************************************/
3225 /* Chapter 3: Declarations and Types: */
3226 /**************************************/
3228 case N_Subtype_Declaration
:
3229 case N_Full_Type_Declaration
:
3230 case N_Incomplete_Type_Declaration
:
3231 case N_Private_Type_Declaration
:
3232 case N_Private_Extension_Declaration
:
3233 case N_Task_Type_Declaration
:
3234 process_type (Defining_Entity (gnat_node
));
3235 gnu_result
= alloc_stmt_list ();
3238 case N_Object_Declaration
:
3239 case N_Exception_Declaration
:
3240 gnat_temp
= Defining_Entity (gnat_node
);
3241 gnu_result
= alloc_stmt_list ();
3243 /* If we are just annotating types and this object has an unconstrained
3244 or task type, don't elaborate it. */
3245 if (type_annotate_only
3246 && (((Is_Array_Type (Etype (gnat_temp
))
3247 || Is_Record_Type (Etype (gnat_temp
)))
3248 && !Is_Constrained (Etype (gnat_temp
)))
3249 || Is_Concurrent_Type (Etype (gnat_temp
))))
3252 if (Present (Expression (gnat_node
))
3253 && !(Nkind (gnat_node
) == N_Object_Declaration
3254 && No_Initialization (gnat_node
))
3255 && (!type_annotate_only
3256 || Compile_Time_Known_Value (Expression (gnat_node
))))
3258 gnu_expr
= gnat_to_gnu (Expression (gnat_node
));
3259 if (Do_Range_Check (Expression (gnat_node
)))
3260 gnu_expr
= emit_range_check (gnu_expr
, Etype (gnat_temp
));
3262 /* If this object has its elaboration delayed, we must force
3263 evaluation of GNU_EXPR right now and save it for when the object
3265 if (Present (Freeze_Node (gnat_temp
)))
3267 if ((Is_Public (gnat_temp
) || global_bindings_p ())
3268 && !TREE_CONSTANT (gnu_expr
))
3270 = create_var_decl (create_concat_name (gnat_temp
, "init"),
3271 NULL_TREE
, TREE_TYPE (gnu_expr
),
3272 gnu_expr
, false, Is_Public (gnat_temp
),
3273 false, false, NULL
, gnat_temp
);
3275 gnu_expr
= maybe_variable (gnu_expr
);
3277 save_gnu_tree (gnat_node
, gnu_expr
, true);
3281 gnu_expr
= NULL_TREE
;
3283 if (type_annotate_only
&& gnu_expr
&& TREE_CODE (gnu_expr
) == ERROR_MARK
)
3284 gnu_expr
= NULL_TREE
;
3286 if (No (Freeze_Node (gnat_temp
)))
3287 gnat_to_gnu_entity (gnat_temp
, gnu_expr
, 1);
3290 case N_Object_Renaming_Declaration
:
3291 gnat_temp
= Defining_Entity (gnat_node
);
3293 /* Don't do anything if this renaming is handled by the front end or if
3294 we are just annotating types and this object has a composite or task
3295 type, don't elaborate it. We return the result in case it has any
3296 SAVE_EXPRs in it that need to be evaluated here. */
3297 if (!Is_Renaming_Of_Object (gnat_temp
)
3298 && ! (type_annotate_only
3299 && (Is_Array_Type (Etype (gnat_temp
))
3300 || Is_Record_Type (Etype (gnat_temp
))
3301 || Is_Concurrent_Type (Etype (gnat_temp
)))))
3303 = gnat_to_gnu_entity (gnat_temp
,
3304 gnat_to_gnu (Renamed_Object (gnat_temp
)), 1);
3306 gnu_result
= alloc_stmt_list ();
3309 case N_Implicit_Label_Declaration
:
3310 gnat_to_gnu_entity (Defining_Entity (gnat_node
), NULL_TREE
, 1);
3311 gnu_result
= alloc_stmt_list ();
3314 case N_Exception_Renaming_Declaration
:
3315 case N_Number_Declaration
:
3316 case N_Package_Renaming_Declaration
:
3317 case N_Subprogram_Renaming_Declaration
:
3318 /* These are fully handled in the front end. */
3319 gnu_result
= alloc_stmt_list ();
3322 /*************************************/
3323 /* Chapter 4: Names and Expressions: */
3324 /*************************************/
3326 case N_Explicit_Dereference
:
3327 gnu_result
= gnat_to_gnu (Prefix (gnat_node
));
3328 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3329 gnu_result
= build_unary_op (INDIRECT_REF
, NULL_TREE
, gnu_result
);
3332 case N_Indexed_Component
:
3334 tree gnu_array_object
= gnat_to_gnu (Prefix (gnat_node
));
3338 Node_Id
*gnat_expr_array
;
3340 gnu_array_object
= maybe_implicit_deref (gnu_array_object
);
3341 gnu_array_object
= maybe_unconstrained_array (gnu_array_object
);
3343 /* If we got a padded type, remove it too. */
3344 if (TREE_CODE (TREE_TYPE (gnu_array_object
)) == RECORD_TYPE
3345 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_array_object
)))
3347 = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_array_object
))),
3350 gnu_result
= gnu_array_object
;
3352 /* First compute the number of dimensions of the array, then
3353 fill the expression array, the order depending on whether
3354 this is a Convention_Fortran array or not. */
3355 for (ndim
= 1, gnu_type
= TREE_TYPE (gnu_array_object
);
3356 TREE_CODE (TREE_TYPE (gnu_type
)) == ARRAY_TYPE
3357 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type
));
3358 ndim
++, gnu_type
= TREE_TYPE (gnu_type
))
3361 gnat_expr_array
= (Node_Id
*) alloca (ndim
* sizeof (Node_Id
));
3363 if (TYPE_CONVENTION_FORTRAN_P (TREE_TYPE (gnu_array_object
)))
3364 for (i
= ndim
- 1, gnat_temp
= First (Expressions (gnat_node
));
3366 i
--, gnat_temp
= Next (gnat_temp
))
3367 gnat_expr_array
[i
] = gnat_temp
;
3369 for (i
= 0, gnat_temp
= First (Expressions (gnat_node
));
3371 i
++, gnat_temp
= Next (gnat_temp
))
3372 gnat_expr_array
[i
] = gnat_temp
;
3374 for (i
= 0, gnu_type
= TREE_TYPE (gnu_array_object
);
3375 i
< ndim
; i
++, gnu_type
= TREE_TYPE (gnu_type
))
3377 gcc_assert (TREE_CODE (gnu_type
) == ARRAY_TYPE
);
3378 gnat_temp
= gnat_expr_array
[i
];
3379 gnu_expr
= gnat_to_gnu (gnat_temp
);
3381 if (Do_Range_Check (gnat_temp
))
3384 (gnu_array_object
, gnu_expr
,
3385 TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
))),
3386 TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
))));
3388 gnu_result
= build_binary_op (ARRAY_REF
, NULL_TREE
,
3389 gnu_result
, gnu_expr
);
3393 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3399 Node_Id gnat_range_node
= Discrete_Range (gnat_node
);
3401 gnu_result
= gnat_to_gnu (Prefix (gnat_node
));
3402 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3404 /* Do any implicit dereferences of the prefix and do any needed
3406 gnu_result
= maybe_implicit_deref (gnu_result
);
3407 gnu_result
= maybe_unconstrained_array (gnu_result
);
3408 gnu_type
= TREE_TYPE (gnu_result
);
3409 if (Do_Range_Check (gnat_range_node
))
3411 /* Get the bounds of the slice. */
3413 = TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_result_type
));
3414 tree gnu_min_expr
= TYPE_MIN_VALUE (gnu_index_type
);
3415 tree gnu_max_expr
= TYPE_MAX_VALUE (gnu_index_type
);
3416 /* Get the permitted bounds. */
3417 tree gnu_base_index_type
3418 = TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type
));
3419 tree gnu_base_min_expr
= TYPE_MIN_VALUE (gnu_base_index_type
);
3420 tree gnu_base_max_expr
= TYPE_MAX_VALUE (gnu_base_index_type
);
3421 tree gnu_expr_l
, gnu_expr_h
, gnu_expr_type
;
3423 /* Check to see that the minimum slice value is in range. */
3424 gnu_expr_l
= emit_index_check (gnu_result
,
3429 /* Check to see that the maximum slice value is in range. */
3430 gnu_expr_h
= emit_index_check (gnu_result
,
3435 /* Derive a good type to convert everything to. */
3436 gnu_expr_type
= get_base_type (TREE_TYPE (gnu_expr_l
));
3438 /* Build a compound expression that does the range checks and
3439 returns the low bound. */
3440 gnu_expr
= build_binary_op (COMPOUND_EXPR
, gnu_expr_type
,
3441 convert (gnu_expr_type
, gnu_expr_h
),
3442 convert (gnu_expr_type
, gnu_expr_l
));
3444 /* Build a conditional expression that does the range check and
3445 returns the low bound if the slice is not empty (max >= min),
3446 and returns the naked low bound otherwise (max < min), unless
3447 it is non-constant and the high bound is; this prevents VRP
3448 from inferring bogus ranges on the unlikely path. */
3449 gnu_expr
= fold_build3 (COND_EXPR
, gnu_expr_type
,
3450 build_binary_op (GE_EXPR
, gnu_expr_type
,
3451 convert (gnu_expr_type
,
3453 convert (gnu_expr_type
,
3456 TREE_CODE (gnu_min_expr
) != INTEGER_CST
3457 && TREE_CODE (gnu_max_expr
) == INTEGER_CST
3458 ? gnu_max_expr
: gnu_min_expr
);
3461 /* Simply return the naked low bound. */
3462 gnu_expr
= TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type
));
3464 gnu_result
= build_binary_op (ARRAY_RANGE_REF
, gnu_result_type
,
3465 gnu_result
, gnu_expr
);
3469 case N_Selected_Component
:
3471 tree gnu_prefix
= gnat_to_gnu (Prefix (gnat_node
));
3472 Entity_Id gnat_field
= Entity (Selector_Name (gnat_node
));
3473 Entity_Id gnat_pref_type
= Etype (Prefix (gnat_node
));
3476 while (IN (Ekind (gnat_pref_type
), Incomplete_Or_Private_Kind
)
3477 || IN (Ekind (gnat_pref_type
), Access_Kind
))
3479 if (IN (Ekind (gnat_pref_type
), Incomplete_Or_Private_Kind
))
3480 gnat_pref_type
= Underlying_Type (gnat_pref_type
);
3481 else if (IN (Ekind (gnat_pref_type
), Access_Kind
))
3482 gnat_pref_type
= Designated_Type (gnat_pref_type
);
3485 gnu_prefix
= maybe_implicit_deref (gnu_prefix
);
3487 /* For discriminant references in tagged types always substitute the
3488 corresponding discriminant as the actual selected component. */
3490 if (Is_Tagged_Type (gnat_pref_type
))
3491 while (Present (Corresponding_Discriminant (gnat_field
)))
3492 gnat_field
= Corresponding_Discriminant (gnat_field
);
3494 /* For discriminant references of untagged types always substitute the
3495 corresponding stored discriminant. */
3497 else if (Present (Corresponding_Discriminant (gnat_field
)))
3498 gnat_field
= Original_Record_Component (gnat_field
);
3500 /* Handle extracting the real or imaginary part of a complex.
3501 The real part is the first field and the imaginary the last. */
3503 if (TREE_CODE (TREE_TYPE (gnu_prefix
)) == COMPLEX_TYPE
)
3504 gnu_result
= build_unary_op (Present (Next_Entity (gnat_field
))
3505 ? REALPART_EXPR
: IMAGPART_EXPR
,
3506 NULL_TREE
, gnu_prefix
);
3509 gnu_field
= gnat_to_gnu_field_decl (gnat_field
);
3511 /* If there are discriminants, the prefix might be
3512 evaluated more than once, which is a problem if it has
3514 if (Has_Discriminants (Is_Access_Type (Etype (Prefix (gnat_node
)))
3515 ? Designated_Type (Etype
3516 (Prefix (gnat_node
)))
3517 : Etype (Prefix (gnat_node
))))
3518 gnu_prefix
= gnat_stabilize_reference (gnu_prefix
, false);
3521 = build_component_ref (gnu_prefix
, NULL_TREE
, gnu_field
,
3522 (Nkind (Parent (gnat_node
))
3523 == N_Attribute_Reference
));
3526 gcc_assert (gnu_result
);
3527 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3531 case N_Attribute_Reference
:
3533 /* The attribute designator (like an enumeration value). */
3534 int attribute
= Get_Attribute_Id (Attribute_Name (gnat_node
));
3536 /* The Elab_Spec and Elab_Body attributes are special in that
3537 Prefix is a unit, not an object with a GCC equivalent. Similarly
3538 for Elaborated, since that variable isn't otherwise known. */
3539 if (attribute
== Attr_Elab_Body
|| attribute
== Attr_Elab_Spec
)
3540 return (create_subprog_decl
3541 (create_concat_name (Entity (Prefix (gnat_node
)),
3542 attribute
== Attr_Elab_Body
3543 ? "elabb" : "elabs"),
3544 NULL_TREE
, void_ftype
, NULL_TREE
, false, true, true, NULL
,
3547 gnu_result
= Attribute_to_gnu (gnat_node
, &gnu_result_type
, attribute
);
3552 /* Like 'Access as far as we are concerned. */
3553 gnu_result
= gnat_to_gnu (Prefix (gnat_node
));
3554 gnu_result
= build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_result
);
3555 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3559 case N_Extension_Aggregate
:
3563 /* ??? It is wrong to evaluate the type now, but there doesn't
3564 seem to be any other practical way of doing it. */
3566 gcc_assert (!Expansion_Delayed (gnat_node
));
3568 gnu_aggr_type
= gnu_result_type
3569 = get_unpadded_type (Etype (gnat_node
));
3571 if (TREE_CODE (gnu_result_type
) == RECORD_TYPE
3572 && TYPE_CONTAINS_TEMPLATE_P (gnu_result_type
))
3574 = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_result_type
)));
3576 if (Null_Record_Present (gnat_node
))
3577 gnu_result
= gnat_build_constructor (gnu_aggr_type
, NULL_TREE
);
3579 else if (TREE_CODE (gnu_aggr_type
) == RECORD_TYPE
3580 || TREE_CODE (gnu_aggr_type
) == UNION_TYPE
)
3582 = assoc_to_constructor (Etype (gnat_node
),
3583 First (Component_Associations (gnat_node
)),
3585 else if (TREE_CODE (gnu_aggr_type
) == ARRAY_TYPE
)
3586 gnu_result
= pos_to_constructor (First (Expressions (gnat_node
)),
3588 Component_Type (Etype (gnat_node
)));
3589 else if (TREE_CODE (gnu_aggr_type
) == COMPLEX_TYPE
)
3592 (COMPLEX_EXPR
, gnu_aggr_type
,
3593 gnat_to_gnu (Expression (First
3594 (Component_Associations (gnat_node
)))),
3595 gnat_to_gnu (Expression
3597 (First (Component_Associations (gnat_node
))))));
3601 gnu_result
= convert (gnu_result_type
, gnu_result
);
3606 gnu_result
= null_pointer_node
;
3607 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3610 case N_Type_Conversion
:
3611 case N_Qualified_Expression
:
3612 /* Get the operand expression. */
3613 gnu_result
= gnat_to_gnu (Expression (gnat_node
));
3614 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3617 = convert_with_check (Etype (gnat_node
), gnu_result
,
3618 Do_Overflow_Check (gnat_node
),
3619 Do_Range_Check (Expression (gnat_node
)),
3620 Nkind (gnat_node
) == N_Type_Conversion
3621 && Float_Truncate (gnat_node
));
3624 case N_Unchecked_Type_Conversion
:
3625 gnu_result
= gnat_to_gnu (Expression (gnat_node
));
3626 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3628 /* If the result is a pointer type, see if we are improperly
3629 converting to a stricter alignment. */
3631 if (STRICT_ALIGNMENT
&& POINTER_TYPE_P (gnu_result_type
)
3632 && IN (Ekind (Etype (gnat_node
)), Access_Kind
))
3634 unsigned int align
= known_alignment (gnu_result
);
3635 tree gnu_obj_type
= TREE_TYPE (gnu_result_type
);
3636 unsigned int oalign
= TYPE_ALIGN (gnu_obj_type
);
3638 if (align
!= 0 && align
< oalign
&& !TYPE_ALIGN_OK (gnu_obj_type
))
3639 post_error_ne_tree_2
3640 ("?source alignment (^) '< alignment of & (^)",
3641 gnat_node
, Designated_Type (Etype (gnat_node
)),
3642 size_int (align
/ BITS_PER_UNIT
), oalign
/ BITS_PER_UNIT
);
3645 gnu_result
= unchecked_convert (gnu_result_type
, gnu_result
,
3646 No_Truncation (gnat_node
));
3652 tree gnu_object
= gnat_to_gnu (Left_Opnd (gnat_node
));
3653 Node_Id gnat_range
= Right_Opnd (gnat_node
);
3657 /* GNAT_RANGE is either an N_Range node or an identifier
3658 denoting a subtype. */
3659 if (Nkind (gnat_range
) == N_Range
)
3661 gnu_low
= gnat_to_gnu (Low_Bound (gnat_range
));
3662 gnu_high
= gnat_to_gnu (High_Bound (gnat_range
));
3664 else if (Nkind (gnat_range
) == N_Identifier
3665 || Nkind (gnat_range
) == N_Expanded_Name
)
3667 tree gnu_range_type
= get_unpadded_type (Entity (gnat_range
));
3669 gnu_low
= TYPE_MIN_VALUE (gnu_range_type
);
3670 gnu_high
= TYPE_MAX_VALUE (gnu_range_type
);
3675 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3677 /* If LOW and HIGH are identical, perform an equality test.
3678 Otherwise, ensure that GNU_OBJECT is only evaluated once
3679 and perform a full range test. */
3680 if (operand_equal_p (gnu_low
, gnu_high
, 0))
3681 gnu_result
= build_binary_op (EQ_EXPR
, gnu_result_type
,
3682 gnu_object
, gnu_low
);
3685 gnu_object
= protect_multiple_eval (gnu_object
);
3687 = build_binary_op (TRUTH_ANDIF_EXPR
, gnu_result_type
,
3688 build_binary_op (GE_EXPR
, gnu_result_type
,
3689 gnu_object
, gnu_low
),
3690 build_binary_op (LE_EXPR
, gnu_result_type
,
3691 gnu_object
, gnu_high
));
3694 if (Nkind (gnat_node
) == N_Not_In
)
3695 gnu_result
= invert_truthvalue (gnu_result
);
3700 gnu_lhs
= gnat_to_gnu (Left_Opnd (gnat_node
));
3701 gnu_rhs
= gnat_to_gnu (Right_Opnd (gnat_node
));
3702 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3703 gnu_result
= build_binary_op (FLOAT_TYPE_P (gnu_result_type
)
3705 : (Rounded_Result (gnat_node
)
3706 ? ROUND_DIV_EXPR
: TRUNC_DIV_EXPR
),
3707 gnu_result_type
, gnu_lhs
, gnu_rhs
);
3710 case N_Op_Or
: case N_Op_And
: case N_Op_Xor
:
3711 /* These can either be operations on booleans or on modular types.
3712 Fall through for boolean types since that's the way GNU_CODES is
3714 if (IN (Ekind (Underlying_Type (Etype (gnat_node
))),
3715 Modular_Integer_Kind
))
3718 = (Nkind (gnat_node
) == N_Op_Or
? BIT_IOR_EXPR
3719 : Nkind (gnat_node
) == N_Op_And
? BIT_AND_EXPR
3722 gnu_lhs
= gnat_to_gnu (Left_Opnd (gnat_node
));
3723 gnu_rhs
= gnat_to_gnu (Right_Opnd (gnat_node
));
3724 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3725 gnu_result
= build_binary_op (code
, gnu_result_type
,
3730 /* ... fall through ... */
3732 case N_Op_Eq
: case N_Op_Ne
: case N_Op_Lt
:
3733 case N_Op_Le
: case N_Op_Gt
: case N_Op_Ge
:
3734 case N_Op_Add
: case N_Op_Subtract
: case N_Op_Multiply
:
3735 case N_Op_Mod
: case N_Op_Rem
:
3736 case N_Op_Rotate_Left
:
3737 case N_Op_Rotate_Right
:
3738 case N_Op_Shift_Left
:
3739 case N_Op_Shift_Right
:
3740 case N_Op_Shift_Right_Arithmetic
:
3741 case N_And_Then
: case N_Or_Else
:
3743 enum tree_code code
= gnu_codes
[Nkind (gnat_node
)];
3744 bool ignore_lhs_overflow
= false;
3747 gnu_lhs
= gnat_to_gnu (Left_Opnd (gnat_node
));
3748 gnu_rhs
= gnat_to_gnu (Right_Opnd (gnat_node
));
3749 gnu_type
= gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3751 /* If this is a comparison operator, convert any references to
3752 an unconstrained array value into a reference to the
3754 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
3756 gnu_lhs
= maybe_unconstrained_array (gnu_lhs
);
3757 gnu_rhs
= maybe_unconstrained_array (gnu_rhs
);
3760 /* If the result type is a private type, its full view may be a
3761 numeric subtype. The representation we need is that of its base
3762 type, given that it is the result of an arithmetic operation. */
3763 else if (Is_Private_Type (Etype (gnat_node
)))
3764 gnu_type
= gnu_result_type
3765 = get_unpadded_type (Base_Type (Full_View (Etype (gnat_node
))));
3767 /* If this is a shift whose count is not guaranteed to be correct,
3768 we need to adjust the shift count. */
3769 if (IN (Nkind (gnat_node
), N_Op_Shift
)
3770 && !Shift_Count_OK (gnat_node
))
3772 tree gnu_count_type
= get_base_type (TREE_TYPE (gnu_rhs
));
3774 = convert (gnu_count_type
, TYPE_SIZE (gnu_type
));
3776 if (Nkind (gnat_node
) == N_Op_Rotate_Left
3777 || Nkind (gnat_node
) == N_Op_Rotate_Right
)
3778 gnu_rhs
= build_binary_op (TRUNC_MOD_EXPR
, gnu_count_type
,
3779 gnu_rhs
, gnu_max_shift
);
3780 else if (Nkind (gnat_node
) == N_Op_Shift_Right_Arithmetic
)
3783 (MIN_EXPR
, gnu_count_type
,
3784 build_binary_op (MINUS_EXPR
,
3787 convert (gnu_count_type
,
3792 /* For right shifts, the type says what kind of shift to do,
3793 so we may need to choose a different type. In this case,
3794 we have to ignore integer overflow lest it propagates all
3795 the way down and causes a CE to be explicitly raised. */
3796 if (Nkind (gnat_node
) == N_Op_Shift_Right
3797 && !TYPE_UNSIGNED (gnu_type
))
3799 gnu_type
= gnat_unsigned_type (gnu_type
);
3800 ignore_lhs_overflow
= true;
3802 else if (Nkind (gnat_node
) == N_Op_Shift_Right_Arithmetic
3803 && TYPE_UNSIGNED (gnu_type
))
3805 gnu_type
= gnat_signed_type (gnu_type
);
3806 ignore_lhs_overflow
= true;
3809 if (gnu_type
!= gnu_result_type
)
3811 tree gnu_old_lhs
= gnu_lhs
;
3812 gnu_lhs
= convert (gnu_type
, gnu_lhs
);
3813 if (TREE_CODE (gnu_lhs
) == INTEGER_CST
&& ignore_lhs_overflow
)
3814 TREE_OVERFLOW (gnu_lhs
) = TREE_OVERFLOW (gnu_old_lhs
);
3815 gnu_rhs
= convert (gnu_type
, gnu_rhs
);
3818 gnu_result
= build_binary_op (code
, gnu_type
, gnu_lhs
, gnu_rhs
);
3820 /* If this is a logical shift with the shift count not verified,
3821 we must return zero if it is too large. We cannot compensate
3822 above in this case. */
3823 if ((Nkind (gnat_node
) == N_Op_Shift_Left
3824 || Nkind (gnat_node
) == N_Op_Shift_Right
)
3825 && !Shift_Count_OK (gnat_node
))
3829 build_binary_op (GE_EXPR
, integer_type_node
,
3831 convert (TREE_TYPE (gnu_rhs
),
3832 TYPE_SIZE (gnu_type
))),
3833 convert (gnu_type
, integer_zero_node
),
3838 case N_Conditional_Expression
:
3840 tree gnu_cond
= gnat_to_gnu (First (Expressions (gnat_node
)));
3841 tree gnu_true
= gnat_to_gnu (Next (First (Expressions (gnat_node
))));
3843 = gnat_to_gnu (Next (Next (First (Expressions (gnat_node
)))));
3845 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3846 gnu_result
= build_cond_expr (gnu_result_type
,
3847 gnat_truthvalue_conversion (gnu_cond
),
3848 gnu_true
, gnu_false
);
3853 gnu_result
= gnat_to_gnu (Right_Opnd (gnat_node
));
3854 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3858 /* This case can apply to a boolean or a modular type.
3859 Fall through for a boolean operand since GNU_CODES is set
3860 up to handle this. */
3861 if (Is_Modular_Integer_Type (Etype (gnat_node
))
3862 || (Ekind (Etype (gnat_node
)) == E_Private_Type
3863 && Is_Modular_Integer_Type (Full_View (Etype (gnat_node
)))))
3865 gnu_expr
= gnat_to_gnu (Right_Opnd (gnat_node
));
3866 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3867 gnu_result
= build_unary_op (BIT_NOT_EXPR
, gnu_result_type
,
3872 /* ... fall through ... */
3874 case N_Op_Minus
: case N_Op_Abs
:
3875 gnu_expr
= gnat_to_gnu (Right_Opnd (gnat_node
));
3877 if (Ekind (Etype (gnat_node
)) != E_Private_Type
)
3878 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3880 gnu_result_type
= get_unpadded_type (Base_Type
3881 (Full_View (Etype (gnat_node
))));
3883 gnu_result
= build_unary_op (gnu_codes
[Nkind (gnat_node
)],
3884 gnu_result_type
, gnu_expr
);
3891 bool ignore_init_type
= false;
3893 gnat_temp
= Expression (gnat_node
);
3895 /* The Expression operand can either be an N_Identifier or
3896 Expanded_Name, which must represent a type, or a
3897 N_Qualified_Expression, which contains both the object type and an
3898 initial value for the object. */
3899 if (Nkind (gnat_temp
) == N_Identifier
3900 || Nkind (gnat_temp
) == N_Expanded_Name
)
3901 gnu_type
= gnat_to_gnu_type (Entity (gnat_temp
));
3902 else if (Nkind (gnat_temp
) == N_Qualified_Expression
)
3904 Entity_Id gnat_desig_type
3905 = Designated_Type (Underlying_Type (Etype (gnat_node
)));
3907 ignore_init_type
= Has_Constrained_Partial_View (gnat_desig_type
);
3908 gnu_init
= gnat_to_gnu (Expression (gnat_temp
));
3910 gnu_init
= maybe_unconstrained_array (gnu_init
);
3911 if (Do_Range_Check (Expression (gnat_temp
)))
3912 gnu_init
= emit_range_check (gnu_init
, gnat_desig_type
);
3914 if (Is_Elementary_Type (gnat_desig_type
)
3915 || Is_Constrained (gnat_desig_type
))
3917 gnu_type
= gnat_to_gnu_type (gnat_desig_type
);
3918 gnu_init
= convert (gnu_type
, gnu_init
);
3922 gnu_type
= gnat_to_gnu_type (Etype (Expression (gnat_temp
)));
3923 if (TREE_CODE (gnu_type
) == UNCONSTRAINED_ARRAY_TYPE
)
3924 gnu_type
= TREE_TYPE (gnu_init
);
3926 gnu_init
= convert (gnu_type
, gnu_init
);
3932 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
3933 return build_allocator (gnu_type
, gnu_init
, gnu_result_type
,
3934 Procedure_To_Call (gnat_node
),
3935 Storage_Pool (gnat_node
), gnat_node
,
3940 /***************************/
3941 /* Chapter 5: Statements: */
3942 /***************************/
3945 gnu_result
= build1 (LABEL_EXPR
, void_type_node
,
3946 gnat_to_gnu (Identifier (gnat_node
)));
3949 case N_Null_Statement
:
3950 gnu_result
= alloc_stmt_list ();
3953 case N_Assignment_Statement
:
3954 /* Get the LHS and RHS of the statement and convert any reference to an
3955 unconstrained array into a reference to the underlying array.
3956 If we are not to do range checking and the RHS is an N_Function_Call,
3957 pass the LHS to the call function. */
3958 gnu_lhs
= maybe_unconstrained_array (gnat_to_gnu (Name (gnat_node
)));
3960 /* If the type has a size that overflows, convert this into raise of
3961 Storage_Error: execution shouldn't have gotten here anyway. */
3962 if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs
))) == INTEGER_CST
3963 && TREE_OVERFLOW (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs
))))
3964 gnu_result
= build_call_raise (SE_Object_Too_Large
, gnat_node
,
3965 N_Raise_Storage_Error
);
3966 else if (Nkind (Expression (gnat_node
)) == N_Function_Call
3967 && !Do_Range_Check (Expression (gnat_node
)))
3968 gnu_result
= call_to_gnu (Expression (gnat_node
),
3969 &gnu_result_type
, gnu_lhs
);
3973 = maybe_unconstrained_array (gnat_to_gnu (Expression (gnat_node
)));
3975 /* If range check is needed, emit code to generate it */
3976 if (Do_Range_Check (Expression (gnat_node
)))
3977 gnu_rhs
= emit_range_check (gnu_rhs
, Etype (Name (gnat_node
)));
3980 = build_binary_op (MODIFY_EXPR
, NULL_TREE
, gnu_lhs
, gnu_rhs
);
3984 case N_If_Statement
:
3986 tree
*gnu_else_ptr
; /* Point to put next "else if" or "else". */
3988 /* Make the outer COND_EXPR. Avoid non-determinism. */
3989 gnu_result
= build3 (COND_EXPR
, void_type_node
,
3990 gnat_to_gnu (Condition (gnat_node
)),
3991 NULL_TREE
, NULL_TREE
);
3992 COND_EXPR_THEN (gnu_result
)
3993 = build_stmt_group (Then_Statements (gnat_node
), false);
3994 TREE_SIDE_EFFECTS (gnu_result
) = 1;
3995 gnu_else_ptr
= &COND_EXPR_ELSE (gnu_result
);
3997 /* Now make a COND_EXPR for each of the "else if" parts. Put each
3998 into the previous "else" part and point to where to put any
3999 outer "else". Also avoid non-determinism. */
4000 if (Present (Elsif_Parts (gnat_node
)))
4001 for (gnat_temp
= First (Elsif_Parts (gnat_node
));
4002 Present (gnat_temp
); gnat_temp
= Next (gnat_temp
))
4004 gnu_expr
= build3 (COND_EXPR
, void_type_node
,
4005 gnat_to_gnu (Condition (gnat_temp
)),
4006 NULL_TREE
, NULL_TREE
);
4007 COND_EXPR_THEN (gnu_expr
)
4008 = build_stmt_group (Then_Statements (gnat_temp
), false);
4009 TREE_SIDE_EFFECTS (gnu_expr
) = 1;
4010 set_expr_location_from_node (gnu_expr
, gnat_temp
);
4011 *gnu_else_ptr
= gnu_expr
;
4012 gnu_else_ptr
= &COND_EXPR_ELSE (gnu_expr
);
4015 *gnu_else_ptr
= build_stmt_group (Else_Statements (gnat_node
), false);
4019 case N_Case_Statement
:
4020 gnu_result
= Case_Statement_to_gnu (gnat_node
);
4023 case N_Loop_Statement
:
4024 gnu_result
= Loop_Statement_to_gnu (gnat_node
);
4027 case N_Block_Statement
:
4028 start_stmt_group ();
4030 process_decls (Declarations (gnat_node
), Empty
, Empty
, true, true);
4031 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node
)));
4033 gnu_result
= end_stmt_group ();
4035 if (Present (Identifier (gnat_node
)))
4036 mark_out_of_scope (Entity (Identifier (gnat_node
)));
4039 case N_Exit_Statement
:
4041 = build2 (EXIT_STMT
, void_type_node
,
4042 (Present (Condition (gnat_node
))
4043 ? gnat_to_gnu (Condition (gnat_node
)) : NULL_TREE
),
4044 (Present (Name (gnat_node
))
4045 ? get_gnu_tree (Entity (Name (gnat_node
)))
4046 : TREE_VALUE (gnu_loop_label_stack
)));
4049 case N_Return_Statement
:
4051 /* The gnu function type of the subprogram currently processed. */
4052 tree gnu_subprog_type
= TREE_TYPE (current_function_decl
);
4053 /* The return value from the subprogram. */
4054 tree gnu_ret_val
= NULL_TREE
;
4055 /* The place to put the return value. */
4058 /* If we are dealing with a "return;" from an Ada procedure with
4059 parameters passed by copy in copy out, we need to return a record
4060 containing the final values of these parameters. If the list
4061 contains only one entry, return just that entry.
4063 For a full description of the copy in copy out parameter mechanism,
4064 see the part of the gnat_to_gnu_entity routine dealing with the
4065 translation of subprograms.
4067 But if we have a return label defined, convert this into
4068 a branch to that label. */
4070 if (TREE_VALUE (gnu_return_label_stack
))
4072 gnu_result
= build1 (GOTO_EXPR
, void_type_node
,
4073 TREE_VALUE (gnu_return_label_stack
));
4077 else if (TYPE_CI_CO_LIST (gnu_subprog_type
))
4079 gnu_lhs
= DECL_RESULT (current_function_decl
);
4080 if (list_length (TYPE_CI_CO_LIST (gnu_subprog_type
)) == 1)
4081 gnu_ret_val
= TREE_VALUE (TYPE_CI_CO_LIST (gnu_subprog_type
));
4084 = gnat_build_constructor (TREE_TYPE (gnu_subprog_type
),
4085 TYPE_CI_CO_LIST (gnu_subprog_type
));
4088 /* If the Ada subprogram is a function, we just need to return the
4089 expression. If the subprogram returns an unconstrained
4090 array, we have to allocate a new version of the result and
4091 return it. If we return by reference, return a pointer. */
4093 else if (Present (Expression (gnat_node
)))
4095 /* If the current function returns by target pointer and we
4096 are doing a call, pass that target to the call. */
4097 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type
)
4098 && Nkind (Expression (gnat_node
)) == N_Function_Call
)
4101 = build_unary_op (INDIRECT_REF
, NULL_TREE
,
4102 DECL_ARGUMENTS (current_function_decl
));
4103 gnu_result
= call_to_gnu (Expression (gnat_node
),
4104 &gnu_result_type
, gnu_lhs
);
4108 gnu_ret_val
= gnat_to_gnu (Expression (gnat_node
));
4110 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type
))
4111 /* The original return type was unconstrained so dereference
4112 the TARGET pointer in the actual return value's type. */
4114 = build_unary_op (INDIRECT_REF
, TREE_TYPE (gnu_ret_val
),
4115 DECL_ARGUMENTS (current_function_decl
));
4117 gnu_lhs
= DECL_RESULT (current_function_decl
);
4119 /* Do not remove the padding from GNU_RET_VAL if the inner
4120 type is self-referential since we want to allocate the fixed
4121 size in that case. */
4122 if (TREE_CODE (gnu_ret_val
) == COMPONENT_REF
4123 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_ret_val
, 0)))
4125 && (TYPE_IS_PADDING_P
4126 (TREE_TYPE (TREE_OPERAND (gnu_ret_val
, 0))))
4127 && (CONTAINS_PLACEHOLDER_P
4128 (TYPE_SIZE (TREE_TYPE (gnu_ret_val
)))))
4129 gnu_ret_val
= TREE_OPERAND (gnu_ret_val
, 0);
4131 if (TYPE_RETURNS_BY_REF_P (gnu_subprog_type
)
4132 || By_Ref (gnat_node
))
4134 = build_unary_op (ADDR_EXPR
, NULL_TREE
, gnu_ret_val
);
4136 else if (TYPE_RETURNS_UNCONSTRAINED_P (gnu_subprog_type
))
4138 gnu_ret_val
= maybe_unconstrained_array (gnu_ret_val
);
4140 /* We have two cases: either the function returns with
4141 depressed stack or not. If not, we allocate on the
4142 secondary stack. If so, we allocate in the stack frame.
4143 if no copy is needed, the front end will set By_Ref,
4144 which we handle in the case above. */
4145 if (TYPE_RETURNS_STACK_DEPRESSED (gnu_subprog_type
))
4147 = build_allocator (TREE_TYPE (gnu_ret_val
),
4149 TREE_TYPE (gnu_subprog_type
),
4150 0, -1, gnat_node
, false);
4153 = build_allocator (TREE_TYPE (gnu_ret_val
),
4155 TREE_TYPE (gnu_subprog_type
),
4156 Procedure_To_Call (gnat_node
),
4157 Storage_Pool (gnat_node
),
4163 /* If the Ada subprogram is a regular procedure, just return. */
4164 gnu_lhs
= NULL_TREE
;
4166 if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type
))
4169 gnu_result
= build_binary_op (MODIFY_EXPR
, NULL_TREE
,
4170 gnu_lhs
, gnu_ret_val
);
4171 add_stmt_with_node (gnu_result
, gnat_node
);
4172 gnu_lhs
= NULL_TREE
;
4175 gnu_result
= build_return_expr (gnu_lhs
, gnu_ret_val
);
4179 case N_Goto_Statement
:
4180 gnu_result
= build1 (GOTO_EXPR
, void_type_node
,
4181 gnat_to_gnu (Name (gnat_node
)));
4184 /****************************/
4185 /* Chapter 6: Subprograms: */
4186 /****************************/
4188 case N_Subprogram_Declaration
:
4189 /* Unless there is a freeze node, declare the subprogram. We consider
4190 this a "definition" even though we're not generating code for
4191 the subprogram because we will be making the corresponding GCC
4194 if (No (Freeze_Node (Defining_Entity (Specification (gnat_node
)))))
4195 gnat_to_gnu_entity (Defining_Entity (Specification (gnat_node
)),
4197 gnu_result
= alloc_stmt_list ();
4200 case N_Abstract_Subprogram_Declaration
:
4201 /* This subprogram doesn't exist for code generation purposes, but we
4202 have to elaborate the types of any parameters and result, unless
4203 they are imported types (nothing to generate in this case). */
4205 /* Process the parameter types first. */
4208 = First_Formal_With_Extras
4209 (Defining_Entity (Specification (gnat_node
)));
4210 Present (gnat_temp
);
4211 gnat_temp
= Next_Formal_With_Extras (gnat_temp
))
4212 if (Is_Itype (Etype (gnat_temp
))
4213 && !From_With_Type (Etype (gnat_temp
)))
4214 gnat_to_gnu_entity (Etype (gnat_temp
), NULL_TREE
, 0);
4217 /* Then the result type, set to Standard_Void_Type for procedures. */
4220 Entity_Id gnat_temp_type
4221 = Etype (Defining_Entity (Specification (gnat_node
)));
4223 if (Is_Itype (gnat_temp_type
) && !From_With_Type (gnat_temp_type
))
4224 gnat_to_gnu_entity (Etype (gnat_temp_type
), NULL_TREE
, 0);
4227 gnu_result
= alloc_stmt_list ();
4230 case N_Defining_Program_Unit_Name
:
4231 /* For a child unit identifier go up a level to get the
4232 specification. We get this when we try to find the spec of
4233 a child unit package that is the compilation unit being compiled. */
4234 gnu_result
= gnat_to_gnu (Parent (gnat_node
));
4237 case N_Subprogram_Body
:
4238 Subprogram_Body_to_gnu (gnat_node
);
4239 gnu_result
= alloc_stmt_list ();
4242 case N_Function_Call
:
4243 case N_Procedure_Call_Statement
:
4244 gnu_result
= call_to_gnu (gnat_node
, &gnu_result_type
, NULL_TREE
);
4247 /*************************/
4248 /* Chapter 7: Packages: */
4249 /*************************/
4251 case N_Package_Declaration
:
4252 gnu_result
= gnat_to_gnu (Specification (gnat_node
));
4255 case N_Package_Specification
:
4257 start_stmt_group ();
4258 process_decls (Visible_Declarations (gnat_node
),
4259 Private_Declarations (gnat_node
), Empty
, true, true);
4260 gnu_result
= end_stmt_group ();
4263 case N_Package_Body
:
4265 /* If this is the body of a generic package - do nothing */
4266 if (Ekind (Corresponding_Spec (gnat_node
)) == E_Generic_Package
)
4268 gnu_result
= alloc_stmt_list ();
4272 start_stmt_group ();
4273 process_decls (Declarations (gnat_node
), Empty
, Empty
, true, true);
4275 if (Present (Handled_Statement_Sequence (gnat_node
)))
4276 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node
)));
4278 gnu_result
= end_stmt_group ();
4281 /*********************************/
4282 /* Chapter 8: Visibility Rules: */
4283 /*********************************/
4285 case N_Use_Package_Clause
:
4286 case N_Use_Type_Clause
:
4287 /* Nothing to do here - but these may appear in list of declarations */
4288 gnu_result
= alloc_stmt_list ();
4291 /***********************/
4292 /* Chapter 9: Tasks: */
4293 /***********************/
4295 case N_Protected_Type_Declaration
:
4296 gnu_result
= alloc_stmt_list ();
4299 case N_Single_Task_Declaration
:
4300 gnat_to_gnu_entity (Defining_Entity (gnat_node
), NULL_TREE
, 1);
4301 gnu_result
= alloc_stmt_list ();
4304 /***********************************************************/
4305 /* Chapter 10: Program Structure and Compilation Issues: */
4306 /***********************************************************/
4308 case N_Compilation_Unit
:
4310 /* This is not called for the main unit, which is handled in function
4312 start_stmt_group ();
4315 Compilation_Unit_to_gnu (gnat_node
);
4316 gnu_result
= alloc_stmt_list ();
4319 case N_Subprogram_Body_Stub
:
4320 case N_Package_Body_Stub
:
4321 case N_Protected_Body_Stub
:
4322 case N_Task_Body_Stub
:
4323 /* Simply process whatever unit is being inserted. */
4324 gnu_result
= gnat_to_gnu (Unit (Library_Unit (gnat_node
)));
4328 gnu_result
= gnat_to_gnu (Proper_Body (gnat_node
));
4331 /***************************/
4332 /* Chapter 11: Exceptions: */
4333 /***************************/
4335 case N_Handled_Sequence_Of_Statements
:
4336 /* If there is an At_End procedure attached to this node, and the EH
4337 mechanism is SJLJ, we must have at least a corresponding At_End
4338 handler, unless the No_Exception_Handlers restriction is set. */
4339 gcc_assert (type_annotate_only
4340 || Exception_Mechanism
!= Setjmp_Longjmp
4341 || No (At_End_Proc (gnat_node
))
4342 || Present (Exception_Handlers (gnat_node
))
4343 || No_Exception_Handlers_Set ());
4345 gnu_result
= Handled_Sequence_Of_Statements_to_gnu (gnat_node
);
4348 case N_Exception_Handler
:
4349 if (Exception_Mechanism
== Setjmp_Longjmp
)
4350 gnu_result
= Exception_Handler_to_gnu_sjlj (gnat_node
);
4351 else if (Exception_Mechanism
== Back_End_Exceptions
)
4352 gnu_result
= Exception_Handler_to_gnu_zcx (gnat_node
);
4358 case N_Push_Constraint_Error_Label
:
4359 push_exception_label_stack (&gnu_constraint_error_label_stack
,
4360 Exception_Label (gnat_node
));
4363 case N_Push_Storage_Error_Label
:
4364 push_exception_label_stack (&gnu_storage_error_label_stack
,
4365 Exception_Label (gnat_node
));
4368 case N_Push_Program_Error_Label
:
4369 push_exception_label_stack (&gnu_program_error_label_stack
,
4370 Exception_Label (gnat_node
));
4373 case N_Pop_Constraint_Error_Label
:
4374 gnu_constraint_error_label_stack
4375 = TREE_CHAIN (gnu_constraint_error_label_stack
);
4378 case N_Pop_Storage_Error_Label
:
4379 gnu_storage_error_label_stack
4380 = TREE_CHAIN (gnu_storage_error_label_stack
);
4383 case N_Pop_Program_Error_Label
:
4384 gnu_program_error_label_stack
4385 = TREE_CHAIN (gnu_program_error_label_stack
);
4388 /*******************************/
4389 /* Chapter 12: Generic Units: */
4390 /*******************************/
4392 case N_Generic_Function_Renaming_Declaration
:
4393 case N_Generic_Package_Renaming_Declaration
:
4394 case N_Generic_Procedure_Renaming_Declaration
:
4395 case N_Generic_Package_Declaration
:
4396 case N_Generic_Subprogram_Declaration
:
4397 case N_Package_Instantiation
:
4398 case N_Procedure_Instantiation
:
4399 case N_Function_Instantiation
:
4400 /* These nodes can appear on a declaration list but there is nothing to
4401 to be done with them. */
4402 gnu_result
= alloc_stmt_list ();
4405 /***************************************************/
4406 /* Chapter 13: Representation Clauses and */
4407 /* Implementation-Dependent Features: */
4408 /***************************************************/
4410 case N_Attribute_Definition_Clause
:
4412 gnu_result
= alloc_stmt_list ();
4414 /* The only one we need deal with is for 'Address. For the others, SEM
4415 puts the information elsewhere. We need only deal with 'Address
4416 if the object has a Freeze_Node (which it never will currently). */
4417 if (Get_Attribute_Id (Chars (gnat_node
)) != Attr_Address
4418 || No (Freeze_Node (Entity (Name (gnat_node
)))))
4421 /* Get the value to use as the address and save it as the
4422 equivalent for GNAT_TEMP. When the object is frozen,
4423 gnat_to_gnu_entity will do the right thing. */
4424 save_gnu_tree (Entity (Name (gnat_node
)),
4425 gnat_to_gnu (Expression (gnat_node
)), true);
4428 case N_Enumeration_Representation_Clause
:
4429 case N_Record_Representation_Clause
:
4431 /* We do nothing with these. SEM puts the information elsewhere. */
4432 gnu_result
= alloc_stmt_list ();
4435 case N_Code_Statement
:
4436 if (!type_annotate_only
)
4438 tree gnu_template
= gnat_to_gnu (Asm_Template (gnat_node
));
4439 tree gnu_inputs
= NULL_TREE
, gnu_outputs
= NULL_TREE
;
4440 tree gnu_clobbers
= NULL_TREE
, tail
;
4441 bool allows_mem
, allows_reg
, fake
;
4442 int ninputs
, noutputs
, i
;
4443 const char **oconstraints
;
4444 const char *constraint
;
4447 /* First retrieve the 3 operand lists built by the front-end. */
4448 Setup_Asm_Outputs (gnat_node
);
4449 while (Present (gnat_temp
= Asm_Output_Variable ()))
4451 tree gnu_value
= gnat_to_gnu (gnat_temp
);
4452 tree gnu_constr
= build_tree_list (NULL_TREE
, gnat_to_gnu
4453 (Asm_Output_Constraint ()));
4455 gnu_outputs
= tree_cons (gnu_constr
, gnu_value
, gnu_outputs
);
4459 Setup_Asm_Inputs (gnat_node
);
4460 while (Present (gnat_temp
= Asm_Input_Value ()))
4462 tree gnu_value
= gnat_to_gnu (gnat_temp
);
4463 tree gnu_constr
= build_tree_list (NULL_TREE
, gnat_to_gnu
4464 (Asm_Input_Constraint ()));
4466 gnu_inputs
= tree_cons (gnu_constr
, gnu_value
, gnu_inputs
);
4470 Clobber_Setup (gnat_node
);
4471 while ((clobber
= Clobber_Get_Next ()))
4473 = tree_cons (NULL_TREE
,
4474 build_string (strlen (clobber
) + 1, clobber
),
4477 /* Then perform some standard checking and processing on the
4478 operands. In particular, mark them addressable if needed. */
4479 gnu_outputs
= nreverse (gnu_outputs
);
4480 noutputs
= list_length (gnu_outputs
);
4481 gnu_inputs
= nreverse (gnu_inputs
);
4482 ninputs
= list_length (gnu_inputs
);
4484 = (const char **) alloca (noutputs
* sizeof (const char *));
4486 for (i
= 0, tail
= gnu_outputs
; tail
; ++i
, tail
= TREE_CHAIN (tail
))
4488 tree output
= TREE_VALUE (tail
);
4490 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail
)));
4491 oconstraints
[i
] = constraint
;
4493 if (parse_output_constraint (&constraint
, i
, ninputs
, noutputs
,
4494 &allows_mem
, &allows_reg
, &fake
))
4496 /* If the operand is going to end up in memory,
4497 mark it addressable. Note that we don't test
4498 allows_mem like in the input case below; this
4499 is modelled on the C front-end. */
4501 && !gnat_mark_addressable (output
))
4502 output
= error_mark_node
;
4505 output
= error_mark_node
;
4507 TREE_VALUE (tail
) = output
;
4510 for (i
= 0, tail
= gnu_inputs
; tail
; ++i
, tail
= TREE_CHAIN (tail
))
4512 tree input
= TREE_VALUE (tail
);
4514 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail
)));
4516 if (parse_input_constraint (&constraint
, i
, ninputs
, noutputs
,
4518 &allows_mem
, &allows_reg
))
4520 /* If the operand is going to end up in memory,
4521 mark it addressable. */
4522 if (!allows_reg
&& allows_mem
4523 && !gnat_mark_addressable (input
))
4524 input
= error_mark_node
;
4527 input
= error_mark_node
;
4529 TREE_VALUE (tail
) = input
;
4532 gnu_result
= build4 (ASM_EXPR
, void_type_node
,
4533 gnu_template
, gnu_outputs
,
4534 gnu_inputs
, gnu_clobbers
);
4535 ASM_VOLATILE_P (gnu_result
) = Is_Asm_Volatile (gnat_node
);
4538 gnu_result
= alloc_stmt_list ();
4542 /***************************************************/
4544 /***************************************************/
4546 case N_Freeze_Entity
:
4547 start_stmt_group ();
4548 process_freeze_entity (gnat_node
);
4549 process_decls (Actions (gnat_node
), Empty
, Empty
, true, true);
4550 gnu_result
= end_stmt_group ();
4553 case N_Itype_Reference
:
4554 if (!present_gnu_tree (Itype (gnat_node
)))
4555 process_type (Itype (gnat_node
));
4557 gnu_result
= alloc_stmt_list ();
4560 case N_Free_Statement
:
4561 if (!type_annotate_only
)
4563 tree gnu_ptr
= gnat_to_gnu (Expression (gnat_node
));
4564 tree gnu_ptr_type
= TREE_TYPE (gnu_ptr
);
4566 tree gnu_actual_obj_type
= 0;
4569 unsigned int default_allocator_alignment
4570 = get_target_default_allocator_alignment () * BITS_PER_UNIT
;
4572 /* If this is a thin pointer, we must dereference it to create
4573 a fat pointer, then go back below to a thin pointer. The
4574 reason for this is that we need a fat pointer someplace in
4575 order to properly compute the size. */
4576 if (TYPE_THIN_POINTER_P (TREE_TYPE (gnu_ptr
)))
4577 gnu_ptr
= build_unary_op (ADDR_EXPR
, NULL_TREE
,
4578 build_unary_op (INDIRECT_REF
, NULL_TREE
,
4581 /* If this is an unconstrained array, we know the object must
4582 have been allocated with the template in front of the object.
4583 So pass the template address, but get the total size. Do this
4584 by converting to a thin pointer. */
4585 if (TYPE_FAT_POINTER_P (TREE_TYPE (gnu_ptr
)))
4587 = convert (build_pointer_type
4588 (TYPE_OBJECT_RECORD_TYPE
4589 (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr
)))),
4592 gnu_obj_type
= TREE_TYPE (TREE_TYPE (gnu_ptr
));
4594 if (Present (Actual_Designated_Subtype (gnat_node
)))
4597 = gnat_to_gnu_type (Actual_Designated_Subtype (gnat_node
));
4599 if (TYPE_FAT_OR_THIN_POINTER_P (gnu_ptr_type
))
4601 = build_unc_object_type_from_ptr (gnu_ptr_type
,
4602 gnu_actual_obj_type
,
4603 get_identifier ("DEALLOC"));
4606 gnu_actual_obj_type
= gnu_obj_type
;
4608 gnu_obj_size
= TYPE_SIZE_UNIT (gnu_actual_obj_type
);
4609 align
= TYPE_ALIGN (gnu_obj_type
);
4611 if (TREE_CODE (gnu_obj_type
) == RECORD_TYPE
4612 && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type
))
4614 tree gnu_char_ptr_type
= build_pointer_type (char_type_node
);
4615 tree gnu_pos
= byte_position (TYPE_FIELDS (gnu_obj_type
));
4616 tree gnu_byte_offset
4617 = convert (sizetype
,
4618 size_diffop (size_zero_node
, gnu_pos
));
4619 gnu_byte_offset
= fold_build1 (NEGATE_EXPR
, sizetype
, gnu_byte_offset
);
4621 gnu_ptr
= convert (gnu_char_ptr_type
, gnu_ptr
);
4622 gnu_ptr
= build_binary_op (POINTER_PLUS_EXPR
, gnu_char_ptr_type
,
4623 gnu_ptr
, gnu_byte_offset
);
4626 /* If the object was allocated from the default storage pool, the
4627 alignement was greater than what the allocator provides, and this
4628 is not a fat or thin pointer, what we have in gnu_ptr here is an
4629 address dynamically adjusted to match the alignment requirement
4630 (see build_allocator). What we need to pass to free is the
4631 initial allocator's return value, which has been stored just in
4632 front of the block we have. */
4634 if (No (Procedure_To_Call (gnat_node
)) && align
> default_allocator_alignment
4635 && ! TYPE_FAT_OR_THIN_POINTER_P (gnu_ptr_type
))
4638 as * (void **)((void *)GNU_PTR - (void *)sizeof(void *))
4641 /* GNU_PTR (void *) = (void *)GNU_PTR - (void *)sizeof (void *)) */
4643 = build_binary_op (MINUS_EXPR
, ptr_void_type_node
,
4644 convert (ptr_void_type_node
, gnu_ptr
),
4645 convert (ptr_void_type_node
,
4646 TYPE_SIZE_UNIT (ptr_void_type_node
)));
4648 /* GNU_PTR (void *) = *(void **)GNU_PTR */
4650 = build_unary_op (INDIRECT_REF
, NULL_TREE
,
4651 convert (build_pointer_type (ptr_void_type_node
),
4655 gnu_result
= build_call_alloc_dealloc (gnu_ptr
, gnu_obj_size
, align
,
4656 Procedure_To_Call (gnat_node
),
4657 Storage_Pool (gnat_node
),
4662 case N_Raise_Constraint_Error
:
4663 case N_Raise_Program_Error
:
4664 case N_Raise_Storage_Error
:
4665 if (type_annotate_only
)
4667 gnu_result
= alloc_stmt_list ();
4671 gnu_result_type
= get_unpadded_type (Etype (gnat_node
));
4673 = build_call_raise (UI_To_Int (Reason (gnat_node
)), gnat_node
,
4676 /* If the type is VOID, this is a statement, so we need to
4677 generate the code for the call. Handle a Condition, if there
4679 if (TREE_CODE (gnu_result_type
) == VOID_TYPE
)
4681 set_expr_location_from_node (gnu_result
, gnat_node
);
4683 if (Present (Condition (gnat_node
)))
4684 gnu_result
= build3 (COND_EXPR
, void_type_node
,
4685 gnat_to_gnu (Condition (gnat_node
)),
4686 gnu_result
, alloc_stmt_list ());
4689 gnu_result
= build1 (NULL_EXPR
, gnu_result_type
, gnu_result
);
4692 case N_Validate_Unchecked_Conversion
:
4693 /* If the result is a pointer type, see if we are either converting
4694 from a non-pointer or from a pointer to a type with a different
4695 alias set and warn if so. If the result defined in the same unit as
4696 this unchecked conversion, we can allow this because we can know to
4697 make that type have alias set 0. */
4699 tree gnu_source_type
= gnat_to_gnu_type (Source_Type (gnat_node
));
4700 tree gnu_target_type
= gnat_to_gnu_type (Target_Type (gnat_node
));
4702 if (POINTER_TYPE_P (gnu_target_type
)
4703 && !In_Same_Source_Unit (Target_Type (gnat_node
), gnat_node
)
4704 && get_alias_set (TREE_TYPE (gnu_target_type
)) != 0
4705 && !No_Strict_Aliasing (Underlying_Type (Target_Type (gnat_node
)))
4706 && (!POINTER_TYPE_P (gnu_source_type
)
4707 || (get_alias_set (TREE_TYPE (gnu_source_type
))
4708 != get_alias_set (TREE_TYPE (gnu_target_type
)))))
4711 ("?possible aliasing problem for type&",
4712 gnat_node
, Target_Type (gnat_node
));
4714 ("\\?use -fno-strict-aliasing switch for references",
4717 ("\\?or use `pragma No_Strict_Aliasing (&);`",
4718 gnat_node
, Target_Type (gnat_node
));
4721 /* The No_Strict_Aliasing flag is not propagated to the back-end for
4722 fat pointers so unconditionally warn in problematic cases. */
4723 else if (TYPE_FAT_POINTER_P (gnu_target_type
))
4726 = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type
)));
4728 if (get_alias_set (array_type
) != 0
4729 && (!TYPE_FAT_POINTER_P (gnu_source_type
)
4730 || (get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_source_type
))))
4731 != get_alias_set (array_type
))))
4734 ("?possible aliasing problem for type&",
4735 gnat_node
, Target_Type (gnat_node
));
4737 ("\\?use -fno-strict-aliasing switch for references",
4742 gnu_result
= alloc_stmt_list ();
4745 case N_Raise_Statement
:
4746 case N_Function_Specification
:
4747 case N_Procedure_Specification
:
4749 case N_Component_Association
:
4752 gcc_assert (type_annotate_only
);
4753 gnu_result
= alloc_stmt_list ();
4756 /* If we pushed our level as part of processing the elaboration routine,
4758 if (went_into_elab_proc
)
4760 add_stmt (gnu_result
);
4762 gnu_result
= end_stmt_group ();
4763 current_function_decl
= NULL_TREE
;
4766 /* Set the location information on the result if it is a real expression.
4767 References can be reused for multiple GNAT nodes and they would get
4768 the location information of their last use. Note that we may have
4769 no result if we tried to build a CALL_EXPR node to a procedure with
4770 no side-effects and optimization is enabled. */
4771 if (gnu_result
&& EXPR_P (gnu_result
) && !REFERENCE_CLASS_P (gnu_result
))
4772 set_expr_location_from_node (gnu_result
, gnat_node
);
4774 /* If we're supposed to return something of void_type, it means we have
4775 something we're elaborating for effect, so just return. */
4776 if (TREE_CODE (gnu_result_type
) == VOID_TYPE
)
4779 /* If the result is a constant that overflows, raise constraint error. */
4780 else if (TREE_CODE (gnu_result
) == INTEGER_CST
4781 && TREE_OVERFLOW (gnu_result
))
4783 post_error ("Constraint_Error will be raised at run-time?", gnat_node
);
4786 = build1 (NULL_EXPR
, gnu_result_type
,
4787 build_call_raise (CE_Overflow_Check_Failed
, gnat_node
,
4788 N_Raise_Constraint_Error
));
4791 /* If our result has side-effects and is of an unconstrained type,
4792 make a SAVE_EXPR so that we can be sure it will only be referenced
4793 once. Note we must do this before any conversions. */
4794 if (TREE_SIDE_EFFECTS (gnu_result
)
4795 && (TREE_CODE (gnu_result_type
) == UNCONSTRAINED_ARRAY_TYPE
4796 || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type
))))
4797 gnu_result
= gnat_stabilize_reference (gnu_result
, false);
4799 /* Now convert the result to the proper type. If the type is void or if
4800 we have no result, return error_mark_node to show we have no result.
4801 If the type of the result is correct or if we have a label (which doesn't
4802 have any well-defined type), return our result. Also don't do the
4803 conversion if the "desired" type involves a PLACEHOLDER_EXPR in its size
4804 since those are the cases where the front end may have the type wrong due
4805 to "instantiating" the unconstrained record with discriminant values
4806 or if this is a FIELD_DECL. If this is the Name of an assignment
4807 statement or a parameter of a procedure call, return what we have since
4808 the RHS has to be converted to our type there in that case, unless
4809 GNU_RESULT_TYPE has a simpler size. Similarly, if the two types are
4810 record types with the same name, the expression type has integral mode,
4811 and GNU_RESULT_TYPE BLKmode, don't convert. This will be the case when
4812 we are converting from a packable type to its actual type and we need
4813 those conversions to be NOPs in order for assignments into these types to
4814 work properly if the inner object is a bitfield and hence can't have
4815 its address taken. Finally, don't convert integral types that are the
4816 operand of an unchecked conversion since we need to ignore those
4817 conversions (for 'Valid). Otherwise, convert the result to the proper
4820 if (Present (Parent (gnat_node
))
4821 && ((Nkind (Parent (gnat_node
)) == N_Assignment_Statement
4822 && Name (Parent (gnat_node
)) == gnat_node
)
4823 || (Nkind (Parent (gnat_node
)) == N_Procedure_Call_Statement
4824 && Name (Parent (gnat_node
)) != gnat_node
)
4825 || (Nkind (Parent (gnat_node
)) == N_Unchecked_Type_Conversion
4826 && !AGGREGATE_TYPE_P (gnu_result_type
)
4827 && !AGGREGATE_TYPE_P (TREE_TYPE (gnu_result
)))
4828 || Nkind (Parent (gnat_node
)) == N_Parameter_Association
)
4829 && !(TYPE_SIZE (gnu_result_type
)
4830 && TYPE_SIZE (TREE_TYPE (gnu_result
))
4831 && (AGGREGATE_TYPE_P (gnu_result_type
)
4832 == AGGREGATE_TYPE_P (TREE_TYPE (gnu_result
)))
4833 && ((TREE_CODE (TYPE_SIZE (gnu_result_type
)) == INTEGER_CST
4834 && (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_result
)))
4836 || (TREE_CODE (TYPE_SIZE (gnu_result_type
)) != INTEGER_CST
4837 && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type
))
4838 && (CONTAINS_PLACEHOLDER_P
4839 (TYPE_SIZE (TREE_TYPE (gnu_result
))))))
4840 && !(TREE_CODE (gnu_result_type
) == RECORD_TYPE
4841 && TYPE_JUSTIFIED_MODULAR_P (gnu_result_type
))))
4843 /* In this case remove padding only if the inner object type is the
4844 same as gnu_result_type or is of self-referential size (in that later
4845 case it must be an object of unconstrained type with a default
4846 discriminant). We want to avoid copying too much data. */
4847 if (TREE_CODE (TREE_TYPE (gnu_result
)) == RECORD_TYPE
4848 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result
))
4849 && (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result
)))
4851 || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS
4852 (TREE_TYPE (gnu_result
)))))))
4853 gnu_result
= convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result
))),
4857 else if (TREE_CODE (gnu_result
) == LABEL_DECL
4858 || TREE_CODE (gnu_result
) == FIELD_DECL
4859 || TREE_CODE (gnu_result
) == ERROR_MARK
4860 || (TYPE_SIZE (gnu_result_type
)
4861 && TREE_CODE (TYPE_SIZE (gnu_result_type
)) != INTEGER_CST
4862 && TREE_CODE (gnu_result
) != INDIRECT_REF
4863 && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type
)))
4864 || ((TYPE_NAME (gnu_result_type
)
4865 == TYPE_NAME (TREE_TYPE (gnu_result
)))
4866 && TREE_CODE (gnu_result_type
) == RECORD_TYPE
4867 && TREE_CODE (TREE_TYPE (gnu_result
)) == RECORD_TYPE
4868 && TYPE_MODE (gnu_result_type
) == BLKmode
4869 && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (gnu_result
)))
4872 /* Remove any padding record, but do nothing more in this case. */
4873 if (TREE_CODE (TREE_TYPE (gnu_result
)) == RECORD_TYPE
4874 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result
)))
4875 gnu_result
= convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result
))),
4879 else if (gnu_result
== error_mark_node
4880 || gnu_result_type
== void_type_node
)
4881 gnu_result
= error_mark_node
;
4882 else if (gnu_result_type
!= TREE_TYPE (gnu_result
))
4883 gnu_result
= convert (gnu_result_type
, gnu_result
);
4885 /* We don't need any NOP_EXPR or NON_LVALUE_EXPR on GNU_RESULT. */
4886 while ((TREE_CODE (gnu_result
) == NOP_EXPR
4887 || TREE_CODE (gnu_result
) == NON_LVALUE_EXPR
)
4888 && TREE_TYPE (TREE_OPERAND (gnu_result
, 0)) == TREE_TYPE (gnu_result
))
4889 gnu_result
= TREE_OPERAND (gnu_result
, 0);
4894 /* Subroutine of above to push the exception label stack. GNU_STACK is
4895 a pointer to the stack to update and GNAT_LABEL, if present, is the
4896 label to push onto the stack. */
4899 push_exception_label_stack (tree
*gnu_stack
, Entity_Id gnat_label
)
4901 tree gnu_label
= (Present (gnat_label
)
4902 ? gnat_to_gnu_entity (gnat_label
, NULL_TREE
, 0)
4905 *gnu_stack
= tree_cons (NULL_TREE
, gnu_label
, *gnu_stack
);
4908 /* Record the current code position in GNAT_NODE. */
4911 record_code_position (Node_Id gnat_node
)
4913 tree stmt_stmt
= build1 (STMT_STMT
, void_type_node
, NULL_TREE
);
4915 add_stmt_with_node (stmt_stmt
, gnat_node
);
4916 save_gnu_tree (gnat_node
, stmt_stmt
, true);
4919 /* Insert the code for GNAT_NODE at the position saved for that node. */
4922 insert_code_for (Node_Id gnat_node
)
4924 STMT_STMT_STMT (get_gnu_tree (gnat_node
)) = gnat_to_gnu (gnat_node
);
4925 save_gnu_tree (gnat_node
, NULL_TREE
, true);
4928 /* Start a new statement group chained to the previous group. */
4931 start_stmt_group (void)
4933 struct stmt_group
*group
= stmt_group_free_list
;
4935 /* First see if we can get one from the free list. */
4937 stmt_group_free_list
= group
->previous
;
4939 group
= (struct stmt_group
*) ggc_alloc (sizeof (struct stmt_group
));
4941 group
->previous
= current_stmt_group
;
4942 group
->stmt_list
= group
->block
= group
->cleanups
= NULL_TREE
;
4943 current_stmt_group
= group
;
4946 /* Add GNU_STMT to the current statement group. */
4949 add_stmt (tree gnu_stmt
)
4951 append_to_statement_list (gnu_stmt
, ¤t_stmt_group
->stmt_list
);
4954 /* Similar, but set the location of GNU_STMT to that of GNAT_NODE. */
4957 add_stmt_with_node (tree gnu_stmt
, Node_Id gnat_node
)
4959 if (Present (gnat_node
))
4960 set_expr_location_from_node (gnu_stmt
, gnat_node
);
4961 add_stmt (gnu_stmt
);
4964 /* Add a declaration statement for GNU_DECL to the current statement group.
4965 Get SLOC from Entity_Id. */
4968 add_decl_expr (tree gnu_decl
, Entity_Id gnat_entity
)
4970 tree type
= TREE_TYPE (gnu_decl
);
4971 tree gnu_stmt
, gnu_init
, gnu_lhs
;
4973 /* If this is a variable that Gigi is to ignore, we may have been given
4974 an ERROR_MARK. So test for it. We also might have been given a
4975 reference for a renaming. So only do something for a decl. Also
4976 ignore a TYPE_DECL for an UNCONSTRAINED_ARRAY_TYPE. */
4977 if (!DECL_P (gnu_decl
)
4978 || (TREE_CODE (gnu_decl
) == TYPE_DECL
4979 && TREE_CODE (type
) == UNCONSTRAINED_ARRAY_TYPE
))
4982 gnu_stmt
= build1 (DECL_EXPR
, void_type_node
, gnu_decl
);
4984 /* If we are global, we don't want to actually output the DECL_EXPR for
4985 this decl since we already have evaluated the expressions in the
4986 sizes and positions as globals and doing it again would be wrong. */
4987 if (global_bindings_p ())
4989 /* Mark everything as used to prevent node sharing with subprograms.
4990 Note that walk_tree knows how to handle TYPE_DECL, but neither
4991 VAR_DECL nor CONST_DECL. This appears to be somewhat arbitrary. */
4992 walk_tree (&gnu_stmt
, mark_visited
, NULL
, NULL
);
4993 if (TREE_CODE (gnu_decl
) == VAR_DECL
4994 || TREE_CODE (gnu_decl
) == CONST_DECL
)
4996 walk_tree (&DECL_SIZE (gnu_decl
), mark_visited
, NULL
, NULL
);
4997 walk_tree (&DECL_SIZE_UNIT (gnu_decl
), mark_visited
, NULL
, NULL
);
4998 walk_tree (&DECL_INITIAL (gnu_decl
), mark_visited
, NULL
, NULL
);
5002 add_stmt_with_node (gnu_stmt
, gnat_entity
);
5004 /* If this is a variable and an initializer is attached to it, it must be
5005 valid for the context. Similar to init_const in create_var_decl_1. */
5006 if (TREE_CODE (gnu_decl
) == VAR_DECL
5007 && (gnu_init
= DECL_INITIAL (gnu_decl
)) != NULL_TREE
5008 && (TYPE_MAIN_VARIANT (type
) != TYPE_MAIN_VARIANT (TREE_TYPE (gnu_init
))
5009 || (TREE_STATIC (gnu_decl
)
5010 && !initializer_constant_valid_p (gnu_init
,
5011 TREE_TYPE (gnu_init
)))))
5013 /* If GNU_DECL has a padded type, convert it to the unpadded
5014 type so the assignment is done properly. */
5015 if (TREE_CODE (type
) == RECORD_TYPE
&& TYPE_IS_PADDING_P (type
))
5016 gnu_lhs
= convert (TREE_TYPE (TYPE_FIELDS (type
)), gnu_decl
);
5020 gnu_stmt
= build_binary_op (MODIFY_EXPR
, NULL_TREE
, gnu_lhs
, gnu_init
);
5022 DECL_INITIAL (gnu_decl
) = NULL_TREE
;
5023 if (TREE_READONLY (gnu_decl
))
5025 TREE_READONLY (gnu_decl
) = 0;
5026 DECL_READONLY_ONCE_ELAB (gnu_decl
) = 1;
5029 add_stmt_with_node (gnu_stmt
, gnat_entity
);
5033 /* Utility function to mark nodes with TREE_VISITED and types as having their
5034 sized gimplified. Called from walk_tree. We use this to indicate all
5035 variable sizes and positions in global types may not be shared by any
5039 mark_visited (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
5041 if (TREE_VISITED (*tp
))
5044 /* Don't mark a dummy type as visited because we want to mark its sizes
5045 and fields once it's filled in. */
5046 else if (!TYPE_IS_DUMMY_P (*tp
))
5047 TREE_VISITED (*tp
) = 1;
5050 TYPE_SIZES_GIMPLIFIED (*tp
) = 1;
5055 /* Utility function to unshare expressions wrapped up in a SAVE_EXPR. */
5058 unshare_save_expr (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
5059 void *data ATTRIBUTE_UNUSED
)
5063 if (TREE_CODE (t
) == SAVE_EXPR
)
5064 TREE_OPERAND (t
, 0) = unshare_expr (TREE_OPERAND (t
, 0));
5069 /* Add GNU_CLEANUP, a cleanup action, to the current code group and
5070 set its location to that of GNAT_NODE if present. */
5073 add_cleanup (tree gnu_cleanup
, Node_Id gnat_node
)
5075 if (Present (gnat_node
))
5076 set_expr_location_from_node (gnu_cleanup
, gnat_node
);
5077 append_to_statement_list (gnu_cleanup
, ¤t_stmt_group
->cleanups
);
5080 /* Set the BLOCK node corresponding to the current code group to GNU_BLOCK. */
5083 set_block_for_group (tree gnu_block
)
5085 gcc_assert (!current_stmt_group
->block
);
5086 current_stmt_group
->block
= gnu_block
;
5089 /* Return code corresponding to the current code group. It is normally
5090 a STATEMENT_LIST, but may also be a BIND_EXPR or TRY_FINALLY_EXPR if
5091 BLOCK or cleanups were set. */
5094 end_stmt_group (void)
5096 struct stmt_group
*group
= current_stmt_group
;
5097 tree gnu_retval
= group
->stmt_list
;
5099 /* If this is a null list, allocate a new STATEMENT_LIST. Then, if there
5100 are cleanups, make a TRY_FINALLY_EXPR. Last, if there is a BLOCK,
5101 make a BIND_EXPR. Note that we nest in that because the cleanup may
5102 reference variables in the block. */
5103 if (gnu_retval
== NULL_TREE
)
5104 gnu_retval
= alloc_stmt_list ();
5106 if (group
->cleanups
)
5107 gnu_retval
= build2 (TRY_FINALLY_EXPR
, void_type_node
, gnu_retval
,
5110 if (current_stmt_group
->block
)
5111 gnu_retval
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (group
->block
),
5112 gnu_retval
, group
->block
);
5114 /* Remove this group from the stack and add it to the free list. */
5115 current_stmt_group
= group
->previous
;
5116 group
->previous
= stmt_group_free_list
;
5117 stmt_group_free_list
= group
;
5122 /* Add a list of statements from GNAT_LIST, a possibly-empty list of
5126 add_stmt_list (List_Id gnat_list
)
5130 if (Present (gnat_list
))
5131 for (gnat_node
= First (gnat_list
); Present (gnat_node
);
5132 gnat_node
= Next (gnat_node
))
5133 add_stmt (gnat_to_gnu (gnat_node
));
5136 /* Build a tree from GNAT_LIST, a possibly-empty list of statements.
5137 If BINDING_P is true, push and pop a binding level around the list. */
5140 build_stmt_group (List_Id gnat_list
, bool binding_p
)
5142 start_stmt_group ();
5146 add_stmt_list (gnat_list
);
5150 return end_stmt_group ();
5153 /* Push and pop routines for stacks. We keep a free list around so we
5154 don't waste tree nodes. */
5157 push_stack (tree
*gnu_stack_ptr
, tree gnu_purpose
, tree gnu_value
)
5159 tree gnu_node
= gnu_stack_free_list
;
5163 gnu_stack_free_list
= TREE_CHAIN (gnu_node
);
5164 TREE_CHAIN (gnu_node
) = *gnu_stack_ptr
;
5165 TREE_PURPOSE (gnu_node
) = gnu_purpose
;
5166 TREE_VALUE (gnu_node
) = gnu_value
;
5169 gnu_node
= tree_cons (gnu_purpose
, gnu_value
, *gnu_stack_ptr
);
5171 *gnu_stack_ptr
= gnu_node
;
5175 pop_stack (tree
*gnu_stack_ptr
)
5177 tree gnu_node
= *gnu_stack_ptr
;
5179 *gnu_stack_ptr
= TREE_CHAIN (gnu_node
);
5180 TREE_CHAIN (gnu_node
) = gnu_stack_free_list
;
5181 gnu_stack_free_list
= gnu_node
;
5184 /* Generate GIMPLE in place for the expression at *EXPR_P. */
5187 gnat_gimplify_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p ATTRIBUTE_UNUSED
)
5189 tree expr
= *expr_p
;
5192 if (IS_ADA_STMT (expr
))
5193 return gnat_gimplify_stmt (expr_p
);
5195 switch (TREE_CODE (expr
))
5198 /* If this is for a scalar, just make a VAR_DECL for it. If for
5199 an aggregate, get a null pointer of the appropriate type and
5201 if (AGGREGATE_TYPE_P (TREE_TYPE (expr
)))
5202 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (expr
),
5203 convert (build_pointer_type (TREE_TYPE (expr
)),
5204 integer_zero_node
));
5207 *expr_p
= create_tmp_var (TREE_TYPE (expr
), NULL
);
5208 TREE_NO_WARNING (*expr_p
) = 1;
5211 gimplify_and_add (TREE_OPERAND (expr
, 0), pre_p
);
5214 case UNCONSTRAINED_ARRAY_REF
:
5215 /* We should only do this if we are just elaborating for side-effects,
5216 but we can't know that yet. */
5217 *expr_p
= TREE_OPERAND (*expr_p
, 0);
5221 op
= TREE_OPERAND (expr
, 0);
5223 /* If we're taking the address of a constant CONSTRUCTOR, force it to
5224 be put into static memory. We know it's going to be readonly given
5225 the semantics we have and it's required to be static memory in
5226 the case when the reference is in an elaboration procedure. */
5227 if (TREE_CODE (op
) == CONSTRUCTOR
&& TREE_CONSTANT (op
))
5229 tree new_var
= create_tmp_var (TREE_TYPE (op
), "C");
5231 TREE_READONLY (new_var
) = 1;
5232 TREE_STATIC (new_var
) = 1;
5233 TREE_ADDRESSABLE (new_var
) = 1;
5234 DECL_INITIAL (new_var
) = op
;
5236 TREE_OPERAND (expr
, 0) = new_var
;
5237 recompute_tree_invariant_for_addr_expr (expr
);
5241 /* If we are taking the address of a SAVE_EXPR, we are typically
5242 processing a misaligned argument to be passed by reference in a
5243 procedure call. We just mark the operand as addressable + not
5244 readonly here and let the common gimplifier code perform the
5245 temporary creation, initialization, and "instantiation" in place of
5246 the SAVE_EXPR in further operands, in particular in the copy back
5247 code inserted after the call. */
5248 else if (TREE_CODE (op
) == SAVE_EXPR
)
5250 TREE_ADDRESSABLE (op
) = 1;
5251 TREE_READONLY (op
) = 0;
5254 /* Otherwise, if we are taking the address of something that is neither
5255 reference, declaration, or constant, make a variable for the operand
5256 here and then take its address. If we don't do it this way, we may
5257 confuse the gimplifier because it needs to know the variable is
5258 addressable at this point. This duplicates code in
5259 internal_get_tmp_var, which is unfortunate. */
5260 else if (TREE_CODE_CLASS (TREE_CODE (op
)) != tcc_reference
5261 && TREE_CODE_CLASS (TREE_CODE (op
)) != tcc_declaration
5262 && TREE_CODE_CLASS (TREE_CODE (op
)) != tcc_constant
)
5264 tree new_var
= create_tmp_var (TREE_TYPE (op
), "A");
5265 tree mod
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (op
), new_var
, op
);
5267 TREE_ADDRESSABLE (new_var
) = 1;
5269 if (EXPR_HAS_LOCATION (op
))
5270 SET_EXPR_LOCUS (mod
, EXPR_LOCUS (op
));
5272 gimplify_and_add (mod
, pre_p
);
5273 TREE_OPERAND (expr
, 0) = new_var
;
5274 recompute_tree_invariant_for_addr_expr (expr
);
5278 /* ... fall through ... */
5281 return GS_UNHANDLED
;
5285 /* Generate GIMPLE in place for the statement at *STMT_P. */
5287 static enum gimplify_status
5288 gnat_gimplify_stmt (tree
*stmt_p
)
5290 tree stmt
= *stmt_p
;
5292 switch (TREE_CODE (stmt
))
5295 *stmt_p
= STMT_STMT_STMT (stmt
);
5300 tree gnu_start_label
= create_artificial_label ();
5301 tree gnu_end_label
= LOOP_STMT_LABEL (stmt
);
5303 /* Set to emit the statements of the loop. */
5304 *stmt_p
= NULL_TREE
;
5306 /* We first emit the start label and then a conditional jump to
5307 the end label if there's a top condition, then the body of the
5308 loop, then a conditional branch to the end label, then the update,
5309 if any, and finally a jump to the start label and the definition
5310 of the end label. */
5311 append_to_statement_list (build1 (LABEL_EXPR
, void_type_node
,
5315 if (LOOP_STMT_TOP_COND (stmt
))
5316 append_to_statement_list (build3 (COND_EXPR
, void_type_node
,
5317 LOOP_STMT_TOP_COND (stmt
),
5324 append_to_statement_list (LOOP_STMT_BODY (stmt
), stmt_p
);
5326 if (LOOP_STMT_BOT_COND (stmt
))
5327 append_to_statement_list (build3 (COND_EXPR
, void_type_node
,
5328 LOOP_STMT_BOT_COND (stmt
),
5335 if (LOOP_STMT_UPDATE (stmt
))
5336 append_to_statement_list (LOOP_STMT_UPDATE (stmt
), stmt_p
);
5338 append_to_statement_list (build1 (GOTO_EXPR
, void_type_node
,
5341 append_to_statement_list (build1 (LABEL_EXPR
, void_type_node
,
5348 /* Build a statement to jump to the corresponding end label, then
5349 see if it needs to be conditional. */
5350 *stmt_p
= build1 (GOTO_EXPR
, void_type_node
, EXIT_STMT_LABEL (stmt
));
5351 if (EXIT_STMT_COND (stmt
))
5352 *stmt_p
= build3 (COND_EXPR
, void_type_node
,
5353 EXIT_STMT_COND (stmt
), *stmt_p
, alloc_stmt_list ());
5361 /* Force references to each of the entities in packages withed by GNAT_NODE.
5362 Operate recursively but check that we aren't elaborating something more
5365 This routine is exclusively called in type_annotate mode, to compute DDA
5366 information for types in withed units, for ASIS use. */
5369 elaborate_all_entities (Node_Id gnat_node
)
5371 Entity_Id gnat_with_clause
, gnat_entity
;
5373 /* Process each unit only once. As we trace the context of all relevant
5374 units transitively, including generic bodies, we may encounter the
5375 same generic unit repeatedly. */
5376 if (!present_gnu_tree (gnat_node
))
5377 save_gnu_tree (gnat_node
, integer_zero_node
, true);
5379 /* Save entities in all context units. A body may have an implicit_with
5380 on its own spec, if the context includes a child unit, so don't save
5382 for (gnat_with_clause
= First (Context_Items (gnat_node
));
5383 Present (gnat_with_clause
);
5384 gnat_with_clause
= Next (gnat_with_clause
))
5385 if (Nkind (gnat_with_clause
) == N_With_Clause
5386 && !present_gnu_tree (Library_Unit (gnat_with_clause
))
5387 && Library_Unit (gnat_with_clause
) != Library_Unit (Cunit (Main_Unit
)))
5389 elaborate_all_entities (Library_Unit (gnat_with_clause
));
5391 if (Ekind (Entity (Name (gnat_with_clause
))) == E_Package
)
5393 for (gnat_entity
= First_Entity (Entity (Name (gnat_with_clause
)));
5394 Present (gnat_entity
);
5395 gnat_entity
= Next_Entity (gnat_entity
))
5396 if (Is_Public (gnat_entity
)
5397 && Convention (gnat_entity
) != Convention_Intrinsic
5398 && Ekind (gnat_entity
) != E_Package
5399 && Ekind (gnat_entity
) != E_Package_Body
5400 && Ekind (gnat_entity
) != E_Operator
5401 && !(IN (Ekind (gnat_entity
), Type_Kind
)
5402 && !Is_Frozen (gnat_entity
))
5403 && !((Ekind (gnat_entity
) == E_Procedure
5404 || Ekind (gnat_entity
) == E_Function
)
5405 && Is_Intrinsic_Subprogram (gnat_entity
))
5406 && !IN (Ekind (gnat_entity
), Named_Kind
)
5407 && !IN (Ekind (gnat_entity
), Generic_Unit_Kind
))
5408 gnat_to_gnu_entity (gnat_entity
, NULL_TREE
, 0);
5410 else if (Ekind (Entity (Name (gnat_with_clause
))) == E_Generic_Package
)
5413 = Corresponding_Body (Unit (Library_Unit (gnat_with_clause
)));
5415 /* Retrieve compilation unit node of generic body. */
5416 while (Present (gnat_body
)
5417 && Nkind (gnat_body
) != N_Compilation_Unit
)
5418 gnat_body
= Parent (gnat_body
);
5420 /* If body is available, elaborate its context. */
5421 if (Present (gnat_body
))
5422 elaborate_all_entities (gnat_body
);
5426 if (Nkind (Unit (gnat_node
)) == N_Package_Body
)
5427 elaborate_all_entities (Library_Unit (gnat_node
));
5430 /* Do the processing of N_Freeze_Entity, GNAT_NODE. */
5433 process_freeze_entity (Node_Id gnat_node
)
5435 Entity_Id gnat_entity
= Entity (gnat_node
);
5439 = (Nkind (Declaration_Node (gnat_entity
)) == N_Object_Declaration
5440 && present_gnu_tree (Declaration_Node (gnat_entity
)))
5441 ? get_gnu_tree (Declaration_Node (gnat_entity
)) : NULL_TREE
;
5443 /* If this is a package, need to generate code for the package. */
5444 if (Ekind (gnat_entity
) == E_Package
)
5447 (Parent (Corresponding_Body
5448 (Parent (Declaration_Node (gnat_entity
)))));
5452 /* Check for old definition after the above call. This Freeze_Node
5453 might be for one its Itypes. */
5455 = present_gnu_tree (gnat_entity
) ? get_gnu_tree (gnat_entity
) : 0;
5457 /* If this entity has an Address representation clause, GNU_OLD is the
5458 address, so discard it here. */
5459 if (Present (Address_Clause (gnat_entity
)))
5462 /* Don't do anything for class-wide types they are always
5463 transformed into their root type. */
5464 if (Ekind (gnat_entity
) == E_Class_Wide_Type
5465 || (Ekind (gnat_entity
) == E_Class_Wide_Subtype
5466 && Present (Equivalent_Type (gnat_entity
))))
5469 /* Don't do anything for subprograms that may have been elaborated before
5470 their freeze nodes. This can happen, for example because of an inner call
5471 in an instance body, or a previous compilation of a spec for inlining
5474 && ((TREE_CODE (gnu_old
) == FUNCTION_DECL
5475 && (Ekind (gnat_entity
) == E_Function
5476 || Ekind (gnat_entity
) == E_Procedure
))
5478 && TREE_CODE (TREE_TYPE (gnu_old
)) == FUNCTION_TYPE
5479 && Ekind (gnat_entity
) == E_Subprogram_Type
)))
5482 /* If we have a non-dummy type old tree, we have nothing to do, except
5483 aborting if this is the public view of a private type whose full view was
5484 not delayed, as this node was never delayed as it should have been. We
5485 let this happen for concurrent types and their Corresponding_Record_Type,
5486 however, because each might legitimately be elaborated before it's own
5487 freeze node, e.g. while processing the other. */
5489 && !(TREE_CODE (gnu_old
) == TYPE_DECL
5490 && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old
))))
5492 gcc_assert ((IN (Ekind (gnat_entity
), Incomplete_Or_Private_Kind
)
5493 && Present (Full_View (gnat_entity
))
5494 && No (Freeze_Node (Full_View (gnat_entity
))))
5495 || Is_Concurrent_Type (gnat_entity
)
5496 || (IN (Ekind (gnat_entity
), Record_Kind
)
5497 && Is_Concurrent_Record_Type (gnat_entity
)));
5501 /* Reset the saved tree, if any, and elaborate the object or type for real.
5502 If there is a full declaration, elaborate it and copy the type to
5503 GNAT_ENTITY. Likewise if this is the record subtype corresponding to
5504 a class wide type or subtype. */
5507 save_gnu_tree (gnat_entity
, NULL_TREE
, false);
5508 if (IN (Ekind (gnat_entity
), Incomplete_Or_Private_Kind
)
5509 && Present (Full_View (gnat_entity
))
5510 && present_gnu_tree (Full_View (gnat_entity
)))
5511 save_gnu_tree (Full_View (gnat_entity
), NULL_TREE
, false);
5512 if (Present (Class_Wide_Type (gnat_entity
))
5513 && Class_Wide_Type (gnat_entity
) != gnat_entity
)
5514 save_gnu_tree (Class_Wide_Type (gnat_entity
), NULL_TREE
, false);
5517 if (IN (Ekind (gnat_entity
), Incomplete_Or_Private_Kind
)
5518 && Present (Full_View (gnat_entity
)))
5520 gnu_new
= gnat_to_gnu_entity (Full_View (gnat_entity
), NULL_TREE
, 1);
5522 /* Propagate back-annotations from full view to partial view. */
5523 if (Unknown_Alignment (gnat_entity
))
5524 Set_Alignment (gnat_entity
, Alignment (Full_View (gnat_entity
)));
5526 if (Unknown_Esize (gnat_entity
))
5527 Set_Esize (gnat_entity
, Esize (Full_View (gnat_entity
)));
5529 if (Unknown_RM_Size (gnat_entity
))
5530 Set_RM_Size (gnat_entity
, RM_Size (Full_View (gnat_entity
)));
5532 /* The above call may have defined this entity (the simplest example
5533 of this is when we have a private enumeral type since the bounds
5534 will have the public view. */
5535 if (!present_gnu_tree (gnat_entity
))
5536 save_gnu_tree (gnat_entity
, gnu_new
, false);
5537 if (Present (Class_Wide_Type (gnat_entity
))
5538 && Class_Wide_Type (gnat_entity
) != gnat_entity
)
5539 save_gnu_tree (Class_Wide_Type (gnat_entity
), gnu_new
, false);
5542 gnu_new
= gnat_to_gnu_entity (gnat_entity
, gnu_init
, 1);
5544 /* If we've made any pointers to the old version of this type, we
5545 have to update them. */
5547 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old
)),
5548 TREE_TYPE (gnu_new
));
5551 /* Process the list of inlined subprograms of GNAT_NODE, which is an
5552 N_Compilation_Unit. */
5555 process_inlined_subprograms (Node_Id gnat_node
)
5557 Entity_Id gnat_entity
;
5560 /* If we can inline, generate RTL for all the inlined subprograms.
5561 Define the entity first so we set DECL_EXTERNAL. */
5562 if (optimize
> 0 && !flag_really_no_inline
)
5563 for (gnat_entity
= First_Inlined_Subprogram (gnat_node
);
5564 Present (gnat_entity
);
5565 gnat_entity
= Next_Inlined_Subprogram (gnat_entity
))
5567 gnat_body
= Parent (Declaration_Node (gnat_entity
));
5569 if (Nkind (gnat_body
) != N_Subprogram_Body
)
5571 /* ??? This really should always be Present. */
5572 if (No (Corresponding_Body (gnat_body
)))
5576 = Parent (Declaration_Node (Corresponding_Body (gnat_body
)));
5579 if (Present (gnat_body
))
5581 gnat_to_gnu_entity (gnat_entity
, NULL_TREE
, 0);
5582 add_stmt (gnat_to_gnu (gnat_body
));
5587 /* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
5588 We make two passes, one to elaborate anything other than bodies (but
5589 we declare a function if there was no spec). The second pass
5590 elaborates the bodies.
5592 GNAT_END_LIST gives the element in the list past the end. Normally,
5593 this is Empty, but can be First_Real_Statement for a
5594 Handled_Sequence_Of_Statements.
5596 We make a complete pass through both lists if PASS1P is true, then make
5597 the second pass over both lists if PASS2P is true. The lists usually
5598 correspond to the public and private parts of a package. */
5601 process_decls (List_Id gnat_decls
, List_Id gnat_decls2
,
5602 Node_Id gnat_end_list
, bool pass1p
, bool pass2p
)
5604 List_Id gnat_decl_array
[2];
5608 gnat_decl_array
[0] = gnat_decls
, gnat_decl_array
[1] = gnat_decls2
;
5611 for (i
= 0; i
<= 1; i
++)
5612 if (Present (gnat_decl_array
[i
]))
5613 for (gnat_decl
= First (gnat_decl_array
[i
]);
5614 gnat_decl
!= gnat_end_list
; gnat_decl
= Next (gnat_decl
))
5616 /* For package specs, we recurse inside the declarations,
5617 thus taking the two pass approach inside the boundary. */
5618 if (Nkind (gnat_decl
) == N_Package_Declaration
5619 && (Nkind (Specification (gnat_decl
)
5620 == N_Package_Specification
)))
5621 process_decls (Visible_Declarations (Specification (gnat_decl
)),
5622 Private_Declarations (Specification (gnat_decl
)),
5623 Empty
, true, false);
5625 /* Similarly for any declarations in the actions of a
5627 else if (Nkind (gnat_decl
) == N_Freeze_Entity
)
5629 process_freeze_entity (gnat_decl
);
5630 process_decls (Actions (gnat_decl
), Empty
, Empty
, true, false);
5633 /* Package bodies with freeze nodes get their elaboration deferred
5634 until the freeze node, but the code must be placed in the right
5635 place, so record the code position now. */
5636 else if (Nkind (gnat_decl
) == N_Package_Body
5637 && Present (Freeze_Node (Corresponding_Spec (gnat_decl
))))
5638 record_code_position (gnat_decl
);
5640 else if (Nkind (gnat_decl
) == N_Package_Body_Stub
5641 && Present (Library_Unit (gnat_decl
))
5642 && Present (Freeze_Node
5645 (Library_Unit (gnat_decl
)))))))
5646 record_code_position
5647 (Proper_Body (Unit (Library_Unit (gnat_decl
))));
5649 /* We defer most subprogram bodies to the second pass. */
5650 else if (Nkind (gnat_decl
) == N_Subprogram_Body
)
5652 if (Acts_As_Spec (gnat_decl
))
5654 Node_Id gnat_subprog_id
= Defining_Entity (gnat_decl
);
5656 if (Ekind (gnat_subprog_id
) != E_Generic_Procedure
5657 && Ekind (gnat_subprog_id
) != E_Generic_Function
)
5658 gnat_to_gnu_entity (gnat_subprog_id
, NULL_TREE
, 1);
5661 /* For bodies and stubs that act as their own specs, the entity
5662 itself must be elaborated in the first pass, because it may
5663 be used in other declarations. */
5664 else if (Nkind (gnat_decl
) == N_Subprogram_Body_Stub
)
5666 Node_Id gnat_subprog_id
=
5667 Defining_Entity (Specification (gnat_decl
));
5669 if (Ekind (gnat_subprog_id
) != E_Subprogram_Body
5670 && Ekind (gnat_subprog_id
) != E_Generic_Procedure
5671 && Ekind (gnat_subprog_id
) != E_Generic_Function
)
5672 gnat_to_gnu_entity (gnat_subprog_id
, NULL_TREE
, 1);
5675 /* Concurrent stubs stand for the corresponding subprogram bodies,
5676 which are deferred like other bodies. */
5677 else if (Nkind (gnat_decl
) == N_Task_Body_Stub
5678 || Nkind (gnat_decl
) == N_Protected_Body_Stub
)
5681 add_stmt (gnat_to_gnu (gnat_decl
));
5684 /* Here we elaborate everything we deferred above except for package bodies,
5685 which are elaborated at their freeze nodes. Note that we must also
5686 go inside things (package specs and freeze nodes) the first pass did. */
5688 for (i
= 0; i
<= 1; i
++)
5689 if (Present (gnat_decl_array
[i
]))
5690 for (gnat_decl
= First (gnat_decl_array
[i
]);
5691 gnat_decl
!= gnat_end_list
; gnat_decl
= Next (gnat_decl
))
5693 if (Nkind (gnat_decl
) == N_Subprogram_Body
5694 || Nkind (gnat_decl
) == N_Subprogram_Body_Stub
5695 || Nkind (gnat_decl
) == N_Task_Body_Stub
5696 || Nkind (gnat_decl
) == N_Protected_Body_Stub
)
5697 add_stmt (gnat_to_gnu (gnat_decl
));
5699 else if (Nkind (gnat_decl
) == N_Package_Declaration
5700 && (Nkind (Specification (gnat_decl
)
5701 == N_Package_Specification
)))
5702 process_decls (Visible_Declarations (Specification (gnat_decl
)),
5703 Private_Declarations (Specification (gnat_decl
)),
5704 Empty
, false, true);
5706 else if (Nkind (gnat_decl
) == N_Freeze_Entity
)
5707 process_decls (Actions (gnat_decl
), Empty
, Empty
, false, true);
5711 /* Emit code for a range check. GNU_EXPR is the expression to be checked,
5712 GNAT_RANGE_TYPE the gnat type or subtype containing the bounds against
5713 which we have to check. */
5716 emit_range_check (tree gnu_expr
, Entity_Id gnat_range_type
)
5718 tree gnu_range_type
= get_unpadded_type (gnat_range_type
);
5719 tree gnu_low
= TYPE_MIN_VALUE (gnu_range_type
);
5720 tree gnu_high
= TYPE_MAX_VALUE (gnu_range_type
);
5721 tree gnu_compare_type
= get_base_type (TREE_TYPE (gnu_expr
));
5723 /* If GNU_EXPR has an integral type that is narrower than GNU_RANGE_TYPE,
5724 we can't do anything since we might be truncating the bounds. No
5725 check is needed in this case. */
5726 if (INTEGRAL_TYPE_P (TREE_TYPE (gnu_expr
))
5727 && (TYPE_PRECISION (gnu_compare_type
)
5728 < TYPE_PRECISION (get_base_type (gnu_range_type
))))
5731 /* Checked expressions must be evaluated only once. */
5732 gnu_expr
= protect_multiple_eval (gnu_expr
);
5734 /* There's no good type to use here, so we might as well use
5735 integer_type_node. Note that the form of the check is
5736 (not (expr >= lo)) or (not (expr <= hi))
5737 the reason for this slightly convoluted form is that NaN's
5738 are not considered to be in range in the float case. */
5740 (build_binary_op (TRUTH_ORIF_EXPR
, integer_type_node
,
5742 (build_binary_op (GE_EXPR
, integer_type_node
,
5743 convert (gnu_compare_type
, gnu_expr
),
5744 convert (gnu_compare_type
, gnu_low
))),
5746 (build_binary_op (LE_EXPR
, integer_type_node
,
5747 convert (gnu_compare_type
, gnu_expr
),
5748 convert (gnu_compare_type
,
5750 gnu_expr
, CE_Range_Check_Failed
);
5753 /* Emit code for an index check. GNU_ARRAY_OBJECT is the array object
5754 which we are about to index, GNU_EXPR is the index expression to be
5755 checked, GNU_LOW and GNU_HIGH are the lower and upper bounds
5756 against which GNU_EXPR has to be checked. Note that for index
5757 checking we cannot use the emit_range_check function (although very
5758 similar code needs to be generated in both cases) since for index
5759 checking the array type against which we are checking the indeces
5760 may be unconstrained and consequently we need to retrieve the
5761 actual index bounds from the array object itself
5762 (GNU_ARRAY_OBJECT). The place where we need to do that is in
5763 subprograms having unconstrained array formal parameters */
5766 emit_index_check (tree gnu_array_object
,
5771 tree gnu_expr_check
;
5773 /* Checked expressions must be evaluated only once. */
5774 gnu_expr
= protect_multiple_eval (gnu_expr
);
5776 /* Must do this computation in the base type in case the expression's
5777 type is an unsigned subtypes. */
5778 gnu_expr_check
= convert (get_base_type (TREE_TYPE (gnu_expr
)), gnu_expr
);
5780 /* If GNU_LOW or GNU_HIGH are a PLACEHOLDER_EXPR, qualify them by
5781 the object we are handling. */
5782 gnu_low
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_low
, gnu_array_object
);
5783 gnu_high
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_high
, gnu_array_object
);
5785 /* There's no good type to use here, so we might as well use
5786 integer_type_node. */
5788 (build_binary_op (TRUTH_ORIF_EXPR
, integer_type_node
,
5789 build_binary_op (LT_EXPR
, integer_type_node
,
5791 convert (TREE_TYPE (gnu_expr_check
),
5793 build_binary_op (GT_EXPR
, integer_type_node
,
5795 convert (TREE_TYPE (gnu_expr_check
),
5797 gnu_expr
, CE_Index_Check_Failed
);
5800 /* GNU_COND contains the condition corresponding to an access, discriminant or
5801 range check of value GNU_EXPR. Build a COND_EXPR that returns GNU_EXPR if
5802 GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true.
5803 REASON is the code that says why the exception was raised. */
5806 emit_check (tree gnu_cond
, tree gnu_expr
, int reason
)
5811 gnu_call
= build_call_raise (reason
, Empty
, N_Raise_Constraint_Error
);
5813 /* Use an outer COMPOUND_EXPR to make sure that GNU_EXPR will get evaluated
5814 in front of the comparison in case it ends up being a SAVE_EXPR. Put the
5815 whole thing inside its own SAVE_EXPR so the inner SAVE_EXPR doesn't leak
5817 gnu_result
= fold_build3 (COND_EXPR
, TREE_TYPE (gnu_expr
), gnu_cond
,
5818 build2 (COMPOUND_EXPR
, TREE_TYPE (gnu_expr
),
5819 gnu_call
, gnu_expr
),
5822 /* If GNU_EXPR has side effects, make the outer COMPOUND_EXPR and
5823 protect it. Otherwise, show GNU_RESULT has no side effects: we
5824 don't need to evaluate it just for the check. */
5825 if (TREE_SIDE_EFFECTS (gnu_expr
))
5827 = build2 (COMPOUND_EXPR
, TREE_TYPE (gnu_expr
), gnu_expr
, gnu_result
);
5829 TREE_SIDE_EFFECTS (gnu_result
) = 0;
5831 /* ??? Unfortunately, if we don't put a SAVE_EXPR around this whole thing,
5832 we will repeatedly do the test. It would be nice if GCC was able
5833 to optimize this and only do it once. */
5834 return save_expr (gnu_result
);
5837 /* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing
5838 overflow checks if OVERFLOW_P is nonzero and range checks if
5839 RANGE_P is nonzero. GNAT_TYPE is known to be an integral type.
5840 If TRUNCATE_P is nonzero, do a float to integer conversion with
5841 truncation; otherwise round. */
5844 convert_with_check (Entity_Id gnat_type
, tree gnu_expr
, bool overflowp
,
5845 bool rangep
, bool truncatep
)
5847 tree gnu_type
= get_unpadded_type (gnat_type
);
5848 tree gnu_in_type
= TREE_TYPE (gnu_expr
);
5849 tree gnu_in_basetype
= get_base_type (gnu_in_type
);
5850 tree gnu_base_type
= get_base_type (gnu_type
);
5851 tree gnu_result
= gnu_expr
;
5853 /* If we are not doing any checks, the output is an integral type, and
5854 the input is not a floating type, just do the conversion. This
5855 shortcut is required to avoid problems with packed array types
5856 and simplifies code in all cases anyway. */
5857 if (!rangep
&& !overflowp
&& INTEGRAL_TYPE_P (gnu_base_type
)
5858 && !FLOAT_TYPE_P (gnu_in_type
))
5859 return convert (gnu_type
, gnu_expr
);
5861 /* First convert the expression to its base type. This
5862 will never generate code, but makes the tests below much simpler.
5863 But don't do this if converting from an integer type to an unconstrained
5864 array type since then we need to get the bounds from the original
5866 if (TREE_CODE (gnu_type
) != UNCONSTRAINED_ARRAY_TYPE
)
5867 gnu_result
= convert (gnu_in_basetype
, gnu_result
);
5869 /* If overflow checks are requested, we need to be sure the result will
5870 fit in the output base type. But don't do this if the input
5871 is integer and the output floating-point. */
5873 && !(FLOAT_TYPE_P (gnu_base_type
) && INTEGRAL_TYPE_P (gnu_in_basetype
)))
5875 /* Ensure GNU_EXPR only gets evaluated once. */
5876 tree gnu_input
= protect_multiple_eval (gnu_result
);
5877 tree gnu_cond
= integer_zero_node
;
5878 tree gnu_in_lb
= TYPE_MIN_VALUE (gnu_in_basetype
);
5879 tree gnu_in_ub
= TYPE_MAX_VALUE (gnu_in_basetype
);
5880 tree gnu_out_lb
= TYPE_MIN_VALUE (gnu_base_type
);
5881 tree gnu_out_ub
= TYPE_MAX_VALUE (gnu_base_type
);
5883 /* Convert the lower bounds to signed types, so we're sure we're
5884 comparing them properly. Likewise, convert the upper bounds
5885 to unsigned types. */
5886 if (INTEGRAL_TYPE_P (gnu_in_basetype
) && TYPE_UNSIGNED (gnu_in_basetype
))
5887 gnu_in_lb
= convert (gnat_signed_type (gnu_in_basetype
), gnu_in_lb
);
5889 if (INTEGRAL_TYPE_P (gnu_in_basetype
)
5890 && !TYPE_UNSIGNED (gnu_in_basetype
))
5891 gnu_in_ub
= convert (gnat_unsigned_type (gnu_in_basetype
), gnu_in_ub
);
5893 if (INTEGRAL_TYPE_P (gnu_base_type
) && TYPE_UNSIGNED (gnu_base_type
))
5894 gnu_out_lb
= convert (gnat_signed_type (gnu_base_type
), gnu_out_lb
);
5896 if (INTEGRAL_TYPE_P (gnu_base_type
) && !TYPE_UNSIGNED (gnu_base_type
))
5897 gnu_out_ub
= convert (gnat_unsigned_type (gnu_base_type
), gnu_out_ub
);
5899 /* Check each bound separately and only if the result bound
5900 is tighter than the bound on the input type. Note that all the
5901 types are base types, so the bounds must be constant. Also,
5902 the comparison is done in the base type of the input, which
5903 always has the proper signedness. First check for input
5904 integer (which means output integer), output float (which means
5905 both float), or mixed, in which case we always compare.
5906 Note that we have to do the comparison which would *fail* in the
5907 case of an error since if it's an FP comparison and one of the
5908 values is a NaN or Inf, the comparison will fail. */
5909 if (INTEGRAL_TYPE_P (gnu_in_basetype
)
5910 ? tree_int_cst_lt (gnu_in_lb
, gnu_out_lb
)
5911 : (FLOAT_TYPE_P (gnu_base_type
)
5912 ? REAL_VALUES_LESS (TREE_REAL_CST (gnu_in_lb
),
5913 TREE_REAL_CST (gnu_out_lb
))
5917 (build_binary_op (GE_EXPR
, integer_type_node
,
5918 gnu_input
, convert (gnu_in_basetype
,
5921 if (INTEGRAL_TYPE_P (gnu_in_basetype
)
5922 ? tree_int_cst_lt (gnu_out_ub
, gnu_in_ub
)
5923 : (FLOAT_TYPE_P (gnu_base_type
)
5924 ? REAL_VALUES_LESS (TREE_REAL_CST (gnu_out_ub
),
5925 TREE_REAL_CST (gnu_in_lb
))
5928 = build_binary_op (TRUTH_ORIF_EXPR
, integer_type_node
, gnu_cond
,
5930 (build_binary_op (LE_EXPR
, integer_type_node
,
5932 convert (gnu_in_basetype
,
5935 if (!integer_zerop (gnu_cond
))
5936 gnu_result
= emit_check (gnu_cond
, gnu_input
,
5937 CE_Overflow_Check_Failed
);
5940 /* Now convert to the result base type. If this is a non-truncating
5941 float-to-integer conversion, round. */
5942 if (INTEGRAL_TYPE_P (gnu_base_type
) && FLOAT_TYPE_P (gnu_in_basetype
)
5945 REAL_VALUE_TYPE half_minus_pred_half
, pred_half
;
5946 tree gnu_conv
, gnu_zero
, gnu_comp
, gnu_saved_result
, calc_type
;
5947 tree gnu_pred_half
, gnu_add_pred_half
, gnu_subtract_pred_half
;
5948 const struct real_format
*fmt
;
5950 /* The following calculations depend on proper rounding to even
5951 of each arithmetic operation. In order to prevent excess
5952 precision from spoiling this property, use the widest hardware
5953 floating-point type.
5955 FIXME: For maximum efficiency, this should only be done for machines
5956 and types where intermediates may have extra precision. */
5958 calc_type
= longest_float_type_node
;
5959 /* FIXME: Should not have padding in the first place */
5960 if (TREE_CODE (calc_type
) == RECORD_TYPE
5961 && TYPE_IS_PADDING_P (calc_type
))
5962 calc_type
= TREE_TYPE (TYPE_FIELDS (calc_type
));
5964 /* Compute the exact value calc_type'Pred (0.5) at compile time. */
5965 fmt
= REAL_MODE_FORMAT (TYPE_MODE (calc_type
));
5966 real_2expN (&half_minus_pred_half
, -(fmt
->p
) - 1, TYPE_MODE (calc_type
));
5967 REAL_ARITHMETIC (pred_half
, MINUS_EXPR
, dconsthalf
,
5968 half_minus_pred_half
);
5969 gnu_pred_half
= build_real (calc_type
, pred_half
);
5971 /* If the input is strictly negative, subtract this value
5972 and otherwise add it from the input. For 0.5, the result
5973 is exactly between 1.0 and the machine number preceding 1.0
5974 (for calc_type). Since the last bit of 1.0 is even, this 0.5
5975 will round to 1.0, while all other number with an absolute
5976 value less than 0.5 round to 0.0. For larger numbers exactly
5977 halfway between integers, rounding will always be correct as
5978 the true mathematical result will be closer to the higher
5979 integer compared to the lower one. So, this constant works
5980 for all floating-point numbers.
5982 The reason to use the same constant with subtract/add instead
5983 of a positive and negative constant is to allow the comparison
5984 to be scheduled in parallel with retrieval of the constant and
5985 conversion of the input to the calc_type (if necessary).
5988 gnu_zero
= convert (gnu_in_basetype
, integer_zero_node
);
5989 gnu_saved_result
= save_expr (gnu_result
);
5990 gnu_conv
= convert (calc_type
, gnu_saved_result
);
5991 gnu_comp
= build2 (GE_EXPR
, integer_type_node
,
5992 gnu_saved_result
, gnu_zero
);
5994 = build2 (PLUS_EXPR
, calc_type
, gnu_conv
, gnu_pred_half
);
5995 gnu_subtract_pred_half
5996 = build2 (MINUS_EXPR
, calc_type
, gnu_conv
, gnu_pred_half
);
5997 gnu_result
= build3 (COND_EXPR
, calc_type
, gnu_comp
,
5998 gnu_add_pred_half
, gnu_subtract_pred_half
);
6001 if (TREE_CODE (gnu_base_type
) == INTEGER_TYPE
6002 && TYPE_HAS_ACTUAL_BOUNDS_P (gnu_base_type
)
6003 && TREE_CODE (gnu_result
) == UNCONSTRAINED_ARRAY_REF
)
6004 gnu_result
= unchecked_convert (gnu_base_type
, gnu_result
, false);
6006 gnu_result
= convert (gnu_base_type
, gnu_result
);
6008 /* Finally, do the range check if requested. Note that if the
6009 result type is a modular type, the range check is actually
6010 an overflow check. */
6013 || (TREE_CODE (gnu_base_type
) == INTEGER_TYPE
6014 && TYPE_MODULAR_P (gnu_base_type
) && overflowp
))
6015 gnu_result
= emit_range_check (gnu_result
, gnat_type
);
6017 return convert (gnu_type
, gnu_result
);
6020 /* Return 1 if GNU_EXPR can be directly addressed. This is the case unless
6021 it is an expression involving computation or if it involves a reference
6022 to a bitfield or to a field not sufficiently aligned for its type. */
6025 addressable_p (tree gnu_expr
)
6027 switch (TREE_CODE (gnu_expr
))
6033 /* All DECLs are addressable: if they are in a register, we can force
6037 case UNCONSTRAINED_ARRAY_REF
:
6045 return (!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr
, 1))
6046 && (!STRICT_ALIGNMENT
6047 /* Even with DECL_BIT_FIELD cleared, we have to ensure that
6048 the field is sufficiently aligned, in case it is subject
6049 to a pragma Component_Alignment. But we don't need to
6050 check the alignment of the containing record, as it is
6051 guaranteed to be not smaller than that of its most
6052 aligned field that is not a bit-field. */
6053 || DECL_ALIGN (TREE_OPERAND (gnu_expr
, 1))
6054 >= TYPE_ALIGN (TREE_TYPE (gnu_expr
)))
6055 && addressable_p (TREE_OPERAND (gnu_expr
, 0)));
6057 case ARRAY_REF
: case ARRAY_RANGE_REF
:
6058 case REALPART_EXPR
: case IMAGPART_EXPR
:
6060 return addressable_p (TREE_OPERAND (gnu_expr
, 0));
6063 return (AGGREGATE_TYPE_P (TREE_TYPE (gnu_expr
))
6064 && addressable_p (TREE_OPERAND (gnu_expr
, 0)));
6066 case VIEW_CONVERT_EXPR
:
6068 /* This is addressable if we can avoid a copy. */
6069 tree type
= TREE_TYPE (gnu_expr
);
6070 tree inner_type
= TREE_TYPE (TREE_OPERAND (gnu_expr
, 0));
6072 return (((TYPE_MODE (type
) == TYPE_MODE (inner_type
)
6073 && (TYPE_ALIGN (type
) <= TYPE_ALIGN (inner_type
)
6074 || TYPE_ALIGN (inner_type
) >= BIGGEST_ALIGNMENT
))
6075 || ((TYPE_MODE (type
) == BLKmode
6076 || TYPE_MODE (inner_type
) == BLKmode
)
6077 && (TYPE_ALIGN (type
) <= TYPE_ALIGN (inner_type
)
6078 || TYPE_ALIGN (inner_type
) >= BIGGEST_ALIGNMENT
6079 || TYPE_ALIGN_OK (type
)
6080 || TYPE_ALIGN_OK (inner_type
))))
6081 && addressable_p (TREE_OPERAND (gnu_expr
, 0)));
6089 /* Do the processing for the declaration of a GNAT_ENTITY, a type. If
6090 a separate Freeze node exists, delay the bulk of the processing. Otherwise
6091 make a GCC type for GNAT_ENTITY and set up the correspondence. */
6094 process_type (Entity_Id gnat_entity
)
6097 = present_gnu_tree (gnat_entity
) ? get_gnu_tree (gnat_entity
) : 0;
6100 /* If we are to delay elaboration of this type, just do any
6101 elaborations needed for expressions within the declaration and
6102 make a dummy type entry for this node and its Full_View (if
6103 any) in case something points to it. Don't do this if it
6104 has already been done (the only way that can happen is if
6105 the private completion is also delayed). */
6106 if (Present (Freeze_Node (gnat_entity
))
6107 || (IN (Ekind (gnat_entity
), Incomplete_Or_Private_Kind
)
6108 && Present (Full_View (gnat_entity
))
6109 && Freeze_Node (Full_View (gnat_entity
))
6110 && !present_gnu_tree (Full_View (gnat_entity
))))
6112 elaborate_entity (gnat_entity
);
6116 tree gnu_decl
= create_type_decl (get_entity_name (gnat_entity
),
6117 make_dummy_type (gnat_entity
),
6118 NULL
, false, false, gnat_entity
);
6120 save_gnu_tree (gnat_entity
, gnu_decl
, false);
6121 if (IN (Ekind (gnat_entity
), Incomplete_Or_Private_Kind
)
6122 && Present (Full_View (gnat_entity
)))
6123 save_gnu_tree (Full_View (gnat_entity
), gnu_decl
, false);
6129 /* If we saved away a dummy type for this node it means that this
6130 made the type that corresponds to the full type of an incomplete
6131 type. Clear that type for now and then update the type in the
6135 gcc_assert (TREE_CODE (gnu_old
) == TYPE_DECL
6136 && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old
)));
6138 save_gnu_tree (gnat_entity
, NULL_TREE
, false);
6141 /* Now fully elaborate the type. */
6142 gnu_new
= gnat_to_gnu_entity (gnat_entity
, NULL_TREE
, 1);
6143 gcc_assert (TREE_CODE (gnu_new
) == TYPE_DECL
);
6145 /* If we have an old type and we've made pointers to this type,
6146 update those pointers. */
6148 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old
)),
6149 TREE_TYPE (gnu_new
));
6151 /* If this is a record type corresponding to a task or protected type
6152 that is a completion of an incomplete type, perform a similar update
6154 /* ??? Including protected types here is a guess. */
6156 if (IN (Ekind (gnat_entity
), Record_Kind
)
6157 && Is_Concurrent_Record_Type (gnat_entity
)
6158 && present_gnu_tree (Corresponding_Concurrent_Type (gnat_entity
)))
6161 = get_gnu_tree (Corresponding_Concurrent_Type (gnat_entity
));
6163 save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity
),
6165 save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity
),
6168 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_task_old
)),
6169 TREE_TYPE (gnu_new
));
6173 /* GNAT_ENTITY is the type of the resulting constructors,
6174 GNAT_ASSOC is the front of the Component_Associations of an N_Aggregate,
6175 and GNU_TYPE is the GCC type of the corresponding record.
6177 Return a CONSTRUCTOR to build the record. */
6180 assoc_to_constructor (Entity_Id gnat_entity
, Node_Id gnat_assoc
, tree gnu_type
)
6182 tree gnu_list
, gnu_result
;
6184 /* We test for GNU_FIELD being empty in the case where a variant
6185 was the last thing since we don't take things off GNAT_ASSOC in
6186 that case. We check GNAT_ASSOC in case we have a variant, but it
6189 for (gnu_list
= NULL_TREE
; Present (gnat_assoc
);
6190 gnat_assoc
= Next (gnat_assoc
))
6192 Node_Id gnat_field
= First (Choices (gnat_assoc
));
6193 tree gnu_field
= gnat_to_gnu_field_decl (Entity (gnat_field
));
6194 tree gnu_expr
= gnat_to_gnu (Expression (gnat_assoc
));
6196 /* The expander is supposed to put a single component selector name
6197 in every record component association */
6198 gcc_assert (No (Next (gnat_field
)));
6200 /* Ignore fields that have Corresponding_Discriminants since we'll
6201 be setting that field in the parent. */
6202 if (Present (Corresponding_Discriminant (Entity (gnat_field
)))
6203 && Is_Tagged_Type (Scope (Entity (gnat_field
))))
6206 /* Also ignore discriminants of Unchecked_Unions. */
6207 else if (Is_Unchecked_Union (gnat_entity
)
6208 && Ekind (Entity (gnat_field
)) == E_Discriminant
)
6211 /* Before assigning a value in an aggregate make sure range checks
6212 are done if required. Then convert to the type of the field. */
6213 if (Do_Range_Check (Expression (gnat_assoc
)))
6214 gnu_expr
= emit_range_check (gnu_expr
, Etype (gnat_field
));
6216 gnu_expr
= convert (TREE_TYPE (gnu_field
), gnu_expr
);
6218 /* Add the field and expression to the list. */
6219 gnu_list
= tree_cons (gnu_field
, gnu_expr
, gnu_list
);
6222 gnu_result
= extract_values (gnu_list
, gnu_type
);
6224 #ifdef ENABLE_CHECKING
6228 /* Verify every enty in GNU_LIST was used. */
6229 for (gnu_field
= gnu_list
; gnu_field
; gnu_field
= TREE_CHAIN (gnu_field
))
6230 gcc_assert (TREE_ADDRESSABLE (gnu_field
));
6237 /* Builds a possibly nested constructor for array aggregates. GNAT_EXPR
6238 is the first element of an array aggregate. It may itself be an
6239 aggregate (an array or record aggregate). GNU_ARRAY_TYPE is the gnu type
6240 corresponding to the array aggregate. GNAT_COMPONENT_TYPE is the type
6241 of the array component. It is needed for range checking. */
6244 pos_to_constructor (Node_Id gnat_expr
, tree gnu_array_type
,
6245 Entity_Id gnat_component_type
)
6247 tree gnu_expr_list
= NULL_TREE
;
6248 tree gnu_index
= TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_array_type
));
6251 for ( ; Present (gnat_expr
); gnat_expr
= Next (gnat_expr
))
6253 /* If the expression is itself an array aggregate then first build the
6254 innermost constructor if it is part of our array (multi-dimensional
6257 if (Nkind (gnat_expr
) == N_Aggregate
6258 && TREE_CODE (TREE_TYPE (gnu_array_type
)) == ARRAY_TYPE
6259 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_array_type
)))
6260 gnu_expr
= pos_to_constructor (First (Expressions (gnat_expr
)),
6261 TREE_TYPE (gnu_array_type
),
6262 gnat_component_type
);
6265 gnu_expr
= gnat_to_gnu (gnat_expr
);
6267 /* before assigning the element to the array make sure it is
6269 if (Do_Range_Check (gnat_expr
))
6270 gnu_expr
= emit_range_check (gnu_expr
, gnat_component_type
);
6274 = tree_cons (gnu_index
, convert (TREE_TYPE (gnu_array_type
), gnu_expr
),
6277 gnu_index
= int_const_binop (PLUS_EXPR
, gnu_index
, integer_one_node
, 0);
6280 return gnat_build_constructor (gnu_array_type
, nreverse (gnu_expr_list
));
6283 /* Subroutine of assoc_to_constructor: VALUES is a list of field associations,
6284 some of which are from RECORD_TYPE. Return a CONSTRUCTOR consisting
6285 of the associations that are from RECORD_TYPE. If we see an internal
6286 record, make a recursive call to fill it in as well. */
6289 extract_values (tree values
, tree record_type
)
6291 tree result
= NULL_TREE
;
6294 for (field
= TYPE_FIELDS (record_type
); field
; field
= TREE_CHAIN (field
))
6298 /* _Parent is an internal field, but may have values in the aggregate,
6299 so check for values first. */
6300 if ((tem
= purpose_member (field
, values
)))
6302 value
= TREE_VALUE (tem
);
6303 TREE_ADDRESSABLE (tem
) = 1;
6306 else if (DECL_INTERNAL_P (field
))
6308 value
= extract_values (values
, TREE_TYPE (field
));
6309 if (TREE_CODE (value
) == CONSTRUCTOR
6310 && VEC_empty (constructor_elt
, CONSTRUCTOR_ELTS (value
)))
6314 /* If we have a record subtype, the names will match, but not the
6315 actual FIELD_DECLs. */
6316 for (tem
= values
; tem
; tem
= TREE_CHAIN (tem
))
6317 if (DECL_NAME (TREE_PURPOSE (tem
)) == DECL_NAME (field
))
6319 value
= convert (TREE_TYPE (field
), TREE_VALUE (tem
));
6320 TREE_ADDRESSABLE (tem
) = 1;
6326 result
= tree_cons (field
, value
, result
);
6329 return gnat_build_constructor (record_type
, nreverse (result
));
6332 /* EXP is to be treated as an array or record. Handle the cases when it is
6333 an access object and perform the required dereferences. */
6336 maybe_implicit_deref (tree exp
)
6338 /* If the type is a pointer, dereference it. */
6340 if (POINTER_TYPE_P (TREE_TYPE (exp
)) || TYPE_FAT_POINTER_P (TREE_TYPE (exp
)))
6341 exp
= build_unary_op (INDIRECT_REF
, NULL_TREE
, exp
);
6343 /* If we got a padded type, remove it too. */
6344 if (TREE_CODE (TREE_TYPE (exp
)) == RECORD_TYPE
6345 && TYPE_IS_PADDING_P (TREE_TYPE (exp
)))
6346 exp
= convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp
))), exp
);
6351 /* Protect EXP from multiple evaluation. This may make a SAVE_EXPR. */
6354 protect_multiple_eval (tree exp
)
6356 tree type
= TREE_TYPE (exp
);
6358 /* If this has no side effects, we don't need to do anything. */
6359 if (!TREE_SIDE_EFFECTS (exp
))
6362 /* If it is a conversion, protect what's inside the conversion.
6363 Similarly, if we're indirectly referencing something, we only
6364 actually need to protect the address since the data itself can't
6365 change in these situations. */
6366 else if (TREE_CODE (exp
) == NON_LVALUE_EXPR
6367 || TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
6368 || TREE_CODE (exp
) == VIEW_CONVERT_EXPR
6369 || TREE_CODE (exp
) == INDIRECT_REF
6370 || TREE_CODE (exp
) == UNCONSTRAINED_ARRAY_REF
)
6371 return build1 (TREE_CODE (exp
), type
,
6372 protect_multiple_eval (TREE_OPERAND (exp
, 0)));
6374 /* If EXP is a fat pointer or something that can be placed into a register,
6375 just make a SAVE_EXPR. */
6376 if (TYPE_FAT_POINTER_P (type
) || TYPE_MODE (type
) != BLKmode
)
6377 return save_expr (exp
);
6379 /* Otherwise, dereference, protect the address, and re-reference. */
6382 build_unary_op (INDIRECT_REF
, type
,
6383 save_expr (build_unary_op (ADDR_EXPR
,
6384 build_reference_type (type
),
6388 /* This is equivalent to stabilize_reference in tree.c, but we know how to
6389 handle our own nodes and we take extra arguments. FORCE says whether to
6390 force evaluation of everything. We set SUCCESS to true unless we walk
6391 through something we don't know how to stabilize. */
6394 maybe_stabilize_reference (tree ref
, bool force
, bool *success
)
6396 tree type
= TREE_TYPE (ref
);
6397 enum tree_code code
= TREE_CODE (ref
);
6400 /* Assume we'll success unless proven otherwise. */
6409 /* No action is needed in this case. */
6416 case FIX_TRUNC_EXPR
:
6417 case VIEW_CONVERT_EXPR
:
6419 = build1 (code
, type
,
6420 maybe_stabilize_reference (TREE_OPERAND (ref
, 0), force
,
6425 case UNCONSTRAINED_ARRAY_REF
:
6426 result
= build1 (code
, type
,
6427 gnat_stabilize_reference_1 (TREE_OPERAND (ref
, 0),
6432 result
= build3 (COMPONENT_REF
, type
,
6433 maybe_stabilize_reference (TREE_OPERAND (ref
, 0), force
,
6435 TREE_OPERAND (ref
, 1), NULL_TREE
);
6439 result
= build3 (BIT_FIELD_REF
, type
,
6440 maybe_stabilize_reference (TREE_OPERAND (ref
, 0), force
,
6442 gnat_stabilize_reference_1 (TREE_OPERAND (ref
, 1),
6444 gnat_stabilize_reference_1 (TREE_OPERAND (ref
, 2),
6449 case ARRAY_RANGE_REF
:
6450 result
= build4 (code
, type
,
6451 maybe_stabilize_reference (TREE_OPERAND (ref
, 0), force
,
6453 gnat_stabilize_reference_1 (TREE_OPERAND (ref
, 1),
6455 NULL_TREE
, NULL_TREE
);
6459 result
= gnat_stabilize_reference_1 (ref
, force
);
6463 /* This generates better code than the scheme in protect_multiple_eval
6464 because large objects will be returned via invisible reference in
6465 most ABIs so the temporary will directly be filled by the callee. */
6466 result
= gnat_stabilize_reference_1 (ref
, force
);
6470 ref
= error_mark_node
;
6472 /* ... Fallthru to failure ... */
6474 /* If arg isn't a kind of lvalue we recognize, make no change.
6475 Caller should recognize the error for an invalid lvalue. */
6481 TREE_READONLY (result
) = TREE_READONLY (ref
);
6483 /* TREE_THIS_VOLATILE and TREE_SIDE_EFFECTS attached to the initial
6484 expression may not be sustained across some paths, such as the way via
6485 build1 for INDIRECT_REF. We re-populate those flags here for the general
6486 case, which is consistent with the GCC version of this routine.
6488 Special care should be taken regarding TREE_SIDE_EFFECTS, because some
6489 paths introduce side effects where there was none initially (e.g. calls
6490 to save_expr), and we also want to keep track of that. */
6492 TREE_THIS_VOLATILE (result
) = TREE_THIS_VOLATILE (ref
);
6493 TREE_SIDE_EFFECTS (result
) |= TREE_SIDE_EFFECTS (ref
);
6498 /* Wrapper around maybe_stabilize_reference, for common uses without
6499 lvalue restrictions and without need to examine the success
6503 gnat_stabilize_reference (tree ref
, bool force
)
6506 return maybe_stabilize_reference (ref
, force
, &dummy
);
6509 /* Similar to stabilize_reference_1 in tree.c, but supports an extra
6510 arg to force a SAVE_EXPR for everything. */
6513 gnat_stabilize_reference_1 (tree e
, bool force
)
6515 enum tree_code code
= TREE_CODE (e
);
6516 tree type
= TREE_TYPE (e
);
6519 /* We cannot ignore const expressions because it might be a reference
6520 to a const array but whose index contains side-effects. But we can
6521 ignore things that are actual constant or that already have been
6522 handled by this function. */
6524 if (TREE_CONSTANT (e
) || code
== SAVE_EXPR
)
6527 switch (TREE_CODE_CLASS (code
))
6529 case tcc_exceptional
:
6531 case tcc_declaration
:
6532 case tcc_comparison
:
6534 case tcc_expression
:
6537 /* If this is a COMPONENT_REF of a fat pointer, save the entire
6538 fat pointer. This may be more efficient, but will also allow
6539 us to more easily find the match for the PLACEHOLDER_EXPR. */
6540 if (code
== COMPONENT_REF
6541 && TYPE_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (e
, 0))))
6542 result
= build3 (COMPONENT_REF
, type
,
6543 gnat_stabilize_reference_1 (TREE_OPERAND (e
, 0),
6545 TREE_OPERAND (e
, 1), TREE_OPERAND (e
, 2));
6546 else if (TREE_SIDE_EFFECTS (e
) || force
)
6547 return save_expr (e
);
6553 /* Constants need no processing. In fact, we should never reach
6558 /* Recursively stabilize each operand. */
6559 result
= build2 (code
, type
,
6560 gnat_stabilize_reference_1 (TREE_OPERAND (e
, 0), force
),
6561 gnat_stabilize_reference_1 (TREE_OPERAND (e
, 1),
6566 /* Recursively stabilize each operand. */
6567 result
= build1 (code
, type
,
6568 gnat_stabilize_reference_1 (TREE_OPERAND (e
, 0),
6576 TREE_READONLY (result
) = TREE_READONLY (e
);
6578 TREE_THIS_VOLATILE (result
) = TREE_THIS_VOLATILE (e
);
6579 TREE_SIDE_EFFECTS (result
) |= TREE_SIDE_EFFECTS (e
);
6583 /* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code
6584 location and false if it doesn't. In the former case, set the Gigi global
6585 variable REF_FILENAME to the simple debug file name as given by sinput. */
6588 Sloc_to_locus (Source_Ptr Sloc
, location_t
*locus
)
6590 if (Sloc
== No_Location
)
6593 if (Sloc
<= Standard_Location
)
6594 #ifdef USE_MAPPED_LOCATION
6596 *locus
= BUILTINS_LOCATION
;
6601 Source_File_Index file
= Get_Source_File_Index (Sloc
);
6602 Logical_Line_Number line
= Get_Logical_Line_Number (Sloc
);
6603 Column_Number column
= Get_Column_Number (Sloc
);
6604 struct line_map
*map
= &line_table
->maps
[file
- 1];
6606 /* Translate the location according to the line-map.h formula. */
6607 *locus
= map
->start_location
6608 + ((line
- map
->to_line
) << map
->column_bits
)
6609 + (column
& ((1 << map
->column_bits
) - 1));
6614 /* Use the identifier table to make a hashed, permanent copy of the filename,
6615 since the name table gets reallocated after Gigi returns but before all
6616 the debugging information is output. The __gnat_to_canonical_file_spec
6617 call translates filenames from pragmas Source_Reference that contain host
6618 style syntax not understood by gdb. */
6620 = IDENTIFIER_POINTER
6622 (__gnat_to_canonical_file_spec
6623 (Get_Name_String (Full_Debug_Name (Get_Source_File_Index (Sloc
))))));
6625 locus
->line
= Get_Logical_Line_Number (Sloc
);
6629 = IDENTIFIER_POINTER
6631 (Get_Name_String (Debug_Source_Name (Get_Source_File_Index (Sloc
)))));;
6636 /* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
6637 don't do anything if it doesn't correspond to a source location. */
6640 set_expr_location_from_node (tree node
, Node_Id gnat_node
)
6644 if (!Sloc_to_locus (Sloc (gnat_node
), &locus
))
6647 set_expr_location (node
, locus
);
6650 /* Post an error message. MSG is the error message, properly annotated.
6651 NODE is the node at which to post the error and the node to use for the
6652 "&" substitution. */
6655 post_error (const char *msg
, Node_Id node
)
6657 String_Template temp
;
6660 temp
.Low_Bound
= 1, temp
.High_Bound
= strlen (msg
);
6661 fp
.Array
= msg
, fp
.Bounds
= &temp
;
6663 Error_Msg_N (fp
, node
);
6666 /* Similar, but NODE is the node at which to post the error and ENT
6667 is the node to use for the "&" substitution. */
6670 post_error_ne (const char *msg
, Node_Id node
, Entity_Id ent
)
6672 String_Template temp
;
6675 temp
.Low_Bound
= 1, temp
.High_Bound
= strlen (msg
);
6676 fp
.Array
= msg
, fp
.Bounds
= &temp
;
6678 Error_Msg_NE (fp
, node
, ent
);
6681 /* Similar, but NODE is the node at which to post the error, ENT is the node
6682 to use for the "&" substitution, and N is the number to use for the ^. */
6685 post_error_ne_num (const char *msg
, Node_Id node
, Entity_Id ent
, int n
)
6687 String_Template temp
;
6690 temp
.Low_Bound
= 1, temp
.High_Bound
= strlen (msg
);
6691 fp
.Array
= msg
, fp
.Bounds
= &temp
;
6692 Error_Msg_Uint_1
= UI_From_Int (n
);
6695 Error_Msg_NE (fp
, node
, ent
);
6698 /* Similar to post_error_ne_num, but T is a GCC tree representing the
6699 number to write. If the tree represents a constant that fits within
6700 a host integer, the text inside curly brackets in MSG will be output
6701 (presumably including a '^'). Otherwise that text will not be output
6702 and the text inside square brackets will be output instead. */
6705 post_error_ne_tree (const char *msg
, Node_Id node
, Entity_Id ent
, tree t
)
6707 char *newmsg
= alloca (strlen (msg
) + 1);
6708 String_Template temp
= {1, 0};
6710 char start_yes
, end_yes
, start_no
, end_no
;
6714 fp
.Array
= newmsg
, fp
.Bounds
= &temp
;
6716 if (host_integerp (t
, 1)
6717 #if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_INT
6720 (t
, (((unsigned HOST_WIDE_INT
) 1 << (HOST_BITS_PER_INT
- 1)) - 1)) < 0
6724 Error_Msg_Uint_1
= UI_From_Int (tree_low_cst (t
, 1));
6725 start_yes
= '{', end_yes
= '}', start_no
= '[', end_no
= ']';
6728 start_yes
= '[', end_yes
= ']', start_no
= '{', end_no
= '}';
6730 for (p
= msg
, q
= newmsg
; *p
; p
++)
6732 if (*p
== start_yes
)
6733 for (p
++; *p
!= end_yes
; p
++)
6735 else if (*p
== start_no
)
6736 for (p
++; *p
!= end_no
; p
++)
6744 temp
.High_Bound
= strlen (newmsg
);
6746 Error_Msg_NE (fp
, node
, ent
);
6749 /* Similar to post_error_ne_tree, except that NUM is a second
6750 integer to write in the message. */
6753 post_error_ne_tree_2 (const char *msg
,
6759 Error_Msg_Uint_2
= UI_From_Int (num
);
6760 post_error_ne_tree (msg
, node
, ent
, t
);
6763 /* Initialize the table that maps GNAT codes to GCC codes for simple
6764 binary and unary operations. */
6767 init_code_table (void)
6769 gnu_codes
[N_And_Then
] = TRUTH_ANDIF_EXPR
;
6770 gnu_codes
[N_Or_Else
] = TRUTH_ORIF_EXPR
;
6772 gnu_codes
[N_Op_And
] = TRUTH_AND_EXPR
;
6773 gnu_codes
[N_Op_Or
] = TRUTH_OR_EXPR
;
6774 gnu_codes
[N_Op_Xor
] = TRUTH_XOR_EXPR
;
6775 gnu_codes
[N_Op_Eq
] = EQ_EXPR
;
6776 gnu_codes
[N_Op_Ne
] = NE_EXPR
;
6777 gnu_codes
[N_Op_Lt
] = LT_EXPR
;
6778 gnu_codes
[N_Op_Le
] = LE_EXPR
;
6779 gnu_codes
[N_Op_Gt
] = GT_EXPR
;
6780 gnu_codes
[N_Op_Ge
] = GE_EXPR
;
6781 gnu_codes
[N_Op_Add
] = PLUS_EXPR
;
6782 gnu_codes
[N_Op_Subtract
] = MINUS_EXPR
;
6783 gnu_codes
[N_Op_Multiply
] = MULT_EXPR
;
6784 gnu_codes
[N_Op_Mod
] = FLOOR_MOD_EXPR
;
6785 gnu_codes
[N_Op_Rem
] = TRUNC_MOD_EXPR
;
6786 gnu_codes
[N_Op_Minus
] = NEGATE_EXPR
;
6787 gnu_codes
[N_Op_Abs
] = ABS_EXPR
;
6788 gnu_codes
[N_Op_Not
] = TRUTH_NOT_EXPR
;
6789 gnu_codes
[N_Op_Rotate_Left
] = LROTATE_EXPR
;
6790 gnu_codes
[N_Op_Rotate_Right
] = RROTATE_EXPR
;
6791 gnu_codes
[N_Op_Shift_Left
] = LSHIFT_EXPR
;
6792 gnu_codes
[N_Op_Shift_Right
] = RSHIFT_EXPR
;
6793 gnu_codes
[N_Op_Shift_Right_Arithmetic
] = RSHIFT_EXPR
;
6796 /* Return a label to branch to for the exception type in KIND or NULL_TREE
6800 get_exception_label (char kind
)
6802 if (kind
== N_Raise_Constraint_Error
)
6803 return TREE_VALUE (gnu_constraint_error_label_stack
);
6804 else if (kind
== N_Raise_Storage_Error
)
6805 return TREE_VALUE (gnu_storage_error_label_stack
);
6806 else if (kind
== N_Raise_Program_Error
)
6807 return TREE_VALUE (gnu_program_error_label_stack
);
6812 #include "gt-ada-trans.h"