diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2014-04-15 09:23:21 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2014-04-15 09:23:21 +0000 |
commit | e297e2eaa6e39126dd216a09dc47458824eb5d52 (patch) | |
tree | 017986e6c0b887f1af51a9d79ce4f4dce42907d4 /gcc/ada/gcc-interface/decl.c | |
parent | e63b36bda5085924a07cb2c57788e0e7e72c6272 (diff) | |
download | gcc-e297e2eaa6e39126dd216a09dc47458824eb5d52.zip gcc-e297e2eaa6e39126dd216a09dc47458824eb5d52.tar.gz gcc-e297e2eaa6e39126dd216a09dc47458824eb5d52.tar.bz2 |
decl.c (gnat_to_gnu_entity): Create a mere scalar constant instead of a reference for renaming of scalar literal.
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Create a mere
scalar constant instead of a reference for renaming of scalar literal.
Do not create a new object for constant renaming except for a function
call. Make sure a VAR_DECL is created for the renaming pointer.
* gcc-interface/trans.c (constant_decl_with_initializer_p): New.
(fold_constant_decl_in_expr): New function.
(Identifier_to_gnu): Use constant_decl_with_initializer_p.
For a constant renaming, try to fold a constant DECL in the result.
(lvalue_required_p) <N_Object_Renaming_Declaration>: Always return 1.
(Identifier_to_gnu): Reference the renamed object of constant renaming
pointers directly.
(Case_Statement_to_gnu): Do not re-fold the bounds of integer types.
Assert that the case values are constant.
* gcc-interface/utils.c (invalidate_global_renaming_pointers): Do not
invalidate constant renaming pointers.
Co-Authored-By: Pierre-Marie de Rodat <derodat@adacore.com>
From-SVN: r209411
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 143 |
1 files changed, 64 insertions, 79 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index aed49b7..7c3f7e5 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -960,18 +960,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnu_type = TREE_TYPE (gnu_expr); /* Case 1: If this is a constant renaming stemming from a function - call, treat it as a normal object whose initial value is what - is being renamed. RM 3.3 says that the result of evaluating a - function call is a constant object. As a consequence, it can - be the inner object of a constant renaming. In this case, the - renaming must be fully instantiated, i.e. it cannot be a mere - reference to (part of) an existing object. */ + call, treat it as a normal object whose initial value is what is + being renamed. RM 3.3 says that the result of evaluating a + function call is a constant object. Treat constant literals + the same way. As a consequence, it can be the inner object of + a constant renaming. In this case, the renaming must be fully + instantiated, i.e. it cannot be a mere reference to (part of) an + existing object. */ if (const_flag) { tree inner_object = gnu_expr; while (handled_component_p (inner_object)) inner_object = TREE_OPERAND (inner_object, 0); - if (TREE_CODE (inner_object) == CALL_EXPR) + if (TREE_CODE (inner_object) == CALL_EXPR + || CONSTANT_CLASS_P (inner_object)) create_normal_object = true; } @@ -1030,15 +1032,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) about that failure. */ } - /* Case 3: If this is a constant renaming and creating a - new object is allowed and cheap, treat it as a normal - object whose initial value is what is being renamed. */ - if (const_flag - && !Is_Composite_Type - (Underlying_Type (Etype (gnat_entity)))) - ; - - /* Case 4: Make this into a constant pointer to the object we + /* Case 3: Make this into a constant pointer to the object we are to rename and attach the object to the pointer if it is something we can stabilize. @@ -1050,68 +1044,59 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) The pointer is called a "renaming" pointer in this case. In the rare cases where we cannot stabilize the renamed - object, we just make a "bare" pointer, and the renamed - entity is always accessed indirectly through it. */ - else - { - /* We need to preserve the volatileness of the renamed - object through the indirection. */ - if (TREE_THIS_VOLATILE (gnu_expr) - && !TYPE_VOLATILE (gnu_type)) - gnu_type - = build_qualified_type (gnu_type, - (TYPE_QUALS (gnu_type) - | TYPE_QUAL_VOLATILE)); - gnu_type = build_reference_type (gnu_type); - inner_const_flag = TREE_READONLY (gnu_expr); - const_flag = true; - - /* If the previous attempt at stabilizing failed, there - is no point in trying again and we reuse 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 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 fine since we are building a pointer initializer and - neither the pointer nor the initializing expression can - be accessed before the pointer elaboration has taken - place in a correct program. - - These SAVE_EXPRs will be evaluated at the right place - by either the evaluation of the initializer for the - non-global case or the elaboration code for the global - case, and will be attached to the elaboration procedure - in the latter case. */ - else - { - maybe_stable_expr - = gnat_stabilize_reference (gnu_expr, true, &stable); + object, we just make a "bare" pointer and the renamed + object will always be accessed indirectly through it. + + Note that we need to preserve the volatility of the renamed + object through the indirection. */ + if (TREE_THIS_VOLATILE (gnu_expr) && !TYPE_VOLATILE (gnu_type)) + gnu_type = build_qualified_type (gnu_type, + (TYPE_QUALS (gnu_type) + | TYPE_QUAL_VOLATILE)); + gnu_type = build_reference_type (gnu_type); + inner_const_flag = TREE_READONLY (gnu_expr); + const_flag = true; - if (stable) - renamed_obj = maybe_stable_expr; + /* If the previous attempt at stabilizing failed, there is + no point in trying again and we reuse 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. + + Otherwise, try to stabilize 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 are at the global level or not. This + is fine since we are building a pointer initializer and + neither the pointer nor the initializing expression can + be accessed before the pointer elaboration has taken + place in a correct program. + + These SAVE_EXPRs will be evaluated at the right place + by either the evaluation of the initializer for the + non-global case or the elaboration code for the global + case, and will be attached to the elaboration procedure + in the latter case. */ + if (!maybe_stable_expr) + { + maybe_stable_expr + = gnat_stabilize_reference (gnu_expr, true, &stable); - /* Attaching is actually performed downstream, as soon - as we have a VAR_DECL for the pointer we make. */ - } + if (stable) + renamed_obj = maybe_stable_expr; + } - if (type_annotate_only - && TREE_CODE (maybe_stable_expr) == ERROR_MARK) - gnu_expr = NULL_TREE; - else - gnu_expr = build_unary_op (ADDR_EXPR, gnu_type, - maybe_stable_expr); + if (type_annotate_only + && TREE_CODE (maybe_stable_expr) == ERROR_MARK) + gnu_expr = NULL_TREE; + else + gnu_expr + = build_unary_op (ADDR_EXPR, gnu_type, maybe_stable_expr); - gnu_size = NULL_TREE; - used_by_ref = true; - } + gnu_size = NULL_TREE; + used_by_ref = true; } } @@ -1483,10 +1468,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* Now create the variable or the constant and set various flags. */ gnu_decl - = create_var_decl (gnu_entity_name, gnu_ext_name, gnu_type, - gnu_expr, const_flag, Is_Public (gnat_entity), - imported_p || !definition, static_p, attr_list, - gnat_entity); + = create_var_decl_1 (gnu_entity_name, gnu_ext_name, gnu_type, + gnu_expr, const_flag, Is_Public (gnat_entity), + imported_p || !definition, static_p, + !renamed_obj, attr_list, gnat_entity); DECL_BY_REF_P (gnu_decl) = used_by_ref; DECL_POINTS_TO_READONLY_P (gnu_decl) = used_by_ref && inner_const_flag; DECL_CAN_NEVER_BE_NULL_P (gnu_decl) = Can_Never_Be_Null (gnat_entity); @@ -1517,7 +1502,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* If this is a renaming pointer, attach the renamed object to it and register it if we are at the global level. Note that an external constant is at the global level. */ - if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj) + if (renamed_obj) { SET_DECL_RENAMED_OBJECT (gnu_decl, renamed_obj); if ((!definition && kind == E_Constant) || global_bindings_p ()) |