* PATCH Re: Simplifying TARGET_EXPR
[not found] ` <20020720135854.C16252@redhat.com>
@ 2002-07-26 4:03 ` Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2002-07-26 4:03 UTC (permalink / raw)
To: Richard Henderson; +Cc: Mark Mitchell, gcc, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]
>>>>> "Richard" == Richard Henderson <rth@redhat.com> writes:
> Given that the front end has to know about the semantics of copying
> objects and how that affects parameter passing anyway, perhaps the
> front end should modify the type of the parameter at the same time.
> Perhaps a REFERENCE_TYPE with DECL_ARTIFICIAL set? Then an ADDR_EXPR
> would match up nicely.
It occurred to me that we already have DECL_ARG_TYPE for handling this sort
of thing. This patch sets DECL_ARG_TYPE to a REFERENCE_TYPE if we want to
pass by invisible reference for frontend-specific reasons. These semantics
are handled by three new functions in cp/call.c; the rest of the patch is
telling other bits of code to use them.
Tested i686-pc-linux-gnu. I'll check this in soon if nobody complains.
2002-07-25 Jason Merrill <jason@redhat.com>
* function.c (assign_parms): Handle frontend-directed pass by
invisible reference.
cp/
* call.c (build_over_call): Likewise.
(cp_convert_parm_for_inlining): New fn.
(convert_for_arg_passing): New fn.
(convert_default_arg, build_over_call): Use it.
(type_passed_as): New fn.
* pt.c (tsubst_decl): Use it.
* decl2.c (cp_build_parm_decl): New fn.
(build_artificial_parm): Use it.
(start_static_storage_duration_function): Likewise.
* decl.c (start_cleanup_fn, grokdeclarater): Likewise.
(grokparms): Don't mess with DECL_ARG_TYPE.
* typeck.c (convert_arguments): Use convert_for_arg_passing.
* cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
Define.
* cp-tree.h: Declare new fns.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 12744 bytes --]
*** ./cp/pt.c.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/pt.c Wed Jul 24 12:35:50 2002
*************** tsubst_decl (t, args, type, complain)
*** 6023,6032 ****
complain, in_decl);
DECL_CONTEXT (r) = NULL_TREE;
! if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES
! && INTEGRAL_TYPE_P (type)
! && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
! DECL_ARG_TYPE (r) = integer_type_node;
if (TREE_CHAIN (t))
TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
complain, TREE_CHAIN (t));
--- 6023,6031 ----
complain, in_decl);
DECL_CONTEXT (r) = NULL_TREE;
!
! if (!DECL_TEMPLATE_PARM_P (r))
! DECL_ARG_TYPE (r) = type_passed_as (type);
if (TREE_CHAIN (t))
TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
complain, TREE_CHAIN (t));
*** ./cp/call.c.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/call.c Wed Jul 24 17:10:12 2002
*************** convert_default_arg (type, arg, fn, parm
*** 4128,4142 ****
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
"default argument", fn, parmnum);
! if (PROMOTE_PROTOTYPES
! && INTEGRAL_TYPE_P (type)
! && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
! arg = default_conversion (arg);
}
return arg;
}
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
--- 4128,4191 ----
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
"default argument", fn, parmnum);
! arg = convert_for_arg_passing (type, arg);
}
return arg;
}
+ /* Returns the type which will really be used for passing an argument of
+ type TYPE. */
+
+ tree
+ type_passed_as (type)
+ tree type;
+ {
+ /* Pass classes with copy ctors by invisible reference. */
+ if (TREE_ADDRESSABLE (type))
+ type = build_reference_type (type);
+ else if (PROMOTE_PROTOTYPES
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ type = integer_type_node;
+
+ return type;
+ }
+
+ /* Actually perform the appropriate conversion. */
+
+ tree
+ convert_for_arg_passing (type, val)
+ tree type, val;
+ {
+ /* Pass classes with copy ctors by invisible reference. */
+ if (TREE_ADDRESSABLE (type))
+ val = build1 (ADDR_EXPR, build_reference_type (type), val);
+ else if (PROMOTE_PROTOTYPES
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ val = default_conversion (val);
+ return val;
+ }
+
+ /* Convert VALUE for assignment into inlined parameter PARM. */
+
+ tree
+ cp_convert_parm_for_inlining (parm, value, fn)
+ tree parm, value;
+ tree fn ATTRIBUTE_UNUSED;
+ {
+ /* When inlining, we don't need to mess with invisible references, so
+ undo the ADDR_EXPR. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (parm)))
+ {
+ if (TREE_TYPE (value) != build_reference_type (TREE_TYPE (parm)))
+ abort ();
+ value = build_indirect_ref (value, NULL);
+ }
+ return value;
+ }
+
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
*************** build_over_call (cand, args, flags)
*** 4222,4231 ****
val = convert_like_with_context
(conv, TREE_VALUE (arg), fn, i - is_method);
! if (PROMOTE_PROTOTYPES
! && INTEGRAL_TYPE_P (type)
! && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
! val = default_conversion (val);
converted_args = tree_cons (NULL_TREE, val, converted_args);
}
--- 4271,4277 ----
val = convert_like_with_context
(conv, TREE_VALUE (arg), fn, i - is_method);
! val = convert_for_arg_passing (type, val);
converted_args = tree_cons (NULL_TREE, val, converted_args);
}
*** ./cp/decl.c.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/decl.c Wed Jul 24 12:35:46 2002
*************** start_cleanup_fn ()
*** 8518,8526 ****
{
tree parmdecl;
! parmdecl = build_decl (PARM_DECL, NULL_TREE, ptr_type_node);
DECL_CONTEXT (parmdecl) = fndecl;
- DECL_ARG_TYPE (parmdecl) = ptr_type_node;
TREE_USED (parmdecl) = 1;
DECL_ARGUMENTS (fndecl) = parmdecl;
}
--- 8518,8525 ----
{
tree parmdecl;
! parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
DECL_CONTEXT (parmdecl) = fndecl;
TREE_USED (parmdecl) = 1;
DECL_ARGUMENTS (fndecl) = parmdecl;
}
*************** grokdeclarator (declarator, declspecs, d
*** 11366,11372 ****
for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
{
! tree decl = build_decl (PARM_DECL, NULL_TREE, TREE_VALUE (args));
TREE_CHAIN (decl) = decls;
decls = decl;
--- 11365,11371 ----
for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
{
! tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args));
TREE_CHAIN (decl) = decls;
decls = decl;
*************** friend declaration requires class-key, i
*** 11510,11526 ****
if (decl_context == PARM)
{
! decl = build_decl (PARM_DECL, declarator, type);
bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE);
-
- /* Compute the type actually passed in the parmlist,
- for the case where there is no prototype.
- (For example, shorts and chars are passed as ints.)
- When there is a prototype, this is overridden later. */
-
- DECL_ARG_TYPE (decl) = type_promotes_to (type);
}
else if (decl_context == FIELD)
{
--- 11509,11518 ----
if (decl_context == PARM)
{
! decl = cp_build_parm_decl (declarator, type);
bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
inlinep, friendp, raises != NULL_TREE);
}
else if (decl_context == FIELD)
{
*************** grokparms (first_parm)
*** 12206,12216 ****
decl, ptr ? "pointer" : "reference", t);
}
- DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
- if (PROMOTE_PROTOTYPES
- && INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
- DECL_ARG_TYPE (decl) = integer_type_node;
if (!any_error && init)
init = check_default_argument (decl, init);
else
--- 12198,12203 ----
*** ./cp/cp-lang.c.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/cp-lang.c Tue Jul 23 17:53:41 2002
*************** static bool cxx_warn_unused_global_decl
*** 120,125 ****
--- 120,128 ----
#undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \
cp_copy_res_decl_for_inlining
+ #undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
+ #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
+ cp_convert_parm_for_inlining
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
#undef LANG_HOOKS_TREE_INLINING_START_INLINING
*** ./cp/cp-tree.h.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/cp-tree.h Wed Jul 24 17:09:43 2002
*************** extern tree convert_default_arg
*** 3683,3688 ****
--- 3683,3691 ----
extern tree convert_arg_to_ellipsis PARAMS ((tree));
extern tree build_x_va_arg PARAMS ((tree, tree));
extern tree cxx_type_promotes_to PARAMS ((tree));
+ extern tree type_passed_as PARAMS ((tree));
+ extern tree convert_for_arg_passing PARAMS ((tree, tree));
+ extern tree cp_convert_parm_for_inlining PARAMS ((tree, tree, tree));
extern int is_properly_derived_from PARAMS ((tree, tree));
extern tree initialize_reference PARAMS ((tree, tree));
extern tree strip_top_quals PARAMS ((tree));
*************** extern void mark_used PARAMS ((tree))
*** 3962,3967 ****
--- 3965,3971 ----
extern tree handle_class_head (enum tag_types, tree, tree, tree, int, int *);
extern tree lookup_arg_dependent PARAMS ((tree, tree, tree));
extern void finish_static_data_member_decl PARAMS ((tree, tree, tree, int));
+ extern tree cp_build_parm_decl PARAMS ((tree, tree));
extern tree build_artificial_parm PARAMS ((tree, tree));
extern tree get_guard PARAMS ((tree));
extern tree get_guard_cond PARAMS ((tree));
*** ./cp/decl2.c.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/decl2.c Wed Jul 24 12:35:47 2002
*************** grok_x_components (specs)
*** 808,813 ****
--- 808,826 ----
finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t));
}
+ /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
+ appropriately. */
+
+ tree
+ cp_build_parm_decl (name, type)
+ tree name;
+ tree type;
+ {
+ tree parm = build_decl (PARM_DECL, name, type);
+ DECL_ARG_TYPE (parm) = type_passed_as (type);
+ return parm;
+ }
+
/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
indicated NAME. */
*************** build_artificial_parm (name, type)
*** 816,829 ****
tree name;
tree type;
{
! tree parm;
!
! parm = build_decl (PARM_DECL, name, type);
DECL_ARTIFICIAL (parm) = 1;
/* All our artificial parms are implicitly `const'; they cannot be
assigned to. */
TREE_READONLY (parm) = 1;
- DECL_ARG_TYPE (parm) = type;
return parm;
}
--- 829,839 ----
tree name;
tree type;
{
! tree parm = cp_build_parm_decl (name, type);
DECL_ARTIFICIAL (parm) = 1;
/* All our artificial parms are implicitly `const'; they cannot be
assigned to. */
TREE_READONLY (parm) = 1;
return parm;
}
*************** start_static_storage_duration_function (
*** 2866,2881 ****
VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl);
/* Create the argument list. */
! initialize_p_decl = build_decl (PARM_DECL,
! get_identifier (INITIALIZE_P_IDENTIFIER),
! integer_type_node);
DECL_CONTEXT (initialize_p_decl) = ssdf_decl;
- DECL_ARG_TYPE (initialize_p_decl) = integer_type_node;
TREE_USED (initialize_p_decl) = 1;
! priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER),
! integer_type_node);
DECL_CONTEXT (priority_decl) = ssdf_decl;
- DECL_ARG_TYPE (priority_decl) = integer_type_node;
TREE_USED (priority_decl) = 1;
TREE_CHAIN (initialize_p_decl) = priority_decl;
--- 2876,2888 ----
VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl);
/* Create the argument list. */
! initialize_p_decl = cp_build_parm_decl
! (get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node);
DECL_CONTEXT (initialize_p_decl) = ssdf_decl;
TREE_USED (initialize_p_decl) = 1;
! priority_decl = cp_build_parm_decl
! (get_identifier (PRIORITY_IDENTIFIER), integer_type_node);
DECL_CONTEXT (priority_decl) = ssdf_decl;
TREE_USED (priority_decl) = 1;
TREE_CHAIN (initialize_p_decl) = priority_decl;
*** ./cp/typeck.c.~1~ Wed Jul 24 12:40:22 2002
--- ./cp/typeck.c Wed Jul 24 17:04:54 2002
*************** convert_arguments (typelist, values, fnd
*** 3145,3155 ****
parmval = convert_for_initialization
(NULL_TREE, type, val, flags,
"argument passing", fndecl, i);
! if (PROMOTE_PROTOTYPES
! && INTEGRAL_TYPE_P (type)
! && (TYPE_PRECISION (type)
! < TYPE_PRECISION (integer_type_node)))
! parmval = default_conversion (parmval);
}
if (parmval == error_mark_node)
--- 3145,3151 ----
parmval = convert_for_initialization
(NULL_TREE, type, val, flags,
"argument passing", fndecl, i);
! parmval = convert_for_arg_passing (type, parmval);
}
if (parmval == error_mark_node)
*** ./function.c.~1~ Wed Jul 24 12:40:22 2002
--- ./function.c Wed Jul 24 12:35:18 2002
*************** assign_parms (fndecl)
*** 4425,4430 ****
--- 4425,4439 ----
passed_pointer = 1;
passed_mode = nominal_mode = Pmode;
}
+ /* See if the frontend wants to pass this by invisible reference. */
+ else if (passed_type != nominal_type
+ && POINTER_TYPE_P (passed_type)
+ && TREE_TYPE (passed_type) == nominal_type)
+ {
+ nominal_type = passed_type;
+ passed_pointer = 1;
+ passed_mode = nominal_mode = Pmode;
+ }
promoted_mode = passed_mode;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-07-26 10:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <wvly9c6ido9.fsf@prospero.cambridge.redhat.com>
[not found] ` <20020720135854.C16252@redhat.com>
2002-07-26 4:03 ` PATCH Re: Simplifying TARGET_EXPR Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).