aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/gigi.h
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2015-05-28 15:24:12 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2015-05-28 15:24:12 +0000
commitfc7a823e1507110aba804cf94415155a8783e698 (patch)
treefb09192367caa4ff2977684a039b071404d51421 /gcc/ada/gcc-interface/gigi.h
parent318a4e6de8f20670c9f9e9dde02dc639f161f68c (diff)
downloadgcc-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.h41
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;
+}