summaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-13 08:22:03 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-13 08:22:03 +0000
commitcc9b8628228057b9b0ab5417b7d8deea36754e44 (patch)
tree9ce1ffbe5f574651dfe2baa17807ad50e4394b8d /gcc/function.c
parent0336f0f0a448f834556a8efb0cf4161c2e2a38d2 (diff)
downloadgcc-cc9b8628228057b9b0ab5417b7d8deea36754e44.tar.gz
* function.c (pass_by_reference): New.
(assign_parm_find_data_types): Use it. * calls.c (initialize_argument_information): Likewise. (emit_library_call_value_1): Likewise. * expr.h (FUNCTION_ARG_PASS_BY_REFERENCE): Remove. * function.h (pass_by_reference): Declare. ada/ * misc.c (default_pass_by_ref): Use pass_by_reference. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84607 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 19698f99214..08b2e439bbc 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2026,6 +2026,33 @@ use_register_for_decl (tree decl)
return (optimize || DECL_REGISTER (decl));
}
+/* Return true if TYPE should be passed by invisible reference. */
+
+bool
+pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, bool named_arg ATTRIBUTE_UNUSED)
+{
+ if (type)
+ {
+ /* If this type contains non-trivial constructors, then it is
+ forbidden for the middle-end to create any new copies. */
+ if (TREE_ADDRESSABLE (type))
+ return true;
+
+ /* If an object's size is dependent on itself, there's no way
+ to *not* pass by reference. */
+ if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type)))
+ return true;
+ }
+
+#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
+ return FUNCTION_ARG_PASS_BY_REFERENCE (*ca, mode, type, named_arg);
+#else
+ return false;
+#endif
+}
+
/* Structures to communicate between the subroutines of assign_parms.
The first holds data persistent across all parameters, the second
is cleared out for each parameter. */
@@ -2236,14 +2263,9 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
&& TYPE_TRANSPARENT_UNION (passed_type)))
passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
- /* See if this arg was passed by invisible reference. It is if it is an
- object whose size depends on the contents of the object itself or if
- the machine requires these objects be passed that way. */
- if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (passed_type))
- || TREE_ADDRESSABLE (passed_type)
- || FUNCTION_ARG_PASS_BY_REFERENCE (all->args_so_far, passed_mode,
- passed_type, data->named_arg)
- )
+ /* See if this arg was passed by invisible reference. */
+ if (pass_by_reference (&all->args_so_far, passed_mode,
+ passed_type, data->named_arg))
{
passed_type = nominal_type = build_pointer_type (passed_type);
data->passed_pointer = true;