diff options
author | Thomas Quinot <quinot@adacore.com> | 2005-11-15 14:53:22 +0100 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2005-11-15 14:53:22 +0100 |
commit | 5e61ef090a8910843dd421fad19eae41c4fca816 (patch) | |
tree | 539f60872b22a416a9e54b3d9d16de22a8182921 /gcc/ada/utils.c | |
parent | fda5d6d4ff7de017167de98a20ffc4110f766795 (diff) | |
download | gcc-5e61ef090a8910843dd421fad19eae41c4fca816.zip gcc-5e61ef090a8910843dd421fad19eae41c4fca816.tar.gz gcc-5e61ef090a8910843dd421fad19eae41c4fca816.tar.bz2 |
decl.c: Factor common code to build a storage type for an unconstrained object from a...
2005-11-14 Thomas Quinot <quinot@adacore.com>
Olivier Hainque <hainque@adacore.com>
Eric Botcazou <ebotcazou@adacore.com>
* decl.c:
Factor common code to build a storage type for an unconstrained object
from a fat or thin pointer type and a constrained object type.
(annotate_value): Handle BIT_AND_EXPR.
(annotate_rep): Don't restrict the back annotation of inherited
components to the type_annotate_only case.
(gnat_to_gnu_entity) <E_Array_Type>: Do not invoke create_type_decl if
we are not defining the type.
<E_Record_Type>: Likewise.
(gnat_to_gnu_entity) <object, renaming>: Adjust comments and structure
to get advantage of the new maybe_stabilize_reference interface, to
ensure that what we reference is indeed stabilized instead of relying
on assumptions on what the stabilizer does.
(gnat_to_gnu_entity) <E_Incomplete_Type>: If the entity is an incomplete
type imported through a limited_with clause, use its non-limited view.
(Has_Stdcall_Convention): New macro, to centralize the Windows vs others
differentiation.
(gnat_to_gnu_entity): Use Has_Stdcall_Convention instead of a spread mix
of #if sections + explicit comparisons of convention identifiers.
(gnat_to_gnu_entity) <E_Variable>: Decrement force_global if necessary
before early-returning for certain types when code generation is
disabled.
(gnat_to_gnu_entity) <object>: Adjust comment attached to the
nullification of gnu_expr we do for objects with address clause and
that we are not defining.
(elaborate_expression_1): Do not create constants when creating
variables needed by the debug info: the dwarf2 writer considers that
CONST_DECLs is used only to represent enumeration constants, and emits
nothing for them.
(gnat_to_gnu_entity) <object>: When turning a non-definition of an
object with an address clause into an indirect reference, drop the
initializing expression.
Include "expr.h".
(STACK_CHECK_BUILTIN): Delete.
(STACK_CHECK_PROBE_INTERVAL): Likewise.
(STACK_CHECK_MAX_FRAME_SIZE): Likewise.
(STACK_CHECK_MAX_VAR_SIZE): Likewise.
(gnat_to_gnu_entity): If gnat_entity is a renaming, do not mark the tree
corresponding to the renamed object as ignored for debugging purposes.
* trans.c (tree_transform, case N_Attribute_Reference, case Attr_Size &
related): For a prefix that is a dereference of a fat or thin pointer,
if there is an actual subtype provided by the front-end, use that
subtype to build an actual type with bounds template.
(tree_transform, case N_Free_Statement): If an Actual_Designated_Subtype
is provided by the front-end, use that subtype to compute the size of
the deallocated object.
(gnat_to_gnu): When adding a statement into an elaboration procedure,
check for a potential violation of a No_Elaboration_Code restriction.
(maybe_stabilize_reference): New function, like gnat_stabilize_reference
with extra arguments to control whether to recurse through non-values
and to let the caller know if the stabilization has succeeded.
(gnat_stabilize_reference): Now a simple wrapper around
maybe_stabilize, for common uses without restriction on lvalues and
without need to check for the success indication.
(gnat_to_gnu, call_to_gnu): Adjust calls to gnat_stabilize_reference, to
pass false instead of 0 as the FORCE argument which is a bool.
(Identifier_to_gnu): Remove checks ensuring that an renamed object
attached to a renaming pointer has been properly stabilized, as no such
object is attached otherwise.
(call_to_gnu): Invoke create_var_decl to create the temporary when the
function uses the "target pointer" return mechanism.
Reinstate conversion of the actual to the type of the formal
parameter before any other specific treatment based on the passing
mechanism. This turns out to be necessary in order for PLACEHOLDER
substitution to work properly when the latter type is unconstrained.
* gigi.h (build_unc_object_type_from_ptr): New subprogram, factoring a
common pattern.
(maybe_stabilize_reference): New function, like gnat_stabilize_reference
with extra arguments to control whether to recurse through non-values
and to let the caller know if the stabilization has succeeded.
* utils2.c (gnat_build_constructor): Only sort the fields for possible
static output of record constructor if all the components are constant.
(gnat_build_constructor): For a record type, sort the list of field
initializers in increasing bit position order.
Factor common code to build a storage type for an unconstrained object
from a fat or thin pointer type and a constrained object type.
(build_unary_op) <ADDR_EXPR>: Always recurse down conversions between
types variants, and process special cases of VIEW_CONVERT expressions
as their NOP_EXPR counterpart to ensure we get to the
CORRESPONDING_VARs associated with CONST_DECls.
(build_binary_op) <MODIFY_EXPR>: Do not strip VIEW_CONVERT_EXPRs
on the right-hand side.
* utils.c (build_unc_object_type_from_ptr): New subprogram, factoring
a common pattern.
(convert) <VIEW_CONVERT_EXPR>: Return the inner operand directly if we
are converting back to its original type.
(convert) <JM input>: Fallthrough regular conversion code instead of
extracting the object if converting to a type variant.
(create_var_decl): When a variable has an initializer requiring code
generation and we are at the top level, check for a potential violation
of a No_Elaboration_Code restriction.
(create_var_decl): call expand_decl for CONST_DECLs, to set MODE, ALIGN
SIZE and SIZE_UNIT which we need for later back-annotations.
* utils.c: (convert) <STRING_CST>: Remove obsolete code.
<VIEW_CONVERT_EXPR>: Do not lift the conversion if the target type
is an unchecked union.
(pushdecl): Set DECL_NO_STATIC_CHAIN on imported nested functions.
(convert) <VIEW_CONVERT_EXPR>: When the types have the same
main variant, just replace the VIEW_CONVERT_EXPR.
<UNION_TYPE>: Revert 2005-03-02 change.
* repinfo.h, repinfo.ads: Add tcode for BIT_AND_EXPR.
* repinfo.adb (Print_Expr, Rep_Value): Handle Bit_And_Expressions.
From-SVN: r106961
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r-- | gcc/ada/utils.c | 100 |
1 files changed, 81 insertions, 19 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c index 1bf0007..2bfafce 100644 --- a/gcc/ada/utils.c +++ b/gcc/ada/utils.c @@ -324,7 +324,13 @@ gnat_pushdecl (tree decl, Node_Id gnat_node) if (global_bindings_p () && TREE_CODE (decl) != PARM_DECL) DECL_CONTEXT (decl) = 0; else - DECL_CONTEXT (decl) = current_function_decl; + { + DECL_CONTEXT (decl) = current_function_decl; + + /* Functions imported in another function are not really nested. */ + if (TREE_CODE (decl) == FUNCTION_DECL && TREE_PUBLIC (decl)) + DECL_NO_STATIC_CHAIN (decl) = 1; + } TREE_NO_WARNING (decl) = (gnat_node == Empty || Warnings_Off (gnat_node)); @@ -1277,6 +1283,12 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init, || (type_annotate_only && var_init && !TREE_CONSTANT (var_init))) var_init = NULL_TREE; + /* At the global level, an initializer requiring code to be generated + produces elaboration statements. Check that such statements are allowed, + that is, not violating a No_Elaboration_Code restriction. */ + if (global_bindings_p () && var_init != 0 && ! init_const) + Check_Elaboration_Code_Allowed (gnat_node); + /* Ada doesn't feature Fortran-like COMMON variables so we shouldn't try to fiddle with DECL_COMMON. However, on platforms that don't support global BSS sections, uninitialized global variables would @@ -1313,6 +1325,10 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init, if (TREE_CODE (var_decl) != CONST_DECL) rest_of_decl_compilation (var_decl, global_bindings_p (), 0); + else + /* expand CONST_DECLs to set their MODE, ALIGN, SIZE and SIZE_UNIT, + which we need for later back-annotations. */ + expand_decl (var_decl); return var_decl; } @@ -1607,7 +1623,7 @@ potential_alignment_gap (tree prev_field, tree curr_field, tree offset) % DECL_ALIGN (curr_field) != 0); /* If both the position and size of the previous field are multiples - of the current field alignment, there can not be any gap. */ + of the current field alignment, there cannot be any gap. */ if (value_factor_p (bit_position (prev_field), DECL_ALIGN (curr_field)) && value_factor_p (DECL_SIZE (prev_field), DECL_ALIGN (curr_field))) return false; @@ -2444,6 +2460,22 @@ build_unc_object_type (tree template_type, tree object_type, tree name) return type; } + +/* Same, taking a thin or fat pointer type instead of a template type. */ + +tree +build_unc_object_type_from_ptr (tree thin_fat_ptr_type, tree object_type, tree name) +{ + tree template_type; + + gcc_assert (TYPE_FAT_OR_THIN_POINTER_P (thin_fat_ptr_type)); + + template_type + = (TYPE_FAT_POINTER_P (thin_fat_ptr_type) + ? TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (thin_fat_ptr_type)))) + : TREE_TYPE (TYPE_FIELDS (TREE_TYPE (thin_fat_ptr_type)))); + return build_unc_object_type (template_type, object_type, name); +} /* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE. In the normal case this is just two adjustments, but we have more to do @@ -2755,11 +2787,15 @@ convert (tree type, tree expr) expr)), TYPE_MIN_VALUE (etype)))); - /* If the input is a justified modular type, we need to extract - the actual object before converting it to any other type with the - exception of an unconstrained array. */ + /* If the input is a justified modular type, we need to extract the actual + object before converting it to any other type with the exceptions of an + unconstrained array or of a mere type variant. It is useful to avoid the + extraction and conversion in the type variant case because it could end + up replacing a VAR_DECL expr by a constructor and we might be about the + take the address of the result. */ if (ecode == RECORD_TYPE && TYPE_JUSTIFIED_MODULAR_P (etype) - && code != UNCONSTRAINED_ARRAY_TYPE) + && code != UNCONSTRAINED_ARRAY_TYPE + && TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (etype)) return convert (type, build_component_ref (expr, NULL_TREE, TYPE_FIELDS (etype), false)); @@ -2804,9 +2840,7 @@ convert (tree type, tree expr) just make a new one in the proper type. */ if (code == ecode && AGGREGATE_TYPE_P (etype) && !(TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST - && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - && (TREE_CODE (expr) == STRING_CST - || get_alias_set (etype) == get_alias_set (type))) + && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)) { expr = copy_node (expr); TREE_TYPE (expr) = type; @@ -2826,9 +2860,40 @@ convert (tree type, tree expr) break; case VIEW_CONVERT_EXPR: - if (AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype) - && !TYPE_FAT_POINTER_P (type) && !TYPE_FAT_POINTER_P (etype)) - return convert (type, TREE_OPERAND (expr, 0)); + { + /* GCC 4.x is very sensitive to type consistency overall, and view + conversions thus are very frequent. Eventhough just "convert"ing + the inner operand to the output type is fine in most cases, it + might expose unexpected input/output type mismatches in special + circumstances so we avoid such recursive calls when we can. */ + + tree op0 = TREE_OPERAND (expr, 0); + + /* If we are converting back to the original type, we can just + lift the input conversion. This is a common occurence with + switches back-and-forth amongst type variants. */ + if (type == TREE_TYPE (op0)) + return op0; + + /* Otherwise, if we're converting between two aggregate types, we + might be allowed to substitute the VIEW_CONVERT target type in + place or to just convert the inner expression. */ + if (AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype)) + { + /* If we are converting between type variants, we can just + substitute the VIEW_CONVERT in place. */ + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype)) + return build1 (VIEW_CONVERT_EXPR, type, op0); + + /* Otherwise, we may just bypass the input view conversion unless + one of the types is a fat pointer, or we're converting to an + unchecked union type. Both are handled by specialized code + below and the latter relies on exact type matching. */ + else if (!TYPE_FAT_POINTER_P (type) && !TYPE_FAT_POINTER_P (etype) + && !(code == UNION_TYPE && TYPE_UNCHECKED_UNION_P (type))) + return convert (type, op0); + } + } break; case INDIRECT_REF: @@ -2957,13 +3022,10 @@ convert (tree type, tree expr) { if (TREE_TYPE (tem) == etype) return build1 (CONVERT_EXPR, type, expr); - - /* Accept slight type variations. */ - if (TREE_TYPE (tem) == TYPE_MAIN_VARIANT (etype) - || (TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE - && (TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (tem)) - || TYPE_IS_PADDING_P (TREE_TYPE (tem))) - && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (tem))) == etype)) + else if (TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE + && (TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (tem)) + || TYPE_IS_PADDING_P (TREE_TYPE (tem))) + && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (tem))) == etype) return build1 (CONVERT_EXPR, type, convert (TREE_TYPE (tem), expr)); } |