mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-24 12:51:15 +08:00
function.c (assign_parms): Handle frontend-directed pass by invisible reference.
* 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. From-SVN: r55781
This commit is contained in:
parent
8a7f132d3d
commit
8e51619a4c
@ -1,3 +1,8 @@
|
||||
2002-07-26 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* function.c (assign_parms): Handle frontend-directed pass by
|
||||
invisible reference.
|
||||
|
||||
2002-07-26 Neil Booth <neil@daikokuya.co.uk>
|
||||
|
||||
* doc/cppopts.texi: Update.
|
||||
|
@ -1,3 +1,21 @@
|
||||
2002-07-26 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2002-07-26 Neil Booth <neil@daikokuya.co.uk>
|
||||
|
||||
* cp-tree.h (flag_operator_names): Remove.
|
||||
|
@ -4128,15 +4128,60 @@ convert_default_arg (type, arg, fn, parmnum)
|
||||
|
||||
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);
|
||||
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)))
|
||||
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
|
||||
@ -4222,10 +4267,7 @@ build_over_call (cand, args, flags)
|
||||
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);
|
||||
val = convert_for_arg_passing (type, val);
|
||||
converted_args = tree_cons (NULL_TREE, val, converted_args);
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,9 @@ static bool cxx_warn_unused_global_decl PARAMS ((tree));
|
||||
#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
|
||||
|
@ -3679,6 +3679,9 @@ extern tree convert_default_arg PARAMS ((tree, tree, tree, int))
|
||||
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));
|
||||
@ -3958,6 +3961,7 @@ extern void mark_used PARAMS ((tree));
|
||||
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));
|
||||
|
@ -8518,9 +8518,8 @@ start_cleanup_fn ()
|
||||
{
|
||||
tree parmdecl;
|
||||
|
||||
parmdecl = build_decl (PARM_DECL, NULL_TREE, ptr_type_node);
|
||||
parmdecl = cp_build_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;
|
||||
}
|
||||
@ -11366,7 +11365,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
|
||||
for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
|
||||
{
|
||||
tree decl = build_decl (PARM_DECL, NULL_TREE, TREE_VALUE (args));
|
||||
tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args));
|
||||
|
||||
TREE_CHAIN (decl) = decls;
|
||||
decls = decl;
|
||||
@ -11510,17 +11509,10 @@ friend declaration requires class-key, i.e. `friend %#T'",
|
||||
|
||||
if (decl_context == PARM)
|
||||
{
|
||||
decl = build_decl (PARM_DECL, declarator, type);
|
||||
decl = cp_build_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)
|
||||
{
|
||||
@ -12206,11 +12198,6 @@ grokparms (first_parm)
|
||||
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
|
||||
|
@ -795,6 +795,19 @@ grok_x_components (specs)
|
||||
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. */
|
||||
|
||||
@ -803,14 +816,11 @@ build_artificial_parm (name, type)
|
||||
tree name;
|
||||
tree type;
|
||||
{
|
||||
tree parm;
|
||||
|
||||
parm = build_decl (PARM_DECL, name, 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;
|
||||
DECL_ARG_TYPE (parm) = type;
|
||||
return parm;
|
||||
}
|
||||
|
||||
@ -2853,16 +2863,13 @@ start_static_storage_duration_function ()
|
||||
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);
|
||||
initialize_p_decl = cp_build_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);
|
||||
priority_decl = cp_build_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;
|
||||
|
@ -2494,7 +2494,9 @@ build_new_1 (exp)
|
||||
constructor, that would fix the nesting problem and we could
|
||||
do away with this complexity. But that would complicate other
|
||||
things; in particular, it would make it difficult to bail out
|
||||
if the allocation function returns null. */
|
||||
if the allocation function returns null. Er, no, it wouldn't;
|
||||
we just don't run the constructor. The standard says it's
|
||||
unspecified whether or not the args are evaluated. */
|
||||
|
||||
if (cleanup)
|
||||
{
|
||||
|
@ -6012,7 +6012,7 @@ tsubst_decl (t, args, type, complain)
|
||||
r = copy_node (t);
|
||||
if (DECL_TEMPLATE_PARM_P (t))
|
||||
SET_DECL_TEMPLATE_PARM_P (r);
|
||||
|
||||
|
||||
TREE_TYPE (r) = type;
|
||||
c_apply_type_quals_to_decl (cp_type_quals (type), r);
|
||||
|
||||
@ -6023,10 +6023,9 @@ tsubst_decl (t, args, type, complain)
|
||||
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 (!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));
|
||||
|
@ -3112,11 +3112,7 @@ convert_arguments (typelist, values, fndecl, flags)
|
||||
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);
|
||||
parmval = convert_for_arg_passing (type, parmval);
|
||||
}
|
||||
|
||||
if (parmval == error_mark_node)
|
||||
|
@ -4425,6 +4425,15 @@ assign_parms (fndecl)
|
||||
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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user