summaryrefslogtreecommitdiff
path: root/gcc/ada/decl.c
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-31 18:19:52 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-31 18:19:52 +0000
commitf682feb7a5bcd72cf2eb9525b920e06c2f94fb09 (patch)
treec5e8ce80b183e80e687e1da8ae37243121191806 /gcc/ada/decl.c
parent560edc4abacc494bd98af69035fec869e436a5c8 (diff)
downloadgcc-f682feb7a5bcd72cf2eb9525b920e06c2f94fb09.tar.gz
2006-10-31 Eric Botcazou <ebotcazou@adacore.com>
Nicolas Setton <setton@adacore.com> Olivier Hainque <hainque@adacore.com> Gary Dismukes <dismukes@adacore.com> * gigi.h: (tree_code_for_record_type): Declare. (add_global_renaming_pointer): Rename to record_global_renaming_pointer. (get_global_renaming_pointers): Rename to invalidate_global_renaming_pointers. (static_ctors): Delete. (static_dtors): Likewise. (gnat_write_global_declarations): Declare. (create_var_decl): Adjust descriptive comment to indicate that the subprogram may return a CONST_DECL node. (create_true_var_decl): Declare new function, similar to create_var_decl but forcing the creation of a VAR_DECL node. (get_global_renaming_pointers): Declare. (add_global_renaming_pointer): Likewise. * ada-tree.h (DECL_READONLY_ONCE_ELAB): New macro. * decl.c (gnat_to_gnu_entity) <case E_Function>: Don't copy the type tree before setting TREE_ADDRESSABLE for by-reference return mechanism processing. (gnat_to_gnu_entity): Remove From_With_Type from computation for imported_p. <E_Access_Type>: Use the Non_Limited_View as the full view of the designated type if the pointer comes from a limited_with clause. Make incomplete designated type if it is in the main unit and has a freeze node. <E_Incomplete_Type>: Rework to treat Non_Limited_View, Full_View, and Underlying_Full_View similarly. Return earlier if the full view already has an associated tree. (gnat_to_gnu_entity) <E_Record_Type>: Restore comment. (gnat_to_gnu_entity) <E_Record_Type>: Do not use a dummy type. (gnat_to_gnu_entity) <E_Variable>: Set TYPE_REF_CAN_ALIAS_ALL on the reference type built for objects with an address clause. Use create_true_var_decl with const_flag set for DECL_CONST_CORRESPONDING_VARs, ensuring a VAR_DECL is created with TREE_READONLY set. (gnat_to_gnu_entity, case E_Enumeration_Type): Set TYPE_NAME for Character and Wide_Character types. This info is read by the dwarf-2 writer, and is needed to be able to use the command "ptype character" in the debugger. (gnat_to_gnu_entity): When generating a type representing a Character or Wide_Character type, set the flag TYPE_STRING_FLAG, so that debug writers can distinguish it from ordinary integers. (elaborate_expression_1): Test the DECL_READONLY_ONCE_ELAB flag in addition to TREE_READONLY to assert the constantness of variables for elaboration purposes. (gnat_to_gnu_entity, subprogram cases): Change loops on formal parameters to call new Einfo function First_Formal_With_Extras. (gnat_to_gnu_entity): In type_annotate mode, replace a discriminant of a protected type with its corresponding discriminant, to obtain a usable declaration (gnat_to_gnu_entity) <E_Access_Protected_Subprogram_Type>: Be prepared for a multiple elaboration of the "equivalent" type. (gnat_to_gnu_entity): Adjust for renaming of add_global_renaming_pointer into record_global_renaming_pointer. (gnat_to_gnu_entity) <E_Array_Type>: Do not force TYPE_NONALIASED_COMPONENT to 0 if the element type is an aggregate. <E_Array_Subtype>: Likewise. (gnat_to_gnu_entity) <E_Incomplete_Subtype>: Add support for regular incomplete subtypes and incomplete subtypes of incomplete types visible through a limited with clause. (gnat_to_gnu_entity) <E_Array_Subtype>: Take into account the bounds of the base index type for the maximum size of the array only if they are constant. (gnat_to_gnu_entity, renaming object case): Do not wrap up the expression into a SAVE_EXPR if stabilization failed. * utils.c (create_subprog_decl): Turn TREE_ADDRESSABLE on the type of a result decl into DECL_BY_REFERENCE on this decl, now what is expected by lower level compilation passes. (gnat_genericize): New function, lowering a function body to GENERIC. Turn the type of RESULT_DECL into a real reference type if the decl has been marked DECL_BY_REFERENCE, and adjust references to the latter accordingly. (gnat_genericize_r): New function. Tree walking callback for gnat_genericize. (convert_from_reference, is_byref_result): New functions. Helpers for gnat_genericize_r. (create_type_decl): Call gnat_pushdecl before calling rest_of_decl_compilation, to make sure that field TYPE_NAME of type_decl is properly set before calling the debug information writers. (write_record_type_debug_info): The heuristics which compute the alignment of a field in a variant record might not be accurate. Add a safety test to make sure no alignment is set to a smaller value than the alignment of the field type. (make_dummy_type): Use the Non_Limited_View as the underlying type if the type comes from a limited_with clause. Do not loop on the full view. (GET_GNU_TREE, SET_GNU_TREE, PRESENT_GNU_TREE): New macros. (dummy_node_table): New global variable, moved from decl.c. (GET_DUMMY_NODE, SET_DUMMY_NODE, PRESENT_DUMMY_NODE): New macros. (save_gnu_tree): Use above macros. (get_gnu_tree): Likewise. (present_gnu_tree): Likewise. (init_dummy_type): New function, moved from decl.c. Use above macros. (make_dummy_type): Likewise. (tree_code_for_record_type): New function extracted from make_dummy_type (init_gigi_decls): Set DECL_IS_MALLOC on gnat_malloc. (static_ctors): Change it to a vector, make static. (static_dtors): Likewise. (end_subprog_body): Adjust for above change. (build_global_cdtor): Moved from trans.c. (gnat_write_global_declarations): Emit global constructor and destructor, and call cgraph_optimize before emitting debug info for global declarations. (global_decls): New global variable. (gnat_pushdecl): Store the global declarations in global_decls, for later use. (gnat_write_global_declarations): Emit debug information for global declarations. (create_var_decl_1): Former create_var_decl, with an extra argument to state whether the creation of a CONST_DECL is allowed. (create_var_decl): Behavior unchanged. Now a wrapper around create_var_decl_1 allowing CONST_DECL creation. (create_true_var_decl): New function, similar to create_var_decl but forcing the creation of a VAR_DECL node (CONST_DECL not allowed). (create_field_decl): Do not always mark the field as addressable if its type is an aggregate. (global_renaming_pointers): New static variable. (add_global_renaming_pointer): New function. (get_global_renaming_pointers): Likewise. * misc.c (gnat_dwarf_name): New function. (LANG_HOOKS_DWARF_NAME): Define to gnat_dwarf_name. (gnat_post_options): Add comment about structural alias analysis. (gnat_parse_file): Do not call cgraph_optimize here. (LANG_HOOKS_WRITE_GLOBALS): Define to gnat_write_global_declarations. * trans.c (process_freeze_entity): Don't abort if we already have a non dummy GCC tree for a Concurrent_Record_Type, as it might legitimately have been elaborated while processing the associated Concurrent_Type prior to this explicit freeze node. (Identifier_to_gnu): Do not make a variable referenced in a SJLJ exception handler volatile if it is of variable size. (process_type): Remove bypass for types coming from a limited_with clause. (call_to_gnu): When processing the copy-out of a N_Type_Conversion GNAT actual, convert the corresponding gnu_actual to the real destination type when necessary. (add_decl_expr): Set the DECL_READONLY_ONCE_ELAB flag on variables originally TREE_READONLY but whose elaboration cannot be performed statically. Part of fix for F504-021. (tree_transform, subprogram cases): Change loops on formal parameters to call new Einfo function First_Formal_With_Extras. (gnat_to_gnu) <N_Op_Shift_Right_Arithmetic>: Ignore constant overflow stemming from type conversion for the lhs. (Attribute_to_gnu) <Attr_Alignment>: Also divide the alignment by the number of bits per unit for components of records. (gnat_to_gnu) <N_Code_Statement>: Mark operands addressable if needed. (Handled_Sequence_Of_Statements_to_gnu): Register the cleanup associated with At_End_Proc after the SJLJ EH cleanup. (Compilation_Unit_to_gnu): Call elaborate_all_entities only on the main compilation unit. (elaborate_all_entities): Do not retest type_annotate_only. (tree_transform) <N_Abstract_Subprogram_Declaration>: Process the result type of an abstract subprogram, which may be an itype associated with an anonymous access result (related to AI-318-02). (build_global_cdtor): Move to utils.c. (Case_Statement_to_gnu): Avoid adding the choice of a when statement if this choice is not a null tree nor an integer constant. (gigi): Run unshare_save_expr via walk_tree_without_duplicates on the body of elaboration routines instead of mark_unvisited. (add_stmt): Do not mark the tree. (add_decl_expr): Tweak comment. (mark_unvisited): Delete. (unshare_save_expr): New static function. (call_to_gnu): Issue an error when making a temporary around a procedure call because of non-addressable actual parameter if the type of the formal is by_reference. (Compilation_Unit_to_gnu): Invalidate the global renaming pointers after building the elaboration routine. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@118331 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/decl.c')
-rw-r--r--gcc/ada/decl.c424
1 files changed, 198 insertions, 226 deletions
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index 870d5cc8427..c18f08d7493 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -176,8 +176,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
: LONG_LONG_TYPE_SIZE);
tree gnu_size = 0;
bool imported_p
- = ((Is_Imported (gnat_entity) && No (Address_Clause (gnat_entity)))
- || From_With_Type (gnat_entity));
+ = (Is_Imported (gnat_entity) && No (Address_Clause (gnat_entity)));
unsigned int align = 0;
/* Since a use of an Itype is a definition, process it as such if it
@@ -424,6 +423,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
break;
}
+ else if (Present (CR_Discriminant (gnat_entity))
+ && type_annotate_only)
+ {
+ gnu_decl = gnat_to_gnu_entity (CR_Discriminant (gnat_entity),
+ gnu_expr, definition);
+ saved = 1;
+ break;
+ }
+
/* If the enclosing record has explicit stored discriminants,
then it is an untagged record. If the Corresponding_Discriminant
is not empty then this must be a renamed discriminant and its
@@ -815,21 +823,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
object, we just make a "bare" pointer, and the renamed
entity is always accessed indirectly through it. */
{
- bool expr_has_side_effects = TREE_SIDE_EFFECTS (gnu_expr);
-
inner_const_flag = TREE_READONLY (gnu_expr);
const_flag = true;
gnu_type = build_reference_type (gnu_type);
/* If a previous attempt at unrestricted stabilization
failed, there is no point trying again and we can reuse
- the result without attaching it to the pointer. */
+ the result without attaching it to the pointer. In this
+ case it will only be used as the initializing expression
+ of the pointer and thus needs no special treatment with
+ regard to multiple evaluations. */
if (maybe_stable_expr)
;
- /* Otherwise, try to stabilize now, restricting to
- lvalues only, and attach the expression to the pointer
- if the stabilization succeeds.
+ /* Otherwise, try to stabilize now, restricting to lvalues
+ only, and attach the expression to the pointer if the
+ stabilization succeeds.
Note that this might introduce SAVE_EXPRs and we don't
check whether we're at the global level or not. This is
@@ -852,21 +861,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (stabilized)
renamed_obj = maybe_stable_expr;
+
/* Attaching is actually performed downstream, as soon
- as we have a DECL for the pointer we make. */
+ as we have a VAR_DECL for the pointer we make. */
}
gnu_expr
= build_unary_op (ADDR_EXPR, gnu_type, maybe_stable_expr);
- /* If the initial expression has side effects, we might
- still have an unstabilized version at this point (for
- instance if it involves a function call). Wrap the
- result into a SAVE_EXPR now, in case it happens to be
- referenced several times. */
- if (expr_has_side_effects && ! stabilized)
- gnu_expr = save_expr (gnu_expr);
-
gnu_size = NULL_TREE;
used_by_ref = true;
}
@@ -930,7 +932,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Ignore the size. It's either meaningless or was handled
above. */
gnu_size = NULL_TREE;
- gnu_type = build_reference_type (gnu_type);
+ /* The address expression contains a conversion from pointer type
+ to the system__address integer type, which means the address
+ of the underlying object escapes. We therefore have no other
+ choice than forcing the type of the object being defined to
+ alias everything in order to make type-based alias analysis
+ aware that it will dereference the escaped address.
+ ??? This uncovers problems in ACATS at -O2 with the volatility
+ of the original type: it may not be correctly propagated, thus
+ causing PRE to enter an infinite loop creating value numbers
+ out of volatile expressions. Disable it for now. */
+ gnu_type
+ = build_reference_type_for_mode (gnu_type, ptr_mode, false);
gnu_address = convert (gnu_type, gnu_address);
used_by_ref = true;
const_flag = !Is_Public (gnat_entity);
@@ -959,7 +972,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| (Is_Imported (gnat_entity)
&& Has_Stdcall_Convention (gnat_entity)))
{
- gnu_type = build_reference_type (gnu_type);
+ /* See the definition case above for the rationale. */
+ gnu_type
+ = build_reference_type_for_mode (gnu_type, ptr_mode, false);
gnu_size = NULL_TREE;
gnu_expr = NULL_TREE;
@@ -1134,17 +1149,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj)
{
SET_DECL_RENAMED_OBJECT (gnu_decl, renamed_obj);
- DECL_RENAMING_GLOBAL_P (gnu_decl) = global_bindings_p ();
+ if (global_bindings_p ())
+ {
+ DECL_RENAMING_GLOBAL_P (gnu_decl) = 1;
+ record_global_renaming_pointer (gnu_decl);
+ }
}
- /* If we have an address clause and we've made this indirect, it's
- not enough to merely mark the type as volatile since volatile
- references only conflict with other volatile references while this
- reference must conflict with all other references. So ensure that
- the dereferenced value has alias set 0. */
- if (Present (Address_Clause (gnat_entity)) && used_by_ref)
- DECL_POINTER_ALIAS_SET (gnu_decl) = 0;
-
if (definition && DECL_SIZE (gnu_decl)
&& get_block_jmpbuf_decl ()
&& (TREE_CODE (DECL_SIZE (gnu_decl)) != INTEGER_CST
@@ -1169,9 +1180,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| Is_Aliased (Etype (gnat_entity))))
{
tree gnu_corr_var
- = create_var_decl (gnu_entity_id, gnu_ext_name, gnu_type,
- gnu_expr, false, Is_Public (gnat_entity),
- false, static_p, NULL, gnat_entity);
+ = create_true_var_decl (gnu_entity_id, gnu_ext_name, gnu_type,
+ gnu_expr, true, Is_Public (gnat_entity),
+ false, static_p, NULL, gnat_entity);
SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl, gnu_corr_var);
}
@@ -1220,6 +1231,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (No (First_Literal (gnat_entity)))
{
gnu_type = make_unsigned_type (esize);
+ TYPE_NAME (gnu_type) = gnu_entity_id;
+
+ /* Set the TYPE_STRING_FLAG for Ada Character and
+ Wide_Character types. This is needed by the dwarf-2 debug writer to
+ distinguish between unsigned integer types and character types. */
+ TYPE_STRING_FLAG (gnu_type) = 1;
break;
}
@@ -1734,18 +1751,16 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tem = build_array_type (tem, gnu_index_types[index]);
TYPE_MULTI_ARRAY_P (tem) = (index > 0);
- /* If the type below this an multi-array type, then this
- does not not have aliased components.
-
- ??? Otherwise, for now, we say that any component of aggregate
- type is addressable because the front end may take 'Reference
- of it. But we have to make it addressable if it must be passed
- by reference or it that is the default. */
- TYPE_NONALIASED_COMPONENT (tem)
- = ((TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
- && TYPE_MULTI_ARRAY_P (TREE_TYPE (tem))) ? 1
- : (!Has_Aliased_Components (gnat_entity)
- && !AGGREGATE_TYPE_P (TREE_TYPE (tem))));
+ /* If the type below this is a multi-array type, then this
+ does not have aliased components. But we have to make
+ them addressable if it must be passed by reference or
+ if that is the default. */
+ if ((TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
+ && TYPE_MULTI_ARRAY_P (TREE_TYPE (tem)))
+ || (!Has_Aliased_Components (gnat_entity)
+ && !must_pass_by_ref (TREE_TYPE (tem))
+ && !default_pass_by_ref (TREE_TYPE (tem))))
+ TYPE_NONALIASED_COMPONENT (tem) = 1;
}
/* If an alignment is specified, use it if valid. But ignore it for
@@ -1957,13 +1972,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if ((TREE_CODE (gnu_min) == INTEGER_CST
&& !TREE_OVERFLOW (gnu_min)
&& !operand_equal_p (gnu_min, gnu_base_base_min, 0))
- || !CONTAINS_PLACEHOLDER_P (gnu_min))
+ || !CONTAINS_PLACEHOLDER_P (gnu_min)
+ || !(TREE_CODE (gnu_base_min) == INTEGER_CST
+ && !TREE_OVERFLOW (gnu_base_min)))
gnu_base_min = gnu_min;
if ((TREE_CODE (gnu_max) == INTEGER_CST
&& !TREE_OVERFLOW (gnu_max)
&& !operand_equal_p (gnu_max, gnu_base_base_max, 0))
- || !CONTAINS_PLACEHOLDER_P (gnu_max))
+ || !CONTAINS_PLACEHOLDER_P (gnu_max)
+ || !(TREE_CODE (gnu_base_max) == INTEGER_CST
+ && !TREE_OVERFLOW (gnu_base_max)))
gnu_base_max = gnu_max;
if ((TREE_CODE (gnu_base_min) == INTEGER_CST
@@ -2054,18 +2073,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
{
gnu_type = build_array_type (gnu_type, gnu_index_type[index]);
TYPE_MULTI_ARRAY_P (gnu_type) = (index > 0);
- /* If the type below this an multi-array type, then this
- does not not have aliased components.
-
- ??? Otherwise, for now, we say that any component of aggregate
- type is addressable because the front end may take 'Reference
- of it. But we have to make it addressable if it must be passed
- by reference or it that is the default. */
- TYPE_NONALIASED_COMPONENT (gnu_type)
- = ((TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
- && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type))) ? 1
- : (!Has_Aliased_Components (gnat_entity)
- && !AGGREGATE_TYPE_P (TREE_TYPE (gnu_type))));
+
+ /* If the type below this is a multi-array type, then this
+ does not have aliased components. But we have to make
+ them addressable if it must be passed by reference or
+ if that is the default. */
+ if ((TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
+ && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type)))
+ || (!Has_Aliased_Components (gnat_entity)
+ && !must_pass_by_ref (TREE_TYPE (gnu_type))
+ && !default_pass_by_ref (TREE_TYPE (gnu_type))))
+ TYPE_NONALIASED_COMPONENT (gnu_type) = 1;
}
/* If we are at file level and this is a multi-dimensional array, we
@@ -2381,27 +2399,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
/* Make a node for the record. If we are not defining the record,
- suppress expanding incomplete types. We use the same RECORD_TYPE
- as for a dummy type and reset TYPE_DUMMY_P to show it's no longer
- a dummy.
-
- It is very tempting to delay resetting this bit until we are done
- with completing the type, e.g. to let possible intermediate
- elaboration of access types designating the record know it is not
- complete and arrange for update_pointer_to to fix things up later.
-
- It would be wrong, however, because dummy types are expected only
- to be created for Ada incomplete or private types, which is not
- what we have here. Doing so would make other parts of gigi think
- we are dealing with a really incomplete or private type, and have
- nasty side effects, typically on the generation of the associated
- debugging information. */
- gnu_type = make_dummy_type (gnat_entity);
- TYPE_DUMMY_P (gnu_type) = 0;
-
- if (TREE_CODE (TYPE_NAME (gnu_type)) == TYPE_DECL && debug_info_p)
- DECL_IGNORED_P (TYPE_NAME (gnu_type)) = 0;
-
+ suppress expanding incomplete types. */
+ gnu_type = make_node (tree_code_for_record_type (gnat_entity));
+ TYPE_NAME (gnu_type) = gnu_entity_id;
+ /* ??? We should have create_type_decl like in the E_Record_Subtype
+ case below. Unfortunately this would cause GNU_TYPE to be marked
+ as visited, thus precluding the subtrees of the type that will be
+ built below from being marked as visited when the real TYPE_DECL
+ is eventually created. A solution could be to devise a special
+ version of the function under the name create_type_stub_decl. */
+ TYPE_STUB_DECL (gnu_type)
+ = build_decl (TYPE_DECL, NULL_TREE, gnu_type);
TYPE_ALIGN (gnu_type) = 0;
TYPE_PACKED (gnu_type) = packed || has_rep;
@@ -2926,10 +2934,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
case E_General_Access_Type:
{
Entity_Id gnat_desig_type = Directly_Designated_Type (gnat_entity);
+ /* Get the "full view" of this entity. If this is an incomplete
+ entity from a limited with, treat its non-limited view as the
+ full view. Otherwise, if this is an incomplete or private
+ type, use the full view. */
Entity_Id gnat_desig_full
- = ((IN (Ekind (Etype (gnat_desig_type)),
- Incomplete_Or_Private_Kind))
- ? Full_View (gnat_desig_type) : 0);
+ = (IN (Ekind (gnat_desig_type), Incomplete_Kind)
+ && From_With_Type (gnat_desig_type))
+ ? Non_Limited_View (gnat_desig_type)
+ : IN (Ekind (gnat_desig_type), Incomplete_Or_Private_Kind)
+ ? Full_View (gnat_desig_type)
+ : Empty;
/* We want to know if we'll be seeing the freeze node for any
incomplete type we may be pointing to. */
bool in_main_unit
@@ -3008,6 +3023,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& defer_incomplete_level
&& !present_gnu_tree (gnat_desig_type)
&& Is_Array_Type (gnat_desig_type)
+ && ! Is_Constrained (gnat_desig_type))
+ || (in_main_unit && From_With_Type (gnat_entity)
+ && (Present (gnat_desig_full)
+ ? Present (Freeze_Node (gnat_desig_full))
+ : Present (Freeze_Node (gnat_desig_type)))
+ && Is_Array_Type (gnat_desig_type)
&& !Is_Constrained (gnat_desig_type)))
{
tree gnu_old
@@ -3089,6 +3110,25 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_desig_type = make_dummy_type (gnat_desig_type);
made_dummy = true;
}
+
+ /* If this is a reference from a limited_with type back to our
+ main unit and there's a Freeze_Node for it, either we have
+ already processed the declaration and made the dummy type,
+ in which case we just reuse the latter, or we have not yet,
+ in which case we make the dummy type and it will be reused
+ when the declaration is processed. In both cases, the pointer
+ eventually created below will be automatically adjusted when
+ the Freeze_Node is processed. Note that the unconstrained
+ array case is handled above. */
+ else if (in_main_unit && From_With_Type (gnat_entity)
+ && (Present (gnat_desig_full)
+ ? Present (Freeze_Node (gnat_desig_full))
+ : Present (Freeze_Node (gnat_desig_type))))
+ {
+ gnu_desig_type = make_dummy_type (gnat_desig_type);
+ made_dummy = true;
+ }
+
else if (gnat_desig_type == gnat_entity)
{
gnu_type
@@ -3097,6 +3137,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
No_Strict_Aliasing (gnat_entity));
TREE_TYPE (gnu_type) = TYPE_POINTER_TO (gnu_type) = gnu_type;
}
+
else
gnu_desig_type = gnat_to_gnu_type (gnat_desig_type);
@@ -3210,8 +3251,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (type_annotate_only && No (Equivalent_Type (gnat_entity)))
gnu_type = build_pointer_type (void_type_node);
else
- /* The runtime representation is the equivalent type. */
- gnu_type = gnat_to_gnu_type (Equivalent_Type (gnat_entity));
+ {
+ /* The runtime representation is the equivalent type. */
+ gnu_type = gnat_to_gnu_type (Equivalent_Type (gnat_entity));
+ maybe_present = 1;
+ }
if (Is_Itype (Directly_Designated_Type (gnat_entity))
&& !present_gnu_tree (Directly_Designated_Type (gnat_entity))
@@ -3373,7 +3417,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_expr, 0);
/* Elaborate any Itypes in the parameters of this entity. */
- for (gnat_temp = First_Formal (gnat_entity);
+ for (gnat_temp = First_Formal_With_Extras (gnat_entity);
Present (gnat_temp);
gnat_temp = Next_Formal_With_Extras (gnat_temp))
if (Is_Itype (Etype (gnat_temp)))
@@ -3413,8 +3457,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
else if (kind == E_Function
&& Mechanism (gnat_entity) == By_Reference)
{
- gnu_return_type = copy_type (gnu_return_type);
TREE_ADDRESSABLE (gnu_return_type) = 1;
+
+ /* We expect this bit to be reset by gigi shortly, so can avoid a
+ type node copy here. This actually also prevents troubles with
+ the generation of debug information for the function, because
+ we might have issued such info for this type already, and would
+ be attaching a distinct type node to the function if we made a
+ copy here. */
}
/* If we are supposed to return an unconstrained array,
@@ -3479,7 +3529,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
each. While doing this, build a copy-out structure if
we need one. */
- for (gnat_param = First_Formal (gnat_entity), parmnum = 0;
+ for (gnat_param = First_Formal_With_Extras (gnat_entity), parmnum = 0;
Present (gnat_param);
gnat_param = Next_Formal_With_Extras (gnat_param), parmnum++)
{
@@ -3858,71 +3908,76 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
break;
case E_Incomplete_Type:
+ case E_Incomplete_Subtype:
case E_Private_Type:
- case E_Limited_Private_Type:
- case E_Record_Type_With_Private:
case E_Private_Subtype:
+ case E_Limited_Private_Type:
case E_Limited_Private_Subtype:
+ case E_Record_Type_With_Private:
case E_Record_Subtype_With_Private:
-
- /* If this type does not have a full view in the unit we are
- compiling, then just get the type from its Etype. */
- if (No (Full_View (gnat_entity)))
- {
- /* If this is an incomplete type with no full view, it must be
- either a limited view brought in by a limited_with clause, in
- which case we use the non-limited view, or a Taft Amendement
- type, in which case we just return a dummy type. */
- if (kind == E_Incomplete_Type)
- {
- if (From_With_Type (gnat_entity)
- && Present (Non_Limited_View (gnat_entity)))
- gnu_decl = gnat_to_gnu_entity (Non_Limited_View (gnat_entity),
+ {
+ /* Get the "full view" of this entity. If this is an incomplete
+ entity from a limited with, treat its non-limited view as the
+ full view. Otherwise, use either the full view or the underlying
+ full view, whichever is present. This is used in all the tests
+ below. */
+ Entity_Id full_view
+ = (IN (Ekind (gnat_entity), Incomplete_Kind)
+ && From_With_Type (gnat_entity))
+ ? Non_Limited_View (gnat_entity)
+ : Present (Full_View (gnat_entity))
+ ? Full_View (gnat_entity)
+ : Underlying_Full_View (gnat_entity);
+
+ /* If this is an incomplete type with no full view, it must be a Taft
+ Amendment type, in which case we return a dummy type. Otherwise,
+ just get the type from its Etype. */
+ if (No (full_view))
+ {
+ if (kind == E_Incomplete_Type)
+ gnu_type = make_dummy_type (gnat_entity);
+ else
+ {
+ gnu_decl = gnat_to_gnu_entity (Etype (gnat_entity),
NULL_TREE, 0);
- else
- gnu_type = make_dummy_type (gnat_entity);
- }
-
- else if (Present (Underlying_Full_View (gnat_entity)))
- gnu_decl = gnat_to_gnu_entity (Underlying_Full_View (gnat_entity),
- NULL_TREE, 0);
- else
- {
- gnu_decl = gnat_to_gnu_entity (Etype (gnat_entity),
- NULL_TREE, 0);
- maybe_present = true;
- }
-
- break;
- }
+ maybe_present = true;
+ }
+ break;
+ }
- /* Otherwise, if we are not defining the type now, get the
- type from the full view. But always get the type from the full
- view for define on use types, since otherwise we won't see them! */
+ /* If we already made a type for the full view, reuse it. */
+ else if (present_gnu_tree (full_view))
+ {
+ gnu_decl = get_gnu_tree (full_view);
+ break;
+ }
- else if (!definition
- || (Is_Itype (Full_View (gnat_entity))
+ /* Otherwise, if we are not defining the type now, get the type
+ from the full view. But always get the type from the full view
+ for define on use types, since otherwise we won't see them! */
+ else if (!definition
+ || (Is_Itype (full_view)
&& No (Freeze_Node (gnat_entity)))
- || (Is_Itype (gnat_entity)
- && No (Freeze_Node (Full_View (gnat_entity)))))
- {
- gnu_decl = gnat_to_gnu_entity (Full_View (gnat_entity),
- NULL_TREE, 0);
- maybe_present = true;
- break;
- }
+ || (Is_Itype (gnat_entity)
+ && No (Freeze_Node (full_view))))
+ {
+ gnu_decl = gnat_to_gnu_entity (full_view, NULL_TREE, 0);
+ maybe_present = true;
+ break;
+ }
- /* For incomplete types, make a dummy type entry which will be
- replaced later. */
- gnu_type = make_dummy_type (gnat_entity);
+ /* For incomplete types, make a dummy type entry which will be
+ replaced later. */
+ gnu_type = make_dummy_type (gnat_entity);
- /* Save this type as the full declaration's type so we can do any needed
- updates when we see it. */
- gnu_decl = create_type_decl (gnu_entity_id, gnu_type, attr_list,
- !Comes_From_Source (gnat_entity),
- debug_info_p, gnat_entity);
- save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
- break;
+ /* Save this type as the full declaration's type so we can do any
+ needed updates when we see it. */
+ gnu_decl = create_type_decl (gnu_entity_id, gnu_type, attr_list,
+ !Comes_From_Source (gnat_entity),
+ debug_info_p, gnat_entity);
+ save_gnu_tree (full_view, gnu_decl, 0);
+ break;
+ }
/* Simple class_wide types are always viewed as their root_type
by Gigi unless an Equivalent_Type is specified. */
@@ -4521,88 +4576,6 @@ substitution_list (Entity_Id gnat_subtype, Entity_Id gnat_type,
return gnu_list;
}
-/* For the following two functions: for each GNAT entity, the GCC
- tree node used as a dummy for that entity, if any. */
-
-static GTY((length ("max_gnat_nodes"))) tree * dummy_node_table;
-
-/* Initialize the above table. */
-
-void
-init_dummy_type (void)
-{
- Node_Id gnat_node;
-
- dummy_node_table = (tree *) ggc_alloc (max_gnat_nodes * sizeof (tree));
-
- for (gnat_node = 0; gnat_node < max_gnat_nodes; gnat_node++)
- dummy_node_table[gnat_node] = NULL_TREE;
-
- dummy_node_table -= First_Node_Id;
-}
-
-/* Make a dummy type corresponding to GNAT_TYPE. */
-
-tree
-make_dummy_type (Entity_Id gnat_type)
-{
- Entity_Id gnat_underlying;
- tree gnu_type;
- enum tree_code code;
-
- /* Find a full type for GNAT_TYPE, taking into account any class wide
- types. */
- if (Is_Class_Wide_Type (gnat_type) && Present (Equivalent_Type (gnat_type)))
- gnat_type = Equivalent_Type (gnat_type);
- else if (Ekind (gnat_type) == E_Class_Wide_Type)
- gnat_type = Root_Type (gnat_type);
-
- for (gnat_underlying = gnat_type;
- (IN (Ekind (gnat_underlying), Incomplete_Or_Private_Kind)
- && Present (Full_View (gnat_underlying)));
- gnat_underlying = Full_View (gnat_underlying))
- ;
-
- /* If it there already a dummy type, use that one. Else make one. */
- if (dummy_node_table[gnat_underlying])
- return dummy_node_table[gnat_underlying];
-
- /* If this is a record, make this a RECORD_TYPE or UNION_TYPE; else make
- it an ENUMERAL_TYPE. */
- if (Is_Record_Type (gnat_underlying))
- {
- Node_Id component_list
- = Component_List (Type_Definition
- (Declaration_Node
- (Implementation_Base_Type (gnat_underlying))));
- Node_Id component;
-
- /* Make this a UNION_TYPE unless it's either not an Unchecked_Union or
- we have a non-discriminant field outside a variant. In either case,
- it's a RECORD_TYPE. */
- code = UNION_TYPE;
- if (!Is_Unchecked_Union (gnat_underlying))
- code = RECORD_TYPE;
- else
- for (component = First_Non_Pragma (Component_Items (component_list));
- Present (component); component = Next_Non_Pragma (component))
- if (Ekind (Defining_Entity (component)) == E_Component)
- code = RECORD_TYPE;
- }
- else
- code = ENUMERAL_TYPE;
-
- gnu_type = make_node (code);
- TYPE_NAME (gnu_type) = get_entity_name (gnat_type);
- TYPE_DUMMY_P (gnu_type) = 1;
- if (AGGREGATE_TYPE_P (gnu_type))
- TYPE_STUB_DECL (gnu_type) = build_decl (TYPE_DECL, NULL_TREE, gnu_type);
-
- dummy_node_table[gnat_underlying] = gnu_type;
-
- return gnu_type;
-}
-
/* Return true if the size represented by GNU_SIZE can be handled by an
allocation. If STATIC_P is true, consider only what can be done with a
static allocation. */
@@ -4830,7 +4803,8 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
expr_variable = (!CONSTANT_CLASS_P (gnu_expr)
&& !(TREE_CODE (gnu_inner_expr) == VAR_DECL
- && TREE_READONLY (gnu_inner_expr))
+ && (TREE_READONLY (gnu_inner_expr)
+ || DECL_READONLY_ONCE_ELAB (gnu_inner_expr)))
&& !CONTAINS_PLACEHOLDER_P (gnu_expr));
/* If this is a static expression or contains a discriminant, we don't
@@ -6875,5 +6849,3 @@ concat_id_with_name (tree gnu_id, const char *suffix)
strcpy (Name_Buffer + len, suffix);
return get_identifier (Name_Buffer);
}
-
-#include "gt-ada-decl.h"