diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-13 08:22:03 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-13 08:22:03 +0000 |
commit | cc9b8628228057b9b0ab5417b7d8deea36754e44 (patch) | |
tree | 9ce1ffbe5f574651dfe2baa17807ad50e4394b8d /gcc/function.c | |
parent | 0336f0f0a448f834556a8efb0cf4161c2e2a38d2 (diff) | |
download | gcc-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.c | 38 |
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; |