diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2015-05-28 15:24:12 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2015-05-28 15:24:12 +0000 |
commit | fc7a823e1507110aba804cf94415155a8783e698 (patch) | |
tree | fb09192367caa4ff2977684a039b071404d51421 /gcc/ada/gcc-interface/gigi.h | |
parent | 318a4e6de8f20670c9f9e9dde02dc639f161f68c (diff) | |
download | gcc-fc7a823e1507110aba804cf94415155a8783e698.zip gcc-fc7a823e1507110aba804cf94415155a8783e698.tar.gz gcc-fc7a823e1507110aba804cf94415155a8783e698.tar.bz2 |
gigi.h (gnat_stabilize_reference): Adjust.
* gcc-interface/gigi.h (gnat_stabilize_reference): Adjust.
(rewrite_fn): Remove third parameter.
(type_is_padding_self_referential): New inline predicate.
(return_type_with_variable_size_p): Likewise.
* gcc-interface/decl.c (allocatable_size_p): More around.
(cannot_be_superflat_p): Rename into...
(cannot_be_superflat ): ...this.
(initial_value_needs_conversion): New predicate.
(gnat_to_gnu_entity): Invoke type_is_padding_self_referential,
initial_value_needs_conversion and adjust to above renaming.
For a renaming, force the materialization if the inner expression
is compound. Adjust calls to elaborate_reference and build a
compound expression if needed.
(struct er_dat): Add N field.
(elaborate_reference_1): Remove N parameter and adjust.
(elaborate_reference): Add INIT parameter and pass it in the call to
gnat_rewrite_reference. Adjust initial expression.
* gcc-interface/trans.c (Call_to_gnu): Treat renamings the same way as
regular object declarations when it comes to creating a temporary.
Adjust call to gnat_stabilize_reference and build a compound expression
if needed. Invoke return_type_with_variable_size_p.
(gnat_to_gnu): Invoke type_is_padding_self_referential. In case #4,
return a call to a function unmodified if it returns with variable size
and is also the initial expression in an object declaration.
* gcc-interface/utils2.c (build_binary_op) <INIT_EXPR>: Use the RHS'
type if it is a call to a function that returns with variable size.
(build_unary_op): Invoke type_is_padding_self_referential.
(gnat_stabilize_reference_1): Remove N parameter and adjust.
(gnat_stabilize_reference): Add INIT parameter and pass it in the call
to gnat_rewrite_reference.
(gnat_rewrite_reference): Remove N, add INIT parameter and adjust.
<COMPOUND_EXPR>: New case.
From-SVN: r223834
Diffstat (limited to 'gcc/ada/gcc-interface/gigi.h')
-rw-r--r-- | gcc/ada/gcc-interface/gigi.h | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index b75cc35..65f871b 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -959,16 +959,16 @@ extern tree gnat_protect_expr (tree exp); /* This is equivalent to stabilize_reference in tree.c but we know how to handle our own nodes and we take extra arguments. FORCE says whether to - force evaluation of everything. */ -extern tree gnat_stabilize_reference (tree ref, bool force); + force evaluation of everything in REF. INIT is set to the first arm of + a COMPOUND_EXPR present in REF, if any. */ +extern tree gnat_stabilize_reference (tree ref, bool force, tree *init); /* Rewrite reference REF and call FUNC on each expression within REF in the - process. DATA is passed unmodified to FUNC and N is bumped each time it - is passed to FUNC, so FUNC is guaranteed to see a given N only once per - reference to be rewritten. */ -typedef tree (*rewrite_fn) (tree, void *, int); + process. DATA is passed unmodified to FUNC. INIT is set to the first + arm of a COMPOUND_EXPR present in REF, if any. */ +typedef tree (*rewrite_fn) (tree, void *); extern tree gnat_rewrite_reference (tree ref, rewrite_fn func, void *data, - int n = 1); + tree *init); /* This is equivalent to get_inner_reference in expr.c but it returns the ultimate containing object only if the reference (lvalue) is constant, @@ -1085,3 +1085,30 @@ call_is_atomic_load (tree exp) enum built_in_function code = DECL_FUNCTION_CODE (fndecl); return BUILT_IN_ATOMIC_LOAD_N <= code && code <= BUILT_IN_ATOMIC_LOAD_16; } + +/* Return true if TYPE is padding a self-referential type. */ + +static inline bool +type_is_padding_self_referential (tree type) +{ + if (!TYPE_IS_PADDING_P (type)) + return false; + + return CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type))); +} + +/* Return true if a function returning TYPE doesn't return a fixed size. */ + +static inline bool +return_type_with_variable_size_p (tree type) +{ + if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + return true; + + /* Return true for an unconstrained type with default discriminant, see + the E_Subprogram_Type case of gnat_to_gnu_entity. */ + if (type_is_padding_self_referential (type)) + return true; + + return false; +} |