diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-10-31 18:19:52 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-10-31 18:19:52 +0000 |
commit | f682feb7a5bcd72cf2eb9525b920e06c2f94fb09 (patch) | |
tree | c5e8ce80b183e80e687e1da8ae37243121191806 /gcc/ada/decl.c | |
parent | 560edc4abacc494bd98af69035fec869e436a5c8 (diff) | |
download | gcc-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.c | 424 |
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" |