diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-14 11:47:59 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-14 11:47:59 +0000 |
commit | dd02c1ab1fd54afca5df41d686bb5ec662b57712 (patch) | |
tree | a467f66a1e0d7395bb33f12af5d1faed7db4a281 /gcc/ada | |
parent | 92e0f7867ab7a1c9f75711be77112c1e0959294c (diff) | |
download | gcc-dd02c1ab1fd54afca5df41d686bb5ec662b57712.tar.gz |
* gcc-interface/decl.c (elaborate_expression_1): Remove GNAT_EXPR
parameter and move check for static expression to...
(elaborate_expression): ...here. Adjust call to above function.
(gnat_to_gnu_entity): Likewise for all calls. Use correct arguments
in calls to elaborate_expression.
(elaborate_entity): Likewise.
(substitution_list): Likewise.
(maybe_variable): Fix formatting.
(substitute_in_type) <REAL_TYPE>: Merge with INTEGER_TYPE case and add
missing guard.
* gcc-interface/trans.c (protect_multiple_eval): Minor cleanup.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147530 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 183 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 39 |
3 files changed, 111 insertions, 125 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 935af74484b..99806dda7fd 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,17 @@ +2009-05-14 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (elaborate_expression_1): Remove GNAT_EXPR + parameter and move check for static expression to... + (elaborate_expression): ...here. Adjust call to above function. + (gnat_to_gnu_entity): Likewise for all calls. Use correct arguments + in calls to elaborate_expression. + (elaborate_entity): Likewise. + (substitution_list): Likewise. + (maybe_variable): Fix formatting. + (substitute_in_type) <REAL_TYPE>: Merge with INTEGER_TYPE case and add + missing guard. + * gcc-interface/trans.c (protect_multiple_eval): Minor cleanup. + 2009-05-07 Arnaud Charlet <charlet@adacore.com> * gcc-interface/Make-lang.in: Update dependencies. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index d55d56b61f6..6feadbdece0 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -128,8 +128,7 @@ static void prepend_one_attribute_to (struct attrib **, static void prepend_attributes (Entity_Id, struct attrib **); static tree elaborate_expression (Node_Id, Entity_Id, tree, bool, bool, bool); static bool is_variable_size (tree); -static tree elaborate_expression_1 (Node_Id, Entity_Id, tree, tree, - bool, bool); +static tree elaborate_expression_1 (tree, Entity_Id, tree, bool, bool); static tree make_packable_type (tree, bool); static tree gnat_to_gnu_field (Entity_Id, tree, int, bool); static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool, @@ -1563,15 +1562,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) TYPE_MIN_VALUE (gnu_type) = convert (TREE_TYPE (gnu_type), elaborate_expression (Type_Low_Bound (gnat_entity), - gnat_entity, - get_identifier ("L"), definition, 1, + gnat_entity, get_identifier ("L"), + definition, true, Needs_Debug_Info (gnat_entity))); TYPE_MAX_VALUE (gnu_type) = convert (TREE_TYPE (gnu_type), elaborate_expression (Type_High_Bound (gnat_entity), - gnat_entity, - get_identifier ("U"), definition, 1, + gnat_entity, get_identifier ("U"), + definition, true, Needs_Debug_Info (gnat_entity))); /* One of the above calls might have caused us to be elaborated, @@ -1747,14 +1746,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = convert (TREE_TYPE (gnu_type), elaborate_expression (Type_Low_Bound (gnat_entity), gnat_entity, get_identifier ("L"), - definition, 1, + definition, true, Needs_Debug_Info (gnat_entity))); TYPE_MAX_VALUE (gnu_type) = convert (TREE_TYPE (gnu_type), elaborate_expression (Type_High_Bound (gnat_entity), gnat_entity, get_identifier ("U"), - definition, 1, + definition, true, Needs_Debug_Info (gnat_entity))); /* One of the above calls might have caused us to be elaborated, @@ -2434,9 +2433,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) tree eltype = TREE_TYPE (gnu_arr_type); TYPE_SIZE (gnu_arr_type) - = elaborate_expression_1 (gnat_entity, gnat_entity, - TYPE_SIZE (gnu_arr_type), - gnu_str_name, definition, 0); + = elaborate_expression_1 (TYPE_SIZE (gnu_arr_type), + gnat_entity, gnu_str_name, + definition, false); /* ??? For now, store the size as a multiple of the alignment of the element type in bytes so that we @@ -2445,12 +2444,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = build_binary_op (MULT_EXPR, sizetype, elaborate_expression_1 - (gnat_entity, gnat_entity, - build_binary_op (EXACT_DIV_EXPR, sizetype, + (build_binary_op (EXACT_DIV_EXPR, sizetype, TYPE_SIZE_UNIT (gnu_arr_type), size_int (TYPE_ALIGN (eltype) / BITS_PER_UNIT)), - concat_name (gnu_str_name, "A_U"), definition, 0), + gnat_entity, concat_name (gnu_str_name, "A_U"), + definition, false), size_int (TYPE_ALIGN (eltype) / BITS_PER_UNIT)); /* ??? create_type_decl is not invoked on the inner types so @@ -4515,19 +4514,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) TYPE_SIZE (gnu_type), 0)) { TYPE_SIZE (gnu_type) - = elaborate_expression_1 (gnat_entity, gnat_entity, - TYPE_SIZE (gnu_type), - get_identifier ("SIZE"), - definition, 0); + = elaborate_expression_1 (TYPE_SIZE (gnu_type), + gnat_entity, get_identifier ("SIZE"), + definition, false); SET_TYPE_ADA_SIZE (gnu_type, TYPE_SIZE (gnu_type)); } else { TYPE_SIZE (gnu_type) - = elaborate_expression_1 (gnat_entity, gnat_entity, - TYPE_SIZE (gnu_type), - get_identifier ("SIZE"), - definition, 0); + = elaborate_expression_1 (TYPE_SIZE (gnu_type), + gnat_entity, get_identifier ("SIZE"), + definition, false); /* ??? For now, store the size as a multiple of the alignment in bytes so that we can see the alignment from the tree. */ @@ -4535,23 +4532,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = build_binary_op (MULT_EXPR, sizetype, elaborate_expression_1 - (gnat_entity, gnat_entity, - build_binary_op (EXACT_DIV_EXPR, sizetype, + (build_binary_op (EXACT_DIV_EXPR, sizetype, TYPE_SIZE_UNIT (gnu_type), size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT)), - get_identifier ("SIZE_A_UNIT"), - definition, 0), + gnat_entity, get_identifier ("SIZE_A_UNIT"), + definition, false), size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT)); if (TREE_CODE (gnu_type) == RECORD_TYPE) SET_TYPE_ADA_SIZE (gnu_type, - elaborate_expression_1 (gnat_entity, + elaborate_expression_1 (TYPE_ADA_SIZE (gnu_type), gnat_entity, - TYPE_ADA_SIZE (gnu_type), get_identifier ("RM_SIZE"), - definition, 0)); + definition, false)); } } @@ -4577,13 +4572,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) = build_binary_op (MULT_EXPR, sizetype, elaborate_expression_1 - (gnat_temp, gnat_temp, - build_binary_op (EXACT_DIV_EXPR, sizetype, + (build_binary_op (EXACT_DIV_EXPR, sizetype, DECL_FIELD_OFFSET (gnu_field), size_int (DECL_OFFSET_ALIGN (gnu_field) / BITS_PER_UNIT)), - get_identifier ("OFFSET"), - definition, 0), + gnat_temp, get_identifier ("OFFSET"), + definition, false), size_int (DECL_OFFSET_ALIGN (gnu_field) / BITS_PER_UNIT)); /* ??? The context of gnu_field is not necessarily gnu_type so @@ -5265,10 +5259,10 @@ elaborate_entity (Entity_Id gnat_entity) conversions on bounds of real types. */ if (!Raises_Constraint_Error (gnat_lb)) elaborate_expression (gnat_lb, gnat_entity, get_identifier ("L"), - 1, 0, Needs_Debug_Info (gnat_entity)); + true, false, Needs_Debug_Info (gnat_entity)); if (!Raises_Constraint_Error (gnat_hb)) elaborate_expression (gnat_hb, gnat_entity, get_identifier ("U"), - 1, 0, Needs_Debug_Info (gnat_entity)); + true, false, Needs_Debug_Info (gnat_entity)); break; } @@ -5304,8 +5298,8 @@ elaborate_entity (Entity_Id gnat_entity) /* ??? For now, ignore access discriminants. */ if (!Is_Access_Type (Etype (Node (gnat_discriminant_expr)))) elaborate_expression (Node (gnat_discriminant_expr), - gnat_entity, - get_entity_name (gnat_field), 1, 0, 0); + gnat_entity, get_entity_name (gnat_field), + true, false, false); } break; @@ -5457,7 +5451,7 @@ substitution_list (Entity_Id gnat_subtype, Entity_Id gnat_type, elaborate_expression (Node (gnat_value), gnat_subtype, get_entity_name (gnat_discrim), definition, - 1, 0), + true, false), gnu_list); return gnu_list; @@ -5591,63 +5585,66 @@ prepend_attributes (Entity_Id gnat_entity, struct attrib ** attr_list) } } -/* Called when we need to protect a variable object using a save_expr. */ +/* Called when we need to protect a variable object using a SAVE_EXPR. */ tree maybe_variable (tree gnu_operand) { - if (TREE_CONSTANT (gnu_operand) || TREE_READONLY (gnu_operand) + if (TREE_CONSTANT (gnu_operand) + || TREE_READONLY (gnu_operand) || TREE_CODE (gnu_operand) == SAVE_EXPR || TREE_CODE (gnu_operand) == NULL_EXPR) return gnu_operand; if (TREE_CODE (gnu_operand) == UNCONSTRAINED_ARRAY_REF) { - tree gnu_result = build1 (UNCONSTRAINED_ARRAY_REF, - TREE_TYPE (gnu_operand), - variable_size (TREE_OPERAND (gnu_operand, 0))); + tree gnu_result + = build1 (UNCONSTRAINED_ARRAY_REF, TREE_TYPE (gnu_operand), + variable_size (TREE_OPERAND (gnu_operand, 0))); TREE_READONLY (gnu_result) = TREE_STATIC (gnu_result) = TYPE_READONLY (TREE_TYPE (TREE_TYPE (gnu_operand))); return gnu_result; } - else - return variable_size (gnu_operand); + + return variable_size (gnu_operand); } /* Given a GNAT tree GNAT_EXPR, for an expression which is a value within a type definition (either a bound or a discriminant value) for GNAT_ENTITY, - return the GCC tree to use for that expression. GNU_NAME is the - qualification to use if an external name is appropriate and DEFINITION is - true if this is a definition of GNAT_ENTITY. If NEED_VALUE is true, we - need a result. Otherwise, we are just elaborating this for side-effects. - If NEED_DEBUG is true we need the symbol for debugging purposes even if it + return the GCC tree to use for that expression. GNU_NAME is the suffix + to use if a variable needs to be created and DEFINITION is true if this + is a definition of GNAT_ENTITY. If NEED_VALUE is true, we need a result; + otherwise, we are just elaborating the expression for side-effects. If + NEED_DEBUG is true, we need a variable for debugging purposes even if it isn't needed for code generation. */ static tree -elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, - tree gnu_name, bool definition, bool need_value, - bool need_debug) +elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, tree gnu_name, + bool definition, bool need_value, bool need_debug) { tree gnu_expr; - /* If we already elaborated this expression (e.g., it was involved + /* If we already elaborated this expression (e.g. it was involved in the definition of a private type), use the old value. */ if (present_gnu_tree (gnat_expr)) return get_gnu_tree (gnat_expr); - /* If we don't need a value and this is static or a discriminant, we - don't need to do anything. */ - else if (!need_value - && (Is_OK_Static_Expression (gnat_expr) - || (Nkind (gnat_expr) == N_Identifier - && Ekind (Entity (gnat_expr)) == E_Discriminant))) - return 0; + /* If we don't need a value and this is static or a discriminant, + we don't need to do anything. */ + if (!need_value + && (Is_OK_Static_Expression (gnat_expr) + || (Nkind (gnat_expr) == N_Identifier + && Ekind (Entity (gnat_expr)) == E_Discriminant))) + return NULL_TREE; + + /* If it's a static expression, we don't need a variable for debugging. */ + if (need_debug && Is_OK_Static_Expression (gnat_expr)) + need_debug = false; - /* Otherwise, convert this tree to its GCC equivalent. */ - gnu_expr - = elaborate_expression_1 (gnat_expr, gnat_entity, gnat_to_gnu (gnat_expr), - gnu_name, definition, need_debug); + /* Otherwise, convert this tree to its GCC equivalent and elaborate it. */ + gnu_expr = elaborate_expression_1 (gnat_to_gnu (gnat_expr), gnat_entity, + gnu_name, definition, need_debug); /* Save the expression in case we try to elaborate this entity again. Since it's not a DECL, don't check it. Don't save if it's a discriminant. */ @@ -5657,29 +5654,27 @@ elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, return need_value ? gnu_expr : error_mark_node; } -/* Similar, but take a GNU expression. */ +/* Similar, but take a GNU expression and always return a result. */ static tree -elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity, - tree gnu_expr, tree gnu_name, bool definition, - bool need_debug) +elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name, + bool definition, bool need_debug) { - tree gnu_decl = NULL_TREE; /* Skip any conversions and simple arithmetics to see if the expression is a read-only variable. ??? This really should remain read-only, but we have to think about the typing of the tree here. */ tree gnu_inner_expr = skip_simple_arithmetic (remove_conversions (gnu_expr, true)); + tree gnu_decl = NULL_TREE; bool expr_global = Is_Public (gnat_entity) || global_bindings_p (); bool expr_variable; - /* In most cases, we won't see a naked FIELD_DECL here because a - discriminant reference will have been replaced with a COMPONENT_REF - when the type is being elaborated. However, there are some cases - involving child types where we will. So convert it to a COMPONENT_REF - here. We have to hope it will be at the highest level of the - expression in these cases. */ + /* In most cases, we won't see a naked FIELD_DECL because a discriminant + reference will have been replaced with a COMPONENT_REF when the type + is being elaborated. However, there are some cases involving child + types where we will. So convert it to a COMPONENT_REF. We hope it + will be at the highest level of the expression in these cases. */ if (TREE_CODE (gnu_expr) == FIELD_DECL) gnu_expr = build3 (COMPONENT_REF, TREE_TYPE (gnu_expr), build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (gnu_expr)), @@ -5693,19 +5688,14 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity, by the variable; otherwise use a SAVE_EXPR if needed. Note that we rely here on the fact that an expression cannot contain both the discriminant and some other variable. */ - expr_variable = (!CONSTANT_CLASS_P (gnu_expr) && !(TREE_CODE (gnu_inner_expr) == VAR_DECL && (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 - need the variable for debugging (and can't elaborate anyway if a - discriminant). */ - if (need_debug - && (Is_OK_Static_Expression (gnat_expr) - || CONTAINS_PLACEHOLDER_P (gnu_expr))) + /* If GNU_EXPR contains a discriminant, we can't elaborate a variable. */ + if (need_debug && CONTAINS_PLACEHOLDER_P (gnu_expr)) need_debug = false; /* Now create the variable if we need it. */ @@ -5721,10 +5711,8 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity, can do the right thing in the local case. */ if (expr_global && expr_variable) return gnu_decl; - else if (!expr_variable) - return gnu_expr; - else - return maybe_variable (gnu_expr); + + return expr_variable ? maybe_variable (gnu_expr) : gnu_expr; } /* Create a record type that contains a SIZE bytes long field of TYPE with a @@ -7714,6 +7702,7 @@ substitute_in_type (tree t, tree f, tree r) case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: + case REAL_TYPE: if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t)) || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t))) { @@ -7726,27 +7715,11 @@ substitute_in_type (tree t, tree f, tree r) new = copy_type (t); TYPE_MIN_VALUE (new) = low; TYPE_MAX_VALUE (new) = high; - if (TYPE_INDEX_TYPE (t)) + + if (TREE_CODE (t) == INTEGER_TYPE && TYPE_INDEX_TYPE (t)) SET_TYPE_INDEX_TYPE (new, substitute_in_type (TYPE_INDEX_TYPE (t), f, r)); - return new; - } - - return t; - - case REAL_TYPE: - if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t)) - || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t))) - { - tree low = SUBSTITUTE_IN_EXPR (TYPE_MIN_VALUE (t), f, r); - tree high = SUBSTITUTE_IN_EXPR (TYPE_MAX_VALUE (t), f, r); - - if (low == TYPE_MIN_VALUE (t) && high == TYPE_MAX_VALUE (t)) - return t; - new = copy_type (t); - TYPE_MIN_VALUE (new) = low; - TYPE_MAX_VALUE (new) = high; return new; } diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index d6aa7dfa123..ee65c81503a 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -7246,30 +7246,29 @@ protect_multiple_eval (tree exp) if (!TREE_SIDE_EFFECTS (exp)) return exp; - /* If it is a conversion, protect what's inside the conversion. + /* If this is a conversion, protect what's inside the conversion. Similarly, if we're indirectly referencing something, we only - actually need to protect the address since the data itself can't - change in these situations. */ - else if (TREE_CODE (exp) == NON_LVALUE_EXPR - || CONVERT_EXPR_P (exp) - || TREE_CODE (exp) == VIEW_CONVERT_EXPR - || TREE_CODE (exp) == INDIRECT_REF - || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF) - return build1 (TREE_CODE (exp), type, - protect_multiple_eval (TREE_OPERAND (exp, 0))); - - /* If EXP is a fat pointer or something that can be placed into a register, - just make a SAVE_EXPR. */ + need to protect the address since the data itself can't change + in these situations. */ + if (TREE_CODE (exp) == NON_LVALUE_EXPR + || CONVERT_EXPR_P (exp) + || TREE_CODE (exp) == VIEW_CONVERT_EXPR + || TREE_CODE (exp) == INDIRECT_REF + || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF) + return build1 (TREE_CODE (exp), type, + protect_multiple_eval (TREE_OPERAND (exp, 0))); + + /* If this is a fat pointer or something that can be placed into a + register, just make a SAVE_EXPR. */ if (TYPE_FAT_POINTER_P (type) || TYPE_MODE (type) != BLKmode) return save_expr (exp); - /* Otherwise, dereference, protect the address, and re-reference. */ - else - return - build_unary_op (INDIRECT_REF, type, - save_expr (build_unary_op (ADDR_EXPR, - build_reference_type (type), - exp))); + /* Otherwise, reference, protect the address and dereference. */ + return + build_unary_op (INDIRECT_REF, type, + save_expr (build_unary_op (ADDR_EXPR, + build_reference_type (type), + exp))); } /* This is equivalent to stabilize_reference in tree.c, but we know how to |